From a111fd417edbae19f3a60605e66e831ab511fd25 Mon Sep 17 00:00:00 2001 From: Erick Date: Tue, 22 Mar 2022 13:54:06 -0300 Subject: [PATCH] feat: fixed positioning (#70) * feat: game uses fixed positioning now * feat: fixed positioning * feat: pr suggestion * lint --- lib/game/components/board.dart | 12 ++--- lib/game/components/jetpack_ramp.dart | 39 ++++++++------ lib/game/components/launcher_ramp.dart | 25 ++++----- lib/game/components/pathway.dart | 5 +- lib/game/components/spaceship.dart | 5 +- lib/game/components/wall.dart | 18 +++---- lib/game/pinball_game.dart | 70 +++++++++++++------------- test/game/components/board_test.dart | 12 ++--- 8 files changed, 98 insertions(+), 88 deletions(-) diff --git a/lib/game/components/board.dart b/lib/game/components/board.dart index 9c34a263..5bd4d92b 100644 --- a/lib/game/components/board.dart +++ b/lib/game/components/board.dart @@ -7,25 +7,23 @@ import 'package:pinball/game/game.dart'; /// {entemplate} class Board extends Component { /// {@macro board} - Board({required Vector2 size}) : _size = size; - - final Vector2 _size; + Board(); @override Future onLoad() async { // TODO(alestiago): adjust positioning once sprites are added. final bottomGroup = _BottomGroup( position: Vector2( - _size.x / 2, - _size.y / 1.25, + PinballGame.boardBounds.center.dx, + PinballGame.boardBounds.bottom + 10, ), spacing: 2, ); final dashForest = _FlutterForest( position: Vector2( - _size.x / 1.25, - _size.y / 4.25, + PinballGame.boardBounds.right - 20, + PinballGame.boardBounds.top - 20, ), ); diff --git a/lib/game/components/jetpack_ramp.dart b/lib/game/components/jetpack_ramp.dart index 985c8f7d..aa5a2d3d 100644 --- a/lib/game/components/jetpack_ramp.dart +++ b/lib/game/components/jetpack_ramp.dart @@ -30,18 +30,23 @@ class JetpackRamp extends Component with HasGameRef { // TODO(ruialonso): Use a bezier curve once control points are defined. color: const Color.fromARGB(255, 8, 218, 241), center: position, - width: 62, - radius: 200, + width: 5, + radius: 18, angle: math.pi, + rotation: math.pi, + )..layer = layer; + + final leftOpening = _JetpackRampOpening( + outsideLayer: Layer.spaceship, + rotation: math.pi, ) - ..initialPosition = position - ..layer = layer; - final leftOpening = _JetpackRampOpening(outsideLayer: Layer.spaceship) - ..initialPosition = position + Vector2(-27.6, 25.3) + ..initialPosition = position - Vector2(2, 22) ..layer = Layer.jetpack; - final rightOpening = _JetpackRampOpening() - ..initialPosition = position + Vector2(-10.6, 25.3) + final rightOpening = _JetpackRampOpening( + rotation: math.pi, + ) + ..initialPosition = position - Vector2(-13, 22) ..layer = Layer.opening; await addAll([ @@ -60,20 +65,26 @@ class _JetpackRampOpening extends RampOpening { /// {@macro jetpack_ramp_opening} _JetpackRampOpening({ Layer? outsideLayer, - }) : super( + required double rotation, + }) : _rotation = rotation, + super( pathwayLayer: Layer.jetpack, outsideLayer: outsideLayer, orientation: RampOrientation.down, ); - // TODO(ruialonso): Avoid magic number 2, should be proportional to + final double _rotation; + + // TODO(ruialonso): Avoid magic number 3, should be propotional to // [JetpackRamp]. - static const _size = 2; + static final Vector2 _size = Vector2(3, .1); @override Shape get shape => PolygonShape() - ..setAsEdge( - Vector2(initialPosition.x - _size, initialPosition.y), - Vector2(initialPosition.x + _size, initialPosition.y), + ..setAsBox( + _size.x, + _size.y, + initialPosition, + _rotation, ); } diff --git a/lib/game/components/launcher_ramp.dart b/lib/game/components/launcher_ramp.dart index 21d4d666..5fdabcdb 100644 --- a/lib/game/components/launcher_ramp.dart +++ b/lib/game/components/launcher_ramp.dart @@ -28,26 +28,27 @@ class LauncherRamp extends Component with HasGameRef { final straightPath = Pathway.straight( color: const Color.fromARGB(255, 34, 255, 0), - start: Vector2(0, 0), - end: Vector2(0, 700), - width: 80, + start: Vector2(position.x, position.y), + end: Vector2(position.x, 74), + width: 5, ) ..initialPosition = position ..layer = layer; + final curvedPath = Pathway.arc( color: const Color.fromARGB(255, 251, 255, 0), - center: position + Vector2(-29, -8), - radius: 300, - angle: 10 * math.pi / 9, - width: 80, - ) - ..initialPosition = position + Vector2(-28.8, -6) - ..layer = layer; + center: position + Vector2(-1, 68), + radius: 20, + angle: 8 * math.pi / 9, + width: 5, + rotation: math.pi, + )..layer = layer; + final leftOpening = _LauncherRampOpening(rotation: 13 * math.pi / 180) - ..initialPosition = position + Vector2(-72.5, 12) + ..initialPosition = position + Vector2(1, 49) ..layer = Layer.opening; final rightOpening = _LauncherRampOpening(rotation: 0) - ..initialPosition = position + Vector2(-46.8, 17) + ..initialPosition = position + Vector2(-16, 46) ..layer = Layer.opening; await addAll([ diff --git a/lib/game/components/pathway.dart b/lib/game/components/pathway.dart index 414442d3..0c29dd7b 100644 --- a/lib/game/components/pathway.dart +++ b/lib/game/components/pathway.dart @@ -150,10 +150,7 @@ class Pathway extends BodyComponent with InitialPosition, Layered { final fixturesDef = []; for (final path in _paths) { - final chain = ChainShape() - ..createChain( - path.map(gameRef.screenToWorld).toList(), - ); + final chain = ChainShape()..createChain(path); fixturesDef.add(FixtureDef(chain)); } diff --git a/lib/game/components/spaceship.dart b/lib/game/components/spaceship.dart index f934d943..d933a79f 100644 --- a/lib/game/components/spaceship.dart +++ b/lib/game/components/spaceship.dart @@ -15,7 +15,10 @@ class Spaceship extends Forge2DBlueprint { @override void build() { - final position = Vector2(30, -50); + final position = Vector2( + PinballGame.boardBounds.left + radius + 0.5, + PinballGame.boardBounds.center.dy + 34, + ); addAllContactCallback([ SpaceshipHoleBallContactCallback(), diff --git a/lib/game/components/wall.dart b/lib/game/components/wall.dart index 017f8c4d..62f9033f 100644 --- a/lib/game/components/wall.dart +++ b/lib/game/components/wall.dart @@ -1,7 +1,9 @@ // ignore_for_file: avoid_renaming_method_parameters +import 'package:flame/extensions.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:pinball/game/components/components.dart'; +import 'package:pinball/game/pinball_game.dart'; /// {@template wall} /// A continuous generic and [BodyType.static] barrier that divides a game area. @@ -39,15 +41,16 @@ class Wall extends BodyComponent { /// Create top, left, and right [Wall]s for the game board. List createBoundaries(Forge2DGame game) { - final topLeft = Vector2.zero(); - final bottomRight = game.screenToWorld(game.camera.viewport.effectiveSize); + final topLeft = PinballGame.boardBounds.topLeft.toVector2(); + final bottomRight = PinballGame.boardBounds.bottomRight.toVector2(); + final topRight = Vector2(bottomRight.x, topLeft.y); final bottomLeft = Vector2(topLeft.x, bottomRight.y); return [ Wall(start: topLeft, end: topRight), Wall(start: topRight, end: bottomRight), - Wall(start: bottomLeft, end: topLeft), + Wall(start: topLeft, end: bottomLeft), ]; } @@ -59,13 +62,10 @@ List createBoundaries(Forge2DGame game) { /// {@endtemplate} class BottomWall extends Wall { /// {@macro bottom_wall} - BottomWall(Forge2DGame game) + BottomWall() : super( - start: game.screenToWorld(game.camera.viewport.effectiveSize), - end: Vector2( - 0, - game.screenToWorld(game.camera.viewport.effectiveSize).y, - ), + start: PinballGame.boardBounds.bottomLeft.toVector2(), + end: PinballGame.boardBounds.bottomRight.toVector2(), ); } diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 86bceef6..c23fa095 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -1,6 +1,7 @@ // ignore_for_file: public_member_api_docs import 'dart:async'; +import 'package:flame/extensions.dart'; import 'package:flame/input.dart'; import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; @@ -16,6 +17,13 @@ class PinballGame extends Forge2DGame late final Plunger plunger; + static final boardSize = Vector2(72, 128); + static final boardBounds = Rect.fromCenter( + center: Offset.zero, + width: boardSize.x, + height: -boardSize.y, + ); + @override void onAttach() { super.onAttach(); @@ -27,11 +35,16 @@ class PinballGame extends Forge2DGame _addContactCallbacks(); await _addGameBoundaries(); - unawaited(_addBoard()); + unawaited(add(Board())); unawaited(_addPlunger()); unawaited(_addBonusWord()); unawaited(_addPaths()); unawaited(addFromBlueprint(Spaceship())); + + // Fix camera on the center of the board size + camera + ..followVector2(screenToWorld(boardSize / 2)) + ..zoom = size.y / 14; } void _addContactCallbacks() { @@ -41,44 +54,27 @@ class PinballGame extends Forge2DGame } Future _addGameBoundaries() async { - await add(BottomWall(this)); + await add(BottomWall()); createBoundaries(this).forEach(add); } - Future _addBoard() async { - final board = Board( - size: screenToWorld( - Vector2( - camera.viewport.effectiveSize.x, - camera.viewport.effectiveSize.y, - ), - ), - ); - await add(board); - } - Future _addPlunger() async { - plunger = Plunger( - compressionDistance: camera.viewport.effectiveSize.y / 12, - ); - plunger.initialPosition = screenToWorld( - Vector2( - camera.viewport.effectiveSize.x / 2 + 450, - camera.viewport.effectiveSize.y - plunger.compressionDistance, - ), - ); + plunger = Plunger(compressionDistance: 2); + plunger.initialPosition = boardBounds.bottomRight.toVector2() - + Vector2( + 8, + -10, + ); await add(plunger); } Future _addBonusWord() async { await add( BonusWord( - position: screenToWorld( - Vector2( - camera.viewport.effectiveSize.x / 2, - camera.viewport.effectiveSize.y - 50, - ), + position: Vector2( + boardBounds.center.dx, + boardBounds.bottom + 10, ), ), ); @@ -86,18 +82,22 @@ class PinballGame extends Forge2DGame Future _addPaths() async { final jetpackRamp = JetpackRamp( - position: Vector2(42.6, -45), + position: Vector2( + PinballGame.boardBounds.left + 25, + PinballGame.boardBounds.top - 20, + ), ); final launcherRamp = LauncherRamp( - position: screenToWorld( - Vector2( - camera.viewport.effectiveSize.x / 2 + 400, - camera.viewport.effectiveSize.y / 2 - 330, - ), + position: Vector2( + PinballGame.boardBounds.right - 23, + PinballGame.boardBounds.bottom + 40, ), ); - await addAll([jetpackRamp, launcherRamp]); + await addAll([ + jetpackRamp, + launcherRamp, + ]); } void spawnBall() { diff --git a/test/game/components/board_test.dart b/test/game/components/board_test.dart index 1b87fd24..04847dec 100644 --- a/test/game/components/board_test.dart +++ b/test/game/components/board_test.dart @@ -15,7 +15,7 @@ void main() { flameTester.test( 'loads correctly', (game) async { - final board = Board(size: Vector2.all(500)); + final board = Board(); await game.ready(); await game.ensureAdd(board); @@ -27,7 +27,7 @@ void main() { flameTester.test( 'has one left flipper', (game) async { - final board = Board(size: Vector2.all(500)); + final board = Board(); await game.ready(); await game.ensureAdd(board); @@ -41,7 +41,7 @@ void main() { flameTester.test( 'has one right flipper', (game) async { - final board = Board(size: Vector2.all(500)); + final board = Board(); await game.ready(); await game.ensureAdd(board); @@ -55,7 +55,7 @@ void main() { flameTester.test( 'has two Baseboards', (game) async { - final board = Board(size: Vector2.all(500)); + final board = Board(); await game.ready(); await game.ensureAdd(board); @@ -67,7 +67,7 @@ void main() { flameTester.test( 'has two Kickers', (game) async { - final board = Board(size: Vector2.all(500)); + final board = Board(); await game.ready(); await game.ensureAdd(board); @@ -80,7 +80,7 @@ void main() { 'has three RoundBumpers', (game) async { // TODO(alestiago): change to [NestBumpers] once provided. - final board = Board(size: Vector2.all(500)); + final board = Board(); await game.ready(); await game.ensureAdd(board);