feat(title): fade-in inicial de negre a escena (500 ms, configurable a ui.yaml)
This commit is contained in:
1 parent
29cb4c2211
commit
1431f27cfa
6 files changed
+36
No files matched your search
@@ -108,6 +108,7 @@ UiConfig::UiConfig()
|
||||
title_fade_out_max_block_(Defaults::UI::Title::FADE_OUT_MAX_BLOCK),
|
||||
title_music_fade_out_ms_(Defaults::UI::Title::MUSIC_FADE_OUT_MS),
|
||||
title_attract_fade_to_black_ms_(Defaults::UI::Title::ATTRACT_FADE_TO_BLACK_MS),
|
||||
title_intro_fade_in_ms_(Defaults::UI::Title::INTRO_FADE_IN_MS),
|
||||
title_heat_haze_{
|
||||
.enabled = Defaults::UI::Title::HeatHaze::ENABLED,
|
||||
.amplitude_px = Defaults::UI::Title::HeatHaze::AMPLITUDE_PX,
|
||||
@@ -238,6 +239,7 @@ void UiConfig::load(const std::string& file_path) {
|
||||
readField(t, "fade_out_max_block", title_fade_out_max_block_);
|
||||
readField(t, "music_fade_out_ms", title_music_fade_out_ms_);
|
||||
readField(t, "attract_fade_to_black_ms", title_attract_fade_to_black_ms_);
|
||||
readField(t, "intro_fade_in_ms", title_intro_fade_in_ms_);
|
||||
if (t.contains("heat_haze")) {
|
||||
const auto& hh = t["heat_haze"];
|
||||
readField(hh, "enabled", title_heat_haze_.enabled);
|
||||
|
||||
@@ -101,6 +101,7 @@ class UiConfig {
|
||||
[[nodiscard]] auto titleFadeOutMaxBlock() const -> int { return title_fade_out_max_block_; }
|
||||
[[nodiscard]] auto titleMusicFadeOutMs() const -> int { return title_music_fade_out_ms_; }
|
||||
[[nodiscard]] auto titleAttractFadeToBlackMs() const -> int { return title_attract_fade_to_black_ms_; }
|
||||
[[nodiscard]] auto titleIntroFadeInMs() const -> int { return title_intro_fade_in_ms_; }
|
||||
[[nodiscard]] auto titleHeatHaze() const -> const TitleHeatHaze& { return title_heat_haze_; }
|
||||
|
||||
// Corbes d'easing triades al YAML. Si el nom no és conegut, s'usa
|
||||
@@ -180,6 +181,7 @@ class UiConfig {
|
||||
int title_fade_out_max_block_;
|
||||
int title_music_fade_out_ms_;
|
||||
int title_attract_fade_to_black_ms_;
|
||||
int title_intro_fade_in_ms_;
|
||||
TitleHeatHaze title_heat_haze_;
|
||||
|
||||
std::string menu_select_sound_;
|
||||
|
||||
@@ -101,6 +101,10 @@ TitleScene::TitleScene(std::shared_ptr<Text> display_font, std::shared_ptr<Text>
|
||||
.max_block_size = UiConfig::get().titleFadeOutMaxBlock(),
|
||||
});
|
||||
attract_fade_.emplace();
|
||||
// Fade-in inicial: arrenquem en negre opac i ens esvaïm cap a la
|
||||
// imatge de fons. Sense lligar a cap fase — viu sempre al frame i
|
||||
// un cop finished, `render()` és no-op fins que la TitleScene mor.
|
||||
intro_fade_.begin(UiConfig::get().titleIntroFadeInMs(), Transitions::FadeToBlack::Direction::FADE_IN);
|
||||
|
||||
// Música de fons en bucle. Es preloda al Director, així que la
|
||||
// primera crida és immediata. El fade-out arrenca en entrar a
|
||||
@@ -122,6 +126,11 @@ void TitleScene::update(int delta_ms) {
|
||||
|
||||
if (heat_haze_) { heat_haze_->tick(delta_ms); }
|
||||
|
||||
// Fade-in inicial: tica sempre. Un cop finished, FadeToBlack::tick
|
||||
// és idempotent (clamp intern al duration_ms_) i `render()` pinta
|
||||
// alpha=0 (no-op) durant la resta del cicle.
|
||||
intro_fade_.tick(delta_ms);
|
||||
|
||||
// Comptador del parpadeig: avança sempre amb `delta_ms` cru. La
|
||||
// lectura (cicle/visible) la decideix `render()` segons la fase:
|
||||
// IDLE usa visible_ms / hidden_ms del yaml (asimètric, 80/20 per
|
||||
@@ -336,6 +345,13 @@ void TitleScene::render() {
|
||||
|
||||
Notifier::get().render();
|
||||
|
||||
// Fade-in inicial: capa negra que s'esvaeix cap a l'escena durant
|
||||
// els primers `title.intro_fade_in_ms` ms. `render()` és no-op un
|
||||
// cop finished, així que es queda penjat aquí sense lògica
|
||||
// condicional. Va per damunt del Notifier — coherent amb la resta
|
||||
// de transicions — però per davall del RenderInfo de debug.
|
||||
intro_fade_.render();
|
||||
|
||||
// Capa de transició final segons la fase. Sempre cobreix l'escena
|
||||
// i el Notifier, mai el RenderInfo (overlay de debug, sempre
|
||||
// visible). STARTING usa mosaic dissolve; ATTRACT_OUT, fade-to-black
|
||||
|
||||
@@ -61,4 +61,9 @@ class TitleScene : public Scene {
|
||||
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_;
|
||||
};
|
||||
@@ -294,6 +294,13 @@ namespace Defaults {
|
||||
// veurà què en fa.
|
||||
constexpr int ATTRACT_FADE_TO_BLACK_MS = 800;
|
||||
|
||||
// Fade-in inicial de l'escena: capa negra al començament que
|
||||
// s'esvaeix cap a la imatge de fons. Lineal, sense mosaic —
|
||||
// mateixa convenció que el `room_intro.fade_in_ms` del joc
|
||||
// perquè l'arribada a la TITLE i l'arribada a una sala de
|
||||
// joc tinguin el mateix ritme visual.
|
||||
constexpr int INTRO_FADE_IN_MS = 500;
|
||||
|
||||
// Distorsió sinusoidal horitzontal de l'imatge de fons
|
||||
// (efecte de calor del desert). `amplitude_px` és el
|
||||
// desplaçament màxim per fila; `wavelength_px` la distància
|
||||
|
||||
Reference in new issue
Block a user