Skip to content
This repository has been archived by the owner on Mar 6, 2024. It is now read-only.

Commit

Permalink
feat: viewport and camera parallax tweaks (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
erickzanardo authored Oct 20, 2023
1 parent 7772c7e commit c95495d
Show file tree
Hide file tree
Showing 7 changed files with 1,025 additions and 876 deletions.
1,678 changes: 839 additions & 839 deletions assets/map/flutter_runnergame_map_v04.tmx

Large diffs are not rendered by default.

87 changes: 87 additions & 0 deletions lib/game/components/camera_debugger.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import 'dart:async';

import 'package:flame/components.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class CameraDebugger extends RectangleComponent {
CameraDebugger({
super.position,
}) : super(
paint: Paint()..color = Colors.pink,
size: Vector2.all(150),
priority: 100,
);

final _direction = Vector2.zero();
double _speed = 300;

@override
void update(double dt) {
super.update(dt);

position += _direction * _speed * dt;
}

@override
FutureOr<void> onLoad() async {
await super.onLoad();

add(
KeyboardListenerComponent(
keyDown: {
LogicalKeyboardKey.keyW: (_) {
_direction.y = -1;
return false;
},
LogicalKeyboardKey.keyS: (_) {
_direction.y = 1;
return false;
},
LogicalKeyboardKey.keyA: (_) {
_direction.x = -1;
return false;
},
LogicalKeyboardKey.keyD: (_) {
_direction.x = 1;
return false;
},
LogicalKeyboardKey.space: (_) {
_speed = 900;
return false;
},
},
keyUp: {
LogicalKeyboardKey.keyW: (_) {
if (_direction.y == -1) {
_direction.y = 0;
}
return false;
},
LogicalKeyboardKey.keyS: (_) {
if (_direction.y == 1) {
_direction.y = 0;
}
return false;
},
LogicalKeyboardKey.keyA: (_) {
if (_direction.x == -1) {
_direction.x = 0;
}
return false;
},
LogicalKeyboardKey.keyD: (_) {
if (_direction.x == 1) {
_direction.x = 0;
}
return false;
},
LogicalKeyboardKey.space: (_) {
_speed = 300;
return false;
},
},
),
);
}
}
1 change: 1 addition & 0 deletions lib/game/components/components.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export 'camera_debugger.dart';
export 'enemies.dart';
export 'items.dart';
export 'player.dart';
Expand Down
51 changes: 43 additions & 8 deletions lib/game/components/player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,70 @@ import 'package:flutter/material.dart';
import 'package:leap/leap.dart';

class PlayerCameraAnchor extends Component
with ParentIsA<Player>
with ParentIsA<PositionComponent>
implements ReadOnlyPositionProvider {
late final Vector2 _anchor;
PlayerCameraAnchor({
required this.cameraViewport,
required this.levelSize,
});

final Vector2 _anchor = Vector2.zero();

final Vector2 cameraViewport;
final Vector2 levelSize;

late final Vector2 _cameraMin = Vector2(
cameraViewport.x / 2,
cameraViewport.y / 2,
);

late final Vector2 _cameraMax = Vector2(
levelSize.x - cameraViewport.x / 2,
levelSize.y - cameraViewport.y / 2,
);

@override
Vector2 get position => _anchor;

void _setAnchor(double x, double y) {
_anchor
..x = x.clamp(_cameraMin.x, _cameraMax.x)
..y = y.clamp(_cameraMin.y, _cameraMax.y);
}

@override
FutureOr<void> onLoad() async {
await super.onLoad();

_anchor = parent.position.clone();
final value = parent.position.clone();
_setAnchor(value.x, value.y);
}

@override
void update(double dt) {
super.update(dt);

_anchor
..x = parent.position.x
..y = parent.position.y - 200;
_setAnchor(
parent.position.x,
parent.position.y,
);
}
}

class Player extends JumperCharacter<DashRunGame> {
Player({super.health = initialHealth});
Player({
required this.cameraViewport,
required this.levelSize,
super.health = initialHealth,
});

static const initialHealth = 3;

late final Vector2 spawn;
late final SimpleCombinedInput input;
late final PlayerCameraAnchor cameraAnchor;
final Vector2 cameraViewport;
final Vector2 levelSize;

final List<Item> items = [];

Expand All @@ -54,7 +86,10 @@ class Player extends JumperCharacter<DashRunGame> {
size = Vector2.all(gameRef.tileSize);
walkSpeed = gameRef.tileSize * 5;
minJumpImpulse = world.gravity * 0.7;
cameraAnchor = PlayerCameraAnchor();
cameraAnchor = PlayerCameraAnchor(
cameraViewport: cameraViewport,
levelSize: levelSize,
);

add(cameraAnchor);
add(PlayerCollidingBehavior());
Expand Down
68 changes: 41 additions & 27 deletions lib/game/dash_run_game.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,12 @@ import 'package:flame/flame.dart';
import 'package:flutter/material.dart';
import 'package:leap/leap.dart';

abstract class FixedResolutionGame extends LeapGame {
FixedResolutionGame({
required super.tileSize,
required this.resolution,
});

final Vector2 resolution;

@mustCallSuper
@override
FutureOr<void> onLoad() async {
await super.onLoad();

await Flame.device.fullScreen();
await Flame.device.setLandscape();

camera = CameraComponent.withFixedResolution(
width: resolution.x,
height: resolution.y,
);
}
}

class DashRunGame extends FixedResolutionGame
class DashRunGame extends LeapGame
with TapCallbacks, HasKeyboardHandlerComponents, HasCollisionDetection {
DashRunGame({
this.customBundle,
}) : super(
tileSize: 64,
resolution: Vector2(2000, 1000),
);

static const prefix = 'assets/map/';
Expand All @@ -49,12 +25,22 @@ class DashRunGame extends FixedResolutionGame

final AssetBundle? customBundle;

static final _cameraViewport = Vector2(592, 1280);

int score = 0;

@override
Future<void> onLoad() async {
await super.onLoad();

await Flame.device.fullScreen();
await Flame.device.setLandscape();

camera = CameraComponent.withFixedResolution(
width: _cameraViewport.x,
height: _cameraViewport.y,
);

images = Images(
prefix: prefix,
bundle: customBundle,
Expand All @@ -74,7 +60,10 @@ class DashRunGame extends FixedResolutionGame

await addAll([items, enemies, input]);

player = Player();
player = Player(
levelSize: leapMap.tiledMap.size.clone(),
cameraViewport: _cameraViewport,
);
world.add(player);
}

Expand All @@ -84,7 +73,32 @@ class DashRunGame extends FixedResolutionGame

Future<void>.delayed(
const Duration(seconds: 1),
() => world.add(Player()),
() => world.add(
Player(
levelSize: leapMap.tiledMap.size.clone(),
cameraViewport: _cameraViewport,
),
),
);
}

void addCameraDebugger() {
if (descendants().whereType<CameraDebugger>().isEmpty) {
final player = world.firstChild<Player>()!;

final cameraDebugger = CameraDebugger(
position: player.position.clone(),
);
world.add(cameraDebugger);

final anchor = PlayerCameraAnchor(
levelSize: leapMap.tiledMap.size.clone(),
cameraViewport: _cameraViewport,
);
cameraDebugger.add(anchor);
camera.follow(anchor);

player.removeFromParent();
}
}
}
9 changes: 7 additions & 2 deletions lib/game/view/game_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ class GameView extends StatelessWidget {

@override
Widget build(BuildContext context) {
return const GameWidget.controlled(
gameFactory: DashRunGame.new,
return const DecoratedBox(
decoration: BoxDecoration(
color: Colors.blueAccent,
),
child: GameWidget.controlled(
gameFactory: DashRunGame.new,
),
);
}
}
7 changes: 7 additions & 0 deletions lib/map_tester/view/map_tester_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ class _MapTesterViewState extends State<MapTesterView> {
},
child: const Text('Reload'),
),
const SizedBox(width: 16),
ElevatedButton(
onPressed: () {
game?.addCameraDebugger();
},
child: const Text('Seize camera control'),
),
],
),
const SizedBox(height: 16),
Expand Down

0 comments on commit c95495d

Please sign in to comment.