diff --git a/source/enter_name.cpp b/source/enter_name.cpp index 22de6bc..5929800 100644 --- a/source/enter_name.cpp +++ b/source/enter_name.cpp @@ -6,7 +6,7 @@ // Constructor EnterName::EnterName() - : character_list_("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789. "), + : character_list_("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789."), selected_index_(0) {} // Inicializa el objeto diff --git a/source/player.cpp b/source/player.cpp index 4c6fa59..74972ea 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -616,7 +616,7 @@ void Player::setPlayingState(State state) { } case State::SHOWING_NAME: { showing_name_time_accumulator_ = 0.0f; // Inicializar acumulador time-based - setScoreboardMode(Scoreboard::Mode::SHOW_NAME); + setScoreboardMode(Scoreboard::Mode::ENTER_TO_SHOW_NAME); // Iniciar animación de transición Scoreboard::get()->setEnterName(scoreboard_panel_, last_enter_name_); addScoreToScoreBoard(); break; diff --git a/source/scoreboard.cpp b/source/scoreboard.cpp index f3c387c..fcc5efd 100644 --- a/source/scoreboard.cpp +++ b/source/scoreboard.cpp @@ -16,6 +16,7 @@ #include "sprite.h" // Para Sprite #include "text.h" // Para Text, Text::CENTER, Text::COLOR #include "texture.h" // Para Texture +#include "utils.h" // Para easeOutCubic // .at(SINGLETON) Hay que definir las variables estáticas, desde el .h sólo la hemos declarado Scoreboard* Scoreboard::instance = nullptr; @@ -51,9 +52,7 @@ Scoreboard::Scoreboard() continue_counter_.at(i) = 0; carousel_prev_index_.at(i) = -1; // Inicializar a -1 para detectar primera inicialización enter_name_ref_.at(i) = nullptr; - previous_mode_.at(i) = Mode::SCORE; text_slide_offset_.at(i) = 0.0f; - is_sliding_.at(i) = false; } panel_.at(static_cast(Id::LEFT)).mode = Mode::SCORE; @@ -204,43 +203,32 @@ void Scoreboard::updateCarouselAnimation(float deltaTime) { // Actualiza la animación de deslizamiento de texto (transición ENTER_NAME -> SHOW_NAME) void Scoreboard::updateTextSlideAnimation(float deltaTime) { - const float ROW_SIZE = rect_.h / 4.0f; // Altura de una fila - for (size_t i = 0; i < static_cast(Id::SIZE); ++i) { Mode current_mode = panel_.at(i).mode; - // Detectar transición de ENTER_NAME a SHOW_NAME - if (previous_mode_.at(i) == Mode::ENTER_NAME && current_mode == Mode::SHOW_NAME) { - // Iniciar animación - is_sliding_.at(i) = true; + if (current_mode == Mode::ENTER_TO_SHOW_NAME) { + // Incrementar progreso de animación (0.0 a 1.0) + text_slide_offset_.at(i) += deltaTime / TEXT_SLIDE_DURATION; + + // Terminar animación y cambiar a SHOW_NAME cuando se complete + if (text_slide_offset_.at(i) >= 1.0f) { + text_slide_offset_.at(i) = 1.0f; + panel_.at(i).mode = Mode::SHOW_NAME; + } + } else if (current_mode != Mode::ENTER_NAME) { + // Resetear offset si no estamos en ENTER_NAME ni en transición text_slide_offset_.at(i) = 0.0f; } - - // Actualizar offset durante animación - if (is_sliding_.at(i)) { - // Incrementar offset basado en tiempo - float slide_speed = ROW_SIZE / TEXT_SLIDE_DURATION; // Píxeles por segundo - text_slide_offset_.at(i) += slide_speed * deltaTime; - - // Terminar animación cuando se complete - if (text_slide_offset_.at(i) >= ROW_SIZE) { - text_slide_offset_.at(i) = ROW_SIZE; - is_sliding_.at(i) = false; - } - } - - // Actualizar modo previo para la próxima iteración - previous_mode_.at(i) = current_mode; } } // Actualiza la lógica del marcador void Scoreboard::update(float deltaTime) { - fillBackgroundTexture(); updateTimeCounter(); updateNameColorIndex(); updateCarouselAnimation(deltaTime); updateTextSlideAnimation(deltaTime); + fillBackgroundTexture(); // Renderizar DESPUÉS de actualizar } // Pinta el marcador @@ -315,6 +303,9 @@ void Scoreboard::renderPanelContent(size_t panel_index) { case Mode::ENTER_NAME: renderEnterNameMode(panel_index); break; + case Mode::ENTER_TO_SHOW_NAME: + renderEnterToShowNameMode(panel_index); + break; case Mode::SHOW_NAME: renderShowNameMode(panel_index); break; @@ -420,27 +411,49 @@ void Scoreboard::renderEnterNameMode(size_t panel_index) { renderCarousel(panel_index, slot4_4_.x, slot4_4_.y); } -void Scoreboard::renderShowNameMode(size_t panel_index) { - // Calcular offset de animación de deslizamiento +void Scoreboard::renderEnterToShowNameMode(size_t panel_index) { + // Calcular progreso suavizado de la animación (0.0 a 1.0) + float progress = text_slide_offset_.at(panel_index); + progress = std::min(progress, 1.0f); // Clampear a 1.0 + const float t = static_cast(easeOutCubic(progress)); const float ROW_SIZE = rect_.h / 4.0f; - float y_offset = 0.0f; + const float y_offset = t * ROW_SIZE; // Desplazamiento en píxeles - if (is_sliding_.at(panel_index)) { - // Durante animación: offset va de -ROW_SIZE (arriba) a 0 (posición final) - y_offset = -ROW_SIZE + text_slide_offset_.at(panel_index); - } + // ========== Texto que ENTRA desde arriba ========== + // name_ (entra desde arriba hacia ROW1) + text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y + y_offset - ROW_SIZE, + name_.at(panel_index), 1, text_color1_); - // NOMBRE DEL JUGADOR (texto0 - entra desde arriba) - text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y + y_offset, name_.at(panel_index), 1, text_color1_); + // ========== Textos que SE MUEVEN (renderizar UNA sola vez) ========== + // SCORE (se mueve de ROW1 a ROW2) + text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y + y_offset, + updateScoreText(score_.at(panel_index)), 1, text_color2_); - // SCORE (texto1 - se desplaza hacia abajo) - text_->writeDX(Text::CENTER | Text::COLOR, slot4_2_.x, slot4_2_.y + y_offset, updateScoreText(score_.at(panel_index)), 1, text_color2_); + // "ENTER NAME" (se mueve de ROW2 a ROW3) + text_->writeDX(Text::CENTER | Text::COLOR, slot4_2_.x, slot4_2_.y + y_offset, + Lang::getText("[SCOREBOARD] 11"), 1, text_color1_); - // "ENTER NAME" (texto2 - se desplaza hacia abajo) - text_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y + y_offset, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_); + // enter_name_ (se mueve de ROW3 a ROW4) + text_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y + y_offset, + enter_name_.at(panel_index), 1, text_color2_); - // NOMBRE INTRODUCIDO (texto3 - se desplaza hacia abajo) - text_->writeDX(Text::CENTER | Text::COLOR, slot4_4_.x, slot4_4_.y + y_offset, enter_name_.at(panel_index), 1, animated_color_); + // ========== Elemento que SALE hacia abajo ========== + // CARRUSEL (sale desde ROW4 hacia abajo, fuera de pantalla) + renderCarousel(panel_index, slot4_4_.x, static_cast(slot4_4_.y + y_offset)); +} + +void Scoreboard::renderShowNameMode(size_t panel_index) { + // NOMBRE DEL JUGADOR + text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y, name_.at(panel_index), 1, text_color1_); + + // SCORE + text_->writeDX(Text::CENTER | Text::COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_.at(panel_index)), 1, text_color2_); + + // "ENTER NAME" + text_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_); + + // NOMBRE INTRODUCIDO (con color animado) + text_->writeDX(Text::CENTER | Text::COLOR, slot4_4_.x, slot4_4_.y, enter_name_.at(panel_index), 1, animated_color_); } void Scoreboard::renderGameCompletedMode(size_t panel_index) { diff --git a/source/scoreboard.h b/source/scoreboard.h index 6e53c3a..c29f802 100644 --- a/source/scoreboard.h +++ b/source/scoreboard.h @@ -36,6 +36,7 @@ class Scoreboard { GAME_OVER, DEMO, ENTER_NAME, + ENTER_TO_SHOW_NAME, // Estado de transición con animación SHOW_NAME, GAME_COMPLETED, NUM_MODES, @@ -90,9 +91,7 @@ class Scoreboard { std::array(Id::SIZE)> carousel_position_ = {}; // Posición actual del carrusel (índice en character_list_) std::array(Id::SIZE)> carousel_target_ = {}; // Posición objetivo del carrusel std::array(Id::SIZE)> carousel_prev_index_ = {}; // Índice previo para detectar cambios - std::array(Id::SIZE)> previous_mode_ = {}; // Modo anterior para detectar transiciones - std::array(Id::SIZE)> text_slide_offset_ = {}; // Offset Y de animación de deslizamiento de texto - std::array(Id::SIZE)> is_sliding_ = {}; // Indica si el panel está animando deslizamiento + 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 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) @@ -113,7 +112,7 @@ class Scoreboard { // --- Constantes --- static constexpr int CAROUSEL_VISIBLE_LETTERS = 9; - static constexpr float TEXT_SLIDE_DURATION = 0.5f; // Duración de la animación de deslizamiento en segundos + static constexpr float TEXT_SLIDE_DURATION = 0.3f; // Duración de la animación de deslizamiento en segundos // --- Variables de aspecto --- Color text_color1_, text_color2_; // Colores para los marcadores del texto; @@ -143,6 +142,7 @@ class Scoreboard { void renderContinueMode(size_t panel_index); void renderEnterNameMode(size_t panel_index); void renderNameInputField(size_t panel_index); + void renderEnterToShowNameMode(size_t panel_index); // Renderiza la transición animada void renderShowNameMode(size_t panel_index); void renderGameCompletedMode(size_t panel_index); void renderCarousel(size_t panel_index, int center_x, int y); // Pinta el carrusel de caracteres con colores LERP