mirror of https://github.com/flutter/pinball.git
feat: add `GoogleRollovers` (#407)
* feat: add google rollovers * fix: spelling * refactor: move zIndex to parent * chore: remove unnecessary wrapper * fix: CI * refactor: PR revisions * refactor: suggestions * style: remove parentheses Co-authored-by: Jorge Coca <jorgecoca@users.noreply.github.com>pull/426/head
parent
ea33c1c889
commit
48c5c80b38
@ -0,0 +1,24 @@
|
|||||||
|
import 'package:flame/components.dart';
|
||||||
|
import 'package:flame_bloc/flame_bloc.dart';
|
||||||
|
import 'package:pinball/game/game.dart';
|
||||||
|
import 'package:pinball_components/pinball_components.dart';
|
||||||
|
import 'package:pinball_flame/pinball_flame.dart';
|
||||||
|
|
||||||
|
/// Adds a [GameBonus.googleWord] when all [GoogleLetter]s are activated.
|
||||||
|
class GoogleWordBonusBehavior extends Component {
|
||||||
|
@override
|
||||||
|
Future<void> onLoad() async {
|
||||||
|
await super.onLoad();
|
||||||
|
await add(
|
||||||
|
FlameBlocListener<GoogleWordCubit, GoogleWordState>(
|
||||||
|
listenWhen: (_, state) => state.letterSpriteStates.values
|
||||||
|
.every((element) => element == GoogleLetterSpriteState.lit),
|
||||||
|
onNewState: (state) {
|
||||||
|
readBloc<GameBloc, GameState>()
|
||||||
|
.add(const BonusActivated(GameBonus.googleWord));
|
||||||
|
readBloc<GoogleWordCubit, GoogleWordState>().onBonusAwarded();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
import 'package:flame/components.dart';
|
||||||
|
import 'package:flame_bloc/flame_bloc.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:pinball/game/behaviors/behaviors.dart';
|
||||||
|
import 'package:pinball/game/components/google_gallery/behaviors/behaviors.dart';
|
||||||
|
import 'package:pinball_components/pinball_components.dart';
|
||||||
|
import 'package:pinball_flame/pinball_flame.dart';
|
||||||
|
|
||||||
|
/// {@template google_gallery}
|
||||||
|
/// Middle section of the board containing the [GoogleWord] and the
|
||||||
|
/// [GoogleRollover]s.
|
||||||
|
/// {@endtemplate}
|
||||||
|
class GoogleGallery extends Component with ZIndex {
|
||||||
|
/// {@macro google_gallery}
|
||||||
|
GoogleGallery()
|
||||||
|
: super(
|
||||||
|
children: [
|
||||||
|
FlameBlocProvider<GoogleWordCubit, GoogleWordState>(
|
||||||
|
create: GoogleWordCubit.new,
|
||||||
|
children: [
|
||||||
|
GoogleRollover(
|
||||||
|
side: BoardSide.right,
|
||||||
|
children: [
|
||||||
|
ScoringContactBehavior(points: Points.fiveThousand),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
GoogleRollover(
|
||||||
|
side: BoardSide.left,
|
||||||
|
children: [
|
||||||
|
ScoringContactBehavior(points: Points.fiveThousand),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
GoogleWord(position: Vector2(-4.45, 1.8)),
|
||||||
|
GoogleWordBonusBehavior(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
) {
|
||||||
|
zIndex = ZIndexes.decal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a [GoogleGallery] without any children.
|
||||||
|
///
|
||||||
|
/// This can be used for testing [GoogleGallery]'s behaviors in isolation.
|
||||||
|
@visibleForTesting
|
||||||
|
GoogleGallery.test();
|
||||||
|
}
|
@ -1,29 +0,0 @@
|
|||||||
import 'package:flame/components.dart';
|
|
||||||
import 'package:flame_bloc/flame_bloc.dart';
|
|
||||||
import 'package:pinball/game/game.dart';
|
|
||||||
import 'package:pinball_components/pinball_components.dart';
|
|
||||||
import 'package:pinball_flame/pinball_flame.dart';
|
|
||||||
|
|
||||||
/// Adds a [GameBonus.googleWord] when all [GoogleLetter]s are activated.
|
|
||||||
class GoogleWordBonusBehavior extends Component
|
|
||||||
with ParentIsA<GoogleWord>, FlameBlocReader<GameBloc, GameState> {
|
|
||||||
@override
|
|
||||||
void onMount() {
|
|
||||||
super.onMount();
|
|
||||||
|
|
||||||
final googleLetters = parent.children.whereType<GoogleLetter>();
|
|
||||||
for (final letter in googleLetters) {
|
|
||||||
letter.bloc.stream.listen((_) {
|
|
||||||
final achievedBonus = googleLetters
|
|
||||||
.every((letter) => letter.bloc.state == GoogleLetterState.lit);
|
|
||||||
|
|
||||||
if (achievedBonus) {
|
|
||||||
bloc.add(const BonusActivated(GameBonus.googleWord));
|
|
||||||
for (final letter in googleLetters) {
|
|
||||||
letter.bloc.onReset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
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_components/pinball_components.dart';
|
|
||||||
import 'package:pinball_flame/pinball_flame.dart';
|
|
||||||
|
|
||||||
/// {@template google_word}
|
|
||||||
/// Loads all [GoogleLetter]s to compose a [GoogleWord].
|
|
||||||
/// {@endtemplate}
|
|
||||||
class GoogleWord extends Component with ZIndex {
|
|
||||||
/// {@macro google_word}
|
|
||||||
GoogleWord({
|
|
||||||
required Vector2 position,
|
|
||||||
}) : super(
|
|
||||||
children: [
|
|
||||||
GoogleLetter(
|
|
||||||
0,
|
|
||||||
children: [ScoringContactBehavior(points: Points.fiveThousand)],
|
|
||||||
)..initialPosition = position + Vector2(-13.1, 1.72),
|
|
||||||
GoogleLetter(
|
|
||||||
1,
|
|
||||||
children: [ScoringContactBehavior(points: Points.fiveThousand)],
|
|
||||||
)..initialPosition = position + Vector2(-8.33, -0.75),
|
|
||||||
GoogleLetter(
|
|
||||||
2,
|
|
||||||
children: [ScoringContactBehavior(points: Points.fiveThousand)],
|
|
||||||
)..initialPosition = position + Vector2(-2.88, -1.85),
|
|
||||||
GoogleLetter(
|
|
||||||
3,
|
|
||||||
children: [ScoringContactBehavior(points: Points.fiveThousand)],
|
|
||||||
)..initialPosition = position + Vector2(2.88, -1.85),
|
|
||||||
GoogleLetter(
|
|
||||||
4,
|
|
||||||
children: [ScoringContactBehavior(points: Points.fiveThousand)],
|
|
||||||
)..initialPosition = position + Vector2(8.33, -0.75),
|
|
||||||
GoogleLetter(
|
|
||||||
5,
|
|
||||||
children: [ScoringContactBehavior(points: Points.fiveThousand)],
|
|
||||||
)..initialPosition = position + Vector2(13.1, 1.72),
|
|
||||||
GoogleWordBonusBehavior(),
|
|
||||||
],
|
|
||||||
) {
|
|
||||||
zIndex = ZIndexes.decal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a [GoogleWord] without any children.
|
|
||||||
///
|
|
||||||
/// This can be used for testing [GoogleWord]'s behaviors in isolation.
|
|
||||||
@visibleForTesting
|
|
||||||
GoogleWord.test();
|
|
||||||
}
|
|
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1,88 @@
|
|||||||
|
import 'package:flame/components.dart';
|
||||||
|
import 'package:flame_bloc/flame_bloc.dart';
|
||||||
|
import 'package:pinball_components/pinball_components.dart';
|
||||||
|
import 'package:pinball_flame/pinball_flame.dart';
|
||||||
|
|
||||||
|
enum GoogleLetterSpriteState {
|
||||||
|
lit,
|
||||||
|
dimmed,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// {@template google_letter}
|
||||||
|
/// Circular decal that represents a letter in "GOOGLE" for a given index.
|
||||||
|
/// {@endtemplate}
|
||||||
|
class GoogleLetter extends SpriteGroupComponent<GoogleLetterSpriteState>
|
||||||
|
with HasGameRef, FlameBlocListenable<GoogleWordCubit, GoogleWordState> {
|
||||||
|
/// {@macro google_letter}
|
||||||
|
GoogleLetter(int index)
|
||||||
|
: _litAssetPath = _spritePaths[index][GoogleLetterSpriteState.lit]!,
|
||||||
|
_dimmedAssetPath = _spritePaths[index][GoogleLetterSpriteState.dimmed]!,
|
||||||
|
_index = index,
|
||||||
|
super(anchor: Anchor.center);
|
||||||
|
|
||||||
|
final String _litAssetPath;
|
||||||
|
final String _dimmedAssetPath;
|
||||||
|
final int _index;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool listenWhen(GoogleWordState previousState, GoogleWordState newState) {
|
||||||
|
return previousState.letterSpriteStates[_index] !=
|
||||||
|
newState.letterSpriteStates[_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onNewState(GoogleWordState state) =>
|
||||||
|
current = state.letterSpriteStates[_index];
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onLoad() async {
|
||||||
|
await super.onLoad();
|
||||||
|
|
||||||
|
final sprites = {
|
||||||
|
GoogleLetterSpriteState.lit: Sprite(
|
||||||
|
gameRef.images.fromCache(_litAssetPath),
|
||||||
|
),
|
||||||
|
GoogleLetterSpriteState.dimmed: Sprite(
|
||||||
|
gameRef.images.fromCache(_dimmedAssetPath),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
this.sprites = sprites;
|
||||||
|
current = readBloc<GoogleWordCubit, GoogleWordState>()
|
||||||
|
.state
|
||||||
|
.letterSpriteStates[_index];
|
||||||
|
size = sprites[current]!.originalSize / 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final _spritePaths = <Map<GoogleLetterSpriteState, String>>[
|
||||||
|
{
|
||||||
|
GoogleLetterSpriteState.lit: Assets.images.googleWord.letter1.lit.keyName,
|
||||||
|
GoogleLetterSpriteState.dimmed:
|
||||||
|
Assets.images.googleWord.letter1.dimmed.keyName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
GoogleLetterSpriteState.lit: Assets.images.googleWord.letter2.lit.keyName,
|
||||||
|
GoogleLetterSpriteState.dimmed:
|
||||||
|
Assets.images.googleWord.letter2.dimmed.keyName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
GoogleLetterSpriteState.lit: Assets.images.googleWord.letter3.lit.keyName,
|
||||||
|
GoogleLetterSpriteState.dimmed:
|
||||||
|
Assets.images.googleWord.letter3.dimmed.keyName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
GoogleLetterSpriteState.lit: Assets.images.googleWord.letter4.lit.keyName,
|
||||||
|
GoogleLetterSpriteState.dimmed:
|
||||||
|
Assets.images.googleWord.letter4.dimmed.keyName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
GoogleLetterSpriteState.lit: Assets.images.googleWord.letter5.lit.keyName,
|
||||||
|
GoogleLetterSpriteState.dimmed:
|
||||||
|
Assets.images.googleWord.letter5.dimmed.keyName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
GoogleLetterSpriteState.lit: Assets.images.googleWord.letter6.lit.keyName,
|
||||||
|
GoogleLetterSpriteState.dimmed:
|
||||||
|
Assets.images.googleWord.letter6.dimmed.keyName,
|
||||||
|
},
|
||||||
|
];
|
@ -1 +0,0 @@
|
|||||||
export 'google_letter_ball_contact_behavior.dart';
|
|
@ -1,15 +0,0 @@
|
|||||||
import 'package:bloc/bloc.dart';
|
|
||||||
|
|
||||||
part 'google_letter_state.dart';
|
|
||||||
|
|
||||||
class GoogleLetterCubit extends Cubit<GoogleLetterState> {
|
|
||||||
GoogleLetterCubit() : super(GoogleLetterState.dimmed);
|
|
||||||
|
|
||||||
void onBallContacted() {
|
|
||||||
emit(GoogleLetterState.lit);
|
|
||||||
}
|
|
||||||
|
|
||||||
void onReset() {
|
|
||||||
emit(GoogleLetterState.dimmed);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
part of 'google_letter_cubit.dart';
|
|
||||||
|
|
||||||
enum GoogleLetterState {
|
|
||||||
lit,
|
|
||||||
dimmed,
|
|
||||||
}
|
|
@ -1,133 +0,0 @@
|
|||||||
import 'package:flame/components.dart';
|
|
||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:pinball_components/pinball_components.dart';
|
|
||||||
import 'package:pinball_components/src/components/google_letter/behaviors/behaviors.dart';
|
|
||||||
import 'package:pinball_flame/pinball_flame.dart';
|
|
||||||
|
|
||||||
export 'cubit/google_letter_cubit.dart';
|
|
||||||
|
|
||||||
final _spritePaths = <Map<GoogleLetterState, String>>[
|
|
||||||
{
|
|
||||||
GoogleLetterState.lit: Assets.images.googleWord.letter1.lit.keyName,
|
|
||||||
GoogleLetterState.dimmed: Assets.images.googleWord.letter1.dimmed.keyName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
GoogleLetterState.lit: Assets.images.googleWord.letter2.lit.keyName,
|
|
||||||
GoogleLetterState.dimmed: Assets.images.googleWord.letter2.dimmed.keyName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
GoogleLetterState.lit: Assets.images.googleWord.letter3.lit.keyName,
|
|
||||||
GoogleLetterState.dimmed: Assets.images.googleWord.letter3.dimmed.keyName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
GoogleLetterState.lit: Assets.images.googleWord.letter4.lit.keyName,
|
|
||||||
GoogleLetterState.dimmed: Assets.images.googleWord.letter4.dimmed.keyName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
GoogleLetterState.lit: Assets.images.googleWord.letter5.lit.keyName,
|
|
||||||
GoogleLetterState.dimmed: Assets.images.googleWord.letter5.dimmed.keyName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
GoogleLetterState.lit: Assets.images.googleWord.letter6.lit.keyName,
|
|
||||||
GoogleLetterState.dimmed: Assets.images.googleWord.letter6.dimmed.keyName,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
/// {@template google_letter}
|
|
||||||
/// Circular sensor that represents a letter in "GOOGLE" for a given index.
|
|
||||||
/// {@endtemplate}
|
|
||||||
class GoogleLetter extends BodyComponent with InitialPosition {
|
|
||||||
/// {@macro google_letter}
|
|
||||||
GoogleLetter(
|
|
||||||
int index, {
|
|
||||||
Iterable<Component>? children,
|
|
||||||
}) : this._(
|
|
||||||
index,
|
|
||||||
bloc: GoogleLetterCubit(),
|
|
||||||
children: children,
|
|
||||||
);
|
|
||||||
|
|
||||||
GoogleLetter._(
|
|
||||||
int index, {
|
|
||||||
required this.bloc,
|
|
||||||
Iterable<Component>? children,
|
|
||||||
}) : super(
|
|
||||||
children: [
|
|
||||||
_GoogleLetterSpriteGroupComponent(
|
|
||||||
litAssetPath: _spritePaths[index][GoogleLetterState.lit]!,
|
|
||||||
dimmedAssetPath: _spritePaths[index][GoogleLetterState.dimmed]!,
|
|
||||||
current: bloc.state,
|
|
||||||
),
|
|
||||||
GoogleLetterBallContactBehavior(),
|
|
||||||
...?children,
|
|
||||||
],
|
|
||||||
renderBody: false,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Creates a [GoogleLetter] without any children.
|
|
||||||
///
|
|
||||||
/// This can be used for testing [GoogleLetter]'s behaviors in isolation.
|
|
||||||
@visibleForTesting
|
|
||||||
GoogleLetter.test({
|
|
||||||
required this.bloc,
|
|
||||||
});
|
|
||||||
|
|
||||||
final GoogleLetterCubit bloc;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onRemove() {
|
|
||||||
bloc.close();
|
|
||||||
super.onRemove();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Body createBody() {
|
|
||||||
final shape = CircleShape()..radius = 1.85;
|
|
||||||
final fixtureDef = FixtureDef(
|
|
||||||
shape,
|
|
||||||
isSensor: true,
|
|
||||||
);
|
|
||||||
final bodyDef = BodyDef(
|
|
||||||
position: initialPosition,
|
|
||||||
userData: this,
|
|
||||||
);
|
|
||||||
|
|
||||||
return world.createBody(bodyDef)..createFixture(fixtureDef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _GoogleLetterSpriteGroupComponent
|
|
||||||
extends SpriteGroupComponent<GoogleLetterState>
|
|
||||||
with HasGameRef, ParentIsA<GoogleLetter> {
|
|
||||||
_GoogleLetterSpriteGroupComponent({
|
|
||||||
required String litAssetPath,
|
|
||||||
required String dimmedAssetPath,
|
|
||||||
required GoogleLetterState current,
|
|
||||||
}) : _litAssetPath = litAssetPath,
|
|
||||||
_dimmedAssetPath = dimmedAssetPath,
|
|
||||||
super(
|
|
||||||
anchor: Anchor.center,
|
|
||||||
current: current,
|
|
||||||
);
|
|
||||||
|
|
||||||
final String _litAssetPath;
|
|
||||||
final String _dimmedAssetPath;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> onLoad() async {
|
|
||||||
await super.onLoad();
|
|
||||||
parent.bloc.stream.listen((state) => current = state);
|
|
||||||
|
|
||||||
final sprites = {
|
|
||||||
GoogleLetterState.lit: Sprite(
|
|
||||||
gameRef.images.fromCache(_litAssetPath),
|
|
||||||
),
|
|
||||||
GoogleLetterState.dimmed: Sprite(
|
|
||||||
gameRef.images.fromCache(_dimmedAssetPath),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
this.sprites = sprites;
|
|
||||||
size = sprites[current]!.originalSize / 10;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1 @@
|
|||||||
|
export 'google_rollover_ball_contact_behavior.dart';
|
@ -1,12 +1,15 @@
|
|||||||
|
import 'package:flame/components.dart';
|
||||||
import 'package:flame_forge2d/flame_forge2d.dart';
|
import 'package:flame_forge2d/flame_forge2d.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';
|
||||||
|
|
||||||
class GoogleLetterBallContactBehavior extends ContactBehavior<GoogleLetter> {
|
class GoogleRolloverBallContactBehavior
|
||||||
|
extends ContactBehavior<GoogleRollover> {
|
||||||
@override
|
@override
|
||||||
void beginContact(Object other, Contact contact) {
|
void beginContact(Object other, Contact contact) {
|
||||||
super.beginContact(other, contact);
|
super.beginContact(other, contact);
|
||||||
if (other is! Ball) return;
|
if (other is! Ball) return;
|
||||||
parent.bloc.onBallContacted();
|
readBloc<GoogleWordCubit, GoogleWordState>().onRolloverContacted();
|
||||||
|
parent.firstChild<SpriteAnimationComponent>()?.playing = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
import 'package:flame/components.dart';
|
||||||
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||||
|
import 'package:pinball_components/pinball_components.dart';
|
||||||
|
import 'package:pinball_components/src/components/google_rollover/behaviors/behaviors.dart';
|
||||||
|
|
||||||
|
/// {@template google_rollover}
|
||||||
|
/// Rollover that lights up [GoogleLetter]s.
|
||||||
|
/// {@endtemplate}
|
||||||
|
class GoogleRollover extends BodyComponent {
|
||||||
|
/// {@macro google_rollover}
|
||||||
|
GoogleRollover({
|
||||||
|
required BoardSide side,
|
||||||
|
Iterable<Component>? children,
|
||||||
|
}) : _side = side,
|
||||||
|
super(
|
||||||
|
renderBody: false,
|
||||||
|
children: [
|
||||||
|
GoogleRolloverBallContactBehavior(),
|
||||||
|
_RolloverDecalSpriteComponent(side: side),
|
||||||
|
_PinSpriteAnimationComponent(side: side),
|
||||||
|
...?children,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
final BoardSide _side;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Body createBody() {
|
||||||
|
final shape = PolygonShape()
|
||||||
|
..setAsBox(
|
||||||
|
0.1,
|
||||||
|
3.4,
|
||||||
|
Vector2(_side.isLeft ? -14.8 : 5.9, -11),
|
||||||
|
0.19 * _side.direction,
|
||||||
|
);
|
||||||
|
final fixtureDef = FixtureDef(shape, isSensor: true);
|
||||||
|
return world.createBody(BodyDef())..createFixture(fixtureDef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RolloverDecalSpriteComponent extends SpriteComponent with HasGameRef {
|
||||||
|
_RolloverDecalSpriteComponent({required BoardSide side})
|
||||||
|
: _side = side,
|
||||||
|
super(
|
||||||
|
anchor: Anchor.center,
|
||||||
|
position: Vector2(side.isLeft ? -14.8 : 5.9, -11),
|
||||||
|
angle: 0.18 * side.direction,
|
||||||
|
);
|
||||||
|
|
||||||
|
final BoardSide _side;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onLoad() async {
|
||||||
|
await super.onLoad();
|
||||||
|
|
||||||
|
final sprite = Sprite(
|
||||||
|
gameRef.images.fromCache(
|
||||||
|
(_side.isLeft)
|
||||||
|
? Assets.images.googleRollover.left.decal.keyName
|
||||||
|
: Assets.images.googleRollover.right.decal.keyName,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
this.sprite = sprite;
|
||||||
|
size = sprite.originalSize / 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PinSpriteAnimationComponent extends SpriteAnimationComponent
|
||||||
|
with HasGameRef {
|
||||||
|
_PinSpriteAnimationComponent({required BoardSide side})
|
||||||
|
: _side = side,
|
||||||
|
super(
|
||||||
|
anchor: Anchor.center,
|
||||||
|
position: Vector2(side.isLeft ? -14.9 : 5.95, -11),
|
||||||
|
angle: 0,
|
||||||
|
playing: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
final BoardSide _side;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onLoad() async {
|
||||||
|
await super.onLoad();
|
||||||
|
|
||||||
|
final spriteSheet = gameRef.images.fromCache(
|
||||||
|
_side.isLeft
|
||||||
|
? Assets.images.googleRollover.left.pin.keyName
|
||||||
|
: Assets.images.googleRollover.right.pin.keyName,
|
||||||
|
);
|
||||||
|
|
||||||
|
const amountPerRow = 3;
|
||||||
|
const amountPerColumn = 1;
|
||||||
|
final textureSize = Vector2(
|
||||||
|
spriteSheet.width / amountPerRow,
|
||||||
|
spriteSheet.height / amountPerColumn,
|
||||||
|
);
|
||||||
|
size = textureSize / 10;
|
||||||
|
|
||||||
|
animation = SpriteAnimation.fromFrameData(
|
||||||
|
spriteSheet,
|
||||||
|
SpriteAnimationData.sequenced(
|
||||||
|
amount: amountPerRow * amountPerColumn,
|
||||||
|
amountPerRow: amountPerRow,
|
||||||
|
stepTime: 1 / 24,
|
||||||
|
textureSize: textureSize,
|
||||||
|
loop: false,
|
||||||
|
),
|
||||||
|
)..onComplete = () {
|
||||||
|
animation?.reset();
|
||||||
|
playing = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:pinball_components/pinball_components.dart';
|
||||||
|
|
||||||
|
part 'google_word_state.dart';
|
||||||
|
|
||||||
|
class GoogleWordCubit extends Cubit<GoogleWordState> {
|
||||||
|
GoogleWordCubit() : super(GoogleWordState.initial());
|
||||||
|
|
||||||
|
static const _lettersInGoogle = 6;
|
||||||
|
|
||||||
|
int _lastLitLetter = 0;
|
||||||
|
|
||||||
|
void onRolloverContacted() {
|
||||||
|
final spriteStatesMap = {...state.letterSpriteStates};
|
||||||
|
if (_lastLitLetter < _lettersInGoogle) {
|
||||||
|
spriteStatesMap.update(
|
||||||
|
_lastLitLetter,
|
||||||
|
(_) => GoogleLetterSpriteState.lit,
|
||||||
|
);
|
||||||
|
emit(GoogleWordState(letterSpriteStates: spriteStatesMap));
|
||||||
|
_lastLitLetter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onBonusAwarded() {
|
||||||
|
emit(GoogleWordState.initial());
|
||||||
|
_lastLitLetter = 0;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
part of 'google_word_cubit.dart';
|
||||||
|
|
||||||
|
class GoogleWordState extends Equatable {
|
||||||
|
const GoogleWordState({required this.letterSpriteStates});
|
||||||
|
|
||||||
|
GoogleWordState.initial()
|
||||||
|
: this(
|
||||||
|
letterSpriteStates: {
|
||||||
|
for (var i = 0; i <= 5; i++) i: GoogleLetterSpriteState.dimmed
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
final Map<int, GoogleLetterSpriteState> letterSpriteStates;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [...letterSpriteStates.values];
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
import 'package:flame/components.dart';
|
||||||
|
import 'package:pinball_components/pinball_components.dart';
|
||||||
|
|
||||||
|
export 'cubit/google_word_cubit.dart';
|
||||||
|
|
||||||
|
/// {@template google_word}
|
||||||
|
/// Loads all [GoogleLetter]s to compose a [GoogleWord].
|
||||||
|
/// {@endtemplate}
|
||||||
|
class GoogleWord extends PositionComponent {
|
||||||
|
/// {@macro google_word}
|
||||||
|
GoogleWord({
|
||||||
|
required Vector2 position,
|
||||||
|
}) : super(
|
||||||
|
position: position,
|
||||||
|
children: [
|
||||||
|
GoogleLetter(0)..position = Vector2(-13.1, 1.72),
|
||||||
|
GoogleLetter(1)..position = Vector2(-8.33, -0.75),
|
||||||
|
GoogleLetter(2)..position = Vector2(-2.88, -1.85),
|
||||||
|
GoogleLetter(3)..position = Vector2(2.88, -1.85),
|
||||||
|
GoogleLetter(4)..position = Vector2(8.33, -0.75),
|
||||||
|
GoogleLetter(5)..position = Vector2(13.1, 1.72),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
@ -1,55 +0,0 @@
|
|||||||
// ignore_for_file: cascade_invocations
|
|
||||||
|
|
||||||
import 'package:bloc_test/bloc_test.dart';
|
|
||||||
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_components/pinball_components.dart';
|
|
||||||
import 'package:pinball_components/src/components/google_letter/behaviors/behaviors.dart';
|
|
||||||
|
|
||||||
import '../../../../helpers/helpers.dart';
|
|
||||||
|
|
||||||
class _MockGoogleLetterCubit extends Mock implements GoogleLetterCubit {}
|
|
||||||
|
|
||||||
class _MockBall extends Mock implements Ball {}
|
|
||||||
|
|
||||||
class _MockContact extends Mock implements Contact {}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
|
||||||
final flameTester = FlameTester(TestGame.new);
|
|
||||||
|
|
||||||
group(
|
|
||||||
'GoogleLetterBallContactBehavior',
|
|
||||||
() {
|
|
||||||
test('can be instantiated', () {
|
|
||||||
expect(
|
|
||||||
GoogleLetterBallContactBehavior(),
|
|
||||||
isA<GoogleLetterBallContactBehavior>(),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
flameTester.test(
|
|
||||||
'beginContact emits onBallContacted when contacts with a ball',
|
|
||||||
(game) async {
|
|
||||||
final behavior = GoogleLetterBallContactBehavior();
|
|
||||||
final bloc = _MockGoogleLetterCubit();
|
|
||||||
whenListen(
|
|
||||||
bloc,
|
|
||||||
const Stream<GoogleLetterState>.empty(),
|
|
||||||
initialState: GoogleLetterState.lit,
|
|
||||||
);
|
|
||||||
|
|
||||||
final googleLetter = GoogleLetter.test(bloc: bloc);
|
|
||||||
await googleLetter.add(behavior);
|
|
||||||
await game.ensureAdd(googleLetter);
|
|
||||||
|
|
||||||
behavior.beginContact(_MockBall(), _MockContact());
|
|
||||||
|
|
||||||
verify(googleLetter.bloc.onBallContacted).called(1);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
import 'package:bloc_test/bloc_test.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:pinball_components/pinball_components.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
group(
|
|
||||||
'GoogleLetterCubit',
|
|
||||||
() {
|
|
||||||
blocTest<GoogleLetterCubit, GoogleLetterState>(
|
|
||||||
'onBallContacted emits active',
|
|
||||||
build: GoogleLetterCubit.new,
|
|
||||||
act: (bloc) => bloc.onBallContacted(),
|
|
||||||
expect: () => [GoogleLetterState.lit],
|
|
||||||
);
|
|
||||||
|
|
||||||
blocTest<GoogleLetterCubit, GoogleLetterState>(
|
|
||||||
'onReset emits inactive',
|
|
||||||
build: GoogleLetterCubit.new,
|
|
||||||
act: (bloc) => bloc.onReset(),
|
|
||||||
expect: () => [GoogleLetterState.dimmed],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,145 +0,0 @@
|
|||||||
// ignore_for_file: cascade_invocations
|
|
||||||
|
|
||||||
import 'package:bloc_test/bloc_test.dart';
|
|
||||||
import 'package:flame/components.dart';
|
|
||||||
import 'package:flame_test/flame_test.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:mocktail/mocktail.dart';
|
|
||||||
import 'package:pinball_components/pinball_components.dart';
|
|
||||||
import 'package:pinball_components/src/components/google_letter/behaviors/behaviors.dart';
|
|
||||||
|
|
||||||
import '../../../helpers/helpers.dart';
|
|
||||||
|
|
||||||
class _MockGoogleLetterCubit extends Mock implements GoogleLetterCubit {}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
|
||||||
final assets = [
|
|
||||||
Assets.images.googleWord.letter1.lit.keyName,
|
|
||||||
Assets.images.googleWord.letter1.dimmed.keyName,
|
|
||||||
Assets.images.googleWord.letter2.lit.keyName,
|
|
||||||
Assets.images.googleWord.letter2.dimmed.keyName,
|
|
||||||
Assets.images.googleWord.letter3.lit.keyName,
|
|
||||||
Assets.images.googleWord.letter3.dimmed.keyName,
|
|
||||||
Assets.images.googleWord.letter4.lit.keyName,
|
|
||||||
Assets.images.googleWord.letter4.dimmed.keyName,
|
|
||||||
Assets.images.googleWord.letter5.lit.keyName,
|
|
||||||
Assets.images.googleWord.letter5.dimmed.keyName,
|
|
||||||
Assets.images.googleWord.letter6.lit.keyName,
|
|
||||||
Assets.images.googleWord.letter6.dimmed.keyName,
|
|
||||||
];
|
|
||||||
final flameTester = FlameTester(() => TestGame(assets));
|
|
||||||
|
|
||||||
group('Google Letter', () {
|
|
||||||
flameTester.test(
|
|
||||||
'0th loads correctly',
|
|
||||||
(game) async {
|
|
||||||
final googleLetter = GoogleLetter(0);
|
|
||||||
await game.ready();
|
|
||||||
await game.ensureAdd(googleLetter);
|
|
||||||
|
|
||||||
expect(game.contains(googleLetter), isTrue);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
flameTester.test(
|
|
||||||
'1st loads correctly',
|
|
||||||
(game) async {
|
|
||||||
final googleLetter = GoogleLetter(1);
|
|
||||||
await game.ready();
|
|
||||||
await game.ensureAdd(googleLetter);
|
|
||||||
|
|
||||||
expect(game.contains(googleLetter), isTrue);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
flameTester.test(
|
|
||||||
'2nd loads correctly',
|
|
||||||
(game) async {
|
|
||||||
final googleLetter = GoogleLetter(2);
|
|
||||||
await game.ready();
|
|
||||||
await game.ensureAdd(googleLetter);
|
|
||||||
|
|
||||||
expect(game.contains(googleLetter), isTrue);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
flameTester.test(
|
|
||||||
'3d loads correctly',
|
|
||||||
(game) async {
|
|
||||||
final googleLetter = GoogleLetter(3);
|
|
||||||
await game.ready();
|
|
||||||
await game.ensureAdd(googleLetter);
|
|
||||||
|
|
||||||
expect(game.contains(googleLetter), isTrue);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
flameTester.test(
|
|
||||||
'4th loads correctly',
|
|
||||||
(game) async {
|
|
||||||
final googleLetter = GoogleLetter(4);
|
|
||||||
await game.ready();
|
|
||||||
await game.ensureAdd(googleLetter);
|
|
||||||
|
|
||||||
expect(game.contains(googleLetter), isTrue);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
flameTester.test(
|
|
||||||
'5th loads correctly',
|
|
||||||
(game) async {
|
|
||||||
final googleLetter = GoogleLetter(5);
|
|
||||||
await game.ready();
|
|
||||||
await game.ensureAdd(googleLetter);
|
|
||||||
|
|
||||||
expect(game.contains(googleLetter), isTrue);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
test('throws error when index out of range', () {
|
|
||||||
expect(() => GoogleLetter(-1), throwsA(isA<RangeError>()));
|
|
||||||
expect(() => GoogleLetter(6), throwsA(isA<RangeError>()));
|
|
||||||
});
|
|
||||||
|
|
||||||
flameTester.test('closes bloc when removed', (game) async {
|
|
||||||
final bloc = _MockGoogleLetterCubit();
|
|
||||||
whenListen(
|
|
||||||
bloc,
|
|
||||||
const Stream<GoogleLetterState>.empty(),
|
|
||||||
initialState: GoogleLetterState.lit,
|
|
||||||
);
|
|
||||||
when(bloc.close).thenAnswer((_) async {});
|
|
||||||
final googleLetter = GoogleLetter.test(bloc: bloc);
|
|
||||||
|
|
||||||
await game.ensureAdd(googleLetter);
|
|
||||||
game.remove(googleLetter);
|
|
||||||
await game.ready();
|
|
||||||
|
|
||||||
verify(bloc.close).called(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
group('adds', () {
|
|
||||||
flameTester.test('new children', (game) async {
|
|
||||||
final component = Component();
|
|
||||||
final googleLetter = GoogleLetter(
|
|
||||||
1,
|
|
||||||
children: [component],
|
|
||||||
);
|
|
||||||
await game.ensureAdd(googleLetter);
|
|
||||||
expect(googleLetter.children, contains(component));
|
|
||||||
});
|
|
||||||
|
|
||||||
flameTester.test('a GoogleLetterBallContactBehavior', (game) async {
|
|
||||||
final googleLetter = GoogleLetter(0);
|
|
||||||
await game.ensureAdd(googleLetter);
|
|
||||||
expect(
|
|
||||||
googleLetter.children
|
|
||||||
.whereType<GoogleLetterBallContactBehavior>()
|
|
||||||
.single,
|
|
||||||
isNotNull,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
@ -0,0 +1,159 @@
|
|||||||
|
// ignore_for_file: cascade_invocations
|
||||||
|
|
||||||
|
import 'package:flame_bloc/flame_bloc.dart';
|
||||||
|
import 'package:flame_forge2d/flame_forge2d.dart';
|
||||||
|
import 'package:flame_test/flame_test.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:pinball_components/pinball_components.dart';
|
||||||
|
|
||||||
|
class _TestGame extends Forge2DGame {
|
||||||
|
@override
|
||||||
|
Future<void> onLoad() async {
|
||||||
|
images.prefix = '';
|
||||||
|
await images.loadAll([
|
||||||
|
Assets.images.googleWord.letter1.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter1.dimmed.keyName,
|
||||||
|
Assets.images.googleWord.letter2.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter2.dimmed.keyName,
|
||||||
|
Assets.images.googleWord.letter3.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter3.dimmed.keyName,
|
||||||
|
Assets.images.googleWord.letter4.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter4.dimmed.keyName,
|
||||||
|
Assets.images.googleWord.letter5.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter5.dimmed.keyName,
|
||||||
|
Assets.images.googleWord.letter6.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter6.dimmed.keyName,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> pump(GoogleLetter child) async {
|
||||||
|
await ensureAdd(
|
||||||
|
FlameBlocProvider<GoogleWordCubit, GoogleWordState>.value(
|
||||||
|
value: GoogleWordCubit(),
|
||||||
|
children: [child],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
final flameTester = FlameTester(_TestGame.new);
|
||||||
|
|
||||||
|
group('Google Letter', () {
|
||||||
|
test('can be instantiated', () {
|
||||||
|
expect(GoogleLetter(0), isA<GoogleLetter>());
|
||||||
|
});
|
||||||
|
|
||||||
|
flameTester.test(
|
||||||
|
'0th loads correctly',
|
||||||
|
(game) async {
|
||||||
|
final googleLetter = GoogleLetter(0);
|
||||||
|
await game.pump(googleLetter);
|
||||||
|
|
||||||
|
expect(game.descendants().contains(googleLetter), isTrue);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
flameTester.test(
|
||||||
|
'1st loads correctly',
|
||||||
|
(game) async {
|
||||||
|
final googleLetter = GoogleLetter(1);
|
||||||
|
await game.pump(googleLetter);
|
||||||
|
|
||||||
|
expect(game.descendants().contains(googleLetter), isTrue);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
flameTester.test(
|
||||||
|
'2nd loads correctly',
|
||||||
|
(game) async {
|
||||||
|
final googleLetter = GoogleLetter(2);
|
||||||
|
await game.pump(googleLetter);
|
||||||
|
|
||||||
|
expect(game.descendants().contains(googleLetter), isTrue);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
flameTester.test(
|
||||||
|
'3d loads correctly',
|
||||||
|
(game) async {
|
||||||
|
final googleLetter = GoogleLetter(3);
|
||||||
|
await game.pump(googleLetter);
|
||||||
|
|
||||||
|
expect(game.descendants().contains(googleLetter), isTrue);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
flameTester.test(
|
||||||
|
'4th loads correctly',
|
||||||
|
(game) async {
|
||||||
|
final googleLetter = GoogleLetter(4);
|
||||||
|
await game.pump(googleLetter);
|
||||||
|
|
||||||
|
expect(game.descendants().contains(googleLetter), isTrue);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
flameTester.test(
|
||||||
|
'5th loads correctly',
|
||||||
|
(game) async {
|
||||||
|
final googleLetter = GoogleLetter(5);
|
||||||
|
await game.pump(googleLetter);
|
||||||
|
|
||||||
|
expect(game.descendants().contains(googleLetter), isTrue);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test('throws error when index out of range', () {
|
||||||
|
expect(() => GoogleLetter(-1), throwsA(isA<RangeError>()));
|
||||||
|
expect(() => GoogleLetter(6), throwsA(isA<RangeError>()));
|
||||||
|
});
|
||||||
|
|
||||||
|
group('sprite', () {
|
||||||
|
const firstLetterLitState = GoogleWordState(
|
||||||
|
letterSpriteStates: {
|
||||||
|
0: GoogleLetterSpriteState.lit,
|
||||||
|
1: GoogleLetterSpriteState.dimmed,
|
||||||
|
2: GoogleLetterSpriteState.dimmed,
|
||||||
|
3: GoogleLetterSpriteState.dimmed,
|
||||||
|
4: GoogleLetterSpriteState.dimmed,
|
||||||
|
5: GoogleLetterSpriteState.dimmed,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
flameTester.test(
|
||||||
|
"listens when its index's state changes",
|
||||||
|
(game) async {
|
||||||
|
final googleLetter = GoogleLetter(0);
|
||||||
|
await game.pump(googleLetter);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
googleLetter.listenWhen(
|
||||||
|
GoogleWordState.initial(),
|
||||||
|
firstLetterLitState,
|
||||||
|
),
|
||||||
|
isTrue,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
flameTester.test(
|
||||||
|
'changes current sprite onNewState',
|
||||||
|
(game) async {
|
||||||
|
final googleLetter = GoogleLetter(0);
|
||||||
|
await game.pump(googleLetter);
|
||||||
|
|
||||||
|
final originalSprite = googleLetter.current;
|
||||||
|
|
||||||
|
googleLetter.onNewState(firstLetterLitState);
|
||||||
|
await game.ready();
|
||||||
|
|
||||||
|
final newSprite = googleLetter.current;
|
||||||
|
expect(newSprite != originalSprite, isTrue);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
// ignore_for_file: cascade_invocations
|
||||||
|
|
||||||
|
import 'package:flame/components.dart';
|
||||||
|
import 'package:flame_bloc/flame_bloc.dart';
|
||||||
|
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_components/pinball_components.dart';
|
||||||
|
import 'package:pinball_components/src/components/google_rollover/behaviors/behaviors.dart';
|
||||||
|
|
||||||
|
class _TestGame extends Forge2DGame {
|
||||||
|
@override
|
||||||
|
Future<void> onLoad() async {
|
||||||
|
images.prefix = '';
|
||||||
|
await images.loadAll([
|
||||||
|
Assets.images.googleRollover.left.decal.keyName,
|
||||||
|
Assets.images.googleRollover.left.pin.keyName,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> pump(
|
||||||
|
GoogleRollover child, {
|
||||||
|
GoogleWordCubit? bloc,
|
||||||
|
}) async {
|
||||||
|
// Not needed once https://github.com/flame-engine/flame/issues/1607
|
||||||
|
// is fixed
|
||||||
|
await onLoad();
|
||||||
|
await ensureAdd(
|
||||||
|
FlameBlocProvider<GoogleWordCubit, GoogleWordState>.value(
|
||||||
|
value: bloc ?? GoogleWordCubit(),
|
||||||
|
children: [child],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MockBall extends Mock implements Ball {}
|
||||||
|
|
||||||
|
class _MockContact extends Mock implements Contact {}
|
||||||
|
|
||||||
|
class _MockGoogleWordCubit extends Mock implements GoogleWordCubit {}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
final flameTester = FlameTester(_TestGame.new);
|
||||||
|
|
||||||
|
group(
|
||||||
|
'GoogleRolloverBallContactBehavior',
|
||||||
|
() {
|
||||||
|
test('can be instantiated', () {
|
||||||
|
expect(
|
||||||
|
GoogleRolloverBallContactBehavior(),
|
||||||
|
isA<GoogleRolloverBallContactBehavior>(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
flameTester.testGameWidget(
|
||||||
|
'beginContact animates pin and calls onRolloverContacted '
|
||||||
|
'when contacts with a ball',
|
||||||
|
setUp: (game, tester) async {
|
||||||
|
final behavior = GoogleRolloverBallContactBehavior();
|
||||||
|
final bloc = _MockGoogleWordCubit();
|
||||||
|
final googleRollover = GoogleRollover(side: BoardSide.left);
|
||||||
|
await googleRollover.add(behavior);
|
||||||
|
await game.pump(googleRollover, bloc: bloc);
|
||||||
|
|
||||||
|
behavior.beginContact(_MockBall(), _MockContact());
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
expect(
|
||||||
|
googleRollover.firstChild<SpriteAnimationComponent>()!.playing,
|
||||||
|
isTrue,
|
||||||
|
);
|
||||||
|
verify(bloc.onRolloverContacted).called(1);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
// ignore_for_file: cascade_invocations
|
||||||
|
|
||||||
|
import 'package:flame/components.dart';
|
||||||
|
import 'package:flame_test/flame_test.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:pinball_components/pinball_components.dart';
|
||||||
|
import 'package:pinball_components/src/components/google_rollover/behaviors/behaviors.dart';
|
||||||
|
|
||||||
|
import '../../../helpers/helpers.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
final assets = [
|
||||||
|
Assets.images.googleRollover.left.decal.keyName,
|
||||||
|
Assets.images.googleRollover.left.pin.keyName,
|
||||||
|
Assets.images.googleRollover.right.decal.keyName,
|
||||||
|
Assets.images.googleRollover.right.pin.keyName,
|
||||||
|
];
|
||||||
|
final flameTester = FlameTester(() => TestGame(assets));
|
||||||
|
|
||||||
|
group('GoogleRollover', () {
|
||||||
|
test('can be instantiated', () {
|
||||||
|
expect(
|
||||||
|
GoogleRollover(side: BoardSide.left),
|
||||||
|
isA<GoogleRollover>(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
flameTester.test('left loads correctly', (game) async {
|
||||||
|
final googleRollover = GoogleRollover(side: BoardSide.left);
|
||||||
|
await game.ensureAdd(googleRollover);
|
||||||
|
expect(game.contains(googleRollover), isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
flameTester.test('right loads correctly', (game) async {
|
||||||
|
final googleRollover = GoogleRollover(side: BoardSide.right);
|
||||||
|
await game.ensureAdd(googleRollover);
|
||||||
|
expect(game.contains(googleRollover), isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
group('adds', () {
|
||||||
|
flameTester.test('new children', (game) async {
|
||||||
|
final component = Component();
|
||||||
|
final googleRollover = GoogleRollover(
|
||||||
|
side: BoardSide.left,
|
||||||
|
children: [component],
|
||||||
|
);
|
||||||
|
await game.ensureAdd(googleRollover);
|
||||||
|
expect(googleRollover.children, contains(component));
|
||||||
|
});
|
||||||
|
|
||||||
|
flameTester.test('a GoogleRolloverBallContactBehavior', (game) async {
|
||||||
|
final googleRollover = GoogleRollover(side: BoardSide.left);
|
||||||
|
await game.ensureAdd(googleRollover);
|
||||||
|
expect(
|
||||||
|
googleRollover.children
|
||||||
|
.whereType<GoogleRolloverBallContactBehavior>()
|
||||||
|
.single,
|
||||||
|
isNotNull,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
flameTester.test(
|
||||||
|
'pin stops animating after animation completes',
|
||||||
|
(game) async {
|
||||||
|
final googleRollover = GoogleRollover(side: BoardSide.left);
|
||||||
|
await game.ensureAdd(googleRollover);
|
||||||
|
|
||||||
|
final pinSpriteAnimationComponent =
|
||||||
|
googleRollover.firstChild<SpriteAnimationComponent>()!;
|
||||||
|
|
||||||
|
pinSpriteAnimationComponent.playing = true;
|
||||||
|
game.update(
|
||||||
|
pinSpriteAnimationComponent.animation!.totalDuration() + 0.1,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(pinSpriteAnimationComponent.playing, isFalse);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
import 'package:bloc_test/bloc_test.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:pinball_components/pinball_components.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group(
|
||||||
|
'GoogleWordCubit',
|
||||||
|
() {
|
||||||
|
blocTest<GoogleWordCubit, GoogleWordState>(
|
||||||
|
'onRolloverContacted emits first letter lit',
|
||||||
|
build: GoogleWordCubit.new,
|
||||||
|
act: (bloc) => bloc.onRolloverContacted(),
|
||||||
|
expect: () => [
|
||||||
|
const GoogleWordState(
|
||||||
|
letterSpriteStates: {
|
||||||
|
0: GoogleLetterSpriteState.lit,
|
||||||
|
1: GoogleLetterSpriteState.dimmed,
|
||||||
|
2: GoogleLetterSpriteState.dimmed,
|
||||||
|
3: GoogleLetterSpriteState.dimmed,
|
||||||
|
4: GoogleLetterSpriteState.dimmed,
|
||||||
|
5: GoogleLetterSpriteState.dimmed,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
blocTest<GoogleWordCubit, GoogleWordState>(
|
||||||
|
'onBonusAwarded emits initial state',
|
||||||
|
build: GoogleWordCubit.new,
|
||||||
|
act: (bloc) => bloc.onBonusAwarded(),
|
||||||
|
expect: () => [GoogleWordState.initial()],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
// ignore_for_file: prefer_const_constructors
|
||||||
|
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:pinball_components/pinball_components.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('GoogleWordState', () {
|
||||||
|
test('supports value equality', () {
|
||||||
|
expect(
|
||||||
|
GoogleWordState(
|
||||||
|
letterSpriteStates: const {
|
||||||
|
0: GoogleLetterSpriteState.dimmed,
|
||||||
|
1: GoogleLetterSpriteState.dimmed,
|
||||||
|
2: GoogleLetterSpriteState.dimmed,
|
||||||
|
3: GoogleLetterSpriteState.dimmed,
|
||||||
|
4: GoogleLetterSpriteState.dimmed,
|
||||||
|
5: GoogleLetterSpriteState.dimmed,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
equals(
|
||||||
|
GoogleWordState(
|
||||||
|
letterSpriteStates: const {
|
||||||
|
0: GoogleLetterSpriteState.dimmed,
|
||||||
|
1: GoogleLetterSpriteState.dimmed,
|
||||||
|
2: GoogleLetterSpriteState.dimmed,
|
||||||
|
3: GoogleLetterSpriteState.dimmed,
|
||||||
|
4: GoogleLetterSpriteState.dimmed,
|
||||||
|
5: GoogleLetterSpriteState.dimmed,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
group('constructor', () {
|
||||||
|
test('can be instantiated', () {
|
||||||
|
expect(
|
||||||
|
const GoogleWordState(letterSpriteStates: {}),
|
||||||
|
isNotNull,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('initial has all dimmed sprite states', () {
|
||||||
|
const initialState = GoogleWordState(
|
||||||
|
letterSpriteStates: {
|
||||||
|
0: GoogleLetterSpriteState.dimmed,
|
||||||
|
1: GoogleLetterSpriteState.dimmed,
|
||||||
|
2: GoogleLetterSpriteState.dimmed,
|
||||||
|
3: GoogleLetterSpriteState.dimmed,
|
||||||
|
4: GoogleLetterSpriteState.dimmed,
|
||||||
|
5: GoogleLetterSpriteState.dimmed,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
expect(GoogleWordState.initial(), equals(initialState));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
// ignore_for_file: cascade_invocations
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:bloc_test/bloc_test.dart';
|
||||||
|
import 'package:flame_bloc/flame_bloc.dart';
|
||||||
|
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/components/google_gallery/behaviors/behaviors.dart';
|
||||||
|
import 'package:pinball/game/game.dart';
|
||||||
|
import 'package:pinball_components/pinball_components.dart';
|
||||||
|
|
||||||
|
class _TestGame extends Forge2DGame {
|
||||||
|
@override
|
||||||
|
Future<void> onLoad() async {
|
||||||
|
images.prefix = '';
|
||||||
|
await images.loadAll([
|
||||||
|
Assets.images.googleWord.letter1.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter1.dimmed.keyName,
|
||||||
|
Assets.images.googleWord.letter2.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter2.dimmed.keyName,
|
||||||
|
Assets.images.googleWord.letter3.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter3.dimmed.keyName,
|
||||||
|
Assets.images.googleWord.letter4.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter4.dimmed.keyName,
|
||||||
|
Assets.images.googleWord.letter5.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter5.dimmed.keyName,
|
||||||
|
Assets.images.googleWord.letter6.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter6.dimmed.keyName,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> pump(
|
||||||
|
GoogleGallery child, {
|
||||||
|
required GameBloc gameBloc,
|
||||||
|
required GoogleWordCubit googleWordBloc,
|
||||||
|
}) async {
|
||||||
|
// Not needed once https://github.com/flame-engine/flame/issues/1607
|
||||||
|
// is fixed
|
||||||
|
await onLoad();
|
||||||
|
await ensureAdd(
|
||||||
|
FlameMultiBlocProvider(
|
||||||
|
providers: [
|
||||||
|
FlameBlocProvider<GameBloc, GameState>.value(
|
||||||
|
value: gameBloc,
|
||||||
|
),
|
||||||
|
FlameBlocProvider<GoogleWordCubit, GoogleWordState>.value(
|
||||||
|
value: googleWordBloc,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
children: [child],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MockGameBloc extends Mock implements GameBloc {}
|
||||||
|
|
||||||
|
class _MockGoogleWordCubit extends Mock implements GoogleWordCubit {}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
group('GoogleWordBonusBehavior', () {
|
||||||
|
late GameBloc gameBloc;
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
gameBloc = _MockGameBloc();
|
||||||
|
});
|
||||||
|
|
||||||
|
final flameTester = FlameTester(_TestGame.new);
|
||||||
|
|
||||||
|
flameTester.testGameWidget(
|
||||||
|
'adds GameBonus.googleWord to the game when all letters '
|
||||||
|
'in google word are activated and calls onBonusAwarded',
|
||||||
|
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();
|
||||||
|
|
||||||
|
verify(
|
||||||
|
() => gameBloc.add(const BonusActivated(GameBonus.googleWord)),
|
||||||
|
).called(1);
|
||||||
|
verify(googleWordBloc.onBonusAwarded).called(1);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
// ignore_for_file: cascade_invocations
|
||||||
|
|
||||||
|
import 'package:flame_bloc/flame_bloc.dart';
|
||||||
|
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';
|
||||||
|
|
||||||
|
class _TestGame extends Forge2DGame {
|
||||||
|
@override
|
||||||
|
Future<void> onLoad() async {
|
||||||
|
images.prefix = '';
|
||||||
|
await images.loadAll([
|
||||||
|
Assets.images.googleWord.letter1.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter1.dimmed.keyName,
|
||||||
|
Assets.images.googleWord.letter2.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter2.dimmed.keyName,
|
||||||
|
Assets.images.googleWord.letter3.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter3.dimmed.keyName,
|
||||||
|
Assets.images.googleWord.letter4.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter4.dimmed.keyName,
|
||||||
|
Assets.images.googleWord.letter5.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter5.dimmed.keyName,
|
||||||
|
Assets.images.googleWord.letter6.lit.keyName,
|
||||||
|
Assets.images.googleWord.letter6.dimmed.keyName,
|
||||||
|
Assets.images.googleRollover.left.decal.keyName,
|
||||||
|
Assets.images.googleRollover.left.pin.keyName,
|
||||||
|
Assets.images.googleRollover.right.decal.keyName,
|
||||||
|
Assets.images.googleRollover.right.pin.keyName,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> pump(GoogleGallery child) async {
|
||||||
|
await ensureAdd(
|
||||||
|
FlameBlocProvider<GameBloc, GameState>.value(
|
||||||
|
value: _MockGameBloc(),
|
||||||
|
children: [child],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MockGameBloc extends Mock implements GameBloc {}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
final flameTester = FlameTester(_TestGame.new);
|
||||||
|
|
||||||
|
group('GoogleGallery', () {
|
||||||
|
flameTester.test('loads correctly', (game) async {
|
||||||
|
final component = GoogleGallery();
|
||||||
|
await game.pump(component);
|
||||||
|
expect(game.descendants(), contains(component));
|
||||||
|
});
|
||||||
|
|
||||||
|
group('loads', () {
|
||||||
|
flameTester.test(
|
||||||
|
'two GoogleRollovers',
|
||||||
|
(game) async {
|
||||||
|
await game.pump(GoogleGallery());
|
||||||
|
expect(
|
||||||
|
game.descendants().whereType<GoogleRollover>().length,
|
||||||
|
equals(2),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
flameTester.test(
|
||||||
|
'a GoogleWord',
|
||||||
|
(game) async {
|
||||||
|
await game.pump(GoogleGallery());
|
||||||
|
expect(
|
||||||
|
game.descendants().whereType<GoogleWord>().length,
|
||||||
|
equals(1),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
group('adds', () {
|
||||||
|
flameTester.test(
|
||||||
|
'ScoringContactBehavior to GoogleRollovers',
|
||||||
|
(game) async {
|
||||||
|
await game.pump(GoogleGallery());
|
||||||
|
|
||||||
|
game.descendants().whereType<GoogleRollover>().forEach(
|
||||||
|
(rollover) => expect(
|
||||||
|
rollover.firstChild<ScoringContactBehavior>(),
|
||||||
|
isNotNull,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
flameTester.test('a GoogleWordBonusBehavior', (game) async {
|
||||||
|
final component = GoogleGallery();
|
||||||
|
await game.pump(component);
|
||||||
|
expect(
|
||||||
|
component.descendants().whereType<GoogleWordBonusBehavior>().single,
|
||||||
|
isNotNull,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -1,94 +0,0 @@
|
|||||||
// ignore_for_file: cascade_invocations
|
|
||||||
|
|
||||||
import 'package:flame_bloc/flame_bloc.dart';
|
|
||||||
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/components/google_word/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';
|
|
||||||
|
|
||||||
class _TestGame extends Forge2DGame {
|
|
||||||
@override
|
|
||||||
Future<void> onLoad() async {
|
|
||||||
images.prefix = '';
|
|
||||||
await images.loadAll([
|
|
||||||
Assets.images.googleWord.letter1.lit.keyName,
|
|
||||||
Assets.images.googleWord.letter1.dimmed.keyName,
|
|
||||||
Assets.images.googleWord.letter2.lit.keyName,
|
|
||||||
Assets.images.googleWord.letter2.dimmed.keyName,
|
|
||||||
Assets.images.googleWord.letter3.lit.keyName,
|
|
||||||
Assets.images.googleWord.letter3.dimmed.keyName,
|
|
||||||
Assets.images.googleWord.letter4.lit.keyName,
|
|
||||||
Assets.images.googleWord.letter4.dimmed.keyName,
|
|
||||||
Assets.images.googleWord.letter5.lit.keyName,
|
|
||||||
Assets.images.googleWord.letter5.dimmed.keyName,
|
|
||||||
Assets.images.googleWord.letter6.lit.keyName,
|
|
||||||
Assets.images.googleWord.letter6.dimmed.keyName,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> pump(GoogleWord child, {required GameBloc gameBloc}) async {
|
|
||||||
await ensureAdd(
|
|
||||||
FlameBlocProvider<GameBloc, GameState>.value(
|
|
||||||
value: gameBloc,
|
|
||||||
children: [
|
|
||||||
FlameProvider<PinballAudioPlayer>.value(
|
|
||||||
_MockPinballAudioPlayer(),
|
|
||||||
children: [child],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MockGameBloc extends Mock implements GameBloc {}
|
|
||||||
|
|
||||||
class _MockPinballAudioPlayer extends Mock implements PinballAudioPlayer {}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
|
||||||
|
|
||||||
group('GoogleWordBonusBehaviors', () {
|
|
||||||
late GameBloc gameBloc;
|
|
||||||
|
|
||||||
setUp(() {
|
|
||||||
gameBloc = _MockGameBloc();
|
|
||||||
});
|
|
||||||
|
|
||||||
final flameTester = FlameTester(_TestGame.new);
|
|
||||||
|
|
||||||
flameTester.testGameWidget(
|
|
||||||
'adds GameBonus.googleWord to the game when all letters are activated',
|
|
||||||
setUp: (game, tester) async {
|
|
||||||
await game.onLoad();
|
|
||||||
final behavior = GoogleWordBonusBehavior();
|
|
||||||
final parent = GoogleWord.test();
|
|
||||||
final letters = [
|
|
||||||
GoogleLetter(0),
|
|
||||||
GoogleLetter(1),
|
|
||||||
GoogleLetter(2),
|
|
||||||
GoogleLetter(3),
|
|
||||||
GoogleLetter(4),
|
|
||||||
GoogleLetter(5),
|
|
||||||
];
|
|
||||||
await parent.addAll(letters);
|
|
||||||
await game.pump(parent, gameBloc: gameBloc);
|
|
||||||
await parent.ensureAdd(behavior);
|
|
||||||
|
|
||||||
for (final letter in letters) {
|
|
||||||
letter.bloc.onBallContacted();
|
|
||||||
}
|
|
||||||
await tester.pump();
|
|
||||||
|
|
||||||
verify(
|
|
||||||
() => gameBloc.add(const BonusActivated(GameBonus.googleWord)),
|
|
||||||
).called(1);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
Loading…
Reference in new issue