From 937a18a207d3e3a913a13c836866fb9be4145207 Mon Sep 17 00:00:00 2001 From: Jochum van der Ploeg Date: Tue, 10 May 2022 16:27:29 +0200 Subject: [PATCH] fix: game controls are only allowed while the game is playing (#459) Co-authored-by: Tom Arra --- lib/game/pinball_game.dart | 5 +- test/game/pinball_game_test.dart | 92 ++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 3 deletions(-) diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 23769756..2b003207 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -155,12 +155,11 @@ class PinballGame extends PinballForge2DGame @override void onTapDown(int pointerId, TapDownInfo info) { - if (info.raw.kind == PointerDeviceKind.touch) { + if (info.raw.kind == PointerDeviceKind.touch && + _gameBloc.state.status.isPlaying) { final rocket = descendants().whereType().first; final bounds = rocket.topLeftPosition & rocket.size; - // NOTE: As long as Flame does not have https://github.com/flame-engine/flame/issues/1586 - // we need to check it at the highest level manually. final tappedRocket = bounds.contains(info.eventPosition.game.toOffset()); if (tappedRocket) { descendants() diff --git a/test/game/pinball_game_test.dart b/test/game/pinball_game_test.dart index b44295ed..92608a1d 100644 --- a/test/game/pinball_game_test.dart +++ b/test/game/pinball_game_test.dart @@ -246,9 +246,61 @@ void main() { }); group('flipper control', () { + flameTester.test('tap control only works if game is playing', + (game) async { + await game.ready(); + + final gameBloc = game + .descendants() + .whereType>() + .first + .bloc; + + final eventPosition = _MockEventPosition(); + when(() => eventPosition.game).thenReturn(Vector2.zero()); + when(() => eventPosition.widget).thenReturn(Vector2.zero()); + + final raw = _MockTapDownDetails(); + when(() => raw.kind).thenReturn(PointerDeviceKind.touch); + + final tapDownEvent = _MockTapDownInfo(); + when(() => tapDownEvent.eventPosition).thenReturn(eventPosition); + when(() => tapDownEvent.raw).thenReturn(raw); + + final flipperBloc = game + .descendants() + .whereType() + .where((flipper) => flipper.side == BoardSide.left) + .single + .descendants() + .whereType>() + .first + .bloc; + + gameBloc.emit(gameBloc.state.copyWith(status: GameStatus.gameOver)); + + game.onTapDown(0, tapDownEvent); + await Future.delayed(Duration.zero); + expect(flipperBloc.state, FlipperState.movingDown); + + gameBloc.emit(gameBloc.state.copyWith(status: GameStatus.playing)); + + game.onTapDown(0, tapDownEvent); + await Future.delayed(Duration.zero); + expect(flipperBloc.state, FlipperState.movingUp); + }); + flameTester.test('tap down moves left flipper up', (game) async { await game.ready(); + final gameBloc = game + .descendants() + .whereType>() + .first + .bloc; + + gameBloc.emit(gameBloc.state.copyWith(status: GameStatus.playing)); + final eventPosition = _MockEventPosition(); when(() => eventPosition.game).thenReturn(Vector2.zero()); when(() => eventPosition.widget).thenReturn(Vector2.zero()); @@ -278,6 +330,14 @@ void main() { flameTester.test('tap down moves right flipper up', (game) async { await game.ready(); + final gameBloc = game + .descendants() + .whereType>() + .first + .bloc; + + gameBloc.emit(gameBloc.state.copyWith(status: GameStatus.playing)); + final eventPosition = _MockEventPosition(); when(() => eventPosition.game).thenReturn(Vector2.zero()); when(() => eventPosition.widget).thenReturn(game.canvasSize); @@ -307,6 +367,14 @@ void main() { flameTester.test('tap up moves flipper down', (game) async { await game.ready(); + final gameBloc = game + .descendants() + .whereType>() + .first + .bloc; + + gameBloc.emit(gameBloc.state.copyWith(status: GameStatus.playing)); + final eventPosition = _MockEventPosition(); when(() => eventPosition.game).thenReturn(Vector2.zero()); when(() => eventPosition.widget).thenReturn(Vector2.zero()); @@ -332,6 +400,14 @@ void main() { flameTester.test('tap cancel moves flipper down', (game) async { await game.ready(); + final gameBloc = game + .descendants() + .whereType>() + .first + .bloc; + + gameBloc.emit(gameBloc.state.copyWith(status: GameStatus.playing)); + final eventPosition = _MockEventPosition(); when(() => eventPosition.game).thenReturn(Vector2.zero()); when(() => eventPosition.widget).thenReturn(Vector2.zero()); @@ -363,6 +439,14 @@ void main() { (game) async { await game.ready(); + final gameBloc = game + .descendants() + .whereType>() + .first + .bloc; + + gameBloc.emit(gameBloc.state.copyWith(status: GameStatus.playing)); + final raw = _MockTapDownDetails(); when(() => raw.kind).thenReturn(PointerDeviceKind.touch); @@ -416,6 +500,14 @@ void main() { flameTester.test('plunger control tap down emits plunging', (game) async { await game.ready(); + final gameBloc = game + .descendants() + .whereType>() + .first + .bloc; + + gameBloc.emit(gameBloc.state.copyWith(status: GameStatus.playing)); + final eventPosition = _MockEventPosition(); when(() => eventPosition.game).thenReturn(Vector2(40, 60));