feat(title): parpadeig STARTING amb cicle 50/50 i període configurable

This commit is contained in:
JailDesigner committed 2026-05-06 14:04:27 +02:00
1 parent 0618452224
commit 36fc496226
5 files changed
+37 -21

No files matched your search

+24 -13
View File
@@ -103,13 +103,12 @@ void TitleScene::update(int delta_ms) {
if (heat_haze_) { heat_haze_->tick(delta_ms); }
// Avanç del comptador del parpadeig: durant STARTING, accelera per
// `starting_blink_speedup` (típicament 2.0). Es manté en enter perquè
// tota la lògica del cicle (visible_ms / hidden_ms) treballa amb int.
const float BLINK_RATE = (phase_ == Phase::STARTING)
? UiConfig::get().titleStartingBlinkSpeedup()
: 1.0F;
blink_elapsed_ms_ += static_cast<int>(static_cast<float>(delta_ms) * BLINK_RATE);
// 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
// defecte); STARTING usa un cicle simètric 50/50 amb període
// `starting_blink_period_ms`.
blink_elapsed_ms_ += delta_ms;
const bool P1_START = pressedStart(0);
const bool P2_START = pressedStart(1);
@@ -169,6 +168,10 @@ void TitleScene::enterStarting(DebugConfig::StartingPlayers players) {
phase_ = Phase::STARTING;
pending_players_ = players;
starting_timer_ms_ = UiConfig::get().titleStartingMs();
// Resetem el comptador del parpadeig perquè el primer frame de
// STARTING comenci visible — sense això, el modulus amb el nou
// període podria caure mig cicle i donar un primer "off" estrany.
blink_elapsed_ms_ = 0;
std::cout << "[scene] " << SCENE_NAME << " STARTING (players=" << DebugConfig::toString(players) << ")\n";
}
@@ -221,12 +224,20 @@ void TitleScene::render() {
}
if (condensed_font_) {
// Cicle de parpadeig: visible_ms ON + hidden_ms OFF, repetint-se.
// Si la suma val 0 (configuració degenerada), cau a "sempre visible".
const int VISIBLE_MS = std::max(0, ui_config.titleBlinkVisibleMs());
const int HIDDEN_MS = std::max(0, ui_config.titleBlinkHiddenMs());
const int CYCLE_MS = VISIBLE_MS + HIDDEN_MS;
const bool VISIBLE = (CYCLE_MS == 0) || ((blink_elapsed_ms_ % CYCLE_MS) < VISIBLE_MS);
// Cicle de parpadeig: a IDLE pren visible_ms+hidden_ms del yaml
// (asimètric, 80/20 per defecte); a STARTING commuta a 50/50 amb
// `starting_blink_period_ms` per donar feedback de "polsat".
// Si el cicle val 0 (configuració degenerada), cau a "sempre visible".
int cycle_ms = 0;
int visible_ms = 0;
if (phase_ == Phase::STARTING) {
cycle_ms = std::max(0, ui_config.titleStartingBlinkPeriodMs());
visible_ms = cycle_ms / 2;
} else {
visible_ms = std::max(0, ui_config.titleBlinkVisibleMs());
cycle_ms = visible_ms + std::max(0, ui_config.titleBlinkHiddenMs());
}
const bool VISIBLE = (cycle_ms == 0) || ((blink_elapsed_ms_ % cycle_ms) < visible_ms);
if (VISIBLE) {
const int PROMPT_Y = (GameCanvas::HEIGHT * PROMPT_Y_PERCENT) / 100;