treballant en redefine keys
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
#include "core/rendering/surface.hpp" // Para Surface
|
#include "core/rendering/surface.hpp" // Para Surface
|
||||||
#include "core/rendering/surface_sprite.hpp" // Para SSprite
|
#include "core/rendering/surface_sprite.hpp" // Para SSprite
|
||||||
#include "core/rendering/text.hpp" // Para Text, TEXT_CENTER, TEXT_COLOR
|
#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/resources/resource.hpp" // Para Resource
|
||||||
#include "core/system/global_events.hpp" // Para check
|
#include "core/system/global_events.hpp" // Para check
|
||||||
#include "game/gameplay/cheevos.hpp" // Para Cheevos, Achievement
|
#include "game/gameplay/cheevos.hpp" // Para Cheevos, Achievement
|
||||||
@@ -33,7 +34,9 @@ Title::Title()
|
|||||||
last_active_letter_(0),
|
last_active_letter_(0),
|
||||||
state_time_(0.0F),
|
state_time_(0.0F),
|
||||||
fade_accumulator_(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
|
// Inicializa variables
|
||||||
state_ = SceneManager::options == SceneManager::Options::TITLE_WITH_LOADING_SCREEN ? State::SHOW_LOADING_SCREEN : State::MAIN_MENU;
|
state_ = SceneManager::options == SceneManager::Options::TITLE_WITH_LOADING_SCREEN ? State::SHOW_LOADING_SCREEN : State::MAIN_MENU;
|
||||||
SceneManager::current = SceneManager::Scene::TITLE;
|
SceneManager::current = SceneManager::Scene::TITLE;
|
||||||
@@ -88,6 +91,7 @@ void Title::handleEvents() {
|
|||||||
|
|
||||||
case SDLK_2:
|
case SDLK_2:
|
||||||
transitionToState(State::CONTROLS_MENU);
|
transitionToState(State::CONTROLS_MENU);
|
||||||
|
controls_menu_state_ = ControlsMenuState::MAIN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_3:
|
case SDLK_3:
|
||||||
@@ -99,6 +103,31 @@ void Title::handleEvents() {
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -132,9 +161,12 @@ void Title::handleInput(float delta_time) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case State::CONTROLS_MENU:
|
case State::CONTROLS_MENU:
|
||||||
if (Input::get()->checkAction(InputAction::ACCEPT, Input::DO_NOT_ALLOW_REPEAT) ||
|
// Solo permitir salir si estamos en el menu principal de controles
|
||||||
Input::get()->checkAction(InputAction::CANCEL, Input::DO_NOT_ALLOW_REPEAT)) {
|
if (controls_menu_state_ == ControlsMenuState::MAIN) {
|
||||||
transitionToState(State::MAIN_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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -438,10 +470,16 @@ void Title::renderCheevosMenu() {
|
|||||||
|
|
||||||
// Dibuja el menu de controles
|
// Dibuja el menu de controles
|
||||||
void Title::renderControlsMenu() {
|
void Title::renderControlsMenu() {
|
||||||
const Uint8 COLOR = stringToColor("green");
|
// Delegar al render apropiado segun el subestado
|
||||||
const int TEXT_SIZE = menu_text_->getCharacterSize();
|
if (controls_menu_state_ == ControlsMenuState::KEYBOARD_REMAP) {
|
||||||
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 11 * TEXT_SIZE, "1. REDEFINE KEYBOARD", 1, COLOR);
|
renderKeyboardRemap();
|
||||||
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 13 * TEXT_SIZE, "2. REDEFINE JOYSTICK", 1, COLOR);
|
} 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
|
// Dibuja los elementos en la surface
|
||||||
@@ -485,4 +523,132 @@ void Title::fillTitleSurface() {
|
|||||||
|
|
||||||
// Deja el renderizador como estaba
|
// Deja el renderizador como estaba
|
||||||
Screen::get()->setRendererSurface(previuos_renderer);
|
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);
|
||||||
}
|
}
|
||||||
@@ -40,6 +40,12 @@ class Title {
|
|||||||
POST_FADE_MENU,
|
POST_FADE_MENU,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ControlsMenuState {
|
||||||
|
MAIN, // Mostrar menu principal de controles
|
||||||
|
KEYBOARD_REMAP, // Redefinir teclas del teclado
|
||||||
|
JOYSTICK_REMAP, // Redefinir botones del joystick (futuro)
|
||||||
|
};
|
||||||
|
|
||||||
// --- Constantes de tiempo (en segundos) ---
|
// --- Constantes de tiempo (en segundos) ---
|
||||||
static constexpr float SHOW_LOADING_DURATION = 5.0F; // Tiempo mostrando loading screen (antes 500 frames)
|
static constexpr float SHOW_LOADING_DURATION = 5.0F; // Tiempo mostrando loading screen (antes 500 frames)
|
||||||
static constexpr float FADE_STEP_INTERVAL = 0.05F; // Intervalo entre pasos de fade (antes cada 4 frames)
|
static constexpr float FADE_STEP_INTERVAL = 0.05F; // Intervalo entre pasos de fade (antes cada 4 frames)
|
||||||
@@ -77,6 +83,12 @@ class Title {
|
|||||||
float fade_accumulator_; // Acumulador para controlar el fade por tiempo
|
float fade_accumulator_; // Acumulador para controlar el fade por tiempo
|
||||||
SceneManager::Scene exit_scene_; // Escena de destino al salir del título
|
SceneManager::Scene exit_scene_; // Escena de destino al salir del título
|
||||||
|
|
||||||
|
// --- Variables para redefinir controles ---
|
||||||
|
ControlsMenuState controls_menu_state_; // Subestado del menu de controles
|
||||||
|
int remap_step_; // Paso actual en la redefinicion (0=LEFT, 1=RIGHT, 2=JUMP)
|
||||||
|
SDL_Scancode temp_keys_[3]; // Almacenamiento temporal de teclas capturadas
|
||||||
|
std::string remap_error_message_; // Mensaje de error si la tecla es invalida
|
||||||
|
|
||||||
// --- Funciones ---
|
// --- Funciones ---
|
||||||
void update(); // Actualiza las variables
|
void update(); // Actualiza las variables
|
||||||
void render(); // Dibuja en pantalla
|
void render(); // Dibuja en pantalla
|
||||||
@@ -98,7 +110,13 @@ class Title {
|
|||||||
void renderMainMenu(); // Dibuja el menu principal
|
void renderMainMenu(); // Dibuja el menu principal
|
||||||
void renderCheevosMenu(); // Dibuja el menu de logros
|
void renderCheevosMenu(); // Dibuja el menu de logros
|
||||||
void renderControlsMenu(); // Dibuja el menu de controles
|
void renderControlsMenu(); // Dibuja el menu de controles
|
||||||
|
void renderKeyboardRemap(); // Dibuja la pantalla de redefinir teclado
|
||||||
void moveCheevosList(int direction, float delta_time); // Desplaza la lista de logros (time-based)
|
void moveCheevosList(int direction, float delta_time); // Desplaza la lista de logros (time-based)
|
||||||
|
void handleControlsMenuKeyboardRemap(const SDL_Event& event); // Maneja la captura de teclas
|
||||||
|
bool isKeyValid(SDL_Scancode scancode); // Valida si una tecla es permitida
|
||||||
|
bool isKeyDuplicate(SDL_Scancode scancode, int current_step); // Valida si una tecla esta duplicada
|
||||||
|
void applyKeyboardRemap(); // Aplica y guarda las teclas redefinidas
|
||||||
|
std::string getActionName(int step); // Retorna el nombre de la accion (LEFT/RIGHT/JUMP)
|
||||||
void createCheevosTexture(); // Crea y rellena la surface para mostrar los logros
|
void createCheevosTexture(); // Crea y rellena la surface para mostrar los logros
|
||||||
void resetCheevosScroll(); // Resetea el scroll de la lista de logros
|
void resetCheevosScroll(); // Resetea el scroll de la lista de logros
|
||||||
void fillTitleSurface(); // Dibuja los elementos en la surface
|
void fillTitleSurface(); // Dibuja los elementos en la surface
|
||||||
|
|||||||
Reference in New Issue
Block a user