diff --git a/source/core/defaults/title.hpp b/source/core/defaults/title.hpp index 8f5c3ff..4546bba 100644 --- a/source/core/defaults/title.hpp +++ b/source/core/defaults/title.hpp @@ -105,7 +105,7 @@ namespace Defaults::Title { namespace Layout { // Posicions verticals (anclatges des del TOP de pantalla lógica, 0.0-1.0) constexpr float LOGO_POS = 0.20F; // Logo "ORNI" - constexpr float PRESS_START_POS = 0.75F; // "PRESS START TO PLAY" + constexpr float PRESS_START_POS = 0.72F; // "PRESS START TO PLAY" (una mica més amunt) constexpr float COPYRIGHT1_POS = 0.90F; // Primera línia copyright // Separacions relatives (proporció respecte Game::HEIGHT = 480px) @@ -113,10 +113,17 @@ namespace Defaults::Title { constexpr float COPYRIGHT_LINE_SPACING = 0.0F; // Entre línies copyright (5px) // Factors de scale - constexpr float LOGO_SCALE = 0.6F; // Escala "ORNI ATTACK!" - constexpr float PRESS_START_SCALE = 1.0F; // Escala "PRESS START TO PLAY" - constexpr float COPYRIGHT_SCALE = 0.5F; // Escala copyright - constexpr float JAILGAMES_SCALE = 0.25F; // Escala del logo JAILGAMES pequeño sobre el copyright + constexpr float LOGO_SCALE = 0.6F; // Escala "ORNI ATTACK!" + constexpr float PRESS_START_SCALE = 1.0F; // Escala "PRESS START TO PLAY" + constexpr float COPYRIGHT_SCALE = 0.5F; // Escala copyright + constexpr float JAILGAMES_BRIGHTNESS = 0.8F; // Logo JAILGAMES una mica menys brillant + constexpr float COPYRIGHT_BRIGHTNESS = 0.55F; // Mateix cian que JAILGAMES, però menys brillant + + // Parpelleig del "PRESS START" (blinks per segon). Ritme pausat quan el + // text apareix (MAIN) i més ràpid quan ja s'ha premut START (join phase). + constexpr float PRESS_START_BLINK_HZ_SLOW = 1.0F; + constexpr float PRESS_START_BLINK_HZ_FAST = 3.0F; + constexpr float JAILGAMES_SCALE = 0.25F; // Escala del logo JAILGAMES pequeño sobre el copyright // Separación entre el logo JAILGAMES y la línea de copyright (proporción de Game::HEIGHT). constexpr float JAILGAMES_COPYRIGHT_GAP = 0.015F; @@ -157,14 +164,14 @@ namespace Defaults::Title { // alpha = 255 (sentinela "color vàlid") fa que el pipeline ignori // el color global de l'oscil·lador per a aquesta crida. namespace Colors { - constexpr SDL_Color LOGO_MAIN = {.r = 80, .g = 240, .b = 255, .a = 255}; // Cian elèctric - constexpr SDL_Color LOGO_SHADOW = {.r = 255, .g = 60, .b = 180, .a = 255}; // Magenta neon (offset) - constexpr SDL_Color SHIP_P1 = {.r = 255, .g = 100, .b = 200, .a = 255}; // Rosa hot - constexpr SDL_Color SHIP_P2 = {.r = 160, .g = 120, .b = 255, .a = 255}; // Violeta elèctric - constexpr SDL_Color STARFIELD = {.r = 200, .g = 220, .b = 255, .a = 255}; // Blanc-blau gel - constexpr SDL_Color PRESS_START = {.r = 255, .g = 200, .b = 70, .a = 255}; // Ambre neon - constexpr SDL_Color JAILGAMES_LOGO = {.r = 120, .g = 220, .b = 200, .a = 255}; // Teal suau - constexpr SDL_Color COPYRIGHT = {.r = 140, .g = 180, .b = 200, .a = 255}; // Gris-cian apagat + constexpr SDL_Color STARFIELD = {.r = 200, .g = 220, .b = 255, .a = 255}; // Blanc-blau gel + constexpr SDL_Color LOGO_MAIN = {.r = 0, .g = 255, .b = 255, .a = 255}; // Cian pur + constexpr SDL_Color LOGO_SHADOW = STARFIELD; // Color de l'starfield (offset) + constexpr SDL_Color SHIP_P1 = {.r = 255, .g = 255, .b = 255, .a = 255}; // Blanc + constexpr SDL_Color SHIP_P2 = {.r = 255, .g = 255, .b = 255, .a = 255}; // Blanc + constexpr SDL_Color PRESS_START = {.r = 255, .g = 255, .b = 255, .a = 255}; // Blanc + constexpr SDL_Color JAILGAMES_LOGO = {.r = 0, .g = 255, .b = 255, .a = 255}; // Cian pur + constexpr SDL_Color COPYRIGHT = {.r = 0, .g = 255, .b = 255, .a = 255}; // Mateix cian (el brillo es baixa al render: COPYRIGHT_BRIGHTNESS) } // namespace Colors } // namespace Defaults::Title diff --git a/source/game/scenes/title_scene.cpp b/source/game/scenes/title_scene.cpp index c930a24..a2f96dd 100644 --- a/source/game/scenes/title_scene.cpp +++ b/source/game/scenes/title_scene.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include "core/audio/audio.hpp" @@ -287,7 +286,7 @@ void TitleScene::dibuixarPeuTitol(float spacing) const { .x = SCREEN_CENTRE_X + (JAILGAMES_S * (letter.position.x - SCREEN_CENTRE_X)), .y = SCREEN_CENTRE_Y + (JAILGAMES_S * (letter.position.y - SCREEN_CENTRE_Y)), }; - Rendering::renderShape(sdl_.getRenderer(), letter.shape, POS, 0.0F, JAILGAMES_RENDER_SCALE, 1.0F, 1.0F, Defaults::Title::Colors::JAILGAMES_LOGO); + Rendering::renderShape(sdl_.getRenderer(), letter.shape, POS, 0.0F, JAILGAMES_RENDER_SCALE, 1.0F, Defaults::Title::Layout::JAILGAMES_BRIGHTNESS, Defaults::Title::Colors::JAILGAMES_LOGO); } std::string copyright = Project::COPYRIGHT; for (char& c : copyright) { @@ -299,7 +298,7 @@ void TitleScene::dibuixarPeuTitol(float spacing) const { const float COPY_X = SCREEN_CENTRE_X; // ja al centre const float COPY_Y = SCREEN_CENTRE_Y + (COPYRIGHT_S * (Y_COPY_FINAL - SCREEN_CENTRE_Y)); const float COPY_RENDER_SCALE = Defaults::Title::Layout::COPYRIGHT_SCALE * COPYRIGHT_S; - text_.renderCentered(copyright, {.x = COPY_X, .y = COPY_Y}, COPY_RENDER_SCALE, spacing, 1.0F, Defaults::Title::Colors::COPYRIGHT); + text_.renderCentered(copyright, {.x = COPY_X, .y = COPY_Y}, COPY_RENDER_SCALE, spacing, Defaults::Title::Layout::COPYRIGHT_BRIGHTNESS, Defaults::Title::Colors::COPYRIGHT); } auto TitleScene::isFinished() const -> bool { @@ -307,6 +306,7 @@ auto TitleScene::isFinished() const -> bool { } void TitleScene::update(float delta_time) { + blink_timer_ += delta_time; // fase del parpelleig del PRESS START (reiniciada a les transicions) if (starfield_) { starfield_->update(delta_time); } @@ -445,6 +445,7 @@ void TitleScene::updateMainState(float delta_time) { if (!press_start_visible_ && state_time_main_ >= T_PRESS_START_VISIBLE) { press_start_visible_ = true; + blink_timer_ = 0.0F; // primer parpelleig (lent) complet en aparèixer } // L'oscil·lació suau del logo arrenca quan el logo ha aterrat. Així @@ -556,6 +557,7 @@ void TitleScene::handleSkipInput() { intro_jailgames_progress_ = 1.0F; intro_copyright_progress_ = 1.0F; press_start_visible_ = true; + blink_timer_ = 0.0F; // primer parpelleig (lent) complet en saltar la intro ships_intro_launched_ = true; if (ship_animator_ != nullptr) { ship_animator_->setVisible(true); @@ -587,6 +589,7 @@ void TitleScene::handleStartInput() { context_.setMatchConfig(match_config_); current_state_ = TitleState::PLAYER_JOIN_PHASE; temps_acumulat_ = 0.0F; + blink_timer_ = 0.0F; // primer parpelleig (ràpid) complet en passar a join phase triggerExitForJoinedPlayers(P1_ABANS, P2_ABANS, ""); @@ -711,12 +714,14 @@ void TitleScene::draw() { const float SPACING = Defaults::Title::Layout::TEXT_SPACING; if (press_start_visible_) { - bool mostrar_text = true; - if (current_state_ == TitleState::PLAYER_JOIN_PHASE) { - const float FASE = temps_acumulat_ * BLINK_FREQUENCY * 2.0F * std::numbers::pi_v; - mostrar_text = (std::sin(FASE) > 0.0F); - } - if (mostrar_text) { + // Parpelleig: lent en aparèixer (MAIN), ràpid en prémer START (join). + // blink_timer_ es reinicia a 0 a cada transició, així el primer mig + // període és sempre visible i complet (no n'agafa un de parcial). + const float BLINK_HZ = (current_state_ == TitleState::PLAYER_JOIN_PHASE) + ? Defaults::Title::Layout::PRESS_START_BLINK_HZ_FAST + : Defaults::Title::Layout::PRESS_START_BLINK_HZ_SLOW; + const bool MOSTRAR_TEXT = std::fmod(blink_timer_ * BLINK_HZ, 1.0F) < 0.5F; + if (MOSTRAR_TEXT) { const std::string MAIN_TEXT = Locale::get().text("title.press_start"); const float MAIN_SCALE = Defaults::Title::Layout::PRESS_START_SCALE; const float CENTRE_X = Defaults::Game::WIDTH / 2.0F; diff --git a/source/game/scenes/title_scene.hpp b/source/game/scenes/title_scene.hpp index f2af90d..6118e93 100644 --- a/source/game/scenes/title_scene.hpp +++ b/source/game/scenes/title_scene.hpp @@ -110,13 +110,16 @@ class TitleScene final : public Scene { float intro_copyright_progress_{0.0F}; bool press_start_visible_{false}; bool ships_intro_launched_{false}; + // Rellotge de fase del parpelleig del "PRESS START". Es reinicia a 0 en cada + // transició (aparició del text i pas a parpelleig ràpid) perquè el primer + // parpelleig siga sempre un període complet, no un de parcial. + float blink_timer_{0.0F}; static constexpr float BRIGHTNESS_STARFIELD = 1.2F; static constexpr float DURATION_FADE_IN = 3.0F; static constexpr float DURATION_INIT = 4.0F; static constexpr float DURATION_TRANSITION = 2.5F; static constexpr float LETTER_SPACING = 10.0F; - static constexpr float BLINK_FREQUENCY = 3.0F; static constexpr float DURATION_BLACK_SCREEN = 2.0F; static constexpr int MUSIC_FADE = 1500;