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
5
# 123 {
3
7
# 124 |
2
# 125 }

View File

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

View File

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

View File

@@ -5,6 +5,7 @@
#include <algorithm> // Para max
#include <cmath> // Para roundf
#include <iomanip> // Para operator<<, setfill, setw
#include <iostream>
#include <sstream> // Para basic_ostream, basic_ostringstream, basic_ostream::operator<<, ostringstream
#include "color.hpp"
@@ -94,6 +95,7 @@ Scoreboard::~Scoreboard() {
}
}
// Configura la animación del carrusel
// Configura la animación del carrusel
void Scoreboard::setCarouselAnimation(Id id, int selected_index, EnterName* enter_name_ptr) {
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_target_.at(idx) = static_cast<float>(selected_index);
carousel_prev_index_.at(idx) = selected_index;
} else {
// Detectar cambio en el índice del carácter seleccionado
return;
}
int prev_index = carousel_prev_index_.at(idx);
if (selected_index != prev_index) {
// Calcular dirección del movimiento
// Si el índice seleccionado no cambia, no hay nada que hacer
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;
// 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
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)
}
// Normalizar a -1 o +1
// Normalizar dirección a -1 o +1
direction = (direction > 0) ? 1 : ((direction < 0) ? -1 : 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);
// Guardar nuevo índice
// Guardar el nuevo índice seleccionado
carousel_prev_index_.at(idx) = selected_index;
}
}
}
}
// Establece el modo del panel y gestiona transiciones
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);
}
}
// 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
@@ -662,73 +683,72 @@ void Scoreboard::renderCarousel(size_t panel_index, int center_x, int y) {
return;
}
// Espacio extra entre letras
// --- Parámetros del carrusel ---
constexpr int EXTRA_SPACING = 2;
constexpr int HALF_VISIBLE = CAROUSEL_VISIBLE_LETTERS / 2; // 4 letras a cada lado
// Carrusel extendido: usar constante de clase
constexpr int HALF_VISIBLE = CAROUSEL_VISIBLE_LETTERS / 2; // 4
// 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));
// Posición flotante actual del carrusel (índice en la lista de caracteres)
float CAROUSEL_POS = carousel_position_.at(panel_index);
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;
// Renderizar las 9 letras visibles
// === Renderizar las letras visibles del carrusel ===
for (int i = -HALF_VISIBLE; i <= HALF_VISIBLE; ++i) {
// Índice real en character_list_ (con wrap-around circular)
int char_index = BASE_INDEX + i;
// Wrap-around circular
char_index = char_index % CHAR_LIST_SIZE;
if (char_index < 0) {
char_index += CHAR_LIST_SIZE;
}
// Obtener el carácter directamente de character_list_
std::string single_char(1, char_list[char_index]);
// --- Calcular distancia circular correcta (corregido el bug de wrap) ---
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 distance_from_center = std::abs(static_cast<float>(char_index) - CAROUSEL_POS);
float diff = std::abs(static_cast<float>(char_index) - normalized_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
if (distance_from_center > static_cast<float>(CHAR_LIST_SIZE) / 2.0F) {
distance_from_center = static_cast<float>(CHAR_LIST_SIZE) - distance_from_center;
}
const float distance_from_center = diff;
// Calcular color con LERP dinámico continuo
// --- Seleccionar color con LERP según la distancia ---
Color letter_color;
if (distance_from_center < 0.5F) {
// Letra cerca del centro: LERP hacia animated_color_
// distance_from_center va de 0.0 (centro exacto) a 0.5 (borde)
// Letra central → transiciona hacia animated_color_
float lerp_to_animated = distance_from_center / 0.5F; // 0.0 a 1.0
letter_color = animated_color_.LERP(text_color1_, lerp_to_animated);
} 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);
base_lerp = std::min(base_lerp, 1.0F);
const float LERP_FACTOR = base_lerp * 0.85F;
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);
// 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);
}
}