From 3a9cbacb57e212f5d125f6d0129fdbcfd9ebe75f Mon Sep 17 00:00:00 2001 From: RuiAlonso Date: Fri, 6 May 2022 12:36:50 +0200 Subject: [PATCH] feat: added replay button and game flow --- lib/game/behaviors/camera_focusing_behavior.dart | 1 + lib/game/bloc/game_bloc.dart | 5 +++++ lib/game/bloc/game_event.dart | 7 +++++++ lib/game/bloc/game_state.dart | 4 +++- lib/game/components/game_bloc_status_listener.dart | 3 +++ lib/game/pinball_game.dart | 2 +- lib/game/view/widgets/replay_button_overlay.dart | 2 +- lib/start_game/bloc/start_game_bloc.dart | 13 +++++++++++++ lib/start_game/bloc/start_game_event.dart | 11 +++++++++++ lib/start_game/bloc/start_game_state.dart | 14 ++++++++++++-- lib/start_game/widgets/start_game_listener.dart | 6 +++++- 11 files changed, 62 insertions(+), 6 deletions(-) diff --git a/lib/game/behaviors/camera_focusing_behavior.dart b/lib/game/behaviors/camera_focusing_behavior.dart index 8a13821d..453b338c 100644 --- a/lib/game/behaviors/camera_focusing_behavior.dart +++ b/lib/game/behaviors/camera_focusing_behavior.dart @@ -37,6 +37,7 @@ class CameraFocusingBehavior extends Component case GameStatus.waiting: break; case GameStatus.playing: + case GameStatus.replaying: _zoom(_foci['game']!); break; case GameStatus.gameOver: diff --git a/lib/game/bloc/game_bloc.dart b/lib/game/bloc/game_bloc.dart index b22baa14..16319c16 100644 --- a/lib/game/bloc/game_bloc.dart +++ b/lib/game/bloc/game_bloc.dart @@ -16,12 +16,17 @@ class GameBloc extends Bloc { on(_onSparkyTurboChargeActivated); on(_onGameOver); on(_onGameStarted); + on(_onGameRestarted); } void _onGameStarted(GameStarted _, Emitter emit) { emit(state.copyWith(status: GameStatus.playing)); } + void _onGameRestarted(GameRestarted _, Emitter emit) { + emit(const GameState.initial().copyWith(status: GameStatus.replaying)); + } + void _onGameOver(GameOver _, Emitter emit) { emit(state.copyWith(status: GameStatus.gameOver)); } diff --git a/lib/game/bloc/game_event.dart b/lib/game/bloc/game_event.dart index 6dba8056..ac3de39e 100644 --- a/lib/game/bloc/game_event.dart +++ b/lib/game/bloc/game_event.dart @@ -67,6 +67,13 @@ class GameStarted extends GameEvent { List get props => []; } +class GameRestarted extends GameEvent { + const GameRestarted(); + + @override + List get props => []; +} + class GameOver extends GameEvent { const GameOver(); diff --git a/lib/game/bloc/game_state.dart b/lib/game/bloc/game_state.dart index d0311442..651b5ff7 100644 --- a/lib/game/bloc/game_state.dart +++ b/lib/game/bloc/game_state.dart @@ -23,12 +23,14 @@ enum GameBonus { enum GameStatus { waiting, playing, + replaying, gameOver, } extension GameStatusX on GameStatus { bool get isWaiting => this == GameStatus.waiting; - bool get isPlaying => this == GameStatus.playing; + bool get isPlaying => + this == GameStatus.playing || this == GameStatus.replaying; bool get isGameOver => this == GameStatus.gameOver; } diff --git a/lib/game/components/game_bloc_status_listener.dart b/lib/game/components/game_bloc_status_listener.dart index 6e11f3d6..396eac5a 100644 --- a/lib/game/components/game_bloc_status_listener.dart +++ b/lib/game/components/game_bloc_status_listener.dart @@ -22,6 +22,9 @@ class GameBlocStatusListener extends Component readProvider().play(PinballAudio.backgroundMusic); gameRef.overlays.remove(PinballGame.playButtonOverlay); break; + case GameStatus.replaying: + gameRef.overlays.remove(PinballGame.replayButtonOverlay); + break; case GameStatus.gameOver: readProvider().play(PinballAudio.gameOverVoiceOver); gameRef.descendants().whereType().first.requestInitials( diff --git a/lib/game/pinball_game.dart b/lib/game/pinball_game.dart index 2c613e65..47eec3b5 100644 --- a/lib/game/pinball_game.dart +++ b/lib/game/pinball_game.dart @@ -17,7 +17,7 @@ import 'package:pinball_flame/pinball_flame.dart'; import 'package:pinball_theme/pinball_theme.dart'; class PinballGame extends PinballForge2DGame - with HasKeyboardHandlerComponents, MultiTouchTapDetector { + with HasKeyboardHandlerComponents, MultiTouchTapDetector, HasTappables { PinballGame({ required CharacterTheme characterTheme, required this.leaderboardRepository, diff --git a/lib/game/view/widgets/replay_button_overlay.dart b/lib/game/view/widgets/replay_button_overlay.dart index ac785d99..4f40ca27 100644 --- a/lib/game/view/widgets/replay_button_overlay.dart +++ b/lib/game/view/widgets/replay_button_overlay.dart @@ -18,7 +18,7 @@ class ReplayButtonOverlay extends StatelessWidget { return PinballButton( text: l10n.replay, onTap: () { - context.read().add(const PlayTapped()); + context.read().add(const ReplayTapped()); }, ); } diff --git a/lib/start_game/bloc/start_game_bloc.dart b/lib/start_game/bloc/start_game_bloc.dart index 3a96b57b..004b3872 100644 --- a/lib/start_game/bloc/start_game_bloc.dart +++ b/lib/start_game/bloc/start_game_bloc.dart @@ -11,6 +11,7 @@ class StartGameBloc extends Bloc { /// {@macro start_game_bloc} StartGameBloc() : super(const StartGameState.initial()) { on(_onPlayTapped); + on(_onReplayTapped); on(_onCharacterSelected); on(_onHowToPlayFinished); } @@ -26,6 +27,18 @@ class StartGameBloc extends Bloc { ); } + void _onReplayTapped( + ReplayTapped event, + Emitter emit, + ) { + emit( + state.copyWith( + status: StartGameStatus.selectCharacter, + restarted: true, + ), + ); + } + void _onCharacterSelected( CharacterSelected event, Emitter emit, diff --git a/lib/start_game/bloc/start_game_event.dart b/lib/start_game/bloc/start_game_event.dart index ce164e97..ae216c32 100644 --- a/lib/start_game/bloc/start_game_event.dart +++ b/lib/start_game/bloc/start_game_event.dart @@ -19,6 +19,17 @@ class PlayTapped extends StartGameEvent { List get props => []; } +/// {@template replay_tapped} +/// Replay tapped event. +/// {@endtemplate} +class ReplayTapped extends StartGameEvent { + /// {@macro replay_tapped} + const ReplayTapped(); + + @override + List get props => []; +} + /// {@template character_selected} /// Character selected event. /// {@endtemplate} diff --git a/lib/start_game/bloc/start_game_state.dart b/lib/start_game/bloc/start_game_state.dart index ad7c7cbe..ea8319cd 100644 --- a/lib/start_game/bloc/start_game_state.dart +++ b/lib/start_game/bloc/start_game_state.dart @@ -22,23 +22,33 @@ class StartGameState extends Equatable { /// {@macro start_game_state} const StartGameState({ required this.status, + this.restarted = false, }); /// Initial [StartGameState]. - const StartGameState.initial() : this(status: StartGameStatus.initial); + const StartGameState.initial() + : this( + status: StartGameStatus.initial, + restarted: false, + ); /// Status of [StartGameState]. final StartGameStatus status; + /// Game has been restarted from game over screen. + final bool restarted; + /// Creates a copy of [StartGameState]. StartGameState copyWith({ StartGameStatus? status, + bool? restarted, }) { return StartGameState( status: status ?? this.status, + restarted: restarted ?? this.restarted, ); } @override - List get props => [status]; + List get props => [status, restarted]; } diff --git a/lib/start_game/widgets/start_game_listener.dart b/lib/start_game/widgets/start_game_listener.dart index 692116f3..336d2474 100644 --- a/lib/start_game/widgets/start_game_listener.dart +++ b/lib/start_game/widgets/start_game_listener.dart @@ -31,7 +31,11 @@ class StartGameListener extends StatelessWidget { break; case StartGameStatus.selectCharacter: _onSelectCharacter(context); - context.read().add(const GameStarted()); + if (state.restarted) { + context.read().add(const GameRestarted()); + } else { + context.read().add(const GameStarted()); + } break; case StartGameStatus.howToPlay: _onHowToPlay(context);