treballant en redefine keys

This commit is contained in:
2025-11-02 17:31:44 +01:00
parent f7aa6a2b8b
commit 13513384d1
2 changed files with 192 additions and 8 deletions

View File

@@ -11,6 +11,7 @@
#include "core/rendering/surface.hpp" // Para Surface
#include "core/rendering/surface_sprite.hpp" // Para SSprite
#include "core/rendering/text.hpp" // Para Text, TEXT_CENTER, TEXT_COLOR
#include "core/resources/asset.hpp" // Para Asset
#include "core/resources/resource.hpp" // Para Resource
#include "core/system/global_events.hpp" // Para check
#include "game/gameplay/cheevos.hpp" // Para Cheevos, Achievement
@@ -33,7 +34,9 @@ Title::Title()
last_active_letter_(0),
state_time_(0.0F),
fade_accumulator_(0.0F),
exit_scene_(SceneManager::Scene::GAME) {
exit_scene_(SceneManager::Scene::GAME),
controls_menu_state_(ControlsMenuState::MAIN),
remap_step_(0) {
// Inicializa variables
state_ = SceneManager::options == SceneManager::Options::TITLE_WITH_LOADING_SCREEN ? State::SHOW_LOADING_SCREEN : State::MAIN_MENU;
SceneManager::current = SceneManager::Scene::TITLE;
@@ -88,6 +91,7 @@ void Title::handleEvents() {
case SDLK_2:
transitionToState(State::CONTROLS_MENU);
controls_menu_state_ = ControlsMenuState::MAIN;
break;
case SDLK_3:
@@ -99,6 +103,31 @@ void Title::handleEvents() {
}
break;
case State::CONTROLS_MENU:
if (controls_menu_state_ == ControlsMenuState::MAIN) {
// Menu principal de controles
switch (event.key.key) {
case SDLK_1:
// Iniciar redefinicion de teclado
controls_menu_state_ = ControlsMenuState::KEYBOARD_REMAP;
remap_step_ = 0;
remap_error_message_.clear();
break;
case SDLK_2:
// Redefinir joystick (futuro)
// controls_menu_state_ = ControlsMenuState::JOYSTICK_REMAP;
break;
default:
break;
}
} else if (controls_menu_state_ == ControlsMenuState::KEYBOARD_REMAP) {
// Captura de teclas para redefinir
handleControlsMenuKeyboardRemap(event);
}
break;
default:
break;
}
@@ -132,9 +161,12 @@ void Title::handleInput(float delta_time) {
break;
case State::CONTROLS_MENU:
if (Input::get()->checkAction(InputAction::ACCEPT, Input::DO_NOT_ALLOW_REPEAT) ||
Input::get()->checkAction(InputAction::CANCEL, Input::DO_NOT_ALLOW_REPEAT)) {
transitionToState(State::MAIN_MENU);
// Solo permitir salir si estamos en el menu principal de controles
if (controls_menu_state_ == ControlsMenuState::MAIN) {
if (Input::get()->checkAction(InputAction::ACCEPT, Input::DO_NOT_ALLOW_REPEAT) ||
Input::get()->checkAction(InputAction::CANCEL, Input::DO_NOT_ALLOW_REPEAT)) {
transitionToState(State::MAIN_MENU);
}
}
break;
@@ -438,10 +470,16 @@ void Title::renderCheevosMenu() {
// Dibuja el menu de controles
void Title::renderControlsMenu() {
const Uint8 COLOR = stringToColor("green");
const int TEXT_SIZE = menu_text_->getCharacterSize();
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 11 * TEXT_SIZE, "1. REDEFINE KEYBOARD", 1, COLOR);
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 13 * TEXT_SIZE, "2. REDEFINE JOYSTICK", 1, COLOR);
// Delegar al render apropiado segun el subestado
if (controls_menu_state_ == ControlsMenuState::KEYBOARD_REMAP) {
renderKeyboardRemap();
} else {
// Menu principal de controles
const Uint8 COLOR = stringToColor("green");
const int TEXT_SIZE = menu_text_->getCharacterSize();
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 11 * TEXT_SIZE, "1. REDEFINE KEYBOARD", 1, COLOR);
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 13 * TEXT_SIZE, "2. REDEFINE JOYSTICK", 1, COLOR);
}
}
// Dibuja los elementos en la surface
@@ -485,4 +523,132 @@ void Title::fillTitleSurface() {
// Deja el renderizador como estaba
Screen::get()->setRendererSurface(previuos_renderer);
}
// Maneja la captura de teclas para redefinir el teclado
void Title::handleControlsMenuKeyboardRemap(const SDL_Event& event) {
SDL_Scancode scancode = event.key.scancode;
// Si presiona ESC, cancela y vuelve al menu principal de controles
if (scancode == SDL_SCANCODE_ESCAPE) {
controls_menu_state_ = ControlsMenuState::MAIN;
remap_error_message_.clear();
return;
}
// Valida la tecla
if (!isKeyValid(scancode)) {
remap_error_message_ = "INVALID KEY! TRY ANOTHER";
return;
}
// Verifica duplicados
if (isKeyDuplicate(scancode, remap_step_)) {
remap_error_message_ = "KEY ALREADY USED! TRY ANOTHER";
return;
}
// Tecla valida, guardar
temp_keys_[remap_step_] = scancode;
remap_error_message_.clear();
remap_step_++;
// Si completamos los 3 pasos, aplicar y guardar
if (remap_step_ >= 3) {
applyKeyboardRemap();
controls_menu_state_ = ControlsMenuState::MAIN;
}
}
// Valida si una tecla es permitida
bool Title::isKeyValid(SDL_Scancode scancode) {
// Prohibir ESC (reservado para cancelar)
if (scancode == SDL_SCANCODE_ESCAPE) {
return false;
}
// Prohibir teclas F1-F12 (reservadas para funciones del sistema)
if (scancode >= SDL_SCANCODE_F1 && scancode <= SDL_SCANCODE_F12) {
return false;
}
// Prohibir Enter/Return (reservado para confirmaciones)
if (scancode == SDL_SCANCODE_RETURN || scancode == SDL_SCANCODE_RETURN2) {
return false;
}
return true;
}
// Verifica si una tecla ya fue usada en pasos anteriores
bool Title::isKeyDuplicate(SDL_Scancode scancode, int current_step) {
for (int i = 0; i < current_step; i++) {
if (temp_keys_[i] == scancode) {
return true;
}
}
return false;
}
// Retorna el nombre de la accion para el paso actual
std::string Title::getActionName(int step) {
switch (step) {
case 0:
return "LEFT";
case 1:
return "RIGHT";
case 2:
return "JUMP";
default:
return "UNKNOWN";
}
}
// Aplica y guarda las teclas redefinidas
void Title::applyKeyboardRemap() {
// Guardar las nuevas teclas en Options::controls
Options::controls.key_left = temp_keys_[0];
Options::controls.key_right = temp_keys_[1];
Options::controls.key_jump = temp_keys_[2];
// Aplicar los bindings al sistema de Input
Input::get()->applyKeyboardBindingsFromOptions();
// Guardar a archivo de configuracion
Options::saveToFile(Asset::get()->get("config.txt"));
}
// Dibuja la pantalla de redefinir teclado
void Title::renderKeyboardRemap() {
const Uint8 COLOR = stringToColor("green");
const Uint8 ERROR_COLOR = stringToColor("red");
const int TEXT_SIZE = menu_text_->getCharacterSize();
// Titulo
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 9 * TEXT_SIZE, "REDEFINE KEYBOARD", 1, COLOR);
// Mensaje principal: "PRESS KEY FOR [ACTION]"
const std::string ACTION = getActionName(remap_step_);
const std::string MESSAGE = "PRESS KEY FOR " + ACTION;
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 12 * TEXT_SIZE, MESSAGE, 1, COLOR);
// Mostrar teclas ya capturadas
if (remap_step_ > 0) {
const std::string LEFT_KEY = SDL_GetScancodeName(temp_keys_[0]);
const std::string LEFT_MSG = "LEFT: " + LEFT_KEY;
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 14 * TEXT_SIZE, LEFT_MSG, 1, COLOR);
}
if (remap_step_ > 1) {
const std::string RIGHT_KEY = SDL_GetScancodeName(temp_keys_[1]);
const std::string RIGHT_MSG = "RIGHT: " + RIGHT_KEY;
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 15 * TEXT_SIZE, RIGHT_MSG, 1, COLOR);
}
// Mensaje de error si existe
if (!remap_error_message_.empty()) {
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 17 * TEXT_SIZE, remap_error_message_, 1, ERROR_COLOR);
}
// Instrucciones para cancelar
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 19 * TEXT_SIZE, "(ESC TO CANCEL)", 1, COLOR);
}