diff --git a/lib/game/behaviors/behaviors.dart b/lib/game/behaviors/behaviors.dart new file mode 100644 index 00000000..ae51fc09 --- /dev/null +++ b/lib/game/behaviors/behaviors.dart @@ -0,0 +1,2 @@ +export 'bumper_noisy_behavior.dart'; +export 'scoring_behavior.dart'; diff --git a/lib/game/behaviors/bumper_noisy_behavior.dart b/lib/game/behaviors/bumper_noisy_behavior.dart new file mode 100644 index 00000000..c837c8c5 --- /dev/null +++ b/lib/game/behaviors/bumper_noisy_behavior.dart @@ -0,0 +1,14 @@ +// ignore_for_file: public_member_api_docs + +import 'package:flame/components.dart'; +import 'package:flame_forge2d/flame_forge2d.dart'; +import 'package:pinball/game/pinball_game.dart'; +import 'package:pinball_flame/pinball_flame.dart'; + +class BumperNoisyBehavior extends ContactBehavior with HasGameRef { + @override + void beginContact(Object other, Contact contact) { + super.beginContact(other, contact); + gameRef.audio.bumper(); + } +} diff --git a/lib/game/components/scoring_behavior.dart b/lib/game/behaviors/scoring_behavior.dart similarity index 56% rename from lib/game/components/scoring_behavior.dart rename to lib/game/behaviors/scoring_behavior.dart index f741e213..31cdb71e 100644 --- a/lib/game/components/scoring_behavior.dart +++ b/lib/game/behaviors/scoring_behavior.dart @@ -6,11 +6,11 @@ import 'package:pinball/game/game.dart'; import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_flame/pinball_flame.dart'; -/// {@template scoring_behavior} -/// Adds points to the score when the ball contacts the [parent]. +/// {@template scoring_contact_behavior} +/// Adds points to the score when the [Ball] contacts the [parent]. /// {@endtemplate} class ScoringBehavior extends ContactBehavior with HasGameRef { - /// {@macro scoring_behavior} + /// {@macro scoring_contact_behavior} ScoringBehavior({ required Points points, }) : _points = points; @@ -31,23 +31,3 @@ class ScoringBehavior extends ContactBehavior with HasGameRef { ); } } - -/// {@template bumper_scoring_behavior} -/// A specific [ScoringBehavior] used for Bumpers. -/// In addition to its parent logic, also plays the -/// SFX for bumpers -/// {@endtemplate} -class BumperScoringBehavior extends ScoringBehavior { - /// {@macro bumper_scoring_behavior} - BumperScoringBehavior({ - required Points points, - }) : super(points: points); - - @override - void beginContact(Object other, Contact contact) { - super.beginContact(other, contact); - if (other is! Ball) return; - - gameRef.audio.bumper(); - } -} diff --git a/lib/game/components/android_acres/android_acres.dart b/lib/game/components/android_acres/android_acres.dart index d29f38d7..032c5b22 100644 --- a/lib/game/components/android_acres/android_acres.dart +++ b/lib/game/components/android_acres/android_acres.dart @@ -2,8 +2,8 @@ import 'package:flame/components.dart'; import 'package:flutter/material.dart'; +import 'package:pinball/game/behaviors/behaviors.dart'; import 'package:pinball/game/components/android_acres/behaviors/behaviors.dart'; -import 'package:pinball/game/game.dart'; import 'package:pinball_components/pinball_components.dart'; /// {@template android_acres} @@ -25,17 +25,20 @@ class AndroidAcres extends Component { )..initialPosition = Vector2(-26, -28.25), AndroidBumper.a( children: [ - BumperScoringBehavior(points: Points.twentyThousand), + ScoringBehavior(points: Points.twentyThousand), + BumperNoisyBehavior(), ], )..initialPosition = Vector2(-25, 1.3), AndroidBumper.b( children: [ - BumperScoringBehavior(points: Points.twentyThousand), + ScoringBehavior(points: Points.twentyThousand), + BumperNoisyBehavior(), ], )..initialPosition = Vector2(-32.8, -9.2), AndroidBumper.cow( children: [ - BumperScoringBehavior(points: Points.twentyThousand), + ScoringBehavior(points: Points.twentyThousand), + BumperNoisyBehavior(), ], )..initialPosition = Vector2(-20.5, -13.8), AndroidSpaceshipBonusBehavior(), diff --git a/lib/game/components/bottom_group.dart b/lib/game/components/bottom_group.dart index c13f21be..8def273f 100644 --- a/lib/game/components/bottom_group.dart +++ b/lib/game/components/bottom_group.dart @@ -1,4 +1,5 @@ import 'package:flame/components.dart'; +import 'package:pinball/game/behaviors/behaviors.dart'; import 'package:pinball/game/game.dart'; import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_flame/pinball_flame.dart'; diff --git a/lib/game/components/components.dart b/lib/game/components/components.dart index b0b81239..19784226 100644 --- a/lib/game/components/components.dart +++ b/lib/game/components/components.dart @@ -12,5 +12,4 @@ export 'google_word/google_word.dart'; export 'launcher.dart'; export 'multiballs/multiballs.dart'; export 'multipliers/multipliers.dart'; -export 'scoring_behavior.dart'; export 'sparky_scorch.dart'; diff --git a/lib/game/components/dino_desert/dino_desert.dart b/lib/game/components/dino_desert/dino_desert.dart index 4d8cd7b6..e415c173 100644 --- a/lib/game/components/dino_desert/dino_desert.dart +++ b/lib/game/components/dino_desert/dino_desert.dart @@ -1,6 +1,7 @@ import 'package:flame/components.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flutter/material.dart'; +import 'package:pinball/game/behaviors/behaviors.dart'; import 'package:pinball/game/components/dino_desert/behaviors/behaviors.dart'; import 'package:pinball/game/game.dart'; import 'package:pinball_components/pinball_components.dart'; diff --git a/lib/game/components/flutter_forest/flutter_forest.dart b/lib/game/components/flutter_forest/flutter_forest.dart index 0f24a3b6..f2b93d00 100644 --- a/lib/game/components/flutter_forest/flutter_forest.dart +++ b/lib/game/components/flutter_forest/flutter_forest.dart @@ -2,8 +2,8 @@ import 'package:flame/components.dart'; import 'package:flutter/material.dart'; +import 'package:pinball/game/behaviors/behaviors.dart'; import 'package:pinball/game/components/flutter_forest/behaviors/behaviors.dart'; -import 'package:pinball/game/game.dart'; import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_flame/pinball_flame.dart'; @@ -18,22 +18,26 @@ class FlutterForest extends Component with ZIndex { children: [ Signpost( children: [ - BumperScoringBehavior(points: Points.fiveThousand), + ScoringBehavior(points: Points.fiveThousand), + BumperNoisyBehavior(), ], )..initialPosition = Vector2(8.35, -58.3), DashNestBumper.main( children: [ - BumperScoringBehavior(points: Points.twoHundredThousand), + ScoringBehavior(points: Points.twoHundredThousand), + BumperNoisyBehavior(), ], )..initialPosition = Vector2(18.55, -59.35), DashNestBumper.a( children: [ - BumperScoringBehavior(points: Points.twentyThousand), + ScoringBehavior(points: Points.twentyThousand), + BumperNoisyBehavior(), ], )..initialPosition = Vector2(8.95, -51.95), DashNestBumper.b( children: [ - BumperScoringBehavior(points: Points.twentyThousand), + ScoringBehavior(points: Points.twentyThousand), + BumperNoisyBehavior(), ], )..initialPosition = Vector2(22.3, -46.75), DashAnimatronic()..position = Vector2(20, -66), diff --git a/lib/game/components/google_word/google_word.dart b/lib/game/components/google_word/google_word.dart index af1faea9..a2f6470a 100644 --- a/lib/game/components/google_word/google_word.dart +++ b/lib/game/components/google_word/google_word.dart @@ -1,7 +1,7 @@ import 'package:flame/components.dart'; import 'package:flutter/material.dart'; +import 'package:pinball/game/behaviors/scoring_behavior.dart'; import 'package:pinball/game/components/google_word/behaviors/behaviors.dart'; -import 'package:pinball/game/game.dart'; import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_flame/pinball_flame.dart'; diff --git a/lib/game/components/sparky_scorch.dart b/lib/game/components/sparky_scorch.dart index f98f71d7..279199c3 100644 --- a/lib/game/components/sparky_scorch.dart +++ b/lib/game/components/sparky_scorch.dart @@ -2,7 +2,8 @@ import 'package:flame/components.dart'; import 'package:flame_forge2d/flame_forge2d.dart'; -import 'package:pinball/game/game.dart'; +import 'package:pinball/game/behaviors/behaviors.dart'; +import 'package:pinball/game/components/components.dart'; import 'package:pinball_components/pinball_components.dart'; /// {@template sparky_scorch} @@ -16,17 +17,19 @@ class SparkyScorch extends Component { children: [ SparkyBumper.a( children: [ - BumperScoringBehavior(points: Points.twentyThousand), + ScoringBehavior(points: Points.twentyThousand), + BumperNoisyBehavior(), ], )..initialPosition = Vector2(-22.9, -41.65), SparkyBumper.b( children: [ - BumperScoringBehavior(points: Points.twentyThousand), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(-21.25, -57.9), SparkyBumper.c( children: [ - BumperScoringBehavior(points: Points.twentyThousand), + ScoringBehavior(points: Points.twentyThousand), + BumperNoisyBehavior(), ], )..initialPosition = Vector2(-3.3, -52.55), SparkyComputerSensor()..initialPosition = Vector2(-13, -49.9), diff --git a/test/game/behaviors/bumper_noisy_behavior_test.dart b/test/game/behaviors/bumper_noisy_behavior_test.dart new file mode 100644 index 00000000..262b317d --- /dev/null +++ b/test/game/behaviors/bumper_noisy_behavior_test.dart @@ -0,0 +1,51 @@ +// 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_components/pinball_components.dart'; + +import '../../helpers/helpers.dart'; + +class _TestBodyComponent extends BodyComponent { + @override + Body createBody() { + return world.createBody(BodyDef()); + } +} + +class _MockPinballAudio extends Mock implements PinballAudio {} + +class _MockContact extends Mock implements Contact {} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('BumperNoisyBehavior', () {}); + + late PinballAudio audio; + final flameTester = FlameTester( + () => EmptyPinballTestGame(audio: audio), + ); + + setUp(() { + audio = _MockPinballAudio(); + }); + + flameTester.testGameWidget( + 'plays bumper sound', + setUp: (game, _) async { + final behavior = BumperNoisyBehavior(); + final parent = _TestBodyComponent(); + await game.ensureAdd(parent); + await parent.ensureAdd(behavior); + behavior.beginContact(Object(), _MockContact()); + }, + verify: (_, __) async { + verify(audio.bumper).called(1); + }, + ); +} diff --git a/test/game/components/scoring_behavior_test.dart b/test/game/behaviors/scoring_behavior_test.dart similarity index 65% rename from test/game/components/scoring_behavior_test.dart rename to test/game/behaviors/scoring_behavior_test.dart index 3e0f7fb4..07c2753a 100644 --- a/test/game/components/scoring_behavior_test.dart +++ b/test/game/behaviors/scoring_behavior_test.dart @@ -5,8 +5,8 @@ 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/game/game.dart'; -import 'package:pinball_audio/pinball_audio.dart'; import 'package:pinball_components/pinball_components.dart'; import 'package:pinball_flame/pinball_flame.dart'; @@ -17,8 +17,6 @@ class _TestBodyComponent extends BodyComponent { Body createBody() => world.createBody(BodyDef()); } -class _MockPinballAudio extends Mock implements PinballAudio {} - class _MockBall extends Mock implements Ball {} class _MockBody extends Mock implements Body {} @@ -39,12 +37,10 @@ void main() { group('ScoringBehavior', () { group('beginContact', () { late GameBloc bloc; - late PinballAudio audio; late Ball ball; late BodyComponent parent; setUp(() { - audio = _MockPinballAudio(); ball = _MockBall(); final ballBody = _MockBody(); when(() => ball.body).thenReturn(ballBody); @@ -54,9 +50,7 @@ void main() { }); final flameBlocTester = FlameBlocTester( - gameBuilder: () => EmptyPinballTestGame( - audio: audio, - ), + gameBuilder: EmptyPinballTestGame.new, blocBuilder: () { bloc = _MockGameBloc(); const state = GameState( @@ -116,57 +110,4 @@ void main() { ); }); }); - - group('BumperScoringBehavior', () { - group('beginContact', () { - late GameBloc bloc; - late PinballAudio audio; - late Ball ball; - late BodyComponent parent; - - setUp(() { - audio = _MockPinballAudio(); - ball = _MockBall(); - final ballBody = _MockBody(); - when(() => ball.body).thenReturn(ballBody); - when(() => ballBody.position).thenReturn(Vector2.all(4)); - - parent = _TestBodyComponent(); - }); - - final flameBlocTester = FlameBlocTester( - gameBuilder: () => EmptyPinballTestGame( - audio: audio, - ), - blocBuilder: () { - bloc = _MockGameBloc(); - const state = GameState( - score: 0, - multiplier: 1, - rounds: 3, - bonusHistory: [], - ); - whenListen(bloc, Stream.value(state), initialState: state); - return bloc; - }, - assets: assets, - ); - - flameBlocTester.testGameWidget( - 'plays bumper sound', - setUp: (game, tester) async { - final scoringBehavior = BumperScoringBehavior( - points: Points.oneMillion, - ); - await parent.add(scoringBehavior); - final canvas = ZCanvasComponent(children: [parent]); - await game.ensureAdd(canvas); - - scoringBehavior.beginContact(ball, _MockContact()); - - verify(audio.bumper).called(1); - }, - ); - }); - }); } diff --git a/test/game/components/dino_desert/dino_desert_test.dart b/test/game/components/dino_desert/dino_desert_test.dart index 20c9ad38..d4c39dbe 100644 --- a/test/game/components/dino_desert/dino_desert_test.dart +++ b/test/game/components/dino_desert/dino_desert_test.dart @@ -2,6 +2,7 @@ import 'package:flame_test/flame_test.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:pinball/game/behaviors/behaviors.dart'; import 'package:pinball/game/components/dino_desert/behaviors/behaviors.dart'; import 'package:pinball/game/game.dart'; import 'package:pinball_components/pinball_components.dart';