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_bloc/flame_bloc.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';
@ -17,6 +18,7 @@ class GoogleWordBonusBehavior extends Component {
readBloc<GameBloc, GameState>()
.add(const BonusActivated(GameBonus.googleWord));
readBloc<GoogleWordCubit, GoogleWordState>().onBonusAwarded();
add(BonusBallSpawningBehavior());
},
),
);

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

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

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

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

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

@ -8,6 +8,7 @@ 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/components/google_gallery/behaviors/behaviors.dart';
import 'package:pinball/game/game.dart';
import 'package:pinball_components/pinball_components.dart';
@ -116,5 +117,51 @@ void main() {
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(
'is false when the bonusHistory has changed '
'with a bonus different than GameBonus.dashNest', () {
'is true when the bonusHistory has changed '
'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 =
GameState.initial().copyWith(bonusHistory: [GameBonus.dashNest]);
final state = previous.copyWith(

Loading…
Cancel
Save