diff --git a/source/director.cpp b/source/director.cpp index f7a81e2..79f7560 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -44,7 +44,7 @@ Director::Director(int argc, std::span argv) { Section::name = Section::Name::GAME; Section::options = Section::Options::GAME_PLAY_1P; #elif _DEBUG - Section::name = Section::Name::CREDITS; + Section::name = Section::Name::GAME; Section::options = Section::Options::GAME_PLAY_1P; #else // NORMAL GAME Section::name = Section::Name::LOGO; diff --git a/source/player.cpp b/source/player.cpp index df325d4..a63b394 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -882,6 +882,7 @@ void Player::updateContinueCounter(float delta_time) { if (continue_time_accumulator_ >= CONTINUE_INTERVAL_S) { continue_time_accumulator_ -= CONTINUE_INTERVAL_S; decContinueCounter(); + Scoreboard::get()->triggerPanelPulse(scoreboard_panel_, 0.2F); } } } diff --git a/source/scoreboard.cpp b/source/scoreboard.cpp index 8d89fc1..ff349ba 100644 --- a/source/scoreboard.cpp +++ b/source/scoreboard.cpp @@ -287,12 +287,41 @@ void Scoreboard::updateTextSlideAnimation(float delta_time) { } } +// Actualiza las animaciones de pulso de los paneles +void Scoreboard::updatePanelPulses(float delta_time) { + for (size_t i = 0; i < static_cast(Id::SIZE); ++i) { + auto& pulse = panel_pulse_.at(i); + + if (!pulse.active) { + continue; + } + + // Avanzar el tiempo transcurrido + pulse.elapsed_s += delta_time; + + // Desactivar el pulso si ha terminado + if (pulse.elapsed_s >= pulse.duration_s) { + pulse.active = false; + pulse.elapsed_s = 0.0f; + } + } +} + +// Activa un pulso en el panel especificado +void Scoreboard::triggerPanelPulse(Id id, float duration_s) { + auto idx = static_cast(id); + panel_pulse_.at(idx).active = true; + panel_pulse_.at(idx).elapsed_s = 0.0f; + panel_pulse_.at(idx).duration_s = duration_s; +} + // Actualiza la lógica del marcador void Scoreboard::update(float delta_time) { updateTimeCounter(); updateNameColorIndex(); updateCarouselAnimation(delta_time); updateTextSlideAnimation(delta_time); + updatePanelPulses(delta_time); fillBackgroundTexture(); // Renderizar DESPUÉS de actualizar } @@ -334,8 +363,30 @@ void Scoreboard::fillPanelTextures() { // Cambia el destino del renderizador SDL_SetRenderTarget(renderer_, panel_texture_.at(i)); + // Calcula el color de fondo del panel (puede tener pulso activo) + Color background_color = Color(0, 0, 0, 0); // Transparente por defecto + + const auto& pulse = panel_pulse_.at(i); + if (pulse.active) { + // Calcular el progreso del pulso (0.0 a 1.0 y de vuelta a 0.0) + float progress = pulse.elapsed_s / pulse.duration_s; + + // Crear curva de ida y vuelta (0 → 1 → 0) + float pulse_intensity; + if (progress < 0.5F) { + pulse_intensity = progress * 2.0F; // 0.0 a 1.0 + } else { + pulse_intensity = (1.0F - progress) * 2.0F; // 1.0 a 0.0 + } + + // Interpolar entre color base y color aclarado + Color target_color = color_.LIGHTEN(PANEL_PULSE_LIGHTEN_AMOUNT); + background_color = color_.LERP(target_color, pulse_intensity); + background_color.a = 255; // Opaco durante el pulso + } + // Dibuja el fondo de la textura - SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0); + SDL_SetRenderDrawColor(renderer_, background_color.r, background_color.g, background_color.b, background_color.a); SDL_RenderClear(renderer_); renderPanelContent(i); diff --git a/source/scoreboard.hpp b/source/scoreboard.hpp index aafaad0..17a176c 100644 --- a/source/scoreboard.hpp +++ b/source/scoreboard.hpp @@ -49,6 +49,12 @@ class Scoreboard { SDL_FRect pos; // Posición donde dibujar el panel dentro del marcador }; + struct PanelPulse { + bool active = false; // Si el pulso está activo + float elapsed_s = 0.0f; // Tiempo transcurrido desde el inicio + float duration_s = 0.5f; // Duración total del pulso + }; + // --- Métodos de singleton --- static void init(); // Crea el objeto Scoreboard static void destroy(); // Libera el objeto Scoreboard @@ -74,6 +80,7 @@ class Scoreboard { void setScore(Id id, int score) { score_.at(static_cast(id)) = score; } void setSelectorPos(Id id, int pos) { selector_pos_.at(static_cast(id)) = pos; } void setStage(int stage) { stage_ = stage; } + void triggerPanelPulse(Id id, float duration_s = 0.5f); // Activa un pulso en el panel especificado private: // --- Objetos y punteros --- @@ -94,6 +101,7 @@ class Scoreboard { std::array(Id::SIZE)> carousel_prev_index_ = {}; // Índice previo para detectar cambios std::array(Id::SIZE)> text_slide_offset_ = {}; // Progreso de animación de deslizamiento (0.0 a 1.0) std::array(Id::SIZE)> panel_ = {}; // Lista con todos los paneles del marcador + std::array(Id::SIZE)> panel_pulse_ = {}; // Estado de pulso para cada panel Colors::Cycle name_color_cycle_; // Ciclo de colores para destacar el nombre una vez introducido Color animated_color_; // Color actual animado (ciclo automático cada 100ms) std::string hi_score_name_; // Nombre del jugador con la máxima puntuación @@ -115,6 +123,7 @@ class Scoreboard { // --- Constantes --- static constexpr int CAROUSEL_VISIBLE_LETTERS = 9; static constexpr float TEXT_SLIDE_DURATION = 0.3F; // Duración de la animación de deslizamiento en segundos + static constexpr int PANEL_PULSE_LIGHTEN_AMOUNT = 100; // Cantidad de aclarado para el pulso del panel // --- Variables de aspecto --- Color text_color1_, text_color2_; // Colores para los marcadores del texto; @@ -134,6 +143,7 @@ class Scoreboard { void updateNameColorIndex(); // Actualiza el índice del color animado del nombre void updateCarouselAnimation(float delta_time); // Actualiza la animación del carrusel void updateTextSlideAnimation(float delta_time); // Actualiza la animación de deslizamiento de texto + void updatePanelPulses(float delta_time); // Actualiza las animaciones de pulso de los paneles void renderSeparator(); // Dibuja la línea que separa la zona de juego del marcador void renderPanelContent(size_t panel_index); void renderScoreMode(size_t panel_index);