From c4012b1c6547bb1d6684b9bda047d3e0d98186f9 Mon Sep 17 00:00:00 2001 From: Alejandro Santiago Date: Tue, 29 Mar 2022 14:21:02 +0100 Subject: [PATCH] feat: implemented `BallType` (#105) * feat: implemented BallType * docs: improved doc comment * refactor: renamed egg to extra --- lib/game/components/ball.dart | 51 ++++++++++++++++++++----- lib/game/components/flutter_forest.dart | 1 + lib/game/pinball_game.dart | 14 ++++++- 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/lib/game/components/ball.dart b/lib/game/components/ball.dart index 756a8a97..aca2b154 100644 --- a/lib/game/components/ball.dart +++ b/lib/game/components/ball.dart @@ -1,33 +1,64 @@ import 'package:flame/components.dart'; -import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:pinball/flame/blueprint.dart'; import 'package:pinball/game/game.dart'; import 'package:pinball_components/pinball_components.dart'; +/// {@template ball_type} +/// Specifies the type of [Ball]. +/// +/// Different [BallType]s are affected by different game mechanics. +/// {@endtemplate} +enum BallType { + /// A [Ball] spawned from the [Plunger]. + /// + /// [normal] balls decrease the [GameState.balls] when they fall through the + /// the [BottomWall]. + normal, + + /// A [Ball] that does not alter [GameState.balls]. + /// + /// For example, a [Ball] spawned by Dash in the [FlutterForest]. + extra, +} + /// {@template ball_blueprint} -/// [Blueprint] which cretes a ball game object +/// [Blueprint] which cretes a ball game object. /// {@endtemplate} class BallBlueprint extends Blueprint { /// {@macro ball_blueprint} - BallBlueprint({required this.position}); + BallBlueprint({ + required this.position, + required this.type, + }); - /// The initial position of the [Ball] + /// The initial position of the [Ball]. final Vector2 position; + /// {@macro ball_type} + final BallType type; + @override void build(PinballGame gameRef) { final baseColor = gameRef.theme.characterTheme.ballColor; - final ball = Ball(baseColor: baseColor)..add(BallController()); + final ball = Ball(baseColor: baseColor) + ..add( + BallController(type: type), + ); add(ball..initialPosition = position + Vector2(0, ball.size.y / 2)); } } -/// {@template ball} -/// A solid, [BodyType.dynamic] sphere that rolls and bounces along the -/// [PinballGame]. +/// {@template ball_controller} +/// Controller attached to a [Ball] that handles its game related logic. /// {@endtemplate} class BallController extends Component with HasGameRef { + /// {@macro ball_controller} + BallController({required this.type}); + + /// {@macro ball_type} + final BallType type; + /// Removes the [Ball] from a [PinballGame]; spawning a new [Ball] if /// any are left. /// @@ -35,9 +66,11 @@ class BallController extends Component with HasGameRef { /// a [BottomWall]. void lost() { parent?.shouldRemove = true; + // TODO(alestiago): Consider adding test for this logic once we remove the + // BallX extension. + if (type != BallType.normal) return; final bloc = gameRef.read()..add(const BallLost()); - final shouldBallRespwan = !bloc.state.isLastBall && !bloc.state.isGameOver; if (shouldBallRespwan) { gameRef.spawnBall(); diff --git a/lib/game/components/flutter_forest.dart b/lib/game/components/flutter_forest.dart index 31ea8c2b..5b91ee40 100644 --- a/lib/game/components/flutter_forest.dart +++ b/lib/game/components/flutter_forest.dart @@ -35,6 +35,7 @@ class FlutterForest extends Component gameRef.addFromBlueprint( BallBlueprint( position: Vector2(17.2, 52.7), + type: BallType.extra, ), ); } diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 89063a27..2b794455 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -88,7 +88,12 @@ class PinballGame extends Forge2DGame } void spawnBall() { - addFromBlueprint(BallBlueprint(position: plunger.body.position)); + addFromBlueprint( + BallBlueprint( + position: plunger.body.position, + type: BallType.normal, + ), + ); } } @@ -120,6 +125,11 @@ class DebugPinballGame extends PinballGame with TapDetector { @override void onTapUp(TapUpInfo info) { - addFromBlueprint(BallBlueprint(position: info.eventPosition.game)); + addFromBlueprint( + BallBlueprint( + position: info.eventPosition.game, + type: BallType.extra, + ), + ); } }