feat(game): CONTINUE? + GAME OVER + fade-to-LOGO (Fase 2)
Sub-FSM nova `GameOverFsm` (CONTINUE_PROMPT → GAME_OVER → FADE_OUT → DONE) que viu en paral·lel a la `RoomFsm`. Es dispara quan tots els jugadors queden DISABLED durant PLAYING, mostra el rètol "Continuar?" amb countdown reusant el panel del room text, i si ningú pulsa START acaba en "Fi del Joc" + fade negre i sol·licita la transició a LOGO. Pulsar START durant CONTINUE? cancel·la el countdown i fa join (revive) del jugador. Després de GAME OVER, el HUD passa a "ESPERA / PER JUGAR" i el START queda bloquejat fins a la transició d'escena. Els helpers d'animació del room text (X i altura del panel) ara reben phase + elapsed_ms per paràmetre per poder ser reaprofitats per les dues sub-FSMs sense duplicar la lògica visual. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
c13b11c501
commit
78e164fce4
8 files changed
+562
-43
No files matched your search
@@ -13,6 +13,7 @@
|
||||
#include "game/entities/entity_manager.hpp"
|
||||
#include "game/map/paint_layer.hpp"
|
||||
#include "game/map/tilemap.hpp"
|
||||
#include "game/scenes/game_over_fsm.hpp"
|
||||
#include "game/scenes/room_fsm.hpp"
|
||||
|
||||
#ifdef _DEBUG
|
||||
@@ -291,15 +292,51 @@ class GameScene : public Scene {
|
||||
void renderRoomFade();
|
||||
void renderRoomText();
|
||||
|
||||
// Helpers de `renderRoomText`. Tots consulten `transition_` i
|
||||
// `transition_config_` directament a través de `this` — així les
|
||||
// signatures es queden netes i la funció pública s'orquestra amb
|
||||
// poques línies. Tres tasques separades:
|
||||
// - X animada d'una línia (entra per un costat, surt per l'altre).
|
||||
// - Altura animada del panel translúcid (creix, manté, decreix).
|
||||
// - Pintat efectiu del panel i d'una línia de text.
|
||||
[[nodiscard]] auto computeRoomTextX(int width, int phase_enter, int phase_exit, int dur_enter, int dur_exit, bool from_right) const -> int;
|
||||
[[nodiscard]] auto computeRoomTextPanelHeight(int phase_enter, int phase_hold, int phase_exit, int dur_enter, int dur_exit) const -> int;
|
||||
// Configuració, estat i transició de la sub-FSM de game over
|
||||
// (CONTINUE? + GAME OVER). Lligada al mateix `game.yaml` que la
|
||||
// RoomFsm via `GameOverFsm::loadConfig`.
|
||||
GameOverFsm::Config game_over_config_{};
|
||||
GameOverFsm::State game_over_state_{GameOverFsm::State::OFF};
|
||||
GameOverFsm::Transition game_over_transition_{};
|
||||
|
||||
// Fade final cap a LOGO. Independent del `outro_fade_` perquè el
|
||||
// game over passa per damunt de la RoomFsm i pot disparar-se durant
|
||||
// PLAYING sense haver d'arrencar un OUTRO de sala. Comença a la
|
||||
// fase 0 de FADE_OUT i es manté pintant alpha=255 durant el
|
||||
// `black_hold` final (mateix patró que `outro_fade_`).
|
||||
Transitions::FadeToBlack game_over_fade_;
|
||||
bool game_over_fade_started_{false};
|
||||
|
||||
// Avança la sub-FSM de game over consumint `delta_ms`. Detecta la
|
||||
// transició de "tots els jugadors fora de partida" durant PLAYING
|
||||
// (entrada a CONTINUE_PROMPT), arma el fade de FADE_OUT i, en
|
||||
// arribar a DONE, demana la transició a `LOGO`.
|
||||
void updateGameOverFlow(int delta_ms);
|
||||
|
||||
// Substitueix `setState` per a la sub-FSM de game over: log
|
||||
// d'entrada/sortida i reset de la `Transition`. També arma el
|
||||
// `game_over_fade_` quan entrem a FADE_OUT, en analogia amb
|
||||
// `outro_fade_`.
|
||||
void setGameOverState(GameOverFsm::State new_state);
|
||||
|
||||
// Pintat del rètol de game over (CONTINUE? + countdown durant
|
||||
// CONTINUE_PROMPT; "GAME OVER" durant GAME_OVER). Reaprofita el
|
||||
// panel translúcid i la font del room text.
|
||||
void renderGameOverText();
|
||||
|
||||
// Pintat del fade negre final (FADE_OUT i black hold). Cridat
|
||||
// després del HUD perquè cobreixi tota la pantalla, inclòs el
|
||||
// marcador.
|
||||
void renderGameOverFade();
|
||||
|
||||
// Helpers d'animació del rètol de transició. Reutilitzats pel
|
||||
// rètol de sala (`renderRoomText`) i pel de game over
|
||||
// (`renderGameOverText`). Reben `phase` i `elapsed_ms` per
|
||||
// paràmetre perquè la mateixa lògica visual serveix les dues
|
||||
// sub-FSMs sense saber a quina pertanyen — només es lliguen al
|
||||
// `transition_config_` per a corbes i geometria del panel.
|
||||
[[nodiscard]] auto computeRoomTextX(int width, int phase, int elapsed_ms, int phase_enter, int phase_exit, int dur_enter, int dur_exit, bool from_right) const -> int;
|
||||
[[nodiscard]] auto computeRoomTextPanelHeight(int phase, int elapsed_ms, int phase_enter, int phase_hold, int phase_exit, int dur_enter, int dur_exit) const -> int;
|
||||
void drawRoomTextPanel(int center_y, int panel_height) const;
|
||||
void drawRoomTextLine(const std::string& text, int x, int y, std::uint8_t fill_color, std::uint8_t outline_color) const;
|
||||
|
||||
|
||||
Reference in new issue
Block a user