70 lines
2.8 KiB
C++
70 lines
2.8 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <optional>
|
|
|
|
#include "core/rendering/effects/heat_haze.hpp"
|
|
#include "core/rendering/transitions/fade_to_black.hpp"
|
|
#include "core/rendering/transitions/mosaic.hpp"
|
|
#include "core/scene/scene.hpp"
|
|
#include "game/debug_config.hpp"
|
|
|
|
class Surface;
|
|
class Text;
|
|
|
|
// Escena TITLE provisional. Pinta dos blocs de text sobre un fons gairebé
|
|
// negre i un prompt "press start" intermitent fins que apareix l'artwork
|
|
// real. Tota la cosmètica (colors, durada, ritme del parpadeig) viu a
|
|
// data/ui.yaml secció `title:` per poder afinar-la sense recompilar.
|
|
class TitleScene : public Scene {
|
|
public:
|
|
// Fases de l'escena.
|
|
// - IDLE: animació atràctil. Només P1 START o P2 START hi fan
|
|
// transició; un timeout `title.duration_ms` porta a ATTRACT_OUT.
|
|
// - STARTING: comptador fix entre la primera pulsació de START i
|
|
// la transició cap a INTRO. Si l'altre jugador prem START dins
|
|
// d'aquesta finestra, el comptador es reseteja amb
|
|
// `pending_players_=BOTH`. Visual: mosaic dissolve + fade-out
|
|
// de música.
|
|
// - ATTRACT_OUT: fase de sortida silenciosa cap a LOGO quan
|
|
// expira el timeout sense pulsacions. Visual: fade-to-black net.
|
|
// NO toca la música ni canvia la freqüència del parpadeig.
|
|
enum class Phase : std::uint8_t { IDLE,
|
|
STARTING,
|
|
ATTRACT_OUT };
|
|
|
|
TitleScene(std::shared_ptr<Text> display_font, std::shared_ptr<Text> condensed_font, std::shared_ptr<Surface> background, std::shared_ptr<Surface> mini_logo);
|
|
~TitleScene() override;
|
|
|
|
void update(int delta_ms) override;
|
|
void render() override;
|
|
|
|
private:
|
|
void tickIdle(int delta_ms, bool p1_start, bool p2_start);
|
|
void tickStarting(int delta_ms, bool p1_start, bool p2_start);
|
|
void tickAttract(int delta_ms);
|
|
void enterStarting(DebugConfig::StartingPlayers players);
|
|
void enterAttract();
|
|
void advanceToIntro(DebugConfig::StartingPlayers players);
|
|
void advanceToLogo();
|
|
|
|
std::shared_ptr<Text> display_font_;
|
|
std::shared_ptr<Text> condensed_font_;
|
|
std::shared_ptr<Surface> background_;
|
|
std::shared_ptr<Surface> mini_logo_;
|
|
int timer_ms_;
|
|
int blink_elapsed_ms_{0};
|
|
std::optional<Effects::HeatHaze> heat_haze_;
|
|
Phase phase_{Phase::IDLE};
|
|
int starting_timer_ms_{0};
|
|
DebugConfig::StartingPlayers pending_players_{DebugConfig::StartingPlayers::BOTH};
|
|
std::optional<Transitions::Mosaic> fade_out_;
|
|
std::optional<Transitions::FadeToBlack> attract_fade_;
|
|
// Fade-in inicial: capa negra que s'esvaeix cap a la imatge de fons
|
|
// durant els primers `title.intro_fade_in_ms` ms. Sempre activa al
|
|
// ctor; un cop finished, `render()` pinta alpha=0 (no-op) la resta
|
|
// del cicle de l'escena.
|
|
Transitions::FadeToBlack intro_fade_;
|
|
};
|