Merge branch 'main' into fix/safari-links

pull/428/head
Jorge Coca 3 years ago committed by GitHub
commit 74a2b1bb39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,5 +1,6 @@
import 'package:flame/components.dart'; import 'package:flame/components.dart';
import 'package:flame_bloc/flame_bloc.dart'; import 'package:flame_bloc/flame_bloc.dart';
import 'package:pinball/game/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';
import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_flame/pinball_flame.dart';
@ -17,6 +18,7 @@ class GoogleWordBonusBehavior extends Component {
readBloc<GameBloc, GameState>() readBloc<GameBloc, GameState>()
.add(const BonusActivated(GameBonus.googleWord)); .add(const BonusActivated(GameBonus.googleWord));
readBloc<GoogleWordCubit, GoogleWordState>().onBonusAwarded(); readBloc<GoogleWordCubit, GoogleWordState>().onBonusAwarded();
add(BonusBallSpawningBehavior());
}, },
), ),
); );

@ -11,7 +11,8 @@ class MultiballsBehavior extends Component
bool listenWhen(GameState? previousState, GameState newState) { bool listenWhen(GameState? previousState, GameState newState) {
final hasChanged = previousState?.bonusHistory != newState.bonusHistory; final hasChanged = previousState?.bonusHistory != newState.bonusHistory;
final lastBonusIsMultiball = newState.bonusHistory.isNotEmpty && final lastBonusIsMultiball = newState.bonusHistory.isNotEmpty &&
newState.bonusHistory.last == GameBonus.dashNest; (newState.bonusHistory.last == GameBonus.dashNest ||
newState.bonusHistory.last == GameBonus.googleWord);
return hasChanged && lastBonusIsMultiball; return hasChanged && lastBonusIsMultiball;
} }

@ -59,7 +59,7 @@ typedef CreateAudioPool = Future<AudioPool> Function(
typedef PlaySingleAudio = Future<void> Function(String); typedef PlaySingleAudio = Future<void> Function(String);
/// Defines the contract for looping a single audio. /// Defines the contract for looping a single audio.
typedef LoopSingleAudio = Future<void> Function(String); typedef LoopSingleAudio = Future<void> Function(String, {double volume});
/// Defines the contract for pre fetching an audio. /// Defines the contract for pre fetching an audio.
typedef PreCacheSingleAudio = Future<void> Function(String); typedef PreCacheSingleAudio = Future<void> Function(String);
@ -101,18 +101,20 @@ class _LoopAudio extends _Audio {
required this.preCacheSingleAudio, required this.preCacheSingleAudio,
required this.loopSingleAudio, required this.loopSingleAudio,
required this.path, required this.path,
this.volume,
}); });
final PreCacheSingleAudio preCacheSingleAudio; final PreCacheSingleAudio preCacheSingleAudio;
final LoopSingleAudio loopSingleAudio; final LoopSingleAudio loopSingleAudio;
final String path; final String path;
final double? volume;
@override @override
Future<void> load() => preCacheSingleAudio(prefixFile(path)); Future<void> load() => preCacheSingleAudio(prefixFile(path));
@override @override
void play() { void play() {
loopSingleAudio(prefixFile(path)); loopSingleAudio(prefixFile(path), volume: volume ?? 1);
} }
} }
@ -121,10 +123,12 @@ class _SingleLoopAudio extends _LoopAudio {
required PreCacheSingleAudio preCacheSingleAudio, required PreCacheSingleAudio preCacheSingleAudio,
required LoopSingleAudio loopSingleAudio, required LoopSingleAudio loopSingleAudio,
required String path, required String path,
double? volume,
}) : super( }) : super(
preCacheSingleAudio: preCacheSingleAudio, preCacheSingleAudio: preCacheSingleAudio,
loopSingleAudio: loopSingleAudio, loopSingleAudio: loopSingleAudio,
path: path, path: path,
volume: volume,
); );
bool _playing = false; bool _playing = false;
@ -296,6 +300,7 @@ class PinballAudioPlayer {
preCacheSingleAudio: _preCacheSingleAudio, preCacheSingleAudio: _preCacheSingleAudio,
loopSingleAudio: _loopSingleAudio, loopSingleAudio: _loopSingleAudio,
path: Assets.music.background, path: Assets.music.background,
volume: .6,
), ),
}; };
} }

@ -33,7 +33,7 @@ class _MockPlaySingleAudio extends Mock {
} }
class _MockLoopSingleAudio extends Mock { class _MockLoopSingleAudio extends Mock {
Future<void> onCall(String url); Future<void> onCall(String url, {double volume});
} }
abstract class _PreCacheSingleAudio { abstract class _PreCacheSingleAudio {
@ -77,7 +77,8 @@ void main() {
when(() => playSingleAudio.onCall(any())).thenAnswer((_) async {}); when(() => playSingleAudio.onCall(any())).thenAnswer((_) async {});
loopSingleAudio = _MockLoopSingleAudio(); loopSingleAudio = _MockLoopSingleAudio();
when(() => loopSingleAudio.onCall(any())).thenAnswer((_) async {}); when(() => loopSingleAudio.onCall(any(), volume: any(named: 'volume')))
.thenAnswer((_) async {});
preCacheSingleAudio = _MockPreCacheSingleAudio(); preCacheSingleAudio = _MockPreCacheSingleAudio();
when(() => preCacheSingleAudio.onCall(any())).thenAnswer((_) async {}); when(() => preCacheSingleAudio.onCall(any())).thenAnswer((_) async {});
@ -443,8 +444,10 @@ void main() {
audioPlayer.play(PinballAudio.backgroundMusic); audioPlayer.play(PinballAudio.backgroundMusic);
verify( verify(
() => loopSingleAudio () => loopSingleAudio.onCall(
.onCall('packages/pinball_audio/${Assets.music.background}'), 'packages/pinball_audio/${Assets.music.background}',
volume: .6,
),
).called(1); ).called(1);
}); });
@ -455,8 +458,10 @@ void main() {
..play(PinballAudio.backgroundMusic); ..play(PinballAudio.backgroundMusic);
verify( verify(
() => loopSingleAudio () => loopSingleAudio.onCall(
.onCall('packages/pinball_audio/${Assets.music.background}'), 'packages/pinball_audio/${Assets.music.background}',
volume: .6,
),
).called(1); ).called(1);
}); });
}); });

@ -9,9 +9,9 @@ import 'package:pinball_flame/pinball_flame.dart';
class MultiballBlinkingBehavior extends TimerComponent class MultiballBlinkingBehavior extends TimerComponent
with ParentIsA<Multiball> { with ParentIsA<Multiball> {
/// {@macro multiball_blinking_behavior} /// {@macro multiball_blinking_behavior}
MultiballBlinkingBehavior() : super(period: 0.1); MultiballBlinkingBehavior() : super(period: 0.18);
final _maxBlinks = 10; final _maxBlinks = 28;
int _blinksCounter = 0; int _blinksCounter = 0;

@ -21,7 +21,7 @@ void main() {
'MultiballBlinkingBehavior', 'MultiballBlinkingBehavior',
() { () {
flameTester.testGameWidget( flameTester.testGameWidget(
'calls onBlink every 0.1 seconds when animation state is animated', 'calls onBlink every 0.18 seconds when animation state is animated',
setUp: (game, tester) async { setUp: (game, tester) async {
final behavior = MultiballBlinkingBehavior(); final behavior = MultiballBlinkingBehavior();
final bloc = _MockMultiballCubit(); final bloc = _MockMultiballCubit();
@ -48,7 +48,7 @@ void main() {
verify(bloc.onBlink).called(1); verify(bloc.onBlink).called(1);
await tester.pump(); await tester.pump();
game.update(0.1); game.update(0.18);
await streamController.close(); await streamController.close();
verify(bloc.onBlink).called(1); verify(bloc.onBlink).called(1);
@ -124,7 +124,7 @@ void main() {
); );
flameTester.testGameWidget( flameTester.testGameWidget(
'onTick stops after 10 blinks repetitions', 'onTick stops after 28 blinks',
setUp: (game, tester) async { setUp: (game, tester) async {
final behavior = MultiballBlinkingBehavior(); final behavior = MultiballBlinkingBehavior();
final bloc = _MockMultiballCubit(); final bloc = _MockMultiballCubit();
@ -148,7 +148,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
for (var i = 0; i < 10; i++) { for (var i = 0; i < 28; i++) {
behavior.onTick(); behavior.onTick();
} }

@ -8,6 +8,7 @@ import 'package:flame_forge2d/flame_forge2d.dart';
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:mocktail/mocktail.dart'; import 'package:mocktail/mocktail.dart';
import 'package:pinball/game/behaviors/behaviors.dart';
import 'package:pinball/game/components/google_gallery/behaviors/behaviors.dart'; import 'package:pinball/game/components/google_gallery/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';
@ -116,5 +117,51 @@ void main() {
verify(googleWordBloc.onBonusAwarded).called(1); verify(googleWordBloc.onBonusAwarded).called(1);
}, },
); );
flameTester.testGameWidget(
'adds BonusBallSpawningBehavior to the game when all letters '
'in google word are activated',
setUp: (game, tester) async {
final behavior = GoogleWordBonusBehavior();
final parent = GoogleGallery.test();
final googleWord = GoogleWord(position: Vector2.zero());
final googleWordBloc = _MockGoogleWordCubit();
final streamController = StreamController<GoogleWordState>();
whenListen(
googleWordBloc,
streamController.stream,
initialState: GoogleWordState.initial(),
);
await parent.add(googleWord);
await game.pump(
parent,
gameBloc: gameBloc,
googleWordBloc: googleWordBloc,
);
await parent.ensureAdd(behavior);
streamController.add(
const GoogleWordState(
letterSpriteStates: {
0: GoogleLetterSpriteState.lit,
1: GoogleLetterSpriteState.lit,
2: GoogleLetterSpriteState.lit,
3: GoogleLetterSpriteState.lit,
4: GoogleLetterSpriteState.lit,
5: GoogleLetterSpriteState.lit,
},
),
);
await tester.pump();
await game.ready();
expect(
game.descendants().whereType<BonusBallSpawningBehavior>().length,
equals(1),
);
},
);
}); });
} }

@ -78,8 +78,24 @@ void main() {
); );
test( test(
'is false when the bonusHistory has changed ' 'is true when the bonusHistory has changed '
'with a bonus different than GameBonus.dashNest', () { 'with a new GameBonus.googleWord',
() {
final previous = GameState.initial();
final state = previous.copyWith(
bonusHistory: [GameBonus.googleWord],
);
expect(
MultiballsBehavior().listenWhen(previous, state),
isTrue,
);
},
);
test(
'is false when the bonusHistory has changed with a bonus other than '
'GameBonus.dashNest or GameBonus.googleWord', () {
final previous = final previous =
GameState.initial().copyWith(bonusHistory: [GameBonus.dashNest]); GameState.initial().copyWith(bonusHistory: [GameBonus.dashNest]);
final state = previous.copyWith( final state = previous.copyWith(

Loading…
Cancel
Save