diff --git a/lib/game/components/controlled_flipper.dart b/lib/game/components/controlled_flipper.dart index 9b73b6d3..f1991fe1 100644 --- a/lib/game/components/controlled_flipper.dart +++ b/lib/game/components/controlled_flipper.dart @@ -1,6 +1,8 @@ import 'package:flame/components.dart'; +import 'package:flame_bloc/flame_bloc.dart'; import 'package:flutter/services.dart'; import 'package:pinball/flame/flame.dart'; +import 'package:pinball/game/game.dart'; import 'package:pinball_components/pinball_components.dart'; /// {@template controlled_flipper} @@ -19,7 +21,7 @@ class ControlledFlipper extends Flipper with Controls { /// A [ComponentController] that controls a [Flipper]s movement. /// {@endtemplate} class FlipperController extends ComponentController - with KeyboardHandler { + with KeyboardHandler, BlocComponent { /// {@macro flipper_controller} FlipperController(Flipper flipper) : _keys = flipper.side.flipperKeys, @@ -35,6 +37,7 @@ class FlipperController extends ComponentController RawKeyEvent event, Set keysPressed, ) { + if (state?.isGameOver ?? false) return true; if (!_keys.contains(event.logicalKey)) return true; if (event is RawKeyDownEvent) { diff --git a/lib/game/components/controlled_plunger.dart b/lib/game/components/controlled_plunger.dart index 167f129e..cec71876 100644 --- a/lib/game/components/controlled_plunger.dart +++ b/lib/game/components/controlled_plunger.dart @@ -1,6 +1,8 @@ import 'package:flame/components.dart'; +import 'package:flame_bloc/flame_bloc.dart'; import 'package:flutter/services.dart'; import 'package:pinball/flame/flame.dart'; +import 'package:pinball/game/game.dart'; import 'package:pinball_components/pinball_components.dart'; /// {@template controlled_plunger} @@ -18,7 +20,7 @@ class ControlledPlunger extends Plunger with Controls { /// A [ComponentController] that controls a [Plunger]s movement. /// {@endtemplate} class PlungerController extends ComponentController - with KeyboardHandler { + with KeyboardHandler, BlocComponent { /// {@macro plunger_controller} PlungerController(Plunger plunger) : super(plunger); @@ -36,6 +38,7 @@ class PlungerController extends ComponentController RawKeyEvent event, Set keysPressed, ) { + if (state?.isGameOver ?? false) return true; if (!_keys.contains(event.logicalKey)) return true; if (event is RawKeyDownEvent) { diff --git a/lib/game/components/game_flow_controller.dart b/lib/game/components/game_flow_controller.dart index b0f6f514..01ee0c32 100644 --- a/lib/game/components/game_flow_controller.dart +++ b/lib/game/components/game_flow_controller.dart @@ -28,7 +28,11 @@ class GameFlowController extends ComponentController /// Puts the game on a game over state void gameOver() { - component.firstChild()?.gameOverMode(); + // TODO(erickzanardo): implement score submission and "navigate" to the + // next page + component.firstChild()?.gameOverMode( + score: state?.score ?? 0, + ); component.firstChild()?.focusOnBackboard(); } diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 0dd1b52e..07d637c0 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -41,7 +41,7 @@ class PinballGame extends Forge2DGame unawaited(add(ScoreEffectController(this))); unawaited(add(gameFlowController = GameFlowController(this))); unawaited(add(CameraController(this))); - unawaited(add(Backboard(position: Vector2(0, -88)))); + unawaited(add(Backboard.waiting(position: Vector2(0, -88)))); await _addGameBoundaries(); unawaited(addFromBlueprint(Boundaries())); diff --git a/packages/pinball_components/lib/src/components/backboard/backboard.dart b/packages/pinball_components/lib/src/components/backboard/backboard.dart index 5b6b73f8..8842d1d2 100644 --- a/packages/pinball_components/lib/src/components/backboard/backboard.dart +++ b/packages/pinball_components/lib/src/components/backboard/backboard.dart @@ -22,15 +22,6 @@ class Backboard extends PositionComponent with HasGameRef { anchor: Anchor.bottomCenter, ); - /// [TextPaint] used on the [Backboard] - static final textPaint = TextPaint( - style: TextStyle( - fontSize: 6, - color: Colors.white, - fontFamily: PinballFonts.pixeloidSans, - ), - ); - /// {@macro backboard} /// /// Returns a [Backboard] initialized in the waiting mode @@ -55,6 +46,15 @@ class Backboard extends PositionComponent with HasGameRef { ); } + /// [TextPaint] used on the [Backboard] + static final textPaint = TextPaint( + style: TextStyle( + fontSize: 6, + color: Colors.white, + fontFamily: PinballFonts.pixeloidSans, + ), + ); + /// Puts the Backboard in waiting mode, where the scoreboard is shown. Future waitingMode() async { children.removeWhere((element) => true); @@ -64,12 +64,14 @@ class Backboard extends PositionComponent with HasGameRef { /// Puts the Backboard in game over mode, where the score input is shown. Future gameOverMode({ required int score, - required BackboardOnSubmit onSubmit, + BackboardOnSubmit? onSubmit, }) async { children.removeWhere((element) => true); - await add(BackboardGameOver( - score: score, - onSubmit: onSubmit, - )); + await add( + BackboardGameOver( + score: score, + onSubmit: onSubmit, + ), + ); } } diff --git a/packages/pinball_components/lib/src/components/backboard/backboard_game_over.dart b/packages/pinball_components/lib/src/components/backboard/backboard_game_over.dart index d8aaf98e..55f4786a 100644 --- a/packages/pinball_components/lib/src/components/backboard/backboard_game_over.dart +++ b/packages/pinball_components/lib/src/components/backboard/backboard_game_over.dart @@ -18,12 +18,12 @@ class BackboardGameOver extends PositionComponent with HasGameRef { /// {@macro backboard_game_over} BackboardGameOver({ required int score, - required BackboardOnSubmit onSubmit, + BackboardOnSubmit? onSubmit, }) : _score = score, _onSubmit = onSubmit; final int _score; - final BackboardOnSubmit _onSubmit; + final BackboardOnSubmit? _onSubmit; final _numberFormat = NumberFormat('#,###,###'); @@ -103,7 +103,7 @@ class BackboardGameOver extends PositionComponent with HasGameRef { .join(); bool _submit() { - _onSubmit(initials); + _onSubmit?.call(initials); return true; } diff --git a/test/game/components/controlled_flipper_test.dart b/test/game/components/controlled_flipper_test.dart index 5446a672..a005de30 100644 --- a/test/game/components/controlled_flipper_test.dart +++ b/test/game/components/controlled_flipper_test.dart @@ -1,5 +1,6 @@ import 'dart:collection'; +import 'package:bloc_test/bloc_test.dart'; import 'package:flame_test/flame_test.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -12,6 +13,22 @@ void main() { TestWidgetsFlutterBinding.ensureInitialized(); final flameTester = FlameTester(EmptyPinballGameTest.new); + final gameOverBlocTester = FlameBlocTester( + gameBuilder: EmptyPinballGameTest.new, + blocBuilder: () { + final bloc = MockGameBloc(); + const state = GameState( + score: 0, + balls: 0, + bonusHistory: [], + activatedBonusLetters: [], + activatedDashNests: {}, + ); + whenListen(bloc, Stream.value(state), initialState: state); + return bloc; + }, + ); + group('FlipperController', () { group('onKeyEvent', () { final leftKeys = UnmodifiableListView([ @@ -48,6 +65,20 @@ void main() { ); }); + testRawKeyDownEvents(leftKeys, (event) { + gameOverBlocTester.testGameWidget( + 'does nothing when is game over', + setUp: (game, tester) async { + await game.ensureAdd(flipper); + controller.onKeyEvent(event, {}); + }, + verify: (game, tester) async { + expect(flipper.body.linearVelocity.y, isZero); + expect(flipper.body.linearVelocity.x, isZero); + }, + ); + }); + testRawKeyUpEvents(leftKeys, (event) { flameTester.test( 'moves downwards ' @@ -119,6 +150,20 @@ void main() { ); }); + testRawKeyDownEvents(rightKeys, (event) { + gameOverBlocTester.testGameWidget( + 'does nothing when is game over', + setUp: (game, tester) async { + await game.ensureAdd(flipper); + controller.onKeyEvent(event, {}); + }, + verify: (game, tester) async { + expect(flipper.body.linearVelocity.y, isZero); + expect(flipper.body.linearVelocity.x, isZero); + }, + ); + }); + testRawKeyUpEvents(leftKeys, (event) { flameTester.test( 'does nothing ' diff --git a/test/game/components/game_flow_controller_test.dart b/test/game/components/game_flow_controller_test.dart index dc1d9ab8..42ce82d7 100644 --- a/test/game/components/game_flow_controller_test.dart +++ b/test/game/components/game_flow_controller_test.dart @@ -42,7 +42,12 @@ void main() { gameFlowController = GameFlowController(game); overlays = MockActiveOverlaysNotifier(); - when(backboard.gameOverMode).thenAnswer((_) async {}); + when( + () => backboard.gameOverMode( + score: any(named: 'score'), + onSubmit: any(named: 'onSubmit'), + ), + ).thenAnswer((_) async {}); when(backboard.waitingMode).thenAnswer((_) async {}); when(cameraController.focusOnBackboard).thenAnswer((_) async {}); when(cameraController.focusOnGame).thenAnswer((_) async {}); @@ -67,7 +72,12 @@ void main() { ), ); - verify(backboard.gameOverMode).called(1); + verify( + () => backboard.gameOverMode( + score: 0, + onSubmit: any(named: 'onSubmit'), + ), + ).called(1); verify(cameraController.focusOnBackboard).called(1); }, );