Merge branch 'main' into feat/leaderboard

pull/352/head
Erick 3 years ago committed by GitHub
commit 7cce80cfde
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,4 +1,4 @@
export 'ball_spawning_behavior.dart'; export 'ball_spawning_behavior.dart';
export 'bumper_noisy_behavior.dart'; export 'bumper_noise_behavior.dart';
export 'camera_focusing_behavior.dart'; export 'camera_focusing_behavior.dart';
export 'scoring_behavior.dart'; export 'scoring_behavior.dart';

@ -6,7 +6,7 @@ import 'package:pinball/game/pinball_game.dart';
import 'package:pinball_audio/pinball_audio.dart'; import 'package:pinball_audio/pinball_audio.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
class BumperNoisyBehavior extends ContactBehavior with HasGameRef<PinballGame> { class BumperNoiseBehavior extends ContactBehavior with HasGameRef<PinballGame> {
@override @override
void beginContact(Object other, Contact contact) { void beginContact(Object other, Contact contact) {
super.beginContact(other, contact); super.beginContact(other, contact);

@ -35,19 +35,19 @@ class AndroidAcres extends Component {
AndroidBumper.a( AndroidBumper.a(
children: [ children: [
ScoringContactBehavior(points: Points.twentyThousand), ScoringContactBehavior(points: Points.twentyThousand),
BumperNoisyBehavior(), BumperNoiseBehavior(),
], ],
)..initialPosition = Vector2(-25, 1.3), )..initialPosition = Vector2(-25, 1.3),
AndroidBumper.b( AndroidBumper.b(
children: [ children: [
ScoringContactBehavior(points: Points.twentyThousand), ScoringContactBehavior(points: Points.twentyThousand),
BumperNoisyBehavior(), BumperNoiseBehavior(),
], ],
)..initialPosition = Vector2(-32.8, -9.2), )..initialPosition = Vector2(-32.8, -9.2),
AndroidBumper.cow( AndroidBumper.cow(
children: [ children: [
ScoringContactBehavior(points: Points.twentyThousand), ScoringContactBehavior(points: Points.twentyThousand),
BumperNoisyBehavior(), BumperNoiseBehavior(),
], ],
)..initialPosition = Vector2(-20.5, -13.8), )..initialPosition = Vector2(-20.5, -13.8),
AndroidSpaceshipBonusBehavior(), AndroidSpaceshipBonusBehavior(),

@ -2,6 +2,7 @@ import 'package:flame/components.dart';
import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_bloc/flame_bloc.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
import 'package:pinball_audio/pinball_audio.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
@ -14,6 +15,29 @@ class ControlledPlunger extends Plunger with Controls<PlungerController> {
: super(compressionDistance: compressionDistance) { : super(compressionDistance: compressionDistance) {
controller = PlungerController(this); controller = PlungerController(this);
} }
@override
void release() {
super.release();
add(PlungerNoiseBehavior());
}
}
/// A behavior attached to the plunger when it launches the ball
/// which plays the related sound effects.
class PlungerNoiseBehavior extends Component with HasGameRef<PinballGame> {
@override
Future<void> onLoad() async {
await super.onLoad();
gameRef.player.play(PinballAudio.launcher);
}
@override
void update(double dt) {
super.update(dt);
removeFromParent();
}
} }
/// {@template plunger_controller} /// {@template plunger_controller}

@ -19,25 +19,25 @@ class FlutterForest extends Component with ZIndex {
Signpost( Signpost(
children: [ children: [
ScoringContactBehavior(points: Points.fiveThousand), ScoringContactBehavior(points: Points.fiveThousand),
BumperNoisyBehavior(), BumperNoiseBehavior(),
], ],
)..initialPosition = Vector2(8.35, -58.3), )..initialPosition = Vector2(8.35, -58.3),
DashNestBumper.main( DashNestBumper.main(
children: [ children: [
ScoringContactBehavior(points: Points.twoHundredThousand), ScoringContactBehavior(points: Points.twoHundredThousand),
BumperNoisyBehavior(), BumperNoiseBehavior(),
], ],
)..initialPosition = Vector2(18.55, -59.35), )..initialPosition = Vector2(18.55, -59.35),
DashNestBumper.a( DashNestBumper.a(
children: [ children: [
ScoringContactBehavior(points: Points.twentyThousand), ScoringContactBehavior(points: Points.twentyThousand),
BumperNoisyBehavior(), BumperNoiseBehavior(),
], ],
)..initialPosition = Vector2(8.95, -51.95), )..initialPosition = Vector2(8.95, -51.95),
DashNestBumper.b( DashNestBumper.b(
children: [ children: [
ScoringContactBehavior(points: Points.twentyThousand), ScoringContactBehavior(points: Points.twentyThousand),
BumperNoisyBehavior(), BumperNoiseBehavior(),
], ],
)..initialPosition = Vector2(22.3, -46.75), )..initialPosition = Vector2(22.3, -46.75),
DashAnimatronic()..position = Vector2(20, -66), DashAnimatronic()..position = Vector2(20, -66),

@ -18,19 +18,19 @@ class SparkyScorch extends Component {
SparkyBumper.a( SparkyBumper.a(
children: [ children: [
ScoringContactBehavior(points: Points.twentyThousand), ScoringContactBehavior(points: Points.twentyThousand),
BumperNoisyBehavior(), BumperNoiseBehavior(),
], ],
)..initialPosition = Vector2(-22.9, -41.65), )..initialPosition = Vector2(-22.9, -41.65),
SparkyBumper.b( SparkyBumper.b(
children: [ children: [
ScoringContactBehavior(points: Points.twentyThousand), ScoringContactBehavior(points: Points.twentyThousand),
BumperNoisyBehavior(), BumperNoiseBehavior(),
], ],
)..initialPosition = Vector2(-21.25, -57.9), )..initialPosition = Vector2(-21.25, -57.9),
SparkyBumper.c( SparkyBumper.c(
children: [ children: [
ScoringContactBehavior(points: Points.twentyThousand), ScoringContactBehavior(points: Points.twentyThousand),
BumperNoisyBehavior(), BumperNoiseBehavior(),
], ],
)..initialPosition = Vector2(-3.3, -52.55), )..initialPosition = Vector2(-3.3, -52.55),
SparkyComputerSensor()..initialPosition = Vector2(-13, -49.9), SparkyComputerSensor()..initialPosition = Vector2(-13, -49.9),

@ -14,11 +14,13 @@ class $AssetsMusicGen {
class $AssetsSfxGen { class $AssetsSfxGen {
const $AssetsSfxGen(); const $AssetsSfxGen();
String get afterLaunch => 'assets/sfx/after_launch.mp3';
String get bumperA => 'assets/sfx/bumper_a.mp3'; String get bumperA => 'assets/sfx/bumper_a.mp3';
String get bumperB => 'assets/sfx/bumper_b.mp3'; String get bumperB => 'assets/sfx/bumper_b.mp3';
String get gameOverVoiceOver => 'assets/sfx/game_over_voice_over.mp3'; String get gameOverVoiceOver => 'assets/sfx/game_over_voice_over.mp3';
String get google => 'assets/sfx/google.mp3'; String get google => 'assets/sfx/google.mp3';
String get ioPinballVoiceOver => 'assets/sfx/io_pinball_voice_over.mp3'; String get ioPinballVoiceOver => 'assets/sfx/io_pinball_voice_over.mp3';
String get launcher => 'assets/sfx/launcher.mp3';
} }
class Assets { class Assets {

@ -22,6 +22,9 @@ enum PinballAudio {
/// Game over /// Game over
gameOverVoiceOver, gameOverVoiceOver,
/// Launcher
launcher,
} }
/// Defines the contract of the creation of an [AudioPool]. /// Defines the contract of the creation of an [AudioPool].
@ -158,6 +161,11 @@ class PinballPlayer {
playSingleAudio: _playSingleAudio, playSingleAudio: _playSingleAudio,
path: Assets.sfx.google, path: Assets.sfx.google,
), ),
PinballAudio.launcher: _SimplePlayAudio(
preCacheSingleAudio: _preCacheSingleAudio,
playSingleAudio: _playSingleAudio,
path: Assets.sfx.launcher,
),
PinballAudio.ioPinballVoiceOver: _SimplePlayAudio( PinballAudio.ioPinballVoiceOver: _SimplePlayAudio(
preCacheSingleAudio: _preCacheSingleAudio, preCacheSingleAudio: _preCacheSingleAudio,
playSingleAudio: _playSingleAudio, playSingleAudio: _playSingleAudio,

@ -151,6 +151,10 @@ void main() {
'packages/pinball_audio/assets/sfx/game_over_voice_over.mp3', 'packages/pinball_audio/assets/sfx/game_over_voice_over.mp3',
), ),
).called(1); ).called(1);
verify(
() => preCacheSingleAudio
.onCall('packages/pinball_audio/assets/sfx/launcher.mp3'),
).called(1);
verify( verify(
() => preCacheSingleAudio () => preCacheSingleAudio
.onCall('packages/pinball_audio/assets/music/background.mp3'), .onCall('packages/pinball_audio/assets/music/background.mp3'),
@ -219,6 +223,18 @@ void main() {
}); });
}); });
group('launcher', () {
test('plays the correct file', () async {
await Future.wait(player.load());
player.play(PinballAudio.launcher);
verify(
() => playSingleAudio
.onCall('packages/pinball_audio/${Assets.sfx.launcher}'),
).called(1);
});
});
group('ioPinballVoiceOver', () { group('ioPinballVoiceOver', () {
test('plays the correct file', () async { test('plays the correct file', () async {
await Future.wait(player.load()); await Future.wait(player.load());

@ -23,7 +23,7 @@ class _MockContact extends Mock implements Contact {}
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized(); TestWidgetsFlutterBinding.ensureInitialized();
group('BumperNoisyBehavior', () {}); group('BumperNoiseBehavior', () {});
late PinballPlayer player; late PinballPlayer player;
final flameTester = FlameTester( final flameTester = FlameTester(
@ -37,7 +37,7 @@ void main() {
flameTester.testGameWidget( flameTester.testGameWidget(
'plays bumper sound', 'plays bumper sound',
setUp: (game, _) async { setUp: (game, _) async {
final behavior = BumperNoisyBehavior(); final behavior = BumperNoiseBehavior();
final parent = _TestBodyComponent(); final parent = _TestBodyComponent();
await game.ensureAdd(parent); await game.ensureAdd(parent);
await parent.ensureAdd(behavior); await parent.ensureAdd(behavior);

@ -2,7 +2,7 @@
import 'package:flame_test/flame_test.dart'; import 'package:flame_test/flame_test.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:pinball/game/behaviors/bumper_noisy_behavior.dart'; import 'package:pinball/game/behaviors/bumper_noise_behavior.dart';
import 'package:pinball/game/components/android_acres/behaviors/behaviors.dart'; import 'package:pinball/game/components/android_acres/behaviors/behaviors.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
@ -103,13 +103,13 @@ void main() {
); );
flameTester.test( flameTester.test(
'three AndroidBumpers with BumperNoisyBehavior', 'three AndroidBumpers with BumperNoiseBehavior',
(game) async { (game) async {
await game.ensureAdd(AndroidAcres()); await game.ensureAdd(AndroidAcres());
final bumpers = game.descendants().whereType<AndroidBumper>(); final bumpers = game.descendants().whereType<AndroidBumper>();
for (final bumper in bumpers) { for (final bumper in bumpers) {
expect( expect(
bumper.firstChild<BumperNoisyBehavior>(), bumper.firstChild<BumperNoiseBehavior>(),
isNotNull, isNotNull,
); );
} }

@ -1,18 +1,25 @@
// ignore_for_file: cascade_invocations
import 'dart:collection'; import 'dart:collection';
import 'package:bloc_test/bloc_test.dart'; import 'package:bloc_test/bloc_test.dart';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame/components.dart';
import 'package:flame_test/flame_test.dart'; import 'package:flame_test/flame_test.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart'; import 'package:mocktail/mocktail.dart';
import 'package:pinball/game/game.dart'; import 'package:pinball/game/game.dart';
import 'package:pinball_audio/pinball_audio.dart';
import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_components/pinball_components.dart';
import '../../helpers/helpers.dart'; import '../../helpers/helpers.dart';
class _MockGameBloc extends Mock implements GameBloc {} class _MockGameBloc extends Mock implements GameBloc {}
class _MockPinballPlayer extends Mock implements PinballPlayer {}
class _MockPinballGame extends Mock implements PinballGame {}
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized(); TestWidgetsFlutterBinding.ensureInitialized();
final flameTester = FlameTester(EmptyPinballTestGame.new); final flameTester = FlameTester(EmptyPinballTestGame.new);
@ -20,31 +27,28 @@ void main() {
group('PlungerController', () { group('PlungerController', () {
late GameBloc gameBloc; late GameBloc gameBloc;
setUp(() {
gameBloc = _MockGameBloc();
});
final flameBlocTester = FlameBlocTester<EmptyPinballTestGame, GameBloc>( final flameBlocTester = FlameBlocTester<EmptyPinballTestGame, GameBloc>(
gameBuilder: EmptyPinballTestGame.new, gameBuilder: EmptyPinballTestGame.new,
blocBuilder: () => gameBloc, blocBuilder: () => gameBloc,
); );
group('onKeyEvent', () {
final downKeys = UnmodifiableListView([
LogicalKeyboardKey.arrowDown,
LogicalKeyboardKey.space,
LogicalKeyboardKey.keyS,
]);
late Plunger plunger; late Plunger plunger;
late PlungerController controller; late PlungerController controller;
setUp(() { setUp(() {
plunger = Plunger(compressionDistance: 10); gameBloc = _MockGameBloc();
plunger = ControlledPlunger(compressionDistance: 10);
controller = PlungerController(plunger); controller = PlungerController(plunger);
plunger.add(controller); plunger.add(controller);
}); });
group('onKeyEvent', () {
final downKeys = UnmodifiableListView([
LogicalKeyboardKey.arrowDown,
LogicalKeyboardKey.space,
LogicalKeyboardKey.keyS,
]);
testRawKeyDownEvents(downKeys, (event) { testRawKeyDownEvents(downKeys, (event) {
flameTester.test( flameTester.test(
'moves down ' 'moves down '
@ -129,5 +133,50 @@ void main() {
); );
}); });
}); });
flameTester.test(
'adds the PlungerNoiseBehavior plunger is released',
(game) async {
await game.ensureAdd(plunger);
plunger.body.setTransform(Vector2(0, 1), 0);
plunger.release();
await game.ready();
final count =
game.descendants().whereType<PlungerNoiseBehavior>().length;
expect(count, equals(1));
},
);
});
group('PlungerNoiseBehavior', () {
late PinballGame game;
late PinballPlayer player;
late PlungerNoiseBehavior behavior;
setUp(() {
game = _MockPinballGame();
player = _MockPinballPlayer();
when(() => game.player).thenReturn(player);
behavior = PlungerNoiseBehavior();
behavior.mockGameRef(game);
});
test('plays the correct sound on load', () async {
await behavior.onLoad();
verify(() => player.play(PinballAudio.launcher)).called(1);
});
test('is removed on the first update', () {
final parent = Component();
parent.add(behavior);
parent.update(0); // Run a tick to ensure it is added
behavior.update(0); // Run its own update where the removal happens
expect(behavior.shouldRemove, isTrue);
});
}); });
} }

@ -76,14 +76,14 @@ void main() {
); );
flameTester.test( flameTester.test(
'three DashNestBumpers with BumperNoisyBehavior', 'three DashNestBumpers with BumperNoiseBehavior',
(game) async { (game) async {
final flutterForest = FlutterForest(); final flutterForest = FlutterForest();
await game.ensureAdd(ZCanvasComponent(children: [flutterForest])); await game.ensureAdd(ZCanvasComponent(children: [flutterForest]));
final bumpers = game.descendants().whereType<DashNestBumper>(); final bumpers = game.descendants().whereType<DashNestBumper>();
for (final bumper in bumpers) { for (final bumper in bumpers) {
expect( expect(
bumper.firstChild<BumperNoisyBehavior>(), bumper.firstChild<BumperNoiseBehavior>(),
isNotNull, isNotNull,
); );
} }

@ -77,13 +77,13 @@ void main() {
); );
flameTester.test( flameTester.test(
'three SparkyBumpers with BumperNoisyBehavior', 'three SparkyBumpers with BumperNoiseBehavior',
(game) async { (game) async {
await game.ensureAdd(SparkyScorch()); await game.ensureAdd(SparkyScorch());
final bumpers = game.descendants().whereType<SparkyBumper>(); final bumpers = game.descendants().whereType<SparkyBumper>();
for (final bumper in bumpers) { for (final bumper in bumpers) {
expect( expect(
bumper.firstChild<BumperNoisyBehavior>(), bumper.firstChild<BumperNoiseBehavior>(),
isNotNull, isNotNull,
); );
} }

Loading…
Cancel
Save