From 031dea0389a7c4058ec1a8b974b94471fb3dfbbb Mon Sep 17 00:00:00 2001 From: Allison Ryan Date: Sun, 8 May 2022 15:16:13 -0500 Subject: [PATCH] feat: add kicker audio group --- lib/game/behaviors/behaviors.dart | 1 + lib/game/behaviors/kicker_noise_behavior.dart | 11 +++ lib/game/components/bottom_group.dart | 1 + .../pinball_audio/assets/sfx/kicker_a.mp3 | Bin 0 -> 10689 bytes .../pinball_audio/assets/sfx/kicker_b.mp3 | Bin 0 -> 9693 bytes .../pinball_audio/lib/gen/assets.gen.dart | 2 + .../pinball_audio/lib/src/pinball_audio.dart | 41 +++++++++++ .../test/src/pinball_audio_test.dart | 65 ++++++++++++++++++ .../behaviors/kicker_noise_behavior_test.dart | 59 ++++++++++++++++ 9 files changed, 180 insertions(+) create mode 100644 lib/game/behaviors/kicker_noise_behavior.dart create mode 100644 packages/pinball_audio/assets/sfx/kicker_a.mp3 create mode 100644 packages/pinball_audio/assets/sfx/kicker_b.mp3 create mode 100644 test/game/behaviors/kicker_noise_behavior_test.dart diff --git a/lib/game/behaviors/behaviors.dart b/lib/game/behaviors/behaviors.dart index 190d014e..bb196cec 100644 --- a/lib/game/behaviors/behaviors.dart +++ b/lib/game/behaviors/behaviors.dart @@ -5,4 +5,5 @@ export 'bumper_noise_behavior.dart'; export 'camera_focusing_behavior.dart'; export 'character_selection_behavior.dart'; export 'cow_bumper_noise_behavior.dart'; +export 'kicker_noise_behavior.dart'; export 'scoring_behavior.dart'; diff --git a/lib/game/behaviors/kicker_noise_behavior.dart b/lib/game/behaviors/kicker_noise_behavior.dart new file mode 100644 index 00000000..a04ffeff --- /dev/null +++ b/lib/game/behaviors/kicker_noise_behavior.dart @@ -0,0 +1,11 @@ +import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:pinball_audio/pinball_audio.dart'; +import 'package:pinball_flame/pinball_flame.dart'; + +class KickerNoiseBehavior extends ContactBehavior { + @override + void beginContact(Object other, Contact contact) { + super.beginContact(other, contact); + readProvider().play(PinballAudio.kicker); + } +} diff --git a/lib/game/components/bottom_group.dart b/lib/game/components/bottom_group.dart index bc644f96..cfa7e434 100644 --- a/lib/game/components/bottom_group.dart +++ b/lib/game/components/bottom_group.dart @@ -52,6 +52,7 @@ class _BottomGroupSide extends Component { children: [ ScoringContactBehavior(points: Points.fiveThousand) ..applyTo(['bouncy_edge']), + KickerNoiseBehavior()..applyTo(['bouncy_edge']), ], )..initialPosition = Vector2( (22.44 * direction) + centerXAdjustment, diff --git a/packages/pinball_audio/assets/sfx/kicker_a.mp3 b/packages/pinball_audio/assets/sfx/kicker_a.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..475cbc13a2fd5fcecc4622dba095ece21d0fe301 GIT binary patch literal 10689 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 literal 0 HcmV?d00001 diff --git a/packages/pinball_audio/assets/sfx/kicker_b.mp3 b/packages/pinball_audio/assets/sfx/kicker_b.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..2b1bdfbc0872101cc86401557a869b917f03004a GIT binary patch literal 9693 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 Z<=?Sg{w!Yx004La0NKl4(*F}<`yc3Z4q5;J 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 bdb1527a..c8b66234 100644 --- a/packages/pinball_audio/lib/gen/assets.gen.dart +++ b/packages/pinball_audio/lib/gen/assets.gen.dart @@ -23,6 +23,8 @@ class $AssetsSfxGen { 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'; + String get kickerA => 'assets/sfx/kicker_a.mp3'; + String get kickerB => 'assets/sfx/kicker_b.mp3'; String get launcher => 'assets/sfx/launcher.mp3'; String get sparky => 'assets/sfx/sparky.mp3'; } diff --git a/packages/pinball_audio/lib/src/pinball_audio.dart b/packages/pinball_audio/lib/src/pinball_audio.dart index e8b9c8ed..0e0ef85b 100644 --- a/packages/pinball_audio/lib/src/pinball_audio.dart +++ b/packages/pinball_audio/lib/src/pinball_audio.dart @@ -30,6 +30,9 @@ enum PinballAudio { /// Launcher. launcher, + /// Kicker. + kicker, + /// Sparky. sparky, @@ -149,6 +152,40 @@ class _BumperAudio extends _Audio { } } +class _KickerAudio extends _Audio { + _KickerAudio({ + required this.createAudioPool, + required this.seed, + }); + + final CreateAudioPool createAudioPool; + final Random seed; + + late AudioPool kickerA; + late AudioPool kickerB; + + @override + Future load() async { + await Future.wait( + [ + createAudioPool( + prefixFile(Assets.sfx.kickerA), + prefix: '', + ).then((pool) => kickerA = pool), + createAudioPool( + prefixFile(Assets.sfx.kickerB), + prefix: '', + ).then((pool) => kickerB = pool), + ], + ); + } + + @override + void play() { + (seed.nextBool() ? kickerA : kickerB).start(volume: 0.6); + } +} + class _ThrottledAudio extends _Audio { _ThrottledAudio({ required this.preCacheSingleAudio, @@ -245,6 +282,10 @@ class PinballAudioPlayer { createAudioPool: _createAudioPool, seed: _seed, ), + PinballAudio.kicker: _KickerAudio( + createAudioPool: _createAudioPool, + seed: _seed, + ), PinballAudio.cowMoo: _ThrottledAudio( 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 d1ff6f06..aaec1198 100644 --- a/packages/pinball_audio/test/src/pinball_audio_test.dart +++ b/packages/pinball_audio/test/src/pinball_audio_test.dart @@ -119,6 +119,24 @@ void main() { ).called(1); }); + test('creates the kicker pools', () async { + await Future.wait(audioPlayer.load()); + + verify( + () => createAudioPool.onCall( + 'packages/pinball_audio/${Assets.sfx.kickerA}', + prefix: '', + ), + ).called(1); + + verify( + () => createAudioPool.onCall( + 'packages/pinball_audio/${Assets.sfx.kickerB}', + prefix: '', + ), + ).called(1); + }); + test('configures the audio cache instance', () async { await Future.wait(audioPlayer.load()); @@ -234,6 +252,53 @@ void main() { }); }); + group('kicker', () { + late AudioPool kickerAPool; + late AudioPool kickerBPool; + + setUp(() { + kickerAPool = _MockAudioPool(); + when(() => kickerAPool.start(volume: any(named: 'volume'))) + .thenAnswer((_) async => () {}); + when( + () => createAudioPool.onCall( + 'packages/pinball_audio/${Assets.sfx.kickerA}', + prefix: any(named: 'prefix'), + ), + ).thenAnswer((_) async => kickerAPool); + + kickerBPool = _MockAudioPool(); + when(() => kickerBPool.start(volume: any(named: 'volume'))) + .thenAnswer((_) async => () {}); + when( + () => createAudioPool.onCall( + 'packages/pinball_audio/${Assets.sfx.kickerB}', + prefix: any(named: 'prefix'), + ), + ).thenAnswer((_) async => kickerBPool); + }); + + group('when seed is true', () { + test('plays the kicker A sound pool', () async { + when(seed.nextBool).thenReturn(true); + await Future.wait(audioPlayer.load()); + audioPlayer.play(PinballAudio.kicker); + + verify(() => kickerAPool.start(volume: 0.6)).called(1); + }); + }); + + group('when seed is false', () { + test('plays the kicker B sound pool', () async { + when(seed.nextBool).thenReturn(false); + await Future.wait(audioPlayer.load()); + audioPlayer.play(PinballAudio.kicker); + + verify(() => kickerBPool.start(volume: 0.6)).called(1); + }); + }); + }); + group('cow moo', () { test('plays the correct file', () async { await Future.wait(audioPlayer.load()); diff --git a/test/game/behaviors/kicker_noise_behavior_test.dart b/test/game/behaviors/kicker_noise_behavior_test.dart new file mode 100644 index 00000000..4db18ab4 --- /dev/null +++ b/test/game/behaviors/kicker_noise_behavior_test.dart @@ -0,0 +1,59 @@ +// ignore_for_file: cascade_invocations + +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_audio/pinball_audio.dart'; +import 'package:pinball_flame/pinball_flame.dart'; + +class _TestGame extends Forge2DGame { + Future pump( + _TestBodyComponent child, { + required PinballAudioPlayer audioPlayer, + }) { + return ensureAdd( + FlameProvider.value( + audioPlayer, + children: [child], + ), + ); + } +} + +class _TestBodyComponent extends BodyComponent { + @override + Body createBody() => world.createBody(BodyDef()); +} + +class _MockPinballAudioPlayer extends Mock implements PinballAudioPlayer {} + +class _MockContact extends Mock implements Contact {} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('KickerNoiseBehavior', () { + late PinballAudioPlayer audioPlayer; + final flameTester = FlameTester(_TestGame.new); + + setUp(() { + audioPlayer = _MockPinballAudioPlayer(); + }); + + flameTester.testGameWidget( + 'plays kicker sound', + setUp: (game, _) async { + final behavior = KickerNoiseBehavior(); + final parent = _TestBodyComponent(); + await game.pump(parent, audioPlayer: audioPlayer); + await parent.ensureAdd(behavior); + behavior.beginContact(Object(), _MockContact()); + }, + verify: (_, __) async { + verify(() => audioPlayer.play(PinballAudio.kicker)).called(1); + }, + ); + }); +}