From 40538eaa2813509363f94de13a6b55fc7a52c2f9 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Wed, 22 Oct 2025 18:56:59 +0200 Subject: [PATCH] =?UTF-8?q?el=20carrusel=20ja=20s'anima=20supersucosetment?= =?UTF-8?q?=20cap=20al=20OK=20de=20manera=20autom=C3=A1tica?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/scoreboard.cpp | 69 ++++++++++++++++++++++--------------------- source/scoreboard.hpp | 1 + 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/source/scoreboard.cpp b/source/scoreboard.cpp index a23af47..8d89fc1 100644 --- a/source/scoreboard.cpp +++ b/source/scoreboard.cpp @@ -99,59 +99,65 @@ Scoreboard::~Scoreboard() { void Scoreboard::setCarouselAnimation(Id id, int selected_index, EnterName* enter_name_ptr) { auto idx = static_cast(id); - // Guardar referencia al objeto EnterName + // Guardar referencia enter_name_ref_.at(idx) = enter_name_ptr; - if ((enter_name_ptr == nullptr) || selected_index < 0) { return; } - // ===== Primera inicialización ===== + // ===== Inicialización (primera vez) ===== if (carousel_prev_index_.at(idx) == -1) { - carousel_position_.at(idx) = static_cast(selected_index); - carousel_target_.at(idx) = static_cast(selected_index); + carousel_position_.at(idx) = static_cast(selected_index); + carousel_target_.at(idx) = static_cast(selected_index); carousel_prev_index_.at(idx) = selected_index; return; } int prev_index = carousel_prev_index_.at(idx); if (selected_index == prev_index) { - return; // No hay cambio + return; // nada que hacer } - // ===== Bloqueo: si aún está animando, ignorar nueva orden ===== + // ===== Bloquear si aún animando ===== if (std::abs(carousel_position_.at(idx) - carousel_target_.at(idx)) > 0.01f) { return; } - // ===== Calcular el salto ===== + // ===== Calcular salto circular ===== int delta = selected_index - prev_index; const int LIST_SIZE = static_cast(enter_name_ptr->getCharacterList().size()); + if (delta > LIST_SIZE / 2) delta -= LIST_SIZE; + else if (delta < -LIST_SIZE / 2) delta += LIST_SIZE; - // Ajustar para wrap-around circular (camino más corto) - if (delta > LIST_SIZE / 2) { - delta -= LIST_SIZE; - } else if (delta < -LIST_SIZE / 2) { - delta += LIST_SIZE; - } + // ===== Alinear posición actual antes de moverse ===== + carousel_position_.at(idx) = std::round(carousel_position_.at(idx)); - // ===== Diferenciar salto corto o largo ===== - if (std::abs(delta) > 2) { - // Salto grande → ir directo sin animación - carousel_position_.at(idx) = static_cast(selected_index); - carousel_target_.at(idx) = static_cast(selected_index); + // ===== Control del salto ===== + const int ABS_DELTA = std::abs(delta); + + if (ABS_DELTA <= 2) { + // Movimiento corto → animación normal + carousel_target_.at(idx) = carousel_position_.at(idx) + static_cast(delta); } else { - // Salto corto → animación suave normal - carousel_position_.at(idx) = std::round(carousel_position_.at(idx)); - carousel_target_.at(idx) = carousel_position_.at(idx) + static_cast(delta); + // Movimiento largo → animado pero limitado en tiempo + // Normalizamos el salto para que visualmente tarde como mucho el doble + const float MAX_DURATION_FACTOR = 2.0f; // máximo 2x la duración de una letra + const float SPEED_SCALE = std::min(1.0f, MAX_DURATION_FACTOR / static_cast(ABS_DELTA)); + + // Guardamos el destino real + float target = std::round(carousel_position_.at(idx)) + static_cast(delta); + + // Interpolaremos más rápido en updateCarouselAnimation usando un factor auxiliar + // guardado en un nuevo vector (si no existe aún, puedes declararlo en la clase): + carousel_speed_scale_.at(idx) = SPEED_SCALE; + + // Asignamos el target real + carousel_target_.at(idx) = target; } - // Actualizar índice actual carousel_prev_index_.at(idx) = selected_index; } - - // Establece el modo del panel y gestiona transiciones void Scoreboard::setMode(Id id, Mode mode) { auto idx = static_cast(id); @@ -227,7 +233,7 @@ void Scoreboard::updateNameColorIndex() { // Actualiza la animación del carrusel void Scoreboard::updateCarouselAnimation(float delta_time) { - constexpr float CAROUSEL_SPEED = 8.0F; // Posiciones por segundo + const float BASE_SPEED = 8.0F; // Posiciones por segundo for (size_t i = 0; i < carousel_position_.size(); ++i) { // Solo animar si no hemos llegado al target @@ -236,7 +242,8 @@ void Scoreboard::updateCarouselAnimation(float delta_time) { float direction = (carousel_target_.at(i) > carousel_position_.at(i)) ? 1.0F : -1.0F; // Calcular movimiento - float movement = CAROUSEL_SPEED * delta_time * direction; + float speed = BASE_SPEED / carousel_speed_scale_.at(i); // ajusta según salto + float movement = speed * delta_time * direction; // Mover, pero no sobrepasar el target float new_position = carousel_position_.at(i) + movement; @@ -250,15 +257,9 @@ void Scoreboard::updateCarouselAnimation(float delta_time) { } else { // Forzar al target exacto cuando estamos muy cerca carousel_position_.at(i) = carousel_target_.at(i); + carousel_speed_scale_.at(i) = 1.0f; // restaurar velocidad normal } } - - // Después del bloque principal en updateCarouselAnimation() - /*for (size_t i = 0; i < carousel_position_.size(); ++i) { - if (std::abs(carousel_position_.at(i) - carousel_target_.at(i)) <= 0.01F) { - carousel_position_.at(i) = std::round(carousel_target_.at(i)); // <-- redondea - } - }*/ } // Actualiza las animaciones de deslizamiento de texto diff --git a/source/scoreboard.hpp b/source/scoreboard.hpp index 599a0f2..aafaad0 100644 --- a/source/scoreboard.hpp +++ b/source/scoreboard.hpp @@ -110,6 +110,7 @@ class Scoreboard { Uint32 name_color_index_ = 0; // Índice actual del color en el ciclo de animación del nombre Uint64 name_color_last_update_ = 0; // Último tick de actualización del color del nombre float power_ = 0; // Poder actual de la fase + std::array(Id::SIZE)> carousel_speed_scale_ = {1.0f, 1.0f, 1.0f}; // --- Constantes --- static constexpr int CAROUSEL_VISIBLE_LETTERS = 9;