Compare commits
3 Commits
fde77affdf
...
88d814f371
| Author | SHA1 | Date | |
|---|---|---|---|
| 88d814f371 | |||
| b933ceee63 | |||
| 75ccddbaa1 |
@@ -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;
|
||||||
|
|||||||
@@ -17,24 +17,31 @@ void EnterName::init(const std::string& name) {
|
|||||||
// Incrementa el índice del carácter seleccionado
|
// Incrementa el índice del carácter seleccionado
|
||||||
void EnterName::incIndex() {
|
void EnterName::incIndex() {
|
||||||
++selected_index_;
|
++selected_index_;
|
||||||
if (selected_index_ >= static_cast<int>(character_list_.size())) {
|
if (selected_index_ >= character_list_.size()) {
|
||||||
selected_index_ = 0;
|
selected_index_ = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrementa el índice del carácter seleccionado
|
// Decrementa el índice del carácter seleccionado
|
||||||
void EnterName::decIndex() {
|
void EnterName::decIndex() {
|
||||||
--selected_index_;
|
if (selected_index_ == 0) {
|
||||||
if (selected_index_ < 0) {
|
|
||||||
selected_index_ = character_list_.size() - 1;
|
selected_index_ = character_list_.size() - 1;
|
||||||
|
} else {
|
||||||
|
--selected_index_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Añade el carácter seleccionado al nombre
|
// Añade el carácter seleccionado al nombre
|
||||||
void EnterName::addCharacter() {
|
void EnterName::addCharacter() {
|
||||||
|
// Si no es el ultimo caracter, lo añade
|
||||||
if (name_.length() < MAX_NAME_SIZE) {
|
if (name_.length() < MAX_NAME_SIZE) {
|
||||||
name_.push_back(character_list_[selected_index_]);
|
name_.push_back(character_list_[selected_index_]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Si el nombre está completo, cambia el caracter seleccionado a el caracter de finalizar
|
||||||
|
if (nameIsFull()) {
|
||||||
|
forceEndCharSelected();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Elimina el último carácter del nombre
|
// Elimina el último carácter del nombre
|
||||||
|
|||||||
@@ -20,19 +20,23 @@ class EnterName {
|
|||||||
void addCharacter(); // Añade el carácter seleccionado al nombre
|
void addCharacter(); // Añade el carácter seleccionado al nombre
|
||||||
void removeLastCharacter(); // Elimina el último carácter del nombre
|
void removeLastCharacter(); // Elimina el último carácter del nombre
|
||||||
|
|
||||||
auto getFinalName() -> std::string; // Obtiene el nombre final (o aleatorio si vacío)
|
auto getFinalName() -> std::string; // Obtiene el nombre final (o aleatorio si vacío)
|
||||||
[[nodiscard]] auto getCurrentName() const -> std::string { return name_; } // Obtiene el nombre actual en proceso
|
[[nodiscard]] auto getCurrentName() const -> std::string { return name_; } // Obtiene el nombre actual en proceso
|
||||||
[[nodiscard]] auto getSelectedCharacter(int offset = 0) const -> std::string; // Devuelve el carácter seleccionado con offset relativo
|
[[nodiscard]] auto getSelectedCharacter(int offset = 0) const -> std::string; // Devuelve el carácter seleccionado con offset relativo
|
||||||
[[nodiscard]] auto getCarousel(int size) const -> std::string; // Devuelve el carrusel de caracteres (size debe ser impar)
|
[[nodiscard]] auto getCarousel(int size) const -> std::string; // Devuelve el carrusel de caracteres (size debe ser impar)
|
||||||
[[nodiscard]] auto getSelectedIndex() const -> int { return selected_index_; } // Obtiene el índice del carácter seleccionado
|
[[nodiscard]] auto getSelectedIndex() const -> int { return selected_index_; } // Obtiene el índice del carácter seleccionado
|
||||||
[[nodiscard]] auto getCharacterList() const -> const std::string& { return character_list_; } // Obtiene la lista completa de caracteres
|
[[nodiscard]] auto getCharacterList() const -> const std::string& { return character_list_; } // Obtiene la lista completa de caracteres
|
||||||
|
[[nodiscard]] auto nameIsFull() const -> bool { return name_.size() == MAX_NAME_SIZE; } // Informa de si el nombre ha alcanzado su limite
|
||||||
|
[[nodiscard]] auto nameIsEmpty() const -> bool { return name_.empty(); } // Informa de si el nombre está vacío
|
||||||
|
[[nodiscard]] auto endCharSelected() const -> bool { return selected_index_ == character_list_.size() - 1; } // Informa de si está seleccionado el caracter de terminar
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Variables de estado ---
|
// --- Variables de estado ---
|
||||||
std::string character_list_; // Lista de caracteres permitidos
|
std::string character_list_; // Lista de caracteres permitidos
|
||||||
std::string name_; // Nombre en proceso
|
std::string name_; // Nombre en proceso
|
||||||
int selected_index_ = 0; // Índice del carácter seleccionado en "character_list_"
|
size_t selected_index_ = 0; // Índice del carácter seleccionado en "character_list_"
|
||||||
|
|
||||||
[[nodiscard]] auto sanitizeName(const std::string& name) const -> std::string; // Valida y limpia el nombre
|
[[nodiscard]] auto sanitizeName(const std::string& name) const -> std::string; // Valida y limpia el nombre
|
||||||
static auto getRandomName() -> std::string; // Devuelve un nombre al azar
|
static auto getRandomName() -> std::string; // Devuelve un nombre al azar
|
||||||
|
void forceEndCharSelected() { selected_index_ = character_list_.size() - 1; } // Establece como seleccionado el caracter de terminar
|
||||||
};
|
};
|
||||||
@@ -78,6 +78,7 @@ void Player::setInput(Input::Action action) {
|
|||||||
setInputPlaying(action);
|
setInputPlaying(action);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case State::SHOWING_NAME:
|
||||||
case State::ENTERING_NAME:
|
case State::ENTERING_NAME:
|
||||||
case State::ENTERING_NAME_GAME_COMPLETED: {
|
case State::ENTERING_NAME_GAME_COMPLETED: {
|
||||||
setInputEnteringName(action);
|
setInputEnteringName(action);
|
||||||
@@ -124,20 +125,50 @@ void Player::setInputPlaying(Input::Action action) {
|
|||||||
// Procesa inputs para cuando está introduciendo el nombre
|
// Procesa inputs para cuando está introduciendo el nombre
|
||||||
void Player::setInputEnteringName(Input::Action action) {
|
void Player::setInputEnteringName(Input::Action action) {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case Input::Action::FIRE_LEFT:
|
case Input::Action::FIRE_LEFT: // Añade una letra
|
||||||
enter_name_->addCharacter();
|
if (isShowingName()) {
|
||||||
|
passShowingName();
|
||||||
|
} else {
|
||||||
|
if (enter_name_->endCharSelected()) {
|
||||||
|
last_enter_name_ = getRecordName();
|
||||||
|
setPlayingState(Player::State::SHOWING_NAME);
|
||||||
|
playSound("name_input_accept.wav");
|
||||||
|
} else {
|
||||||
|
enter_name_->addCharacter();
|
||||||
|
playSound("service_menu_select.wav");
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Input::Action::FIRE_CENTER:
|
case Input::Action::FIRE_CENTER: // Borra una letra
|
||||||
enter_name_->removeLastCharacter();
|
if (isShowingName()) {
|
||||||
|
passShowingName();
|
||||||
|
} else {
|
||||||
|
if (!enter_name_->nameIsEmpty()) {
|
||||||
|
enter_name_->removeLastCharacter();
|
||||||
|
playSound("service_menu_back.wav");
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Input::Action::RIGHT:
|
case Input::Action::RIGHT:
|
||||||
enter_name_->incIndex();
|
if (!enter_name_->nameIsFull()) {
|
||||||
|
enter_name_->incIndex();
|
||||||
|
playSound("service_menu_move.wav");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Input::Action::LEFT:
|
case Input::Action::LEFT:
|
||||||
enter_name_->decIndex();
|
if (!enter_name_->nameIsFull()) {
|
||||||
|
enter_name_->decIndex();
|
||||||
|
playSound("service_menu_move.wav");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Input::Action::START:
|
case Input::Action::START:
|
||||||
last_enter_name_ = getRecordName();
|
if (isShowingName()) {
|
||||||
|
passShowingName();
|
||||||
|
} else {
|
||||||
|
last_enter_name_ = getRecordName();
|
||||||
|
setPlayingState(Player::State::SHOWING_NAME);
|
||||||
|
playSound("name_input_accept.wav");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -95,67 +95,63 @@ 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);
|
||||||
|
|
||||||
// Guardar referencia a EnterName
|
// Guardar referencia al objeto EnterName
|
||||||
enter_name_ref_.at(idx) = enter_name_ptr;
|
enter_name_ref_.at(idx) = enter_name_ptr;
|
||||||
|
|
||||||
if ((enter_name_ptr == nullptr) || selected_index < 0) {
|
if ((enter_name_ptr == nullptr) || selected_index < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Primera inicialización: posicionar directamente sin animar
|
// ===== Primera inicialización =====
|
||||||
if (carousel_prev_index_.at(idx) == -1) {
|
if (carousel_prev_index_.at(idx) == -1) {
|
||||||
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;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int prev_index = carousel_prev_index_.at(idx);
|
int prev_index = carousel_prev_index_.at(idx);
|
||||||
|
|
||||||
// Si el índice seleccionado no cambia, no hay nada que hacer
|
|
||||||
if (selected_index == prev_index) {
|
if (selected_index == prev_index) {
|
||||||
|
return; // No hay cambio
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== Bloqueo: si aún está animando, ignorar nueva orden =====
|
||||||
|
if (std::abs(carousel_position_.at(idx) - carousel_target_.at(idx)) > 0.01f) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🚫 BLOQUEO: si todavía hay una animación en curso, ignoramos el nuevo movimiento
|
// ===== Calcular el salto =====
|
||||||
if (std::abs(carousel_position_.at(idx) - carousel_target_.at(idx)) > 0.01f) {
|
int delta = selected_index - prev_index;
|
||||||
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 = static_cast<int>(enter_name_ptr->getCharacterList().size());
|
const int LIST_SIZE = static_cast<int>(enter_name_ptr->getCharacterList().size());
|
||||||
|
|
||||||
// Manejar wrap-around circular
|
// Ajustar para wrap-around circular (camino más corto)
|
||||||
if (direction > LIST_SIZE / 2) {
|
if (delta > LIST_SIZE / 2) {
|
||||||
direction = -(LIST_SIZE - direction); // Wrap backward (ej: Z → A)
|
delta -= LIST_SIZE;
|
||||||
} else if (direction < -LIST_SIZE / 2) {
|
} else if (delta < -LIST_SIZE / 2) {
|
||||||
direction = LIST_SIZE + direction; // Wrap forward (ej: A → Z)
|
delta += LIST_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalizar dirección a -1 o +1
|
// ===== Diferenciar salto corto o largo =====
|
||||||
direction = (direction > 0) ? 1 : ((direction < 0) ? -1 : 0);
|
if (std::abs(delta) > 2) {
|
||||||
|
// Salto grande → ir directo sin animación
|
||||||
if (direction != 0) {
|
carousel_position_.at(idx) = static_cast<float>(selected_index);
|
||||||
// Asegurar que partimos de una posición alineada
|
carousel_target_.at(idx) = static_cast<float>(selected_index);
|
||||||
carousel_position_.at(idx) = std::round(carousel_position_.at(idx));
|
} else {
|
||||||
|
// Salto corto → animación suave normal
|
||||||
// Actualizar el nuevo target relativo
|
carousel_position_.at(idx) = std::round(carousel_position_.at(idx));
|
||||||
carousel_target_.at(idx) = carousel_position_.at(idx) + static_cast<float>(direction);
|
carousel_target_.at(idx) = carousel_position_.at(idx) + static_cast<float>(delta);
|
||||||
|
|
||||||
// Guardar el nuevo índice seleccionado
|
|
||||||
carousel_prev_index_.at(idx) = selected_index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actualizar índice actual
|
||||||
|
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) {
|
||||||
auto idx = static_cast<size_t>(id);
|
auto idx = static_cast<size_t>(id);
|
||||||
|
|||||||
@@ -1438,46 +1438,28 @@ void Game::handlePlayerWaitingInput(const std::shared_ptr<Player>& player) {
|
|||||||
// Procesa las entradas para la introducción del nombre del jugador.
|
// Procesa las entradas para la introducción del nombre del jugador.
|
||||||
void Game::handleNameInput(const std::shared_ptr<Player>& player) {
|
void Game::handleNameInput(const std::shared_ptr<Player>& player) {
|
||||||
if (input_->checkAction(Input::Action::FIRE_LEFT, Input::DO_NOT_ALLOW_REPEAT, player->getUsesKeyboard(), player->getGamepad())) {
|
if (input_->checkAction(Input::Action::FIRE_LEFT, Input::DO_NOT_ALLOW_REPEAT, player->getUsesKeyboard(), player->getGamepad())) {
|
||||||
if (player->isShowingName()) {
|
|
||||||
player->passShowingName();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
player->setInput(Input::Action::FIRE_LEFT);
|
player->setInput(Input::Action::FIRE_LEFT);
|
||||||
playSound("service_menu_select.wav");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_->checkAction(Input::Action::FIRE_CENTER, Input::DO_NOT_ALLOW_REPEAT, player->getUsesKeyboard(), player->getGamepad()) ||
|
if (input_->checkAction(Input::Action::FIRE_CENTER, Input::DO_NOT_ALLOW_REPEAT, player->getUsesKeyboard(), player->getGamepad()) ||
|
||||||
input_->checkAction(Input::Action::FIRE_RIGHT, Input::DO_NOT_ALLOW_REPEAT, player->getUsesKeyboard(), player->getGamepad())) {
|
input_->checkAction(Input::Action::FIRE_RIGHT, Input::DO_NOT_ALLOW_REPEAT, player->getUsesKeyboard(), player->getGamepad())) {
|
||||||
if (player->isShowingName()) {
|
|
||||||
player->passShowingName();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
player->setInput(Input::Action::FIRE_CENTER);
|
player->setInput(Input::Action::FIRE_CENTER);
|
||||||
playSound("service_menu_back.wav");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_->checkAction(Input::Action::LEFT, Input::DO_NOT_ALLOW_REPEAT, player->getUsesKeyboard(), player->getGamepad())) {
|
if (input_->checkAction(Input::Action::LEFT, Input::DO_NOT_ALLOW_REPEAT, player->getUsesKeyboard(), player->getGamepad())) {
|
||||||
player->setInput(Input::Action::LEFT);
|
player->setInput(Input::Action::LEFT);
|
||||||
playSound("service_menu_move.wav");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_->checkAction(Input::Action::RIGHT, Input::DO_NOT_ALLOW_REPEAT, player->getUsesKeyboard(), player->getGamepad())) {
|
if (input_->checkAction(Input::Action::RIGHT, Input::DO_NOT_ALLOW_REPEAT, player->getUsesKeyboard(), player->getGamepad())) {
|
||||||
player->setInput(Input::Action::RIGHT);
|
player->setInput(Input::Action::RIGHT);
|
||||||
playSound("service_menu_move.wav");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_->checkAction(Input::Action::START, Input::DO_NOT_ALLOW_REPEAT, player->getUsesKeyboard(), player->getGamepad())) {
|
if (input_->checkAction(Input::Action::START, Input::DO_NOT_ALLOW_REPEAT, player->getUsesKeyboard(), player->getGamepad())) {
|
||||||
if (player->isShowingName()) {
|
|
||||||
player->passShowingName();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
player->setInput(Input::Action::START);
|
player->setInput(Input::Action::START);
|
||||||
player->setPlayingState(Player::State::SHOWING_NAME);
|
|
||||||
playSound("name_input_accept.wav");
|
|
||||||
updateHiScoreName();
|
updateHiScoreName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user