diff --git a/lib/game/components/baseboard.dart b/lib/game/components/baseboard.dart index 9153d4f3..8e37b8a3 100644 --- a/lib/game/components/baseboard.dart +++ b/lib/game/components/baseboard.dart @@ -30,6 +30,18 @@ class Baseboard extends BodyComponent { side: BoardSide.right, ); + factory Baseboard.fromSide({ + required BoardSide side, + required Vector2 position, + }) { + switch (side) { + case BoardSide.left: + return Baseboard.left(position: position); + case BoardSide.right: + return Baseboard.right(position: position); + } + } + /// The width of the [Baseboard]. static const width = 10.0; diff --git a/lib/game/components/board.dart b/lib/game/components/board.dart new file mode 100644 index 00000000..11b524c0 --- /dev/null +++ b/lib/game/components/board.dart @@ -0,0 +1,73 @@ +import 'package:flame/components.dart'; +import 'package:pinball/game/game.dart'; + +/// {@template bottom_group} +/// +/// {@endtemplate} +class BottomGroup extends Component { + /// {@macro bottom_group} + BottomGroup({ + required this.position, + required this.spacing, + }); + + /// The amount of space between the line of symmetry. + final double spacing; + + /// The position of this [BottomGroup]. + final Vector2 position; + + @override + Future onLoad() async { + final spacing = this.spacing + Flipper.width / 2; + final rightSide = _BottomGroupSide.right( + position: position + Vector2(spacing, 0), + ); + final leftSide = _BottomGroupSide.left( + position: position + Vector2(-spacing, 0), + ); + + await addAll([rightSide, leftSide]); + } +} + +/// Group with [BottomGroup]'s symmetric [Component]s. +/// +/// For example, [Flipper.right] and [Flipper.left] are symmetric components. +class _BottomGroupSide extends Component { + _BottomGroupSide._({ + required BoardSide side, + required Vector2 position, + }) : _side = side, + _position = position; + + _BottomGroupSide.right({required Vector2 position}) + : this._(side: BoardSide.right, position: position); + + _BottomGroupSide.left({required Vector2 position}) + : this._(side: BoardSide.left, position: position); + + final BoardSide _side; + + final Vector2 _position; + + @override + Future onLoad() async { + final magnitude = _side.isLeft ? -1 : 1; + final flipper = Flipper.fromSide( + side: _side, + position: _position, + ); + await add(flipper); + + final bumper = Baseboard.fromSide( + side: _side, + position: _position + + Vector2( + (Flipper.width * magnitude) - magnitude, + Flipper.height, + ), + ); + await add(bumper); + } +} diff --git a/lib/game/components/components.dart b/lib/game/components/components.dart index 71108fcc..7694f62a 100644 --- a/lib/game/components/components.dart +++ b/lib/game/components/components.dart @@ -1,5 +1,6 @@ export 'ball.dart'; export 'baseboard.dart'; +export 'board.dart'; export 'board_side.dart'; export 'bonus_word.dart'; export 'flipper.dart'; diff --git a/lib/game/components/flipper.dart b/lib/game/components/flipper.dart index 9035daaf..55617f86 100644 --- a/lib/game/components/flipper.dart +++ b/lib/game/components/flipper.dart @@ -82,6 +82,18 @@ class Flipper extends BodyComponent with KeyboardHandler { ], ); + factory Flipper.fromSide({ + required BoardSide side, + required Vector2 position, + }) { + switch (side) { + case BoardSide.left: + return Flipper.left(position: position); + case BoardSide.right: + return Flipper.right(position: position); + } + } + /// Asset location of the sprite that renders with the [Flipper]. /// /// Sprite is preloaded by [PinballGameAssetsX]. diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index b67a8dad..112f0522 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -48,9 +48,20 @@ class PinballGame extends Forge2DGame ), ); - unawaited(_addFlippers()); - unawaited(_addBonusWord()); + unawaited( + add( + BottomGroup( + position: screenToWorld( + Vector2( + camera.viewport.effectiveSize.x / 2, + camera.viewport.effectiveSize.y / 1.25, + ), + ), + spacing: 2, + ), + ), + ); } Future _addBonusWord() async { @@ -66,25 +77,6 @@ class PinballGame extends Forge2DGame ); } - Future _addFlippers() async { - final flippersPosition = screenToWorld( - Vector2( - camera.viewport.effectiveSize.x / 2, - camera.viewport.effectiveSize.y / 1.1, - ), - ); - - unawaited( - add( - FlipperGroup( - position: flippersPosition, - spacing: 2, - ), - ), - ); - unawaited(_addBaseboards()); - } - void spawnBall() { add(Ball(position: plunger.body.position)); } @@ -115,31 +107,6 @@ class PinballGame extends Forge2DGame ), ); } - - Future _addBaseboards() async { - final spaceBetweenBaseboards = camera.viewport.effectiveSize.x / 2; - final baseboardY = camera.viewport.effectiveSize.y / 1.12; - - final leftBaseboard = Baseboard.left( - position: screenToWorld( - Vector2( - camera.viewport.effectiveSize.x / 2 - (spaceBetweenBaseboards / 2), - baseboardY, - ), - ), - ); - await add(leftBaseboard); - - final rightBaseboard = Baseboard.right( - position: screenToWorld( - Vector2( - camera.viewport.effectiveSize.x / 2 + (spaceBetweenBaseboards / 2), - baseboardY, - ), - ), - ); - await add(rightBaseboard); - } } class DebugPinballGame extends PinballGame with TapDetector {