diff --git a/source/game/escenes/escena_logo.cpp b/source/game/escenes/escena_logo.cpp index 8ef295f..736e207 100644 --- a/source/game/escenes/escena_logo.cpp +++ b/source/game/escenes/escena_logo.cpp @@ -14,15 +14,14 @@ // en funció del progrés global (efecte seqüencial) static float calcular_progress_letra(size_t letra_index, size_t num_letras, - float global_progress) { + float global_progress, + float threshold) { if (num_letras == 0) return 1.0f; - constexpr float THRESHOLD = 0.5f; // Següent comença al 50% - // Calcular temps per lletra float duration_per_letra = 1.0f / static_cast(num_letras); - float step = THRESHOLD * duration_per_letra; + float step = threshold * duration_per_letra; float start = static_cast(letra_index) * step; float end = start + duration_per_letra; @@ -37,7 +36,9 @@ static float calcular_progress_letra(size_t letra_index, } EscenaLogo::EscenaLogo(SDLManager& sdl) - : sdl_(sdl), temps_acumulat_(0.0f) { + : sdl_(sdl), + estat_actual_(EstatAnimacio::PRE_ANIMATION), + temps_estat_actual_(0.0f) { std::cout << "Escena Logo: Inicialitzant...\n"; inicialitzar_lletres(); } @@ -161,12 +162,38 @@ void EscenaLogo::inicialitzar_lletres() { << " lletres carregades, ancho total: " << ancho_total << " px\n"; } -void EscenaLogo::actualitzar(float delta_time) { - temps_acumulat_ += delta_time; +void EscenaLogo::canviar_estat(EstatAnimacio nou_estat) { + estat_actual_ = nou_estat; + temps_estat_actual_ = 0.0f; // Reset temps + std::cout << "[EscenaLogo] Canvi a estat: " << static_cast(nou_estat) << "\n"; +} - // Després de DURACIO_TOTAL segons, saltar al joc - if (temps_acumulat_ >= DURACIO_TOTAL) { - GestorEscenes::actual = GestorEscenes::Escena::JOC; +bool EscenaLogo::totes_lletres_completes() const { + // Quan global_progress = 1.0, totes les lletres tenen letra_progress = 1.0 + return temps_estat_actual_ >= DURACIO_ZOOM; +} + +void EscenaLogo::actualitzar(float delta_time) { + temps_estat_actual_ += delta_time; + + switch (estat_actual_) { + case EstatAnimacio::PRE_ANIMATION: + if (temps_estat_actual_ >= DURACIO_PRE) { + canviar_estat(EstatAnimacio::ANIMATION); + } + break; + + case EstatAnimacio::ANIMATION: + if (totes_lletres_completes()) { + canviar_estat(EstatAnimacio::POST_ANIMATION); + } + break; + + case EstatAnimacio::POST_ANIMATION: + if (temps_estat_actual_ >= DURACIO_POST) { + GestorEscenes::actual = GestorEscenes::Escena::JOC; + } + break; } } @@ -174,28 +201,36 @@ void EscenaLogo::dibuixar() { // Fons negre sdl_.neteja(0, 0, 0); - // Progrés global normalitzat (0.0 → 1.0) - float global_progress = std::min(temps_acumulat_ / DURACIO_ZOOM, 1.0f); + // PRE_ANIMATION: Només pantalla negra + if (estat_actual_ == EstatAnimacio::PRE_ANIMATION) { + sdl_.presenta(); + return; // No renderitzar lletres + } - // Centre de la pantalla (punt inicial de totes les lletres) - constexpr Punt CENTRE_PANTALLA = {640.0f / 2.0f, 480.0f / 2.0f}; + // ANIMATION o POST_ANIMATION: Calcular progrés + float global_progress = (estat_actual_ == EstatAnimacio::ANIMATION) + ? std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0f) + : 1.0f; // POST: mantenir al 100% + + // Punt inicial del zoom (configurable amb ORIGEN_ZOOM_X/Y) + const Punt ORIGEN_ZOOM = {ORIGEN_ZOOM_X, ORIGEN_ZOOM_Y}; // Dibuixar cada lletra amb animació seqüencial for (size_t i = 0; i < lletres_.size(); i++) { const auto& lletra = lletres_[i]; // Calcular progrés individual d'aquesta lletra (0.0 → 1.0) - float letra_progress = calcular_progress_letra(i, lletres_.size(), global_progress); + float letra_progress = calcular_progress_letra(i, lletres_.size(), global_progress, THRESHOLD_LETRA); // Si la lletra encara no ha començat, saltar-la if (letra_progress <= 0.0f) { continue; } - // Interpolar posició: des del centre cap a posició final + // Interpolar posició: des del origen zoom cap a posició final Punt pos_actual; - pos_actual.x = CENTRE_PANTALLA.x + (lletra.posicio.x - CENTRE_PANTALLA.x) * letra_progress; - pos_actual.y = CENTRE_PANTALLA.y + (lletra.posicio.y - CENTRE_PANTALLA.y) * letra_progress; + pos_actual.x = ORIGEN_ZOOM.x + (lletra.posicio.x - ORIGEN_ZOOM.x) * letra_progress; + pos_actual.y = ORIGEN_ZOOM.y + (lletra.posicio.y - ORIGEN_ZOOM.y) * letra_progress; // Aplicar ease-out quadràtic per suavitat float t = letra_progress; diff --git a/source/game/escenes/escena_logo.hpp b/source/game/escenes/escena_logo.hpp index 2cb3c38..dedec66 100644 --- a/source/game/escenes/escena_logo.hpp +++ b/source/game/escenes/escena_logo.hpp @@ -17,8 +17,16 @@ public: void executar(); // Bucle principal de l'escena private: + // Màquina d'estats per l'animació + enum class EstatAnimacio { + PRE_ANIMATION, // Pantalla negra inicial + ANIMATION, // Animació de zoom de lletres + POST_ANIMATION // Logo complet visible + }; + SDLManager& sdl_; - float temps_acumulat_; + EstatAnimacio estat_actual_; // Estat actual de la màquina + float temps_estat_actual_; // Temps en l'estat actual (reset en cada transició) // Estructura per a cada lletra del logo struct LetraLogo { @@ -31,15 +39,25 @@ private: std::vector lletres_; // 9 lletres: J-A-I-L-G-A-M-E-S // Constants d'animació - static constexpr float DURACIO_ZOOM = 4.0f; // Duració del zoom (segons) - static constexpr float DURACIO_TOTAL = 20.0f; // Duració total abans d'anar al joc - static constexpr float ESCALA_INICIAL = 0.1f; // Escala inicial (10%) - static constexpr float ESCALA_FINAL = 0.8f; // Escala final (100%) - static constexpr float ESPAI_ENTRE_LLETRES = 10.0f; // Espaiat entre lletres + static constexpr float DURACIO_PRE = 1.5f; // Duració PRE_ANIMATION (pantalla negra) + static constexpr float DURACIO_ZOOM = 4.0f; // Duració del zoom (segons) + static constexpr float DURACIO_POST = 4.0f; // Duració POST_ANIMATION (logo complet) + static constexpr float ESCALA_INICIAL = 0.1f; // Escala inicial (10%) + static constexpr float ESCALA_FINAL = 0.8f; // Escala final (80%) + static constexpr float ESPAI_ENTRE_LLETRES = 10.0f; // Espaiat entre lletres + + // Constants d'animació seqüencial + static constexpr float THRESHOLD_LETRA = 0.6f; // Umbral per activar següent lletra (0.0-1.0) + static constexpr float ORIGEN_ZOOM_X = 640.0f / 2.0f; // Punt inicial X del zoom (320) + static constexpr float ORIGEN_ZOOM_Y = 480.0f * 0.4f; // Punt inicial Y del zoom (240) // Mètodes privats void inicialitzar_lletres(); void actualitzar(float delta_time); void dibuixar(); void processar_events(const SDL_Event& event); + + // Mètodes de gestió d'estats + void canviar_estat(EstatAnimacio nou_estat); + bool totes_lletres_completes() const; };