diff --git a/source/game/scene_manager.hpp b/source/game/scene_manager.hpp index 140a7eff..fd240bef 100644 --- a/source/game/scene_manager.hpp +++ b/source/game/scene_manager.hpp @@ -33,11 +33,11 @@ enum class Options { }; // --- Variables de estado globales --- -#ifndef _DEBUG -inline Scene current = Scene::LOGO; // Escena actual +#ifdef _DEBUG +inline Scene current = Scene::CREDITS; // Escena actual inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual #else -inline Scene current = Scene::GAME; // Escena actual +inline Scene current = Scene::LOGO; // Escena actual inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual #endif diff --git a/source/game/scenes/credits.cpp b/source/game/scenes/credits.cpp index a1e2f3ed..b27adf22 100644 --- a/source/game/scenes/credits.cpp +++ b/source/game/scenes/credits.cpp @@ -10,15 +10,17 @@ #include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite #include "core/rendering/text.hpp" // Para Text, TEXT_CENTER, TEXT_COLOR #include "core/resources/resource.hpp" // Para Resource +#include "core/system/global_events.hpp" // Para check #include "game/options.hpp" // Para Options, options, OptionsGame, Sectio... #include "game/scene_manager.hpp" // Para SceneManager #include "utils/defines.hpp" // Para GAME_SPEED, PLAY_AREA_CENTER_X, PLAY_... -#include "core/system/global_events.hpp" // Para check +#include "utils/delta_timer.hpp" // Para DeltaTimer #include "utils/utils.hpp" // Para PaletteColor // Constructor Credits::Credits() - : shining_sprite_(std::make_shared(Resource::get()->getAnimations("shine.ani"))) { + : shining_sprite_(std::make_shared(Resource::get()->getAnimations("shine.ani"))), + delta_timer_(std::make_unique()) { // Inicializa variables SceneManager::current = SceneManager::Scene::CREDITS; SceneManager::options = SceneManager::Options::NONE; @@ -148,47 +150,99 @@ void Credits::fillTexture() { cover_surface_->fillRect(&rect, color); } -// Actualiza el contador -void Credits::updateCounter() { - // Incrementa el contador - if (counter_enabled_) { - counter_++; - if (counter_ == 224 || counter_ == 544 || counter_ == 672) { - counter_enabled_ = false; - } - } else { - sub_counter_++; - if (sub_counter_ == 100) { - counter_enabled_ = true; - sub_counter_ = 0; - } - } +// Actualiza las variables +void Credits::update() { + // Obtiene el delta time + current_delta_ = delta_timer_->tick(); - // Comprueba si ha terminado la sección - if (counter_ > 1200) { - SceneManager::current = SceneManager::Scene::DEMO; + // Comprueba las entradas + checkInput(); + + // Actualiza el tiempo total + total_time_ += current_delta_; + + // Actualiza la máquina de estados + updateState(current_delta_); + + // Actualiza la pantalla + Screen::get()->update(current_delta_); + + // Actualiza el sprite con el brillo si está después del tiempo de inicio + if (reveal_time_ > SHINE_START_TIME) { + shining_sprite_->update(current_delta_); } } -// Actualiza las variables -void Credits::update() { - // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego - if (SDL_GetTicks() - ticks_ > GAME_SPEED) { - // Actualiza el contador de ticks - ticks_ = SDL_GetTicks(); +// Transición entre estados +void Credits::transitionToState(State new_state) { + state_ = new_state; + state_time_ = 0.0F; +} - // Comprueba las entradas - checkInput(); +// Actualiza la máquina de estados +void Credits::updateState(float delta_time) { + state_time_ += delta_time; - // Actualiza el contador - updateCounter(); + switch (state_) { + case State::REVEALING_TEXT: + reveal_time_ += delta_time; // Incrementa reveal_time durante revelación + if (state_time_ >= REVEAL_PHASE_1_DURATION) { + transitionToState(State::PAUSE_1); + } + break; - Screen::get()->update(); + case State::PAUSE_1: + // reveal_time_ NO incrementa durante pausa (se congela) + if (state_time_ >= PAUSE_DURATION) { + transitionToState(State::REVEALING_TEXT_2); + } + break; - // Actualiza el sprite con el brillo - if (counter_ > 770) { - shining_sprite_->update(); - } + case State::REVEALING_TEXT_2: + reveal_time_ += delta_time; // Incrementa reveal_time durante revelación + if (state_time_ >= REVEAL_PHASE_2_DURATION) { + transitionToState(State::PAUSE_2); + } + break; + + case State::PAUSE_2: + // reveal_time_ NO incrementa durante pausa (se congela) + if (state_time_ >= PAUSE_DURATION) { + transitionToState(State::REVEALING_TEXT_3); + } + break; + + case State::REVEALING_TEXT_3: + reveal_time_ += delta_time; // Incrementa reveal_time durante revelación + if (state_time_ >= REVEAL_PHASE_3_DURATION) { + transitionToState(State::PAUSE_3); + } + break; + + case State::PAUSE_3: + // reveal_time_ NO incrementa durante pausa (se congela) + if (state_time_ >= PAUSE_DURATION) { + transitionToState(State::DISPLAYING_WITH_SHINE); + } + break; + + case State::DISPLAYING_WITH_SHINE: + reveal_time_ += delta_time; // Incrementa reveal_time durante revelación + if (state_time_ >= DISPLAY_WITH_SHINE_DURATION) { + transitionToState(State::FADING_OUT); + } + break; + + case State::FADING_OUT: + reveal_time_ += delta_time; // Incrementa reveal_time durante fade + if (state_time_ >= FADE_OUT_DURATION) { + transitionToState(State::EXITING); + } + break; + + case State::EXITING: + SceneManager::current = SceneManager::Scene::DEMO; + break; } } @@ -200,14 +254,15 @@ void Credits::render() { // Limpia la pantalla Screen::get()->clearSurface(static_cast(PaletteColor::BLACK)); - if (counter_ < 1150) { + if (state_ != State::EXITING) { // Dibuja la textura con el texto en pantalla text_surface_->render(0, 0); // Dibuja la textura que cubre el texto - const int OFFSET = std::min(counter_ / 8, 192 / 2); + // OFFSET basado en reveal_time_ (que se congela durante pausas, como counter_ original) + const float OFFSET = std::min(reveal_time_ * REVEAL_SPEED / 8.0F, 192.0F / 2.0F); SDL_FRect src_rect = {0.0F, 0.0F, 256.0F, 192.0F - (OFFSET * 2.0F)}; - cover_surface_->render(0, OFFSET * 2, &src_rect); + cover_surface_->render(0, static_cast(OFFSET * 2.0F), &src_rect); // Dibuja el sprite con el brillo shining_sprite_->render(1, static_cast(PaletteColor::BRIGHT_WHITE)); diff --git a/source/game/scenes/credits.hpp b/source/game/scenes/credits.hpp index c6a11fea..91d20362 100644 --- a/source/game/scenes/credits.hpp +++ b/source/game/scenes/credits.hpp @@ -7,6 +7,7 @@ #include // Para vector class SurfaceAnimatedSprite; // lines 11-11 class Surface; +class DeltaTimer; class Credits { public: @@ -18,6 +19,30 @@ class Credits { void run(); private: + // --- Estados --- + enum class State { + REVEALING_TEXT, + PAUSE_1, + REVEALING_TEXT_2, + PAUSE_2, + REVEALING_TEXT_3, + PAUSE_3, + DISPLAYING_WITH_SHINE, + FADING_OUT, + EXITING + }; + + // --- Constantes de tiempo (basado en 60 FPS) --- + static constexpr float REVEAL_PHASE_1_DURATION = 3.733F; // 224 frames @ 60fps + static constexpr float PAUSE_DURATION = 1.667F; // 100 frames @ 60fps + static constexpr float REVEAL_PHASE_2_DURATION = 5.333F; // 320 frames (544-224) @ 60fps + static constexpr float REVEAL_PHASE_3_DURATION = 2.133F; // 128 frames (672-544) @ 60fps + static constexpr float DISPLAY_WITH_SHINE_DURATION = 7.967F; // 478 frames (1150-672) @ 60fps + static constexpr float FADE_OUT_DURATION = 0.833F; // 50 frames (1200-1150) @ 60fps + static constexpr float TOTAL_DURATION = 20.0F; // 1200 frames @ 60fps + static constexpr float SHINE_START_TIME = 12.833F; // 770 frames @ 60fps + static constexpr float FADE_OUT_START = 19.167F; // 1150 frames @ 60fps + static constexpr float REVEAL_SPEED = 60.0F; // counter equivalente por segundo @ 60fps struct Captions { std::string label; // Texto a escribir Uint8 color; // Color del texto @@ -29,18 +54,21 @@ class Credits { std::shared_ptr shining_sprite_; // Sprite para el brillo del corazón // --- Variables --- - int counter_ = 0; // Contador - bool counter_enabled_ = true; // Indica si esta activo el contador - int sub_counter_ = 0; // Contador secundario - Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa - std::vector texts_; // Vector con los textos + std::unique_ptr delta_timer_; // Temporizador delta para time-based update + State state_ = State::REVEALING_TEXT; // Estado actual + float state_time_ = 0.0F; // Tiempo acumulado en el estado actual + float total_time_ = 0.0F; // Tiempo total acumulado + float reveal_time_ = 0.0F; // Tiempo acumulado solo durante revelación (se congela en pausas) + float current_delta_ = 0.0F; // Delta time del frame actual + std::vector texts_; // Vector con los textos // --- Funciones --- - void update(); // Actualiza las variables - void render(); // Dibuja en pantalla - static void checkEvents(); // Comprueba el manejador de eventos - static void checkInput(); // Comprueba las entradas - void updateCounter(); // Actualiza el contador - void iniTexts(); // Inicializa los textos - void fillTexture(); // Escribe el texto en la textura + void update(); // Actualiza las variables + void render(); // Dibuja en pantalla + static void checkEvents(); // Comprueba el manejador de eventos + static void checkInput(); // Comprueba las entradas + void updateState(float delta_time); // Actualiza la máquina de estados + void transitionToState(State new_state); // Transición entre estados + void iniTexts(); // Inicializa los textos + void fillTexture(); // Escribe el texto en la textura };