afegit caracter de acabar de posar el nom (no en us encara)

corregida la logica de animacio i desplaçament del carrusel de posar nom
This commit is contained in:
2025-10-22 15:05:57 +02:00
parent d4e09e1e88
commit bb132aade2
5 changed files with 86 additions and 66 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -185,7 +185,7 @@
# 122 z # 122 z
5 5
# 123 { # 123 {
3 7
# 124 | # 124 |
2 2
# 125 } # 125 }

View File

@@ -44,7 +44,7 @@ Director::Director(int argc, std::span<char*> argv) {
Section::name = Section::Name::GAME; Section::name = Section::Name::GAME;
Section::options = Section::Options::GAME_PLAY_1P; Section::options = Section::Options::GAME_PLAY_1P;
#elif _DEBUG #elif _DEBUG
Section::name = Section::Name::HI_SCORE_TABLE; Section::name = Section::Name::GAME;
Section::options = Section::Options::GAME_PLAY_1P; Section::options = Section::Options::GAME_PLAY_1P;
#else // NORMAL GAME #else // NORMAL GAME
Section::name = Section::Name::LOGO; Section::name = Section::Name::LOGO;

View File

@@ -6,7 +6,7 @@
// Constructor // Constructor
EnterName::EnterName() EnterName::EnterName()
: character_list_("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.") {} : character_list_("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{") {}
// Inicializa el objeto // Inicializa el objeto
void EnterName::init(const std::string& name) { void EnterName::init(const std::string& name) {

View File

@@ -5,6 +5,7 @@
#include <algorithm> // Para max #include <algorithm> // Para max
#include <cmath> // Para roundf #include <cmath> // Para roundf
#include <iomanip> // Para operator<<, setfill, setw #include <iomanip> // Para operator<<, setfill, setw
#include <iostream>
#include <sstream> // Para basic_ostream, basic_ostringstream, basic_ostream::operator<<, ostringstream #include <sstream> // Para basic_ostream, basic_ostringstream, basic_ostream::operator<<, ostringstream
#include "color.hpp" #include "color.hpp"
@@ -94,6 +95,7 @@ Scoreboard::~Scoreboard() {
} }
} }
// Configura la animación del carrusel
// Configura la animación del carrusel // Configura la animación del carrusel
void Scoreboard::setCarouselAnimation(Id id, int selected_index, EnterName* enter_name_ptr) { void Scoreboard::setCarouselAnimation(Id id, int selected_index, EnterName* enter_name_ptr) {
auto idx = static_cast<size_t>(id); auto idx = static_cast<size_t>(id);
@@ -110,16 +112,26 @@ void Scoreboard::setCarouselAnimation(Id id, int selected_index, EnterName* ente
carousel_position_.at(idx) = static_cast<float>(selected_index); carousel_position_.at(idx) = static_cast<float>(selected_index);
carousel_target_.at(idx) = static_cast<float>(selected_index); carousel_target_.at(idx) = static_cast<float>(selected_index);
carousel_prev_index_.at(idx) = selected_index; carousel_prev_index_.at(idx) = selected_index;
} else { return;
// Detectar cambio en el índice del carácter seleccionado }
int prev_index = carousel_prev_index_.at(idx); int prev_index = carousel_prev_index_.at(idx);
if (selected_index != prev_index) { // Si el índice seleccionado no cambia, no hay nada que hacer
// Calcular dirección del movimiento if (selected_index == prev_index) {
return;
}
// 🚫 BLOQUEO: si todavía hay una animación en curso, ignoramos el nuevo movimiento
if (std::abs(carousel_position_.at(idx) - carousel_target_.at(idx)) > 0.01f) {
return; // Aún animando: no aceptar nuevo target hasta terminar
}
// ---- Animación completada → procesar el nuevo movimiento ----
int direction = selected_index - prev_index; int direction = selected_index - prev_index;
// Obtener tamaño de la lista para manejar wrap-around // Obtener tamaño de la lista para manejar wrap-around
const int LIST_SIZE = enter_name_ptr->getCharacterList().size(); const int LIST_SIZE = static_cast<int>(enter_name_ptr->getCharacterList().size());
// Manejar wrap-around circular // Manejar wrap-around circular
if (direction > LIST_SIZE / 2) { if (direction > LIST_SIZE / 2) {
@@ -128,19 +140,21 @@ void Scoreboard::setCarouselAnimation(Id id, int selected_index, EnterName* ente
direction = LIST_SIZE + direction; // Wrap forward (ej: A → Z) direction = LIST_SIZE + direction; // Wrap forward (ej: A → Z)
} }
// Normalizar a -1 o +1 // Normalizar dirección a -1 o +1
direction = (direction > 0) ? 1 : ((direction < 0) ? -1 : 0); direction = (direction > 0) ? 1 : ((direction < 0) ? -1 : 0);
if (direction != 0) { if (direction != 0) {
// Actualizar target con movimiento relativo // Asegurar que partimos de una posición alineada
carousel_position_.at(idx) = std::round(carousel_position_.at(idx));
// Actualizar el nuevo target relativo
carousel_target_.at(idx) = carousel_position_.at(idx) + static_cast<float>(direction); carousel_target_.at(idx) = carousel_position_.at(idx) + static_cast<float>(direction);
// Guardar nuevo índice // Guardar el nuevo índice seleccionado
carousel_prev_index_.at(idx) = selected_index; carousel_prev_index_.at(idx) = selected_index;
} }
} }
}
}
// Establece el modo del panel y gestiona transiciones // Establece el modo del panel y gestiona transiciones
void Scoreboard::setMode(Id id, Mode mode) { void Scoreboard::setMode(Id id, Mode mode) {
@@ -242,6 +256,13 @@ void Scoreboard::updateCarouselAnimation(float delta_time) {
carousel_position_.at(i) = carousel_target_.at(i); carousel_position_.at(i) = carousel_target_.at(i);
} }
} }
// 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 // Actualiza las animaciones de deslizamiento de texto
@@ -662,73 +683,72 @@ void Scoreboard::renderCarousel(size_t panel_index, int center_x, int y) {
return; return;
} }
// Espacio extra entre letras // --- Parámetros del carrusel ---
constexpr int EXTRA_SPACING = 2; constexpr int EXTRA_SPACING = 2;
constexpr int HALF_VISIBLE = CAROUSEL_VISIBLE_LETTERS / 2; // 4 letras a cada lado
// Carrusel extendido: usar constante de clase // Posición flotante actual del carrusel (índice en la lista de caracteres)
constexpr int HALF_VISIBLE = CAROUSEL_VISIBLE_LETTERS / 2; // 4 float CAROUSEL_POS = carousel_position_.at(panel_index);
// Posición flotante actual del carrusel (índice en character_list_)
const float CAROUSEL_POS = carousel_position_.at(panel_index);
// Calcular ancho promedio de una letra (asumimos ancho uniforme)
std::string sample_char(1, char_list[0]);
const int AVG_CHAR_WIDTH = text_->length(sample_char, 1);
const int CHAR_STEP = AVG_CHAR_WIDTH + EXTRA_SPACING;
// Calcular offset de píxeles basado en la parte fraccionaria de carousel_pos
const float FRACTIONAL_OFFSET = CAROUSEL_POS - std::floor(CAROUSEL_POS);
const int PIXEL_OFFSET = static_cast<int>(FRACTIONAL_OFFSET * CHAR_STEP);
// Índice base en character_list_ (centro del carrusel)
const int BASE_INDEX = static_cast<int>(std::floor(CAROUSEL_POS));
const int CHAR_LIST_SIZE = static_cast<int>(char_list.size()); const int CHAR_LIST_SIZE = static_cast<int>(char_list.size());
// Calcular posición X inicial (centrar el conjunto de 9 letras) // Calcular ancho promedio de una letra (asumimos ancho uniforme)
const int AVG_CHAR_WIDTH = text_->getCharacterSize();
const int CHAR_STEP = AVG_CHAR_WIDTH + EXTRA_SPACING;
// --- Corrección visual de residuales flotantes (evita “baile”) ---
float frac = CAROUSEL_POS - std::floor(CAROUSEL_POS);
if (frac > 0.999f || frac < 0.001f) {
CAROUSEL_POS = std::round(CAROUSEL_POS);
frac = 0.0f;
}
const float FRACTIONAL_OFFSET = frac;
const int PIXEL_OFFSET = static_cast<int>(FRACTIONAL_OFFSET * CHAR_STEP + 0.5f);
// Índice base en la lista de caracteres (posición central)
const int BASE_INDEX = static_cast<int>(std::floor(CAROUSEL_POS));
// Calcular posición X inicial (centrar las 9 letras visibles)
int start_x = center_x - (HALF_VISIBLE * CHAR_STEP) - (AVG_CHAR_WIDTH / 2) - PIXEL_OFFSET; int start_x = center_x - (HALF_VISIBLE * CHAR_STEP) - (AVG_CHAR_WIDTH / 2) - PIXEL_OFFSET;
// Renderizar las 9 letras visibles // === Renderizar las letras visibles del carrusel ===
for (int i = -HALF_VISIBLE; i <= HALF_VISIBLE; ++i) { for (int i = -HALF_VISIBLE; i <= HALF_VISIBLE; ++i) {
// Índice real en character_list_ (con wrap-around circular) // Índice real en character_list_ (con wrap-around circular)
int char_index = BASE_INDEX + i; int char_index = BASE_INDEX + i;
// Wrap-around circular
char_index = char_index % CHAR_LIST_SIZE; char_index = char_index % CHAR_LIST_SIZE;
if (char_index < 0) { if (char_index < 0) {
char_index += CHAR_LIST_SIZE; char_index += CHAR_LIST_SIZE;
} }
// Obtener el carácter directamente de character_list_ // --- Calcular distancia circular correcta (corregido el bug de wrap) ---
std::string single_char(1, char_list[char_index]); float normalized_pos = std::fmod(CAROUSEL_POS, static_cast<float>(CHAR_LIST_SIZE));
if (normalized_pos < 0.0f) normalized_pos += static_cast<float>(CHAR_LIST_SIZE);
// Calcular distancia flotante al centro visual basada en posición real del carácter float diff = std::abs(static_cast<float>(char_index) - normalized_pos);
float distance_from_center = std::abs(static_cast<float>(char_index) - CAROUSEL_POS); if (diff > static_cast<float>(CHAR_LIST_SIZE) / 2.0f)
diff = static_cast<float>(CHAR_LIST_SIZE) - diff;
// Manejar wrap-around circular: elegir el camino más corto const float distance_from_center = diff;
if (distance_from_center > static_cast<float>(CHAR_LIST_SIZE) / 2.0F) {
distance_from_center = static_cast<float>(CHAR_LIST_SIZE) - distance_from_center;
}
// Calcular color con LERP dinámico continuo // --- Seleccionar color con LERP según la distancia ---
Color letter_color; Color letter_color;
if (distance_from_center < 0.5F) { if (distance_from_center < 0.5F) {
// Letra cerca del centro: LERP hacia animated_color_ // Letra central → transiciona hacia animated_color_
// distance_from_center va de 0.0 (centro exacto) a 0.5 (borde)
float lerp_to_animated = distance_from_center / 0.5F; // 0.0 a 1.0 float lerp_to_animated = distance_from_center / 0.5F; // 0.0 a 1.0
letter_color = animated_color_.LERP(text_color1_, lerp_to_animated); letter_color = animated_color_.LERP(text_color1_, lerp_to_animated);
} else { } else {
// Letras alejadas: LERP hacia color_ (fade out) // Letras alejadas → degradan hacia color_ base
float base_lerp = (distance_from_center - 0.5F) / (HALF_VISIBLE - 0.5F); float base_lerp = (distance_from_center - 0.5F) / (HALF_VISIBLE - 0.5F);
base_lerp = std::min(base_lerp, 1.0F); base_lerp = std::min(base_lerp, 1.0F);
const float LERP_FACTOR = base_lerp * 0.85F; const float LERP_FACTOR = base_lerp * 0.85F;
letter_color = text_color1_.LERP(color_, LERP_FACTOR); letter_color = text_color1_.LERP(color_, LERP_FACTOR);
} }
// Calcular posición X de esta letra // Calcular posición X de la letra
const int LETTER_X = start_x + ((i + HALF_VISIBLE) * CHAR_STEP); const int LETTER_X = start_x + ((i + HALF_VISIBLE) * CHAR_STEP);
// Pintar la letra // Renderizar la letra
std::string single_char(1, char_list[char_index]);
text_->writeDX(Text::COLOR, LETTER_X, y, single_char, 1, letter_color); text_->writeDX(Text::COLOR, LETTER_X, y, single_char, 1, letter_color);
} }
} }