feat: add kicker audio group (#418)

* feat: add kicker audio group

* refactor: add RandomABAudio
pull/421/head
Allison Ryan 2 years ago committed by GitHub
parent 18d40aa85d
commit d601af7307
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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';

@ -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<PinballAudioPlayer>().play(PinballAudio.kicker);
}
}

@ -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,

@ -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';
}

@ -30,6 +30,9 @@ enum PinballAudio {
/// Launcher.
launcher,
/// Kicker.
kicker,
/// Sparky.
sparky,
@ -113,39 +116,45 @@ class _LoopAudio extends _Audio {
}
}
class _BumperAudio extends _Audio {
_BumperAudio({
class _RandomABAudio extends _Audio {
_RandomABAudio({
required this.createAudioPool,
required this.seed,
required this.audioAssetA,
required this.audioAssetB,
this.volume,
});
final CreateAudioPool createAudioPool;
final Random seed;
final String audioAssetA;
final String audioAssetB;
final double? volume;
late AudioPool bumperA;
late AudioPool bumperB;
late AudioPool audioA;
late AudioPool audioB;
@override
Future<void> load() async {
await Future.wait(
[
createAudioPool(
prefixFile(Assets.sfx.bumperA),
prefixFile(audioAssetA),
maxPlayers: 4,
prefix: '',
).then((pool) => bumperA = pool),
).then((pool) => audioA = pool),
createAudioPool(
prefixFile(Assets.sfx.bumperB),
prefixFile(audioAssetB),
maxPlayers: 4,
prefix: '',
).then((pool) => bumperB = pool),
).then((pool) => audioB = pool),
],
);
}
@override
void play() {
(seed.nextBool() ? bumperA : bumperB).start(volume: 0.6);
(seed.nextBool() ? audioA : audioB).start(volume: volume ?? 1);
}
}
@ -241,9 +250,19 @@ class PinballAudioPlayer {
playSingleAudio: _playSingleAudio,
path: Assets.sfx.gameOverVoiceOver,
),
PinballAudio.bumper: _BumperAudio(
PinballAudio.bumper: _RandomABAudio(
createAudioPool: _createAudioPool,
seed: _seed,
audioAssetA: Assets.sfx.bumperA,
audioAssetB: Assets.sfx.bumperB,
volume: 0.6,
),
PinballAudio.kicker: _RandomABAudio(
createAudioPool: _createAudioPool,
seed: _seed,
audioAssetA: Assets.sfx.kickerA,
audioAssetB: Assets.sfx.kickerB,
volume: 0.6,
),
PinballAudio.cowMoo: _ThrottledAudio(
preCacheSingleAudio: _preCacheSingleAudio,

@ -119,6 +119,26 @@ void main() {
).called(1);
});
test('creates the kicker pools', () async {
await Future.wait(audioPlayer.load());
verify(
() => createAudioPool.onCall(
'packages/pinball_audio/${Assets.sfx.kickerA}',
maxPlayers: 4,
prefix: '',
),
).called(1);
verify(
() => createAudioPool.onCall(
'packages/pinball_audio/${Assets.sfx.kickerB}',
maxPlayers: 4,
prefix: '',
),
).called(1);
});
test('configures the audio cache instance', () async {
await Future.wait(audioPlayer.load());
@ -234,6 +254,55 @@ 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}',
maxPlayers: any(named: 'maxPlayers'),
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}',
maxPlayers: any(named: 'maxPlayers'),
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());

@ -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<void> pump(
_TestBodyComponent child, {
required PinballAudioPlayer audioPlayer,
}) {
return ensureAdd(
FlameProvider<PinballAudioPlayer>.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);
},
);
});
}
Loading…
Cancel
Save