From 855e93ec565470ae6fca2f153cee690541da19c9 Mon Sep 17 00:00:00 2001 From: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> Date: Mon, 9 May 2022 18:23:40 -0500 Subject: [PATCH 1/4] feat: flutter forest reset (#448) Co-authored-by: Tom Arra --- .../components/game_bloc_status_listener.dart | 5 + .../signpost/cubit/signpost_cubit.dart | 2 + .../signpost/cubit/signpost_cubit_test.dart | 7 ++ .../game_bloc_status_listener_test.dart | 100 ++++++++++++++++-- 4 files changed, 108 insertions(+), 6 deletions(-) diff --git a/lib/game/components/game_bloc_status_listener.dart b/lib/game/components/game_bloc_status_listener.dart index efd085a5..6ffd2ad3 100644 --- a/lib/game/components/game_bloc_status_listener.dart +++ b/lib/game/components/game_bloc_status_listener.dart @@ -61,6 +61,11 @@ class GameBlocStatusListener extends Component .single .bloc .onReset(); + gameRef + .descendants() + .whereType() + .forEach((bumper) => bumper.bloc.onReset()); + gameRef.descendants().whereType().single.bloc.onReset(); } void _addPlungerBehaviors(Plunger plunger) { diff --git a/packages/pinball_components/lib/src/components/signpost/cubit/signpost_cubit.dart b/packages/pinball_components/lib/src/components/signpost/cubit/signpost_cubit.dart index dc5bce9c..3beb638c 100644 --- a/packages/pinball_components/lib/src/components/signpost/cubit/signpost_cubit.dart +++ b/packages/pinball_components/lib/src/components/signpost/cubit/signpost_cubit.dart @@ -12,5 +12,7 @@ class SignpostCubit extends Cubit { ); } + void onReset() => emit(SignpostState.inactive); + bool isFullyProgressed() => state == SignpostState.active3; } diff --git a/packages/pinball_components/test/src/components/signpost/cubit/signpost_cubit_test.dart b/packages/pinball_components/test/src/components/signpost/cubit/signpost_cubit_test.dart index 081beab2..bd41aa33 100644 --- a/packages/pinball_components/test/src/components/signpost/cubit/signpost_cubit_test.dart +++ b/packages/pinball_components/test/src/components/signpost/cubit/signpost_cubit_test.dart @@ -22,6 +22,13 @@ void main() { ], ); + blocTest( + 'onReset emits inactive', + build: SignpostCubit.new, + act: (bloc) => bloc.onReset(), + expect: () => [SignpostState.inactive], + ); + test('isFullyProgressed when on active3', () { final bloc = SignpostCubit(); expect(bloc.isFullyProgressed(), isFalse); diff --git a/test/game/components/game_bloc_status_listener_test.dart b/test/game/components/game_bloc_status_listener_test.dart index 47a273ba..069731fd 100644 --- a/test/game/components/game_bloc_status_listener_test.dart +++ b/test/game/components/game_bloc_status_listener_test.dart @@ -86,6 +86,10 @@ class _MockPlungerCubit extends Mock implements PlungerCubit {} class _MockGoogleWordCubit extends Mock implements GoogleWordCubit {} +class _MockDashBumperCubit extends Mock implements DashBumperCubit {} + +class _MockSignpostCubit extends Mock implements SignpostCubit {} + class _MockFlipperCubit extends Mock implements FlipperCubit {} class _MockAppLocalizations extends Mock implements AppLocalizations { @@ -332,7 +336,15 @@ void main() { (game) async { final audioPlayer = _MockPinballAudioPlayer(); final component = GameBlocStatusListener(); - await game.pump([component], pinballAudioPlayer: audioPlayer); + await game.pump( + [ + component, + Signpost.test( + bloc: _MockSignpostCubit(), + ), + ], + pinballAudioPlayer: audioPlayer, + ); expect(state.status, equals(GameStatus.playing)); component.onNewState(state); @@ -350,7 +362,15 @@ void main() { (game) async { final googleWordBloc = _MockGoogleWordCubit(); final component = GameBlocStatusListener(); - await game.pump([component], googleWordBloc: googleWordBloc); + await game.pump( + [ + component, + Signpost.test( + bloc: _MockSignpostCubit(), + ), + ], + googleWordBloc: googleWordBloc, + ); expect(state.status, equals(GameStatus.playing)); component.onNewState(state); @@ -359,6 +379,46 @@ void main() { }, ); + flameTester.test( + 'resets the DashBumperCubits', + (game) async { + final dashBumper1Bloc = _MockDashBumperCubit(); + final dashBumper2Bloc = _MockDashBumperCubit(); + final dashBumper1 = DashBumper.test(bloc: dashBumper1Bloc); + final dashBumper2 = DashBumper.test(bloc: dashBumper2Bloc); + final component = GameBlocStatusListener(); + await game.pump([ + component, + dashBumper1, + dashBumper2, + Signpost.test( + bloc: _MockSignpostCubit(), + ), + ]); + + expect(state.status, equals(GameStatus.playing)); + component.onNewState(state); + + verify(dashBumper1Bloc.onReset).called(1); + verify(dashBumper2Bloc.onReset).called(1); + }, + ); + + flameTester.test( + 'resets the SignpostCubit', + (game) async { + final signpostBloc = _MockSignpostCubit(); + final signpost = Signpost.test(bloc: signpostBloc); + final component = GameBlocStatusListener(); + await game.pump([component, signpost]); + + expect(state.status, equals(GameStatus.playing)); + component.onNewState(state); + + verify(signpostBloc.onReset).called(1); + }, + ); + flameTester.test( 'adds FlipperKeyControllingBehavior to Flippers', (game) async { @@ -372,7 +432,14 @@ void main() { ); final flipper = Flipper.test(side: BoardSide.left); - await game.pump([component, backbox, flipper]); + await game.pump([ + component, + backbox, + flipper, + Signpost.test( + bloc: _MockSignpostCubit(), + ), + ]); await flipper.ensureAdd( FlameBlocProvider( create: _MockFlipperCubit.new, @@ -407,7 +474,14 @@ void main() { ); final plunger = Plunger.test(); await game.pump( - [component, backbox, plunger], + [ + component, + backbox, + plunger, + Signpost.test( + bloc: _MockSignpostCubit(), + ), + ], platformHelper: platformHelper, ); await plunger.ensureAdd( @@ -446,7 +520,14 @@ void main() { ); final plunger = Plunger.test(); await game.pump( - [component, backbox, plunger], + [ + component, + backbox, + plunger, + Signpost.test( + bloc: _MockSignpostCubit(), + ), + ], platformHelper: platformHelper, ); await plunger.ensureAdd( @@ -482,7 +563,14 @@ void main() { ); final plunger = Plunger.test(); await game.pump( - [component, backbox, plunger], + [ + component, + backbox, + plunger, + Signpost.test( + bloc: _MockSignpostCubit(), + ), + ], platformHelper: platformHelper, ); await plunger.ensureAdd( From 5431f2058a7d45c186f5d97222934b27845075b1 Mon Sep 17 00:00:00 2001 From: Erick Date: Mon, 9 May 2022 20:34:11 -0300 Subject: [PATCH 2/4] feat: flipper sfx (#449) * feat: flipper sfx * lint * Apply suggestions from code review Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * pr * lint * Update packages/pinball_audio/lib/src/pinball_audio.dart Co-authored-by: Alejandro Santiago Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> Co-authored-by: Alejandro Santiago --- packages/pinball_audio/assets/sfx/flipper.mp3 | Bin 0 -> 10702 bytes .../pinball_audio/lib/gen/assets.gen.dart | 1 + .../pinball_audio/lib/src/pinball_audio.dart | 39 ++++++++- .../test/src/pinball_audio_test.dart | 41 +++++++++ .../flipper/behaviors/behaviors.dart | 1 + .../behaviors/flipper_moving_behavior.dart | 4 +- .../behaviors/flipper_noise_behavior.dart | 18 ++++ .../lib/src/components/flipper/flipper.dart | 5 +- .../flipper_moving_behavior_test.dart | 2 + .../flipper_noise_behavior_test.dart | 79 ++++++++++++++++++ 10 files changed, 185 insertions(+), 5 deletions(-) create mode 100644 packages/pinball_audio/assets/sfx/flipper.mp3 create mode 100644 packages/pinball_components/lib/src/components/flipper/behaviors/flipper_noise_behavior.dart create mode 100644 packages/pinball_components/test/src/components/flipper/behaviors/flipper_noise_behavior_test.dart diff --git a/packages/pinball_audio/assets/sfx/flipper.mp3 b/packages/pinball_audio/assets/sfx/flipper.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..c4d31a475d79c399053086ca3b66701bd38b109b GIT binary patch literal 10702 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 I|8yGv0|VVrCIA2c literal 0 HcmV?d00001 diff --git a/packages/pinball_audio/lib/gen/assets.gen.dart b/packages/pinball_audio/lib/gen/assets.gen.dart index 0b8fb20b..915573b4 100644 --- a/packages/pinball_audio/lib/gen/assets.gen.dart +++ b/packages/pinball_audio/lib/gen/assets.gen.dart @@ -20,6 +20,7 @@ class $AssetsSfxGen { String get cowMoo => 'assets/sfx/cow_moo.mp3'; String get dash => 'assets/sfx/dash.mp3'; String get dino => 'assets/sfx/dino.mp3'; + String get flipper => 'assets/sfx/flipper.mp3'; String get gameOverVoiceOver => 'assets/sfx/game_over_voice_over.mp3'; String get google => 'assets/sfx/google.mp3'; String get ioPinballVoiceOver => 'assets/sfx/io_pinball_voice_over.mp3'; diff --git a/packages/pinball_audio/lib/src/pinball_audio.dart b/packages/pinball_audio/lib/src/pinball_audio.dart index 1e1a7688..c62f197d 100644 --- a/packages/pinball_audio/lib/src/pinball_audio.dart +++ b/packages/pinball_audio/lib/src/pinball_audio.dart @@ -39,14 +39,17 @@ enum PinballAudio { /// Sparky. sparky, - /// Android + /// Android. android, - /// Dino + /// Dino. dino, - /// Dash + /// Dash. dash, + + /// Flipper. + flipper, } /// Defines the contract of the creation of an [AudioPool]. @@ -147,6 +150,31 @@ class _SingleLoopAudio extends _LoopAudio { } } +class _SingleAudioPool extends _Audio { + _SingleAudioPool({ + required this.path, + required this.createAudioPool, + required this.maxPlayers, + }); + + final String path; + final CreateAudioPool createAudioPool; + final int maxPlayers; + late AudioPool pool; + + @override + Future load() async { + pool = await createAudioPool( + prefixFile(path), + maxPlayers: maxPlayers, + prefix: '', + ); + } + + @override + void play() => pool.start(); +} + class _RandomABAudio extends _Audio { _RandomABAudio({ required this.createAudioPool, @@ -277,6 +305,11 @@ class PinballAudioPlayer { path: Assets.sfx.rollover, volume: 0.3, ), + PinballAudio.flipper: _SingleAudioPool( + path: Assets.sfx.flipper, + createAudioPool: _createAudioPool, + maxPlayers: 2, + ), PinballAudio.ioPinballVoiceOver: _SimplePlayAudio( preCacheSingleAudio: _preCacheSingleAudio, playSingleAudio: _playSingleAudio, diff --git a/packages/pinball_audio/test/src/pinball_audio_test.dart b/packages/pinball_audio/test/src/pinball_audio_test.dart index 47d788bf..554e9752 100644 --- a/packages/pinball_audio/test/src/pinball_audio_test.dart +++ b/packages/pinball_audio/test/src/pinball_audio_test.dart @@ -145,6 +145,20 @@ void main() { ).called(1); }); + test('creates the flipper pool', () async { + await Future.wait( + audioPlayer.load().map((loadableBuilder) => loadableBuilder()), + ); + + verify( + () => createAudioPool.onCall( + 'packages/pinball_audio/${Assets.sfx.flipper}', + maxPlayers: 2, + prefix: '', + ), + ).called(1); + }); + test('configures the audio cache instance', () async { await Future.wait( audioPlayer.load().map((loadableBuilder) => loadableBuilder()), @@ -327,6 +341,33 @@ void main() { }); }); + group('flipper', () { + late AudioPool pool; + + setUp(() { + pool = _MockAudioPool(); + when(() => pool.start(volume: any(named: 'volume'))) + .thenAnswer((_) async => () {}); + when( + () => createAudioPool.onCall( + 'packages/pinball_audio/${Assets.sfx.flipper}', + maxPlayers: any(named: 'maxPlayers'), + prefix: any(named: 'prefix'), + ), + ).thenAnswer((_) async => pool); + }); + + test('plays the flipper sound pool', () async { + when(seed.nextBool).thenReturn(true); + await Future.wait( + audioPlayer.load().map((loadableBuilder) => loadableBuilder()), + ); + audioPlayer.play(PinballAudio.flipper); + + verify(() => pool.start()).called(1); + }); + }); + group('cow moo', () { test('plays the correct file', () async { await Future.wait( diff --git a/packages/pinball_components/lib/src/components/flipper/behaviors/behaviors.dart b/packages/pinball_components/lib/src/components/flipper/behaviors/behaviors.dart index d3743ae9..2325227d 100644 --- a/packages/pinball_components/lib/src/components/flipper/behaviors/behaviors.dart +++ b/packages/pinball_components/lib/src/components/flipper/behaviors/behaviors.dart @@ -1,3 +1,4 @@ export 'flipper_jointing_behavior.dart'; export 'flipper_key_controlling_behavior.dart'; export 'flipper_moving_behavior.dart'; +export 'flipper_noise_behavior.dart'; diff --git a/packages/pinball_components/lib/src/components/flipper/behaviors/flipper_moving_behavior.dart b/packages/pinball_components/lib/src/components/flipper/behaviors/flipper_moving_behavior.dart index 13989192..e0189fdb 100644 --- a/packages/pinball_components/lib/src/components/flipper/behaviors/flipper_moving_behavior.dart +++ b/packages/pinball_components/lib/src/components/flipper/behaviors/flipper_moving_behavior.dart @@ -15,7 +15,9 @@ class FlipperMovingBehavior extends Component late final Flipper _flipper; - void _moveUp() => _flipper.body.linearVelocity = Vector2(0, -_strength); + void _moveUp() { + _flipper.body.linearVelocity = Vector2(0, -_strength); + } void _moveDown() => _flipper.body.linearVelocity = Vector2(0, _strength); diff --git a/packages/pinball_components/lib/src/components/flipper/behaviors/flipper_noise_behavior.dart b/packages/pinball_components/lib/src/components/flipper/behaviors/flipper_noise_behavior.dart new file mode 100644 index 00000000..6dc4a88e --- /dev/null +++ b/packages/pinball_components/lib/src/components/flipper/behaviors/flipper_noise_behavior.dart @@ -0,0 +1,18 @@ +import 'package:flame/components.dart'; +import 'package:flame_bloc/flame_bloc.dart'; +import 'package:pinball_audio/pinball_audio.dart'; +import 'package:pinball_components/pinball_components.dart'; +import 'package:pinball_flame/pinball_flame.dart'; + +class FlipperNoiseBehavior extends Component + with + FlameBlocListenable, + FlameBlocReader { + @override + void onNewState(FlipperState state) { + super.onNewState(state); + if (bloc.state.isMovingUp) { + readProvider().play(PinballAudio.flipper); + } + } +} diff --git a/packages/pinball_components/lib/src/components/flipper/flipper.dart b/packages/pinball_components/lib/src/components/flipper/flipper.dart index 265e7924..cc6ef13a 100644 --- a/packages/pinball_components/lib/src/components/flipper/flipper.dart +++ b/packages/pinball_components/lib/src/components/flipper/flipper.dart @@ -25,7 +25,10 @@ class Flipper extends BodyComponent with KeyboardHandler, InitialPosition { FlipperJointingBehavior(), FlameBlocProvider( create: FlipperCubit.new, - children: [FlipperMovingBehavior(strength: 90)], + children: [ + FlipperMovingBehavior(strength: 90), + FlipperNoiseBehavior(), + ], ), ], ); diff --git a/packages/pinball_components/test/src/components/flipper/behaviors/flipper_moving_behavior_test.dart b/packages/pinball_components/test/src/components/flipper/behaviors/flipper_moving_behavior_test.dart index be48d795..de379201 100644 --- a/packages/pinball_components/test/src/components/flipper/behaviors/flipper_moving_behavior_test.dart +++ b/packages/pinball_components/test/src/components/flipper/behaviors/flipper_moving_behavior_test.dart @@ -8,12 +8,14 @@ import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_test/flame_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; +import 'package:pinball_audio/pinball_audio.dart'; import 'package:pinball_components/pinball_components.dart'; class _TestGame extends Forge2DGame { Future pump( FlipperMovingBehavior behavior, { FlipperCubit? flipperBloc, + PinballAudioPlayer? audioPlayer, }) async { final flipper = Flipper.test(side: BoardSide.left); await ensureAdd(flipper); diff --git a/packages/pinball_components/test/src/components/flipper/behaviors/flipper_noise_behavior_test.dart b/packages/pinball_components/test/src/components/flipper/behaviors/flipper_noise_behavior_test.dart new file mode 100644 index 00000000..2a046a0b --- /dev/null +++ b/packages/pinball_components/test/src/components/flipper/behaviors/flipper_noise_behavior_test.dart @@ -0,0 +1,79 @@ +// ignore_for_file: avoid_dynamic_calls, cascade_invocations + +import 'dart:async'; + +import 'package:bloc_test/bloc_test.dart'; +import 'package:flame_bloc/flame_bloc.dart'; +import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:flame_test/flame_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:pinball_audio/pinball_audio.dart'; +import 'package:pinball_components/pinball_components.dart'; +import 'package:pinball_flame/pinball_flame.dart'; + +class _TestGame extends Forge2DGame { + Future pump( + FlipperNoiseBehavior behavior, { + FlipperCubit? flipperBloc, + PinballAudioPlayer? audioPlayer, + }) async { + final flipper = Flipper.test(side: BoardSide.left); + await ensureAdd( + FlameProvider.value( + audioPlayer ?? _MockPinballAudioPlayer(), + children: [ + flipper, + ], + ), + ); + await flipper.ensureAdd( + FlameBlocProvider.value( + value: flipperBloc ?? FlipperCubit(), + children: [behavior], + ), + ); + } +} + +class _MockPinballAudioPlayer extends Mock implements PinballAudioPlayer {} + +class _MockFlipperCubit extends Mock implements FlipperCubit {} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + final flameTester = FlameTester(_TestGame.new); + + group('FlipperNoiseBehavior', () { + test('can be instantiated', () { + expect( + FlipperNoiseBehavior(), + isA(), + ); + }); + + flameTester.test( + 'plays the flipper sound when moving up', + (game) async { + final audioPlayer = _MockPinballAudioPlayer(); + final bloc = _MockFlipperCubit(); + whenListen( + bloc, + Stream.fromIterable([FlipperState.movingUp]), + initialState: FlipperState.movingUp, + ); + + final behavior = FlipperNoiseBehavior(); + await game.pump( + behavior, + flipperBloc: bloc, + audioPlayer: audioPlayer, + ); + behavior.onNewState(FlipperState.movingUp); + game.update(0); + + verify(() => audioPlayer.play(PinballAudio.flipper)).called(1); + }, + ); + }); +} From 1c8813e0391f941c7dbf8601fab4fe0e6b620d7a Mon Sep 17 00:00:00 2001 From: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> Date: Mon, 9 May 2022 18:53:45 -0500 Subject: [PATCH 3/4] feat: loop animatronics (#452) * feat: loop animatronics * chore: rename animationCooldown * fix: appease cspell Co-authored-by: Tom Arra --- .../animatronic_looping_behavior.dart | 26 +++++ lib/game/behaviors/behaviors.dart | 1 + .../flutter_forest_bonus_behavior.dart | 2 - .../flutter_forest/flutter_forest.dart | 6 +- .../sparky_computer_bonus_behavior.dart | 2 - .../sparky_scorch/sparky_scorch.dart | 6 +- .../lib/src/components/dash_animatronic.dart | 8 +- .../src/components/sparky_animatronic.dart | 8 +- .../src/components/dash_animatronic_test.dart | 22 ++-- .../components/sparky_animatronic_test.dart | 24 ++-- .../animatronic_looping_behavior_test.dart | 105 ++++++++++++++++++ .../flutter_forest_bonus_behavior_test.dart | 14 +-- .../sparky_computer_bonus_behavior_test.dart | 10 +- 13 files changed, 172 insertions(+), 62 deletions(-) create mode 100644 lib/game/behaviors/animatronic_looping_behavior.dart create mode 100644 test/game/behaviors/animatronic_looping_behavior_test.dart diff --git a/lib/game/behaviors/animatronic_looping_behavior.dart b/lib/game/behaviors/animatronic_looping_behavior.dart new file mode 100644 index 00000000..ec741608 --- /dev/null +++ b/lib/game/behaviors/animatronic_looping_behavior.dart @@ -0,0 +1,26 @@ +import 'package:flame/components.dart'; +import 'package:pinball_flame/pinball_flame.dart'; + +class AnimatronicLoopingBehavior extends TimerComponent + with ParentIsA { + AnimatronicLoopingBehavior({ + required double animationCoolDown, + }) : super(period: animationCoolDown); + + @override + Future onLoad() async { + await super.onLoad(); + parent.animation?.onComplete = () { + parent.animation?.reset(); + parent.playing = false; + timer + ..reset() + ..start(); + }; + } + + @override + void onTick() { + parent.playing = true; + } +} diff --git a/lib/game/behaviors/behaviors.dart b/lib/game/behaviors/behaviors.dart index bca8be14..03a99b57 100644 --- a/lib/game/behaviors/behaviors.dart +++ b/lib/game/behaviors/behaviors.dart @@ -1,3 +1,4 @@ +export 'animatronic_looping_behavior.dart'; export 'ball_spawning_behavior.dart'; export 'bonus_ball_spawning_behavior.dart'; export 'bonus_noise_behavior.dart'; diff --git a/lib/game/components/flutter_forest/behaviors/flutter_forest_bonus_behavior.dart b/lib/game/components/flutter_forest/behaviors/flutter_forest_bonus_behavior.dart index 3c4ef02a..d13297f0 100644 --- a/lib/game/components/flutter_forest/behaviors/flutter_forest_bonus_behavior.dart +++ b/lib/game/components/flutter_forest/behaviors/flutter_forest_bonus_behavior.dart @@ -21,7 +21,6 @@ class FlutterForestBonusBehavior extends Component final bumpers = parent.children.whereType(); final signpost = parent.firstChild()!; - final animatronic = parent.firstChild()!; for (final bumper in bumpers) { bumper.bloc.stream.listen((state) { @@ -38,7 +37,6 @@ class FlutterForestBonusBehavior extends Component if (signpost.bloc.isFullyProgressed()) { bloc.add(const BonusActivated(GameBonus.dashNest)); add(BonusBallSpawningBehavior()); - animatronic.playing = true; signpost.bloc.onProgressed(); } } diff --git a/lib/game/components/flutter_forest/flutter_forest.dart b/lib/game/components/flutter_forest/flutter_forest.dart index 39783bb1..57bd24c4 100644 --- a/lib/game/components/flutter_forest/flutter_forest.dart +++ b/lib/game/components/flutter_forest/flutter_forest.dart @@ -40,7 +40,11 @@ class FlutterForest extends Component with ZIndex { BumperNoiseBehavior(), ], )..initialPosition = Vector2(21.8, -46.75), - DashAnimatronic()..position = Vector2(20, -66), + DashAnimatronic( + children: [ + AnimatronicLoopingBehavior(animationCoolDown: 4), + ], + )..position = Vector2(20, -66), FlutterForestBonusBehavior(), ], ) { diff --git a/lib/game/components/sparky_scorch/behaviors/sparky_computer_bonus_behavior.dart b/lib/game/components/sparky_scorch/behaviors/sparky_computer_bonus_behavior.dart index d1b8898e..3cd2fc0b 100644 --- a/lib/game/components/sparky_scorch/behaviors/sparky_computer_bonus_behavior.dart +++ b/lib/game/components/sparky_scorch/behaviors/sparky_computer_bonus_behavior.dart @@ -12,13 +12,11 @@ class SparkyComputerBonusBehavior extends Component void onMount() { super.onMount(); final sparkyComputer = parent.firstChild()!; - final animatronic = parent.firstChild()!; sparkyComputer.bloc.stream.listen((state) async { final listenWhen = state == SparkyComputerState.withBall; if (!listenWhen) return; bloc.add(const BonusActivated(GameBonus.sparkyTurboCharge)); - animatronic.playing = true; }); } } diff --git a/lib/game/components/sparky_scorch/sparky_scorch.dart b/lib/game/components/sparky_scorch/sparky_scorch.dart index da624361..c7cd71d3 100644 --- a/lib/game/components/sparky_scorch/sparky_scorch.dart +++ b/lib/game/components/sparky_scorch/sparky_scorch.dart @@ -33,7 +33,11 @@ class SparkyScorch extends Component { BumperNoiseBehavior(), ], )..initialPosition = Vector2(-3.3, -52.55), - SparkyAnimatronic()..position = Vector2(-14, -58.2), + SparkyAnimatronic( + children: [ + AnimatronicLoopingBehavior(animationCoolDown: 3), + ], + )..position = Vector2(-14, -58.2), SparkyComputer( children: [ ScoringContactBehavior(points: Points.twoHundredThousand) diff --git a/packages/pinball_components/lib/src/components/dash_animatronic.dart b/packages/pinball_components/lib/src/components/dash_animatronic.dart index bb7d983b..7202dd09 100644 --- a/packages/pinball_components/lib/src/components/dash_animatronic.dart +++ b/packages/pinball_components/lib/src/components/dash_animatronic.dart @@ -6,10 +6,11 @@ import 'package:pinball_components/pinball_components.dart'; /// {@endtemplate} class DashAnimatronic extends SpriteAnimationComponent with HasGameRef { /// {@macro dash_animatronic} - DashAnimatronic() + DashAnimatronic({Iterable? children}) : super( anchor: Anchor.center, playing: false, + children: children, ); @override @@ -37,9 +38,6 @@ class DashAnimatronic extends SpriteAnimationComponent with HasGameRef { textureSize: textureSize, loop: false, ), - )..onComplete = () { - animation?.reset(); - playing = false; - }; + ); } } diff --git a/packages/pinball_components/lib/src/components/sparky_animatronic.dart b/packages/pinball_components/lib/src/components/sparky_animatronic.dart index 2ee2803c..05a16e47 100644 --- a/packages/pinball_components/lib/src/components/sparky_animatronic.dart +++ b/packages/pinball_components/lib/src/components/sparky_animatronic.dart @@ -8,10 +8,11 @@ import 'package:pinball_flame/pinball_flame.dart'; class SparkyAnimatronic extends SpriteAnimationComponent with HasGameRef, ZIndex { /// {@macro sparky_animatronic} - SparkyAnimatronic() + SparkyAnimatronic({Iterable? children}) : super( anchor: Anchor.center, playing: false, + children: children, ) { zIndex = ZIndexes.sparkyAnimatronic; } @@ -41,9 +42,6 @@ class SparkyAnimatronic extends SpriteAnimationComponent textureSize: textureSize, loop: false, ), - )..onComplete = () { - animation?.reset(); - playing = false; - }; + ); } } diff --git a/packages/pinball_components/test/src/components/dash_animatronic_test.dart b/packages/pinball_components/test/src/components/dash_animatronic_test.dart index d64c3f07..282e9f8d 100644 --- a/packages/pinball_components/test/src/components/dash_animatronic_test.dart +++ b/packages/pinball_components/test/src/components/dash_animatronic_test.dart @@ -1,6 +1,6 @@ // ignore_for_file: cascade_invocations -import 'package:flame/extensions.dart'; +import 'package:flame/components.dart'; import 'package:flame_test/flame_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pinball_components/pinball_components.dart'; @@ -56,17 +56,13 @@ void main() { }, ); - flameTester.test( - 'stops animating after animation completes', - (game) async { - final dashAnimatronic = DashAnimatronic(); - await game.ensureAdd(dashAnimatronic); - - dashAnimatronic.playing = true; - game.update(4); - - expect(dashAnimatronic.playing, isFalse); - }, - ); + flameTester.test('adds new children', (game) async { + final component = Component(); + final dashAnimatronic = DashAnimatronic( + children: [component], + ); + await game.ensureAdd(dashAnimatronic); + expect(dashAnimatronic.children, contains(component)); + }); }); } diff --git a/packages/pinball_components/test/src/components/sparky_animatronic_test.dart b/packages/pinball_components/test/src/components/sparky_animatronic_test.dart index 66c2e0a6..175c9596 100644 --- a/packages/pinball_components/test/src/components/sparky_animatronic_test.dart +++ b/packages/pinball_components/test/src/components/sparky_animatronic_test.dart @@ -1,6 +1,6 @@ // ignore_for_file: cascade_invocations -import 'package:flame/extensions.dart'; +import 'package:flame/components.dart'; import 'package:flame_test/flame_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pinball_components/pinball_components.dart'; @@ -58,19 +58,13 @@ void main() { }, ); - flameTester.test( - 'stops animating after animation completes', - (game) async { - final sparkyAnimatronic = SparkyAnimatronic(); - await game.ensureAdd(sparkyAnimatronic); - - sparkyAnimatronic.playing = true; - final animationDuration = - game.firstChild()!.animation!.totalDuration(); - game.update(animationDuration); - - expect(sparkyAnimatronic.playing, isFalse); - }, - ); + flameTester.test('adds new children', (game) async { + final component = Component(); + final sparkyAnimatronic = SparkyAnimatronic( + children: [component], + ); + await game.ensureAdd(sparkyAnimatronic); + expect(sparkyAnimatronic.children, contains(component)); + }); }); } diff --git a/test/game/behaviors/animatronic_looping_behavior_test.dart b/test/game/behaviors/animatronic_looping_behavior_test.dart new file mode 100644 index 00000000..0aacd508 --- /dev/null +++ b/test/game/behaviors/animatronic_looping_behavior_test.dart @@ -0,0 +1,105 @@ +// ignore_for_file: cascade_invocations + +import 'package:flame/components.dart'; +import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:flame_test/flame_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:pinball/game/behaviors/behaviors.dart'; +import 'package:pinball_components/pinball_components.dart'; + +class _TestGame extends Forge2DGame { + @override + Future onLoad() async { + images.prefix = ''; + await images.load(Assets.images.dash.animatronic.keyName); + } +} + +class _TestSpriteAnimationComponent extends SpriteAnimationComponent {} + +class _MockSpriteAnimation extends Mock implements SpriteAnimation {} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + final flameTester = FlameTester(_TestGame.new); + + group('AnimatronicLoopingBehavior', () { + test('can be instantiated', () { + expect( + AnimatronicLoopingBehavior(animationCoolDown: 1), + isA(), + ); + }); + + flameTester.test( + 'can be added', + (game) async { + final behavior = AnimatronicLoopingBehavior(animationCoolDown: 1); + final animation = _MockSpriteAnimation(); + final spriteAnimationComponent = _TestSpriteAnimationComponent() + ..animation = animation; + await game.ensureAdd(spriteAnimationComponent); + await spriteAnimationComponent.add(behavior); + await game.ready(); + + expect(game.contains(spriteAnimationComponent), isTrue); + expect(spriteAnimationComponent.contains(behavior), isTrue); + }, + ); + + flameTester.test( + 'onTick starts playing the animation', + (game) async { + final behavior = AnimatronicLoopingBehavior(animationCoolDown: 1); + final spriteAnimationComponent = _TestSpriteAnimationComponent(); + await game.ensureAdd(spriteAnimationComponent); + await spriteAnimationComponent.add(behavior); + + spriteAnimationComponent.playing = false; + game.update(behavior.timer.limit); + + expect(spriteAnimationComponent.playing, isTrue); + }, + ); + + flameTester.test( + 'animation onComplete resets and stops playing the animation', + (game) async { + final behavior = AnimatronicLoopingBehavior(animationCoolDown: 1); + final spriteAnimationComponent = DashAnimatronic(); + + await game.ensureAdd(spriteAnimationComponent); + await spriteAnimationComponent.add(behavior); + + game.update(1); + expect(spriteAnimationComponent.playing, isTrue); + + spriteAnimationComponent.animation!.onComplete!.call(); + + expect(spriteAnimationComponent.playing, isFalse); + expect(spriteAnimationComponent.animation!.currentIndex, equals(0)); + }, + ); + + flameTester.test( + 'animation onComplete resets and starts the timer', + (game) async { + final behavior = AnimatronicLoopingBehavior(animationCoolDown: 1); + final spriteAnimationComponent = DashAnimatronic(); + + await game.ensureAdd(spriteAnimationComponent); + await spriteAnimationComponent.add(behavior); + + game.update(0.5); + expect(behavior.timer.current, equals(0.5)); + + spriteAnimationComponent.animation!.onComplete!.call(); + + expect(behavior.timer.current, equals(0)); + expect(behavior.timer.isRunning(), isTrue); + }, + ); + }); +} diff --git a/test/game/components/flutter_forest/behaviors/flutter_forest_bonus_behavior_test.dart b/test/game/components/flutter_forest/behaviors/flutter_forest_bonus_behavior_test.dart index 7fc1946b..fdef2f39 100644 --- a/test/game/components/flutter_forest/behaviors/flutter_forest_bonus_behavior_test.dart +++ b/test/game/components/flutter_forest/behaviors/flutter_forest_bonus_behavior_test.dart @@ -16,10 +16,7 @@ class _TestGame extends Forge2DGame { @override Future onLoad() async { images.prefix = ''; - await images.loadAll([ - Assets.images.dash.animatronic.keyName, - theme.Assets.images.dash.ball.keyName, - ]); + await images.load(theme.Assets.images.dash.ball.keyName); } Future pump( @@ -67,10 +64,9 @@ void main() { DashBumper.test(bloc: DashBumperCubit()), DashBumper.test(bloc: DashBumperCubit()), ]; - final animatronic = DashAnimatronic(); final signpost = Signpost.test(bloc: SignpostCubit()); await game.pump(parent, gameBloc: gameBloc); - await parent.ensureAddAll([...bumpers, animatronic, signpost]); + await parent.ensureAddAll([...bumpers, signpost]); await parent.ensureAdd(behavior); expect(game.descendants().whereType(), equals(bumpers)); @@ -99,10 +95,9 @@ void main() { DashBumper.test(bloc: DashBumperCubit()), DashBumper.test(bloc: DashBumperCubit()), ]; - final animatronic = DashAnimatronic(); final signpost = Signpost.test(bloc: SignpostCubit()); await game.pump(parent, gameBloc: gameBloc); - await parent.ensureAddAll([...bumpers, animatronic, signpost]); + await parent.ensureAddAll([...bumpers, signpost]); await parent.ensureAdd(behavior); expect(game.descendants().whereType(), equals(bumpers)); @@ -133,10 +128,9 @@ void main() { DashBumper.test(bloc: DashBumperCubit()), DashBumper.test(bloc: DashBumperCubit()), ]; - final animatronic = DashAnimatronic(); final signpost = Signpost.test(bloc: SignpostCubit()); await game.pump(parent, gameBloc: gameBloc); - await parent.ensureAddAll([...bumpers, animatronic, signpost]); + await parent.ensureAddAll([...bumpers, signpost]); await parent.ensureAdd(behavior); expect(game.descendants().whereType(), equals(bumpers)); diff --git a/test/game/components/sparky_scorch/behaviors/sparky_computer_bonus_behavior_test.dart b/test/game/components/sparky_scorch/behaviors/sparky_computer_bonus_behavior_test.dart index fbfeef0b..2dfb54cf 100644 --- a/test/game/components/sparky_scorch/behaviors/sparky_computer_bonus_behavior_test.dart +++ b/test/game/components/sparky_scorch/behaviors/sparky_computer_bonus_behavior_test.dart @@ -17,7 +17,6 @@ class _TestGame extends Forge2DGame { Assets.images.sparky.computer.top.keyName, Assets.images.sparky.computer.base.keyName, Assets.images.sparky.computer.glow.keyName, - Assets.images.sparky.animatronic.keyName, Assets.images.sparky.bumper.a.lit.keyName, Assets.images.sparky.bumper.a.dimmed.keyName, Assets.images.sparky.bumper.b.lit.keyName, @@ -58,18 +57,14 @@ void main() { final flameTester = FlameTester(_TestGame.new); flameTester.testGameWidget( - 'adds GameBonus.sparkyTurboCharge to the game and plays animatronic ' + 'adds GameBonus.sparkyTurboCharge to the game ' 'when SparkyComputerState.withBall is emitted', setUp: (game, tester) async { final behavior = SparkyComputerBonusBehavior(); final parent = SparkyScorch.test(); final sparkyComputer = SparkyComputer(); - final animatronic = SparkyAnimatronic(); - await parent.addAll([ - sparkyComputer, - animatronic, - ]); + await parent.add(sparkyComputer); await game.pump(parent, gameBloc: gameBloc); await parent.ensureAdd(behavior); @@ -79,7 +74,6 @@ void main() { verify( () => gameBloc.add(const BonusActivated(GameBonus.sparkyTurboCharge)), ).called(1); - expect(animatronic.playing, isTrue); }, ); }); From ad77839d3ad682873161d3b9b2340b057c953094 Mon Sep 17 00:00:00 2001 From: Alejandro Santiago Date: Tue, 10 May 2022 01:33:17 +0100 Subject: [PATCH 4/4] revert: changed `CameraFocusingBehavior` logic (#451) * revert: changed CameraFocusingBehavior logic * refactor: removed unnecessary type Co-authored-by: Erick * fix: coverage Co-authored-by: Erick Co-authored-by: Tom Arra --- .../behaviors/camera_focusing_behavior.dart | 41 ++++++++----------- .../camera_focusing_behavior_test.dart | 27 ++++++------ 2 files changed, 30 insertions(+), 38 deletions(-) diff --git a/lib/game/behaviors/camera_focusing_behavior.dart b/lib/game/behaviors/camera_focusing_behavior.dart index 1d454f02..ec3e918f 100644 --- a/lib/game/behaviors/camera_focusing_behavior.dart +++ b/lib/game/behaviors/camera_focusing_behavior.dart @@ -1,5 +1,3 @@ -import 'dart:math'; - import 'package:flame/components.dart'; import 'package:flame/game.dart'; import 'package:flame_bloc/flame_bloc.dart'; @@ -43,30 +41,25 @@ class CameraFocusingBehavior extends Component @override void onGameResize(Vector2 size) { super.onGameResize(size); - if (size == _previousSize) { - return; - } + if (size == _previousSize) return; _previousSize.setFrom(size); - final maxWidth = size.x / 90; - final maxHeight = size.y / 160; - - final scale = min(maxHeight, maxWidth); - - _foci.addAll({ - GameStatus.waiting: _FocusData( - zoom: scale + (maxWidth > maxHeight ? 0.3 : -0.5), - position: Vector2(0, -112), - ), - GameStatus.playing: _FocusData( - zoom: scale + (maxWidth > maxHeight ? 0.5 : -0.2), - position: Vector2(0, -7.8), - ), - GameStatus.gameOver: _FocusData( - zoom: scale + (maxWidth > maxHeight ? 2.8 : 3.3), - position: Vector2(0, -111), - ), - }); + _foci.addAll( + { + GameStatus.waiting: _FocusData( + zoom: size.y / 175, + position: _foci[GameStatus.waiting]?.position ?? Vector2(0, -112), + ), + GameStatus.playing: _FocusData( + zoom: size.y / 165, + position: _foci[GameStatus.playing]?.position ?? Vector2(0, -7.8), + ), + GameStatus.gameOver: _FocusData( + zoom: size.y / 100, + position: _foci[GameStatus.gameOver]?.position ?? Vector2(0, -111), + ), + }, + ); if (_activeFocus != null) { _snap(_activeFocus!); diff --git a/test/game/behaviors/camera_focusing_behavior_test.dart b/test/game/behaviors/camera_focusing_behavior_test.dart index 092f3efe..fb0d91c5 100644 --- a/test/game/behaviors/camera_focusing_behavior_test.dart +++ b/test/game/behaviors/camera_focusing_behavior_test.dart @@ -34,6 +34,19 @@ void main() { expect(game.descendants(), contains(behavior)); }); + flameTester.test('resizes and snaps', (game) async { + final behavior = CameraFocusingBehavior(); + await game.ensureAdd( + FlameBlocProvider.value( + value: GameBloc(), + children: [behavior], + ), + ); + + behavior.onGameResize(Vector2.all(10)); + expect(game.camera.zoom, greaterThan(0)); + }); + flameTester.test( 'changes focus when loaded', (game) async { @@ -53,20 +66,6 @@ void main() { }, ); - flameTester.test('sets zoom on resize', (game) async { - final behavior = CameraFocusingBehavior(); - - await game.ensureAdd( - FlameBlocProvider.value( - value: GameBloc(), - children: [behavior], - ), - ); - - game.onGameResize(game.canvasSize * 2); - expect(game.camera.zoom, equals(6.55)); - }); - flameTester.test( 'listenWhen only listens when status changes', (game) async {