diff --git a/lib/flame/component_controller.dart b/lib/flame/component_controller.dart index 1d6e0173..b9568348 100644 --- a/lib/flame/component_controller.dart +++ b/lib/flame/component_controller.dart @@ -33,7 +33,7 @@ abstract class ComponentController extends Component { /// Mixin that attaches a single [ComponentController] to a [Component]. mixin Controls on Component { /// The [ComponentController] attached to this [Component]. - late final T controller; + late T controller; @override @mustCallSuper diff --git a/lib/game/components/controlled_ball.dart b/lib/game/components/controlled_ball.dart index 8c501918..51abe16f 100644 --- a/lib/game/components/controlled_ball.dart +++ b/lib/game/components/controlled_ball.dart @@ -33,7 +33,7 @@ class ControlledBall extends Ball with Controls { /// [Ball] used in [DebugPinballGame]. ControlledBall.debug() : super(baseColor: const Color(0xFFFF0000)) { - controller = _DebugBallController(this); + controller = DebugBallController(this); } } @@ -57,8 +57,10 @@ class BallController extends ComponentController } } -class _DebugBallController extends BallController { - _DebugBallController(Ball component) : super(component); +/// {@macro ball_controller} +class DebugBallController extends BallController { + /// {@macro ball_controller} + DebugBallController(Ball component) : super(component); @override void lost() { diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 7ab91477..a487e5d3 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -142,7 +142,9 @@ class DebugPinballGame extends PinballGame with TapDetector { }) : super( theme: theme, audio: audio, - ); + ) { + controller = _DebugGameBallsController(this); + } @override Future onLoad() async { @@ -174,3 +176,21 @@ class DebugPinballGame extends PinballGame with TapDetector { ); } } + +class _DebugGameBallsController extends _GameBallsController { + _DebugGameBallsController(PinballGame game) : super(game); + + @override + bool listenWhen(GameState? previousState, GameState newState) { + final noBallsLeft = component + .descendants() + .whereType() + .where( + (ball) => ball.controller is! DebugBallController, + ) + .isEmpty; + final canBallRespawn = newState.balls > 0; + + return noBallsLeft && canBallRespawn; + } +} diff --git a/test/game/pinball_game_test.dart b/test/game/pinball_game_test.dart index 4632bd75..aca1d4ae 100644 --- a/test/game/pinball_game_test.dart +++ b/test/game/pinball_game_test.dart @@ -11,11 +11,11 @@ import 'package:pinball_components/pinball_components.dart'; import '../helpers/helpers.dart'; void main() { - group('PinballGame', () { - TestWidgetsFlutterBinding.ensureInitialized(); - final flameTester = FlameTester(PinballGameTest.new); - final debugModeFlameTester = FlameTester(DebugPinballGameTest.new); + TestWidgetsFlutterBinding.ensureInitialized(); + final flameTester = FlameTester(PinballGameTest.new); + final debugModeFlameTester = FlameTester(DebugPinballGameTest.new); + group('PinballGame', () { // TODO(alestiago): test if [PinballGame] registers // [BallScorePointsCallback] once the following issue is resolved: // https://github.com/flame-engine/flame/issues/1416 @@ -139,7 +139,9 @@ void main() { ); }); }); + }); + group('DebugPinballGame', () { debugModeFlameTester.test('adds a ball on tap up', (game) async { await game.ready(); @@ -159,5 +161,23 @@ void main() { equals(previousBalls.length + 1), ); }); + + group('controller', () { + debugModeFlameTester.test( + 'ignores debug balls', + (game) async { + final newState = MockGameState(); + when(() => newState.balls).thenReturn(2); + game.descendants().whereType().forEach(game.remove); + await game.ready(); + await game.ensureAdd(ControlledBall.debug()); + + expect( + game.controller.listenWhen(MockGameState(), newState), + isTrue, + ); + }, + ); + }); }); }