diff --git a/lib/assets_manager/views/assets_loading_page.dart b/lib/assets_manager/views/assets_loading_page.dart index 4e75a3a5..72476064 100644 --- a/lib/assets_manager/views/assets_loading_page.dart +++ b/lib/assets_manager/views/assets_loading_page.dart @@ -17,29 +17,32 @@ class AssetsLoadingPage extends StatelessWidget { Widget build(BuildContext context) { final l10n = context.l10n; final headline1 = Theme.of(context).textTheme.headline1; - return Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Assets.images.loadingGame.ioPinball.image(), - ), - const SizedBox(height: 40), - AnimatedEllipsisText( - l10n.loading, - style: headline1, - ), - const SizedBox(height: 40), - FractionallySizedBox( - widthFactor: 0.8, - child: BlocBuilder( - builder: (context, state) { - return PinballLoadingIndicator(value: state.progress); - }, + return Container( + decoration: const CrtBackground(), + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Assets.images.loadingGame.ioPinball.image(), ), - ), - ], + const SizedBox(height: 40), + AnimatedEllipsisText( + l10n.loading, + style: headline1, + ), + const SizedBox(height: 40), + FractionallySizedBox( + widthFactor: 0.8, + child: BlocBuilder( + builder: (context, state) { + return PinballLoadingIndicator(value: state.progress); + }, + ), + ), + ], + ), ), ); } diff --git a/lib/game/behaviors/behaviors.dart b/lib/game/behaviors/behaviors.dart index 5900f2b3..8d5ee04e 100644 --- a/lib/game/behaviors/behaviors.dart +++ b/lib/game/behaviors/behaviors.dart @@ -1,7 +1,7 @@ export 'ball_spawning_behavior.dart'; -export 'ball_theming_behavior.dart'; export 'bonus_ball_spawning_behavior.dart'; export 'bonus_noise_behavior.dart'; export 'bumper_noise_behavior.dart'; export 'camera_focusing_behavior.dart'; +export 'character_selection_behavior.dart'; export 'scoring_behavior.dart'; diff --git a/lib/game/behaviors/ball_theming_behavior.dart b/lib/game/behaviors/character_selection_behavior.dart similarity index 57% rename from lib/game/behaviors/ball_theming_behavior.dart rename to lib/game/behaviors/character_selection_behavior.dart index 5e12a720..27003d75 100644 --- a/lib/game/behaviors/ball_theming_behavior.dart +++ b/lib/game/behaviors/character_selection_behavior.dart @@ -3,18 +3,25 @@ import 'package:flame_bloc/flame_bloc.dart'; import 'package:pinball/select_character/select_character.dart'; import 'package:pinball_components/pinball_components.dart'; -/// Updates the launch [Ball] to reflect character selections. -class BallThemingBehavior extends Component +/// Updates the [ArcadeBackground] and launch [Ball] to reflect character +/// selections. +class CharacterSelectionBehavior extends Component with FlameBlocListenable, HasGameRef { @override void onNewState(CharacterThemeState state) { + gameRef + .descendants() + .whereType() + .single + .bloc + .onCharacterSelected(state.characterTheme); gameRef .descendants() .whereType() .single .bloc - .onThemeChanged(state.characterTheme); + .onCharacterSelected(state.characterTheme); } } diff --git a/lib/game/game_assets.dart b/lib/game/game_assets.dart index e0b66b15..c10a11ed 100644 --- a/lib/game/game_assets.dart +++ b/lib/game/game_assets.dart @@ -139,13 +139,17 @@ extension PinballGameAssetsX on PinballGame { images.load(components.Assets.images.skillShot.pin.keyName), images.load(components.Assets.images.skillShot.lit.keyName), images.load(components.Assets.images.skillShot.dimmed.keyName), - images.load(dashTheme.leaderboardIcon.keyName), - images.load(sparkyTheme.leaderboardIcon.keyName), images.load(androidTheme.leaderboardIcon.keyName), - images.load(dinoTheme.leaderboardIcon.keyName), + images.load(androidTheme.background.keyName), images.load(androidTheme.ball.keyName), + images.load(dashTheme.leaderboardIcon.keyName), + images.load(dashTheme.background.keyName), images.load(dashTheme.ball.keyName), + images.load(dinoTheme.leaderboardIcon.keyName), + images.load(dinoTheme.background.keyName), images.load(dinoTheme.ball.keyName), + images.load(sparkyTheme.leaderboardIcon.keyName), + images.load(sparkyTheme.background.keyName), images.load(sparkyTheme.ball.keyName), ]; } diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 89250986..8c018085 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -90,7 +90,7 @@ class PinballGame extends PinballForge2DGame BonusNoiseBehavior(), GameBlocStatusListener(), BallSpawningBehavior(), - BallThemingBehavior(), + CharacterSelectionBehavior(), CameraFocusingBehavior(), CanvasComponent( onSpritePainted: (paint) { @@ -101,6 +101,7 @@ class PinballGame extends PinballForge2DGame children: [ ZCanvasComponent( children: [ + ArcadeBackground(), BoardBackgroundSpriteComponent(), Boundaries(), Backbox( diff --git a/lib/game/view/pinball_game_page.dart b/lib/game/view/pinball_game_page.dart index 5c21f257..6e910817 100644 --- a/lib/game/view/pinball_game_page.dart +++ b/lib/game/view/pinball_game_page.dart @@ -43,14 +43,11 @@ class PinballGamePage extends StatelessWidget { gameBloc: gameBloc, ); - return Container( - decoration: const CrtBackground(), - child: Scaffold( - backgroundColor: PinballColors.transparent, - body: BlocProvider( - create: (_) => AssetsManagerCubit(game, audioPlayer)..load(), - child: PinballGameView(game), - ), + return Scaffold( + backgroundColor: PinballColors.black, + body: BlocProvider( + create: (_) => AssetsManagerCubit(game, audioPlayer)..load(), + child: PinballGameView(game), ), ); } diff --git a/packages/pinball_components/lib/src/components/arcade_background/arcade_background.dart b/packages/pinball_components/lib/src/components/arcade_background/arcade_background.dart new file mode 100644 index 00000000..e9936367 --- /dev/null +++ b/packages/pinball_components/lib/src/components/arcade_background/arcade_background.dart @@ -0,0 +1,92 @@ +import 'package:flame/components.dart'; +import 'package:flame_bloc/flame_bloc.dart'; +import 'package:flutter/material.dart'; +import 'package:pinball_components/pinball_components.dart'; +import 'package:pinball_flame/pinball_flame.dart'; +import 'package:pinball_theme/pinball_theme.dart' as theme; + +export 'cubit/arcade_background_cubit.dart'; + +/// {@template arcade_background} +/// Background of the arcade that the pinball machine lives in. +/// {@endtemplate} +class ArcadeBackground extends Component with ZIndex { + /// {@macro arcade_background} + ArcadeBackground({String? assetPath}) + : this._( + bloc: ArcadeBackgroundCubit(), + assetPath: assetPath, + ); + + ArcadeBackground._({required this.bloc, String? assetPath}) + : super( + children: [ + FlameBlocProvider.value( + value: bloc, + children: [ArcadeBackgroundSpriteComponent(assetPath: assetPath)], + ) + ], + ) { + zIndex = ZIndexes.arcadeBackground; + } + + /// Creates an [ArcadeBackground] without any behaviors. + /// + /// This can be used for testing [ArcadeBackground]'s behaviors in isolation. + @visibleForTesting + ArcadeBackground.test({ + ArcadeBackgroundCubit? bloc, + String? assetPath, + }) : bloc = bloc ?? ArcadeBackgroundCubit(), + super( + children: [ + FlameBlocProvider.value( + value: bloc ?? ArcadeBackgroundCubit(), + children: [ArcadeBackgroundSpriteComponent(assetPath: assetPath)], + ) + ], + ); + + /// Bloc to update the arcade background sprite when a new character is + /// selected. + final ArcadeBackgroundCubit bloc; +} + +/// {@template arcade_background_sprite_component} +/// [SpriteComponent] for the [ArcadeBackground]. +/// {@endtemplate} +@visibleForTesting +class ArcadeBackgroundSpriteComponent extends SpriteComponent + with + FlameBlocListenable, + HasGameRef { + /// {@macro arcade_background_sprite_component} + ArcadeBackgroundSpriteComponent({required String? assetPath}) + : _assetPath = assetPath, + super( + anchor: Anchor.bottomCenter, + position: Vector2(0, 72.3), + ); + + final String? _assetPath; + + @override + void onNewState(ArcadeBackgroundState state) { + sprite = Sprite( + gameRef.images.fromCache(state.characterTheme.background.keyName), + ); + } + + @override + Future onLoad() async { + await super.onLoad(); + final sprite = Sprite( + gameRef.images + .fromCache(_assetPath ?? theme.Assets.images.dash.background.keyName), + ); + this.sprite = sprite; + size = sprite.originalSize / 10; + } +} diff --git a/packages/pinball_components/lib/src/components/arcade_background/cubit/arcade_background_cubit.dart b/packages/pinball_components/lib/src/components/arcade_background/cubit/arcade_background_cubit.dart new file mode 100644 index 00000000..5b2188bc --- /dev/null +++ b/packages/pinball_components/lib/src/components/arcade_background/cubit/arcade_background_cubit.dart @@ -0,0 +1,15 @@ +// ignore_for_file: public_member_api_docs + +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:pinball_theme/pinball_theme.dart'; + +part 'arcade_background_state.dart'; + +class ArcadeBackgroundCubit extends Cubit { + ArcadeBackgroundCubit() : super(const ArcadeBackgroundState.initial()); + + void onCharacterSelected(CharacterTheme characterTheme) { + emit(ArcadeBackgroundState(characterTheme: characterTheme)); + } +} diff --git a/packages/pinball_components/lib/src/components/arcade_background/cubit/arcade_background_state.dart b/packages/pinball_components/lib/src/components/arcade_background/cubit/arcade_background_state.dart new file mode 100644 index 00000000..d2406105 --- /dev/null +++ b/packages/pinball_components/lib/src/components/arcade_background/cubit/arcade_background_state.dart @@ -0,0 +1,15 @@ +// ignore_for_file: public_member_api_docs + +part of 'arcade_background_cubit.dart'; + +class ArcadeBackgroundState extends Equatable { + const ArcadeBackgroundState({required this.characterTheme}); + + const ArcadeBackgroundState.initial() + : this(characterTheme: const DashTheme()); + + final CharacterTheme characterTheme; + + @override + List get props => [characterTheme]; +} diff --git a/packages/pinball_components/lib/src/components/ball/cubit/ball_cubit.dart b/packages/pinball_components/lib/src/components/ball/cubit/ball_cubit.dart index 7d5c7dda..248a0e4f 100644 --- a/packages/pinball_components/lib/src/components/ball/cubit/ball_cubit.dart +++ b/packages/pinball_components/lib/src/components/ball/cubit/ball_cubit.dart @@ -7,7 +7,7 @@ part 'ball_state.dart'; class BallCubit extends Cubit { BallCubit() : super(const BallState.initial()); - void onThemeChanged(CharacterTheme characterTheme) { + void onCharacterSelected(CharacterTheme characterTheme) { emit(BallState(characterTheme: characterTheme)); } } diff --git a/packages/pinball_components/lib/src/components/components.dart b/packages/pinball_components/lib/src/components/components.dart index 2e37f927..75ba12dc 100644 --- a/packages/pinball_components/lib/src/components/components.dart +++ b/packages/pinball_components/lib/src/components/components.dart @@ -1,6 +1,7 @@ export 'android_animatronic.dart'; export 'android_bumper/android_bumper.dart'; export 'android_spaceship/android_spaceship.dart'; +export 'arcade_background/arcade_background.dart'; export 'ball/ball.dart'; export 'baseboard.dart'; export 'board_background_sprite_component.dart'; diff --git a/packages/pinball_components/lib/src/components/z_indexes.dart b/packages/pinball_components/lib/src/components/z_indexes.dart index 0d0fab98..543ad7a7 100644 --- a/packages/pinball_components/lib/src/components/z_indexes.dart +++ b/packages/pinball_components/lib/src/components/z_indexes.dart @@ -18,6 +18,8 @@ abstract class ZIndexes { // Background + static const arcadeBackground = _below + boardBackground; + static const boardBackground = 5 * _below + _base; static const decal = _above + boardBackground; diff --git a/packages/pinball_components/test/src/components/arcade_background/arcade_background_test.dart b/packages/pinball_components/test/src/components/arcade_background/arcade_background_test.dart new file mode 100644 index 00000000..a5c336d5 --- /dev/null +++ b/packages/pinball_components/test/src/components/arcade_background/arcade_background_test.dart @@ -0,0 +1,79 @@ +// 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_theme/pinball_theme.dart' as theme; + +import '../../../helpers/helpers.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + final assets = [ + theme.Assets.images.android.background.keyName, + theme.Assets.images.dash.background.keyName, + theme.Assets.images.dino.background.keyName, + theme.Assets.images.sparky.background.keyName, + ]; + + final flameTester = FlameTester(() => TestGame(assets)); + + group('ArcadeBackground', () { + test( + 'can be instantiated', + () { + expect(ArcadeBackground(), isA()); + expect(ArcadeBackground.test(), isA()); + }, + ); + + flameTester.test( + 'loads correctly', + (game) async { + final ball = ArcadeBackground(); + await game.ready(); + await game.ensureAdd(ball); + + expect(game.contains(ball), isTrue); + }, + ); + + flameTester.test( + 'has only one SpriteComponent', + (game) async { + final ball = ArcadeBackground(); + await game.ready(); + await game.ensureAdd(ball); + + expect( + ball.descendants().whereType().length, + equals(1), + ); + }, + ); + + flameTester.test( + 'ArcadeBackgroundSpriteComponent changes sprite onNewState', + (game) async { + final ball = ArcadeBackground(); + await game.ready(); + await game.ensureAdd(ball); + + final ballSprite = ball + .descendants() + .whereType() + .single; + final originalSprite = ballSprite.sprite; + + ballSprite.onNewState( + const ArcadeBackgroundState(characterTheme: theme.DinoTheme()), + ); + await game.ready(); + + final newSprite = ballSprite.sprite; + expect(newSprite != originalSprite, isTrue); + }, + ); + }); +} diff --git a/packages/pinball_components/test/src/components/arcade_background/cubit/arcade_background_cubit_test.dart b/packages/pinball_components/test/src/components/arcade_background/cubit/arcade_background_cubit_test.dart new file mode 100644 index 00000000..f2e99247 --- /dev/null +++ b/packages/pinball_components/test/src/components/arcade_background/cubit/arcade_background_cubit_test.dart @@ -0,0 +1,22 @@ +import 'package:bloc_test/bloc_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pinball_components/pinball_components.dart'; +import 'package:pinball_theme/pinball_theme.dart'; + +void main() { + group( + 'ArcadeBackgroundCubit', + () { + blocTest( + 'onCharacterSelected emits new theme', + build: ArcadeBackgroundCubit.new, + act: (bloc) => bloc.onCharacterSelected(const DinoTheme()), + expect: () => [ + const ArcadeBackgroundState( + characterTheme: DinoTheme(), + ), + ], + ); + }, + ); +} diff --git a/packages/pinball_components/test/src/components/arcade_background/cubit/arcade_background_state_test.dart b/packages/pinball_components/test/src/components/arcade_background/cubit/arcade_background_state_test.dart new file mode 100644 index 00000000..97925fb6 --- /dev/null +++ b/packages/pinball_components/test/src/components/arcade_background/cubit/arcade_background_state_test.dart @@ -0,0 +1,32 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter_test/flutter_test.dart'; +import 'package:pinball_components/pinball_components.dart'; +import 'package:pinball_theme/pinball_theme.dart'; + +void main() { + group('ArcadeBackgroundState', () { + test('supports value equality', () { + expect( + ArcadeBackgroundState(characterTheme: DashTheme()), + equals(ArcadeBackgroundState(characterTheme: DashTheme())), + ); + }); + + group('constructor', () { + test('can be instantiated', () { + expect( + ArcadeBackgroundState(characterTheme: DashTheme()), + isNotNull, + ); + }); + + test('initial contains DashTheme', () { + expect( + ArcadeBackgroundState.initial().characterTheme, + DashTheme(), + ); + }); + }); + }); +} diff --git a/packages/pinball_components/test/src/components/ball/cubit/ball_cubit_test.dart b/packages/pinball_components/test/src/components/ball/cubit/ball_cubit_test.dart index c5a03213..c3a89120 100644 --- a/packages/pinball_components/test/src/components/ball/cubit/ball_cubit_test.dart +++ b/packages/pinball_components/test/src/components/ball/cubit/ball_cubit_test.dart @@ -8,9 +8,9 @@ void main() { 'BallCubit', () { blocTest( - 'onThemeChanged emits new theme', + 'onCharacterSelected emits new theme', build: BallCubit.new, - act: (bloc) => bloc.onThemeChanged(const DinoTheme()), + act: (bloc) => bloc.onCharacterSelected(const DinoTheme()), expect: () => [const BallState(characterTheme: DinoTheme())], ); }, diff --git a/packages/pinball_theme/assets/images/android/background.jpg b/packages/pinball_theme/assets/images/android/background.jpg new file mode 100644 index 00000000..f446e140 Binary files /dev/null and b/packages/pinball_theme/assets/images/android/background.jpg differ diff --git a/packages/pinball_theme/assets/images/android/background.png b/packages/pinball_theme/assets/images/android/background.png deleted file mode 100644 index f751dcdc..00000000 Binary files a/packages/pinball_theme/assets/images/android/background.png and /dev/null differ diff --git a/packages/pinball_theme/assets/images/dash/background.jpg b/packages/pinball_theme/assets/images/dash/background.jpg new file mode 100644 index 00000000..dc698060 Binary files /dev/null and b/packages/pinball_theme/assets/images/dash/background.jpg differ diff --git a/packages/pinball_theme/assets/images/dash/background.png b/packages/pinball_theme/assets/images/dash/background.png deleted file mode 100644 index a36601c9..00000000 Binary files a/packages/pinball_theme/assets/images/dash/background.png and /dev/null differ diff --git a/packages/pinball_theme/assets/images/dino/background.jpg b/packages/pinball_theme/assets/images/dino/background.jpg new file mode 100644 index 00000000..45272247 Binary files /dev/null and b/packages/pinball_theme/assets/images/dino/background.jpg differ diff --git a/packages/pinball_theme/assets/images/dino/background.png b/packages/pinball_theme/assets/images/dino/background.png deleted file mode 100644 index e42f1705..00000000 Binary files a/packages/pinball_theme/assets/images/dino/background.png and /dev/null differ diff --git a/packages/pinball_theme/assets/images/sparky/background.jpg b/packages/pinball_theme/assets/images/sparky/background.jpg new file mode 100644 index 00000000..ad19a47a Binary files /dev/null and b/packages/pinball_theme/assets/images/sparky/background.jpg differ diff --git a/packages/pinball_theme/assets/images/sparky/background.png b/packages/pinball_theme/assets/images/sparky/background.png deleted file mode 100644 index 5044376c..00000000 Binary files a/packages/pinball_theme/assets/images/sparky/background.png and /dev/null differ diff --git a/packages/pinball_theme/lib/src/generated/assets.gen.dart b/packages/pinball_theme/lib/src/generated/assets.gen.dart index 545f514b..17ec4caf 100644 --- a/packages/pinball_theme/lib/src/generated/assets.gen.dart +++ b/packages/pinball_theme/lib/src/generated/assets.gen.dart @@ -32,9 +32,9 @@ class $AssetsImagesAndroidGen { AssetGenImage get animation => const AssetGenImage('assets/images/android/animation.png'); - /// File path: assets/images/android/background.png + /// File path: assets/images/android/background.jpg AssetGenImage get background => - const AssetGenImage('assets/images/android/background.png'); + const AssetGenImage('assets/images/android/background.jpg'); /// File path: assets/images/android/ball.png AssetGenImage get ball => @@ -56,9 +56,9 @@ class $AssetsImagesDashGen { AssetGenImage get animation => const AssetGenImage('assets/images/dash/animation.png'); - /// File path: assets/images/dash/background.png + /// File path: assets/images/dash/background.jpg AssetGenImage get background => - const AssetGenImage('assets/images/dash/background.png'); + const AssetGenImage('assets/images/dash/background.jpg'); /// File path: assets/images/dash/ball.png AssetGenImage get ball => const AssetGenImage('assets/images/dash/ball.png'); @@ -78,9 +78,9 @@ class $AssetsImagesDinoGen { AssetGenImage get animation => const AssetGenImage('assets/images/dino/animation.png'); - /// File path: assets/images/dino/background.png + /// File path: assets/images/dino/background.jpg AssetGenImage get background => - const AssetGenImage('assets/images/dino/background.png'); + const AssetGenImage('assets/images/dino/background.jpg'); /// File path: assets/images/dino/ball.png AssetGenImage get ball => const AssetGenImage('assets/images/dino/ball.png'); @@ -100,9 +100,9 @@ class $AssetsImagesSparkyGen { AssetGenImage get animation => const AssetGenImage('assets/images/sparky/animation.png'); - /// File path: assets/images/sparky/background.png + /// File path: assets/images/sparky/background.jpg AssetGenImage get background => - const AssetGenImage('assets/images/sparky/background.png'); + const AssetGenImage('assets/images/sparky/background.jpg'); /// File path: assets/images/sparky/ball.png AssetGenImage get ball => diff --git a/packages/pinball_ui/lib/src/theme/pinball_colors.dart b/packages/pinball_ui/lib/src/theme/pinball_colors.dart index eb920129..250db02c 100644 --- a/packages/pinball_ui/lib/src/theme/pinball_colors.dart +++ b/packages/pinball_ui/lib/src/theme/pinball_colors.dart @@ -5,6 +5,9 @@ abstract class PinballColors { /// Color: 0xFFFFFFFF static const Color white = Color(0xFFFFFFFF); + /// Color: 0xFF000000 + static const Color black = Color(0xFF000000); + /// Color: 0xFF0C32A4 static const Color darkBlue = Color(0xFF0C32A4); diff --git a/packages/pinball_ui/test/src/theme/pinball_colors_test.dart b/packages/pinball_ui/test/src/theme/pinball_colors_test.dart index 469ab142..ddc95eda 100644 --- a/packages/pinball_ui/test/src/theme/pinball_colors_test.dart +++ b/packages/pinball_ui/test/src/theme/pinball_colors_test.dart @@ -8,6 +8,10 @@ void main() { expect(PinballColors.white, const Color(0xFFFFFFFF)); }); + test('black is 0xFF000000', () { + expect(PinballColors.black, const Color(0xFF000000)); + }); + test('darkBlue is 0xFF0C32A4', () { expect(PinballColors.darkBlue, const Color(0xFF0C32A4)); }); diff --git a/test/game/behaviors/ball_theming_behavior_test.dart b/test/game/behaviors/character_selection_behavior_test.dart similarity index 57% rename from test/game/behaviors/ball_theming_behavior_test.dart rename to test/game/behaviors/character_selection_behavior_test.dart index 0c1e0b36..67a8b0a5 100644 --- a/test/game/behaviors/ball_theming_behavior_test.dart +++ b/test/game/behaviors/character_selection_behavior_test.dart @@ -20,6 +20,8 @@ class _TestGame extends Forge2DGame { await images.loadAll([ theme.Assets.images.dash.ball.keyName, theme.Assets.images.dino.ball.keyName, + theme.Assets.images.dash.background.keyName, + theme.Assets.images.dino.background.keyName, ]); } @@ -38,32 +40,66 @@ class _TestGame extends Forge2DGame { class _MockBallCubit extends Mock implements BallCubit {} +class _MockArcadeBackgroundCubit extends Mock implements ArcadeBackgroundCubit { +} + void main() { TestWidgetsFlutterBinding.ensureInitialized(); group( - 'BallThemingBehavior', + 'CharacterSelectionBehavior', () { final flameTester = FlameTester(_TestGame.new); test('can be instantiated', () { expect( - BallThemingBehavior(), - isA(), + CharacterSelectionBehavior(), + isA(), ); }); flameTester.test( 'loads', (game) async { - final behavior = BallThemingBehavior(); + final behavior = CharacterSelectionBehavior(); await game.pump([behavior]); expect(game.descendants(), contains(behavior)); }, ); flameTester.test( - 'onNewState calls onThemeChanged on the ball bloc', + 'onNewState calls onCharacterSelected on the arcade background bloc', + (game) async { + final arcadeBackgroundBloc = _MockArcadeBackgroundCubit(); + whenListen( + arcadeBackgroundBloc, + const Stream.empty(), + initialState: const ArcadeBackgroundState.initial(), + ); + final arcadeBackground = + ArcadeBackground.test(bloc: arcadeBackgroundBloc); + final behavior = CharacterSelectionBehavior(); + await game.pump([ + arcadeBackground, + behavior, + ZCanvasComponent(), + Plunger.test(compressionDistance: 10), + Ball.test(), + ]); + + const dinoThemeState = CharacterThemeState(theme.DinoTheme()); + behavior.onNewState(dinoThemeState); + await game.ready(); + + verify( + () => arcadeBackgroundBloc + .onCharacterSelected(dinoThemeState.characterTheme), + ).called(1); + }, + ); + + flameTester.test( + 'onNewState calls onCharacterSelected on the ball bloc', (game) async { final ballBloc = _MockBallCubit(); whenListen( @@ -72,20 +108,22 @@ void main() { initialState: const BallState.initial(), ); final ball = Ball.test(bloc: ballBloc); - final behavior = BallThemingBehavior(); + final behavior = CharacterSelectionBehavior(); await game.pump([ ball, behavior, ZCanvasComponent(), Plunger.test(compressionDistance: 10), + ArcadeBackground.test(), ]); const dinoThemeState = CharacterThemeState(theme.DinoTheme()); behavior.onNewState(dinoThemeState); await game.ready(); - verify(() => ballBloc.onThemeChanged(dinoThemeState.characterTheme)) - .called(1); + verify( + () => ballBloc.onCharacterSelected(dinoThemeState.characterTheme), + ).called(1); }, ); }, diff --git a/test/game/pinball_game_test.dart b/test/game/pinball_game_test.dart index ba54939c..d64333cc 100644 --- a/test/game/pinball_game_test.dart +++ b/test/game/pinball_game_test.dart @@ -113,11 +113,11 @@ void main() { ); flameTester.test( - 'has only one BallThemingBehavior', + 'has only one CharacterSelectionBehavior', (game) async { await game.ready(); expect( - game.descendants().whereType().length, + game.descendants().whereType().length, equals(1), ); },