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:
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -185,7 +185,7 @@
|
||||
# 122 z
|
||||
5
|
||||
# 123 {
|
||||
3
|
||||
7
|
||||
# 124 |
|
||||
2
|
||||
# 125 }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
// Constructor
|
||||
EnterName::EnterName()
|
||||
: character_list_("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.") {}
|
||||
: character_list_("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{") {}
|
||||
|
||||
// Inicializa el objeto
|
||||
void EnterName::init(const std::string& name) {
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
#include <algorithm> // Para max
|
||||
#include <cmath> // Para roundf
|
||||
#include <iomanip> // Para operator<<, setfill, setw
|
||||
#include <sstream> // Para basic_ostream, basic_ostringstream, basic_ostream::operator<<, ostringstream
|
||||
#include <iostream>
|
||||
#include <sstream> // Para basic_ostream, basic_ostringstream, basic_ostream::operator<<, ostringstream
|
||||
|
||||
#include "color.hpp"
|
||||
#include "enter_name.hpp" // Para NAME_SIZE
|
||||
@@ -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);
|
||||
@@ -108,40 +110,52 @@ void Scoreboard::setCarouselAnimation(Id id, int selected_index, EnterName* ente
|
||||
// Primera inicialización: posicionar directamente sin animar
|
||||
if (carousel_prev_index_.at(idx) == -1) {
|
||||
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;
|
||||
} else {
|
||||
// Detectar cambio en el índice del carácter seleccionado
|
||||
int prev_index = carousel_prev_index_.at(idx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (selected_index != prev_index) {
|
||||
// Calcular dirección del movimiento
|
||||
int direction = selected_index - prev_index;
|
||||
int prev_index = carousel_prev_index_.at(idx);
|
||||
|
||||
// Obtener tamaño de la lista para manejar wrap-around
|
||||
const int LIST_SIZE = enter_name_ptr->getCharacterList().size();
|
||||
// Si el índice seleccionado no cambia, no hay nada que hacer
|
||||
if (selected_index == prev_index) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Manejar wrap-around circular
|
||||
if (direction > LIST_SIZE / 2) {
|
||||
direction = -(LIST_SIZE - direction); // Wrap backward (ej: Z → A)
|
||||
} else if (direction < -LIST_SIZE / 2) {
|
||||
direction = LIST_SIZE + direction; // Wrap forward (ej: A → Z)
|
||||
}
|
||||
// 🚫 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
|
||||
}
|
||||
|
||||
// Normalizar a -1 o +1
|
||||
direction = (direction > 0) ? 1 : ((direction < 0) ? -1 : 0);
|
||||
// ---- Animación completada → procesar el nuevo movimiento ----
|
||||
int direction = selected_index - prev_index;
|
||||
|
||||
if (direction != 0) {
|
||||
// Actualizar target con movimiento relativo
|
||||
carousel_target_.at(idx) = carousel_position_.at(idx) + static_cast<float>(direction);
|
||||
// Obtener tamaño de la lista para manejar wrap-around
|
||||
const int LIST_SIZE = static_cast<int>(enter_name_ptr->getCharacterList().size());
|
||||
|
||||
// Guardar nuevo índice
|
||||
carousel_prev_index_.at(idx) = selected_index;
|
||||
}
|
||||
}
|
||||
// Manejar wrap-around circular
|
||||
if (direction > LIST_SIZE / 2) {
|
||||
direction = -(LIST_SIZE - direction); // Wrap backward (ej: Z → A)
|
||||
} else if (direction < -LIST_SIZE / 2) {
|
||||
direction = LIST_SIZE + direction; // Wrap forward (ej: A → Z)
|
||||
}
|
||||
|
||||
// Normalizar dirección a -1 o +1
|
||||
direction = (direction > 0) ? 1 : ((direction < 0) ? -1 : 0);
|
||||
|
||||
if (direction != 0) {
|
||||
// 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 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) {
|
||||
auto idx = static_cast<size_t>(id);
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user