diff --git a/source/ending2.cpp b/source/ending2.cpp index 6b3d4ca..93f2309 100644 --- a/source/ending2.cpp +++ b/source/ending2.cpp @@ -17,12 +17,7 @@ #include "utils.h" // Para PaletteColor, stringToColor // Constructor -Ending2::Ending2() - : counter_enabled_(false), - pre_counter_(0), - post_counter_(0), - post_counter_enabled_(false), - ticks_(0) +Ending2::Ending2() : state_(EndingState::PRE_CREDITS, SDL_GetTicks(), STATE_PRE_CREDITS_DURATION_) { options.section.section = Section::ENDING2; options.section.subsection = Subsection::NONE; @@ -65,27 +60,32 @@ void Ending2::update() // Comprueba las entradas checkInput(); - // Actualiza los contadores - updateCounters(); + // Actualiza el estado + updateState(); - if (counter_enabled_) + switch (state_.state) { - // Actualiza los sprites - updateSprites(); + case EndingState::CREDITS: + // Actualiza los sprites, los textos y los textos del final + for (int i = 0; i < 25; ++i) + { + updateSprites(); + updateTextSprites(); + updateTexts(); + } + break; - // Actualiza los sprites de texto - updateTextSprites(); + case EndingState::FADING: + // Actualiza el fade final y el volumen de la música + updateFinalFade(); + updateMusicVolume(); + break; - // Actualiza los sprites de texto del final - updateTexts(); + default: + // No hacer nada si el estado no corresponde a un caso manejado + break; } - // Actualiza el fade final - updateFinalFade(); - - // Actualiza el volumen de la musica - updateMusicVolume(); - // Actualiza el objeto Screen::get()->update(); } @@ -167,28 +167,42 @@ void Ending2::run() JA_SetVolume(128); } -// Actualiza los contadores -void Ending2::updateCounters() +// Actualiza el estado +void Ending2::updateState() { - // Incrementa el contador - if (pre_counter_ < 200) + switch (state_.state) { - pre_counter_++; - } - else - { - counter_enabled_ = true; - } + case EndingState::PRE_CREDITS: + if (state_.hasEnded(EndingState::PRE_CREDITS)) + { + state_.set(EndingState::CREDITS, 0); + } + break; - if (post_counter_enabled_) - { - post_counter_++; - } + case EndingState::CREDITS: + if (texts_.back()->getPosY() <= GAMECANVAS_CENTER_Y) + { + state_.set(EndingState::POST_CREDITS, STATE_POST_CREDITS_DURATION_); + } + break; - if (post_counter_ > 600) - { - options.section.section = Section::LOGO; - options.section.subsection = Subsection::LOGO_TO_INTRO; + case EndingState::POST_CREDITS: + if (state_.hasEnded(EndingState::POST_CREDITS)) + { + state_.set(EndingState::FADING, STATE_FADE_DURATION_); + } + break; + + case EndingState::FADING: + if (state_.hasEnded(EndingState::FADING)) + { + options.section.section = Section::LOGO; + options.section.subsection = Subsection::LOGO_TO_INTRO; + } + break; + + default: + break; } } @@ -307,16 +321,9 @@ void Ending2::updateTextSprites() // Actualiza los sprites de texto del final void Ending2::updateTexts() { - if (texts_.back()->getPosY() > GAMECANVAS_CENTER_Y) + for (auto sprite : texts_) { - for (auto sprite : texts_) - { - sprite->update(); - } - } - else - { - post_counter_enabled_ = true; + sprite->update(); } } @@ -498,25 +505,34 @@ void Ending2::createTexts() // Actualiza el fade final void Ending2::updateFinalFade() -{ /* - // La variable step va de 0 a 40 en el tramo de postCounter que va de 500 a 540. Al dividirlo por 40, va de 0.0f a 1.0f - const float STEP = std::min(std::max(post_counter_, 500) - 500, 40) / 40.0f; - const int INDEX = (colors_.size() - 1) * STEP; - - for (const auto &text : texts_) - { - text->getTexture()->setColor(colors_.at(INDEX).r, colors_.at(INDEX).g, colors_.at(INDEX).b); - } - */ +{ + for (auto sprite : texts_) + { + sprite->getSurface()->fadeSubPalette(0); + } } // Actualiza el volumen de la musica void Ending2::updateMusicVolume() { - if (post_counter_ > 0) - { - const float step = (600.0f - post_counter_) / 600.0f; - const int volume = 128 * step; - JA_SetVolume(volume); - } -} \ No newline at end of file + // Constante para la duración en milisegundos + constexpr Uint32 VOLUME_FADE_DURATION = 3000; + + // Tiempo actual + const Uint32 CURRENT_TICKS = SDL_GetTicks(); + + // Calcular el tiempo transcurrido desde init_ticks + Uint32 elapsed_ticks = CURRENT_TICKS - state_.init_ticks; + + // Limitar el tiempo máximo a la duración definida + elapsed_ticks = std::min(elapsed_ticks, VOLUME_FADE_DURATION); + + // Calcular el step basado en la duración + const float STEP = (static_cast(VOLUME_FADE_DURATION) - elapsed_ticks) / VOLUME_FADE_DURATION; + + // Calcular el volumen en función del step + const int VOLUME = static_cast(128 * STEP); + + // Actualizar el volumen + JA_SetVolume(VOLUME); +} diff --git a/source/ending2.h b/source/ending2.h index 134aaa8..c043c47 100644 --- a/source/ending2.h +++ b/source/ending2.h @@ -11,12 +11,57 @@ class SMovingSprite; // lines 10-10 class Ending2 { private: + // Enum para representar los estados del final + enum class EndingState : int + { + PRE_CREDITS, // Estado previo a los créditos + CREDITS, // Estado de los créditos + POST_CREDITS, // Estado posterior a los créditos + FADING, // Estado de fundido de los textos a negrp + }; + + // Estructura para controlar los estados y su duración + struct State + { + EndingState state; // Estado actual + Uint32 init_ticks; // Ticks en los que se inicializó el estado + Uint32 duration; // Duración en milisegundos para el estado actual + + // Constructor parametrizado para inicializar la estructura + State(EndingState initialState, Uint32 initialTicks, Uint32 stateDuration) + : state(initialState), init_ticks(initialTicks), duration(stateDuration) {} + + // Método para comprobar si el estado ha terminado y verifica el nombre del estado + bool hasEnded(EndingState expectedState) const + { + // Comprobar si el estado actual coincide con el estado esperado + if (state != expectedState) + { + return false; // Si no coincide, considerar que no ha terminado + } + + // Comprobar si el tiempo transcurrido excede la duración + return (SDL_GetTicks() - init_ticks) >= duration; + } + + // Método para establecer un nuevo estado + void set(EndingState newState, Uint32 newDuration) + { + state = newState; // Actualizar el estado + init_ticks = SDL_GetTicks(); // Reiniciar el tiempo de inicio + duration = newDuration; // Actualizar la duración + } + }; + // Constantes static constexpr int FIRST_COL_ = GAMECANVAS_FIRST_QUARTER_X + (GAMECANVAS_WIDTH / 16); // Primera columna por donde desfilan los sprites static constexpr int SECOND_COL_ = GAMECANVAS_THIRD_QUARTER_X - (GAMECANVAS_WIDTH / 16); // Segunda columna por donde desfilan los sprites static constexpr int DIST_SPRITE_TEXT_ = 8; // Distancia entre el sprite y el texto que lo acompaña static constexpr int DIST_SPRITE_SPRITE_ = 0; // Distancia entre dos sprites de la misma columna static constexpr float SPRITE_DESP_SPEED_ = -0.2f; // Velocidad de desplazamiento de los sprites + static constexpr int STATE_PRE_CREDITS_DURATION_ = 3000; + static constexpr int STATE_POST_CREDITS_DURATION_ = 5000; + static constexpr int STATE_FADE_DURATION_ = 5000; // Objetos y punteros std::vector> sprites_; // Vector con todos los sprites a dibujar @@ -24,15 +69,12 @@ private: std::vector> texts_; // Vector con los sprites de texto // Variables - bool counter_enabled_; // Indica si está el contador habilitado - int pre_counter_; // Contador previo - int post_counter_; // Contador posterior - bool post_counter_enabled_; // Indica si está habilitado el contador - Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa + Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa std::vector sprite_list_; // Lista con todos los sprites a dibujar std::vector colors_; // Vector con los colores para el fade - int sprite_max_width_; // El valor de ancho del sprite mas ancho - int sprite_max_height_; // El valor de alto del sprite mas alto + int sprite_max_width_ = 0; // El valor de ancho del sprite mas ancho + int sprite_max_height_ = 0; // El valor de alto del sprite mas alto + State state_; // Controla el estado de la clase // Actualiza el objeto void update(); @@ -46,8 +88,8 @@ private: // Comprueba las entradas void checkInput(); - // Actualiza los contadores - void updateCounters(); + // Actualiza el estado + void updateState(); // Inicializa la lista de sprites void iniSpriteList(); diff --git a/source/options.cpp b/source/options.cpp index fafaee8..3572d0c 100644 --- a/source/options.cpp +++ b/source/options.cpp @@ -21,7 +21,7 @@ void initOptions() options = Options(); #ifdef DEBUG - options.section = SectionState(Section::LOGO, Subsection::LOGO_TO_INTRO); + options.section = SectionState(Section::ENDING2, Subsection::LOGO_TO_INTRO); options.console = true; #else options.section = SectionState(Section::LOGO, Subsection::LOGO_TO_INTRO); diff --git a/source/surface.cpp b/source/surface.cpp index f945d0e..fdc2cd3 100644 --- a/source/surface.cpp +++ b/source/surface.cpp @@ -1,7 +1,8 @@ +// IWYU pragma: no_include #include "surface.h" #include // Para SDL_GetError -#include // Para abs -#include // Para abs +#include // Para SDL_GetTicks +#include // Para abs #include // Para min, max, copy_n, fill #include // Para uint32_t #include // Para memcpy, size_t @@ -179,7 +180,7 @@ void Surface::setColor(int index, Uint32 color) void Surface::clear(Uint8 color) { const size_t total_pixels = surface_data_->width * surface_data_->height; - Uint8* data_ptr = surface_data_->data.get(); + Uint8 *data_ptr = surface_data_->data.get(); std::fill(data_ptr, data_ptr + total_pixels, color); } @@ -566,7 +567,6 @@ void Surface::copyToTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Re } } - // Realiza un efecto de fundido en la paleta principal bool Surface::fadePalette() { @@ -591,8 +591,23 @@ bool Surface::fadePalette() } // Realiza un efecto de fundido en la paleta secundaria -bool Surface::fadeSubPalette() +bool Surface::fadeSubPalette(Uint32 delay) { + // Variable estática para almacenar el último tick + static Uint32 last_tick = 0; + + // Obtener el tiempo actual + Uint32 current_tick = SDL_GetTicks(); + + // Verificar si ha pasado el tiempo de retardo + if (current_tick - last_tick < delay) + { + return false; // No se realiza el fade + } + + // Actualizar el último tick + last_tick = current_tick; + // Verificar que el tamaño mínimo de sub_palette_ sea adecuado static constexpr int sub_palette_size = 19; if (sizeof(sub_palette_) / sizeof(sub_palette_[0]) < sub_palette_size) @@ -611,4 +626,4 @@ bool Surface::fadeSubPalette() // Devolver si el índice 15 coincide con el índice 0 return sub_palette_[15] == sub_palette_[0]; -} \ No newline at end of file +} diff --git a/source/surface.h b/source/surface.h index 4f2391b..6a2b1dc 100644 --- a/source/surface.h +++ b/source/surface.h @@ -91,7 +91,7 @@ public: // Realiza un efecto de fundido en las paletas bool fadePalette(); - bool fadeSubPalette(); + bool fadeSubPalette(Uint32 delay = 0); // Pone un pixel en la SurfaceData void putPixel(int x, int y, Uint8 color);