From 3421f34a84813a99ced5a1576b3779ed4c677473 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 16 May 2026 15:49:21 +0200 Subject: [PATCH] treball en curs: correccions de tidy --- source/core/input/global_inputs.cpp | 12 +- source/core/input/input.cpp | 335 ++++++++++--------- source/core/input/input.h | 169 +++++----- source/core/input/mouse.cpp | 22 +- source/core/input/mouse.hpp | 6 +- source/core/rendering/screen.cpp | 6 +- source/core/system/director.cpp | 54 ++-- source/game/entities/player.cpp | 10 +- source/game/game.cpp | 478 +++++++++++++++------------- source/game/game.h | 18 ++ source/game/options.cpp | 10 +- source/game/scenes/instructions.cpp | 4 +- source/game/scenes/intro.cpp | 4 +- source/game/scenes/logo.cpp | 4 +- source/game/scenes/title.cpp | 20 +- source/game/ui/menu.cpp | 8 +- source/utils/utils.cpp | 140 ++++---- source/utils/utils.h | 9 +- 18 files changed, 658 insertions(+), 651 deletions(-) diff --git a/source/core/input/global_inputs.cpp b/source/core/input/global_inputs.cpp index 0cd469b..b148cf8 100644 --- a/source/core/input/global_inputs.cpp +++ b/source/core/input/global_inputs.cpp @@ -8,29 +8,29 @@ namespace GlobalInputs { auto handle() -> bool { if (Screen::get() == nullptr || Input::get() == nullptr) { return false; } - if (Input::get()->checkInput(input_window_fullscreen, REPEAT_FALSE)) { + if (Input::get()->checkInput(WINDOW_FULLSCREEN, REPEAT_FALSE)) { Screen::get()->toggleVideoMode(); return true; } - if (Input::get()->checkInput(input_window_dec_size, REPEAT_FALSE)) { + if (Input::get()->checkInput(WINDOW_DEC_ZOOM, REPEAT_FALSE)) { Screen::get()->decWindowZoom(); return true; } - if (Input::get()->checkInput(input_window_inc_size, REPEAT_FALSE)) { + if (Input::get()->checkInput(WINDOW_INC_ZOOM, REPEAT_FALSE)) { Screen::get()->incWindowZoom(); return true; } - if (Input::get()->checkInput(input_toggle_shader, REPEAT_FALSE)) { + if (Input::get()->checkInput(TOGGLE_SHADER, REPEAT_FALSE)) { Screen::get()->toggleShaderEnabled(); return true; } // F5/F6 només actuen quan el post-procesado està actiu. if (Screen::get()->isShaderEnabled()) { - if (Input::get()->checkInput(input_toggle_shader_type, REPEAT_FALSE)) { + if (Input::get()->checkInput(TOGGLE_SHADER_TYPE, REPEAT_FALSE)) { Screen::get()->toggleActiveShader(); return true; } - if (Input::get()->checkInput(input_next_preset, REPEAT_FALSE)) { + if (Input::get()->checkInput(NEXT_SHADER_PRESET, REPEAT_FALSE)) { Screen::get()->nextPreset(); return true; } diff --git a/source/core/input/input.cpp b/source/core/input/input.cpp index 65d9217..bedb2f8 100644 --- a/source/core/input/input.cpp +++ b/source/core/input/input.cpp @@ -45,8 +45,8 @@ static void installWebStandardMapping(SDL_JoystickID jid) { Input *Input::instance = nullptr; // Singleton API -void Input::init(const std::string &gameControllerDbPath) { - Input::instance = new Input(gameControllerDbPath); +void Input::init(const std::string &game_controller_db_path) { + Input::instance = new Input(game_controller_db_path); } void Input::destroy() { @@ -60,111 +60,99 @@ auto Input::get() -> Input * { // Constructor Input::Input(std::string file) - : dbPath(std::move(file)) { + : db_path_(std::move(file)) { // Inicializa las variables KeyBindings kb; kb.scancode = 0; kb.active = false; - keyBindings.resize(input_number_of_inputs, kb); + key_bindings_.resize(NUMBER_OF_INPUTS, kb); GameControllerBindings gcb; gcb.button = SDL_GAMEPAD_BUTTON_INVALID; gcb.active = false; - gameControllerBindings.resize(input_number_of_inputs, gcb); + game_controller_bindings_.resize(NUMBER_OF_INPUTS, gcb); } // Destructor Input::~Input() { - for (auto *pad : connectedControllers) { + for (auto *pad : connected_controllers_) { if (pad != nullptr) { SDL_CloseGamepad(pad); } } - connectedControllers.clear(); - connectedControllerIds.clear(); - controllerNames.clear(); - numGamepads = 0; + connected_controllers_.clear(); + connected_controller_ids_.clear(); + controller_names_.clear(); + num_gamepads_ = 0; } // Actualiza el estado del objeto void Input::update() { - if (disabledUntil == d_keyPressed && !checkAnyInput()) { + if (disabled_until_ == KEY_PRESSED && !checkAnyInput()) { enable(); } } // Asigna inputs a teclas void Input::bindKey(Uint8 input, SDL_Scancode code) { - keyBindings[input].scancode = code; + key_bindings_[input].scancode = code; } // Asigna inputs a botones del mando void Input::bindGameControllerButton(Uint8 input, SDL_GamepadButton button) { - gameControllerBindings[input].button = button; + game_controller_bindings_[input].button = button; } // Comprueba si un input esta activo auto Input::checkInput(Uint8 input, bool repeat, int device, int index) -> bool { - if (!enabled) { + if (!enabled_) { return false; } - bool successKeyboard = false; - bool successGameController = false; - if (device == INPUT_USE_ANY) { index = 0; } + bool success_keyboard = false; if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY) { - const bool *keyStates = SDL_GetKeyboardState(nullptr); - - if (repeat) { - successKeyboard = keyStates[keyBindings[input].scancode]; - } else { - if (!keyBindings[input].active) { - if (keyStates[keyBindings[input].scancode]) { - keyBindings[input].active = true; - successKeyboard = true; - } else { - successKeyboard = false; - } - } else { - if (!keyStates[keyBindings[input].scancode]) { - keyBindings[input].active = false; - successKeyboard = false; - } else { - successKeyboard = false; - } - } - } + success_keyboard = checkKeyboardInput(input, repeat); } - if (gameControllerFound() && index >= 0 && index < (int)connectedControllers.size()) { - if ((device == INPUT_USE_GAMECONTROLLER) || (device == INPUT_USE_ANY)) { - if (repeat) { - successGameController = SDL_GetGamepadButton(connectedControllers[index], gameControllerBindings[input].button); - } else { - if (!gameControllerBindings[input].active) { - if (SDL_GetGamepadButton(connectedControllers[index], gameControllerBindings[input].button)) { - gameControllerBindings[input].active = true; - successGameController = true; - } else { - successGameController = false; - } - } else { - if (!SDL_GetGamepadButton(connectedControllers[index], gameControllerBindings[input].button)) { - gameControllerBindings[input].active = false; - successGameController = false; - } else { - successGameController = false; - } - } - } - } + bool success_game_controller = false; + if ((device == INPUT_USE_GAMECONTROLLER || device == INPUT_USE_ANY) && gameControllerFound() && index >= 0 && index < (int)connected_controllers_.size()) { + success_game_controller = checkGameControllerInput(input, repeat, index); } - return (successKeyboard || successGameController); + return success_keyboard || success_game_controller; +} + +// Helper de checkInput: comprueba el estado de una tecla +auto Input::checkKeyboardInput(Uint8 input, bool repeat) -> bool { + const bool *key_states = SDL_GetKeyboardState(nullptr); + const bool IS_DOWN = key_states[key_bindings_[input].scancode]; + + if (repeat) { + return IS_DOWN; + } + + // Modo edge-trigger: éxito sólo en el frame en que la tecla pasa de up a down + const bool PRESS_EDGE = IS_DOWN && !key_bindings_[input].active; + key_bindings_[input].active = IS_DOWN; + return PRESS_EDGE; +} + +// Helper de checkInput: comprueba el estado de un botón de mando +auto Input::checkGameControllerInput(Uint8 input, bool repeat, int index) -> bool { + const bool IS_DOWN = SDL_GetGamepadButton(connected_controllers_[index], game_controller_bindings_[input].button); + + if (repeat) { + return IS_DOWN; + } + + // Modo edge-trigger: éxito sólo en el frame en que el botón pasa de up a down + const bool PRESS_EDGE = IS_DOWN && !game_controller_bindings_[input].active; + game_controller_bindings_[input].active = IS_DOWN; + return PRESS_EDGE; } // Comprueba si hay almenos un input activo @@ -174,19 +162,19 @@ auto Input::checkAnyInput(int device, int index) -> bool { } if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY) { - const bool *mKeystates = SDL_GetKeyboardState(nullptr); + const bool *key_states = SDL_GetKeyboardState(nullptr); - for (auto &keyBinding : keyBindings) { - if (mKeystates[keyBinding.scancode]) { + for (auto &key_binding : key_bindings_) { + if (key_states[key_binding.scancode]) { return true; } } } - if (gameControllerFound() && index >= 0 && index < (int)connectedControllers.size()) { + if (gameControllerFound() && index >= 0 && index < (int)connected_controllers_.size()) { if (device == INPUT_USE_GAMECONTROLLER || device == INPUT_USE_ANY) { - for (auto &gameControllerBinding : gameControllerBindings) { - if (SDL_GetGamepadButton(connectedControllers[index], gameControllerBinding.button)) { + for (auto &game_controller_binding : game_controller_bindings_) { + if (SDL_GetGamepadButton(connected_controllers_[index], game_controller_binding.button)) { return true; } } @@ -199,13 +187,13 @@ auto Input::checkAnyInput(int device, int index) -> bool { // Construye el nombre visible de un mando. // Recorta des del primer '(' o '[' (per a evitar coses tipus // "Retroid Controller (vendor: 1001) ...") i talla a 25 caràcters. -auto Input::buildControllerName(SDL_Gamepad *pad, int padIndex) -> std::string { - (void)padIndex; - const char *padName = SDL_GetGamepadName(pad); - std::string name = (padName != nullptr) ? padName : "Unknown"; - const auto pos = name.find_first_of("(["); - if (pos != std::string::npos) { - name.erase(pos); +auto Input::buildControllerName(SDL_Gamepad *pad, int pad_index) -> std::string { + (void)pad_index; + const char *pad_name = SDL_GetGamepadName(pad); + std::string name = (pad_name != nullptr) ? pad_name : "Unknown"; + const auto POS = name.find_first_of("(["); + if (POS != std::string::npos) { + name.erase(POS); } while (!name.empty() && name.back() == ' ') { name.pop_back(); @@ -219,136 +207,145 @@ auto Input::buildControllerName(SDL_Gamepad *pad, int padIndex) -> std::string { // Busca si hay un mando conectado. Cierra y limpia el estado previo para // que la función sea idempotente si se invoca más de una vez. auto Input::discoverGameController() -> bool { - // Cierra los mandos ya abiertos y limpia los vectores paralelos - for (auto *pad : connectedControllers) { + resetGameControllerState(); + ensureGamepadSubsystem(); + + int num_joysticks = 0; + SDL_JoystickID *joysticks = SDL_GetJoysticks(&num_joysticks); + if (joysticks == nullptr) { + return false; + } + + int gamepad_count = 0; + for (int i = 0; i < num_joysticks; ++i) { + if (SDL_IsGamepad(joysticks[i])) { + gamepad_count++; + } + } + + if (verbose_) { + std::cout << "\nChecking for game controllers...\n"; + std::cout << num_joysticks << " joysticks found, " << gamepad_count << " are gamepads\n"; + } + + bool found = false; + if (gamepad_count > 0) { + found = true; + int pad_index = 0; + for (int i = 0; i < num_joysticks; i++) { + if (!SDL_IsGamepad(joysticks[i])) { + continue; + } + if (openGamepad(joysticks[i], pad_index)) { + pad_index++; + } + } + SDL_SetGamepadEventsEnabled(true); + } + + SDL_free(joysticks); + return found; +} + +// Helper de discoverGameController: cierra mandos previos y limpia vectores paralelos +void Input::resetGameControllerState() { + for (auto *pad : connected_controllers_) { if (pad != nullptr) { SDL_CloseGamepad(pad); } } - connectedControllers.clear(); - connectedControllerIds.clear(); - controllerNames.clear(); - numGamepads = 0; - - bool found = false; + connected_controllers_.clear(); + connected_controller_ids_.clear(); + controller_names_.clear(); + num_gamepads_ = 0; +} +// Helper de discoverGameController: inicializa el subsystem de gamepad y carga el mapping +void Input::ensureGamepadSubsystem() { if (SDL_WasInit(SDL_INIT_GAMEPAD) != SDL_INIT_GAMEPAD) { SDL_InitSubSystem(SDL_INIT_GAMEPAD); } + if (SDL_AddGamepadMappingsFromFile(db_path_.c_str()) < 0 && verbose_) { + std::cout << "Error, could not load " << db_path_.c_str() << " file: " << SDL_GetError() << '\n'; + } +} - if (SDL_AddGamepadMappingsFromFile(dbPath.c_str()) < 0) { - if (verbose) { - std::cout << "Error, could not load " << dbPath.c_str() << " file: " << SDL_GetError() << '\n'; +// Helper de discoverGameController: abre y registra un mando. Devuelve true si tuvo éxito. +auto Input::openGamepad(SDL_JoystickID joystick_id, int pad_index) -> bool { + installWebStandardMapping(joystick_id); + SDL_Gamepad *pad = SDL_OpenGamepad(joystick_id); + if (pad == nullptr) { + if (verbose_) { + std::cout << "SDL_GetError() = " << SDL_GetError() << '\n'; } + return false; } - int nJoysticks = 0; - SDL_JoystickID *joysticks = SDL_GetJoysticks(&nJoysticks); - - if (joysticks != nullptr) { - int gamepadCount = 0; - for (int i = 0; i < nJoysticks; ++i) { - if (SDL_IsGamepad(joysticks[i])) { - gamepadCount++; - } - } - - if (verbose) { - std::cout << "\nChecking for game controllers...\n"; - std::cout << nJoysticks << " joysticks found, " << gamepadCount << " are gamepads\n"; - } - - if (gamepadCount > 0) { - found = true; - int padIndex = 0; - - for (int i = 0; i < nJoysticks; i++) { - if (!SDL_IsGamepad(joysticks[i])) { - continue; - } - - installWebStandardMapping(joysticks[i]); - SDL_Gamepad *pad = SDL_OpenGamepad(joysticks[i]); - if (pad != nullptr) { - const std::string name = buildControllerName(pad, padIndex); - connectedControllers.push_back(pad); - connectedControllerIds.push_back(joysticks[i]); - controllerNames.push_back(name); - numGamepads++; - padIndex++; - if (verbose) { - std::cout << name << '\n'; - } - } else { - if (verbose) { - std::cout << "SDL_GetError() = " << SDL_GetError() << '\n'; - } - } - } - - SDL_SetGamepadEventsEnabled(true); - } - - SDL_free(joysticks); + const std::string NAME = buildControllerName(pad, pad_index); + connected_controllers_.push_back(pad); + connected_controller_ids_.push_back(joystick_id); + controller_names_.push_back(NAME); + num_gamepads_++; + if (verbose_) { + std::cout << NAME << '\n'; } - - return found; + return true; } // Procesa un evento SDL_EVENT_GAMEPAD_ADDED -auto Input::handleGamepadAdded(SDL_JoystickID jid, std::string &outName) -> bool { +auto Input::handleGamepadAdded(SDL_JoystickID jid, std::string &out_name) -> bool { if (!SDL_IsGamepad(jid)) { return false; } // Si el mando ya está registrado no hace nada (ej. evento retroactivo tras el scan inicial) - if (std::ranges::any_of(connectedControllerIds, [jid](SDL_JoystickID existing) { return existing == jid; })) { + if (std::ranges::any_of(connected_controller_ids_, [jid](SDL_JoystickID existing) { return existing == jid; })) { return false; } installWebStandardMapping(jid); SDL_Gamepad *pad = SDL_OpenGamepad(jid); if (pad == nullptr) { - if (verbose) { + if (verbose_) { std::cout << "Failed to open gamepad " << jid << ": " << SDL_GetError() << '\n'; } return false; } - const int padIndex = (int)connectedControllers.size(); - const std::string name = buildControllerName(pad, padIndex); - connectedControllers.push_back(pad); - connectedControllerIds.push_back(jid); - controllerNames.push_back(name); - numGamepads++; + const int PAD_INDEX = (int)connected_controllers_.size(); + const std::string NAME = buildControllerName(pad, PAD_INDEX); + connected_controllers_.push_back(pad); + connected_controller_ids_.push_back(jid); + controller_names_.push_back(NAME); + num_gamepads_++; - if (verbose) { - std::cout << "Gamepad connected: " << name << '\n'; + if (verbose_) { + std::cout << "Gamepad connected: " << NAME << '\n'; } - outName = name; + out_name = NAME; return true; } // Procesa un evento SDL_EVENT_GAMEPAD_REMOVED -auto Input::handleGamepadRemoved(SDL_JoystickID jid, std::string &outName) -> bool { - for (size_t i = 0; i < connectedControllerIds.size(); ++i) { - if (connectedControllerIds[i] != jid) { +auto Input::handleGamepadRemoved(SDL_JoystickID jid, std::string &out_name) -> bool { + for (size_t i = 0; i < connected_controller_ids_.size(); ++i) { + if (connected_controller_ids_[i] != jid) { continue; } - outName = controllerNames[i]; - if (connectedControllers[i] != nullptr) { - SDL_CloseGamepad(connectedControllers[i]); + out_name = controller_names_[i]; + if (connected_controllers_[i] != nullptr) { + SDL_CloseGamepad(connected_controllers_[i]); } - connectedControllers.erase(connectedControllers.begin() + i); - connectedControllerIds.erase(connectedControllerIds.begin() + i); - controllerNames.erase(controllerNames.begin() + i); - numGamepads--; - numGamepads = std::max(numGamepads, 0); + connected_controllers_.erase(connected_controllers_.begin() + i); + connected_controller_ids_.erase(connected_controller_ids_.begin() + i); + controller_names_.erase(controller_names_.begin() + i); + num_gamepads_--; + num_gamepads_ = std::max(num_gamepads_, 0); - if (verbose) { - std::cout << "Gamepad disconnected: " << outName << '\n'; + if (verbose_) { + std::cout << "Gamepad disconnected: " << out_name << '\n'; } return true; @@ -358,35 +355,35 @@ auto Input::handleGamepadRemoved(SDL_JoystickID jid, std::string &outName) -> bo // Comprueba si hay algun mando conectado auto Input::gameControllerFound() const -> bool { - return numGamepads > 0; + return num_gamepads_ > 0; } // Obten el nombre de un mando de juego auto Input::getControllerName(int index) -> std::string { - if (numGamepads > 0) { - return controllerNames[index]; + if (num_gamepads_ > 0) { + return controller_names_[index]; } return ""; } // Obten el numero de mandos conectados auto Input::getNumControllers() const -> int { - return numGamepads; + return num_gamepads_; } // Establece si ha de mostrar mensajes void Input::setVerbose(bool value) { - verbose = value; + verbose_ = value; } // Deshabilita las entradas durante un periodo de tiempo void Input::disableUntil(InputDisable value) { - disabledUntil = value; - enabled = false; + disabled_until_ = value; + enabled_ = false; } // Hablita las entradas void Input::enable() { - enabled = true; - disabledUntil = d_notDisabled; + enabled_ = true; + disabled_until_ = NOT_DISABLED; } diff --git a/source/core/input/input.h b/source/core/input/input.h index 6abe620..3ddcbbe 100644 --- a/source/core/input/input.h +++ b/source/core/input/input.h @@ -17,40 +17,73 @@ constexpr int INPUT_USE_ANY = 2; enum InputAction : std::uint8_t { // Inputs obligatorios - input_null, - input_up, - input_down, - input_left, - input_right, - input_pause, - input_exit, - input_accept, - input_cancel, + INVALID, + UP, + DOWN, + LEFT, + RIGHT, + PAUSE, + EXIT, + ACCEPT, + CANCEL, // Inputs personalizados - input_fire_left, - input_fire_center, - input_fire_right, - input_window_fullscreen, - input_window_inc_size, - input_window_dec_size, + FIRE_LEFT, + FIRE_CENTER, + FIRE_RIGHT, + WINDOW_FULLSCREEN, + WINDOW_INC_ZOOM, + WINDOW_DEC_ZOOM, // GPU / shaders (hotkeys provisionales hasta que haya menú de opciones) - input_next_preset, - input_toggle_shader, - input_toggle_shader_type, + NEXT_SHADER_PRESET, + TOGGLE_SHADER, + TOGGLE_SHADER_TYPE, // Input obligatorio - input_number_of_inputs + NUMBER_OF_INPUTS }; enum InputDisable : std::uint8_t { - d_notDisabled, - d_forever, - d_keyPressed + NOT_DISABLED, + FOREVER, + KEY_PRESSED }; class Input { + public: + // Singleton API + static void init(const std::string &game_controller_db_path); // Crea la instancia + static void destroy(); // Libera la instancia + static auto get() -> Input *; // Obtiene el puntero a la instancia + + ~Input(); // Destructor + + void update(); // Actualiza el estado del objeto + void bindKey(Uint8 input, SDL_Scancode code); // Asigna inputs a teclas + void bindGameControllerButton(Uint8 input, SDL_GamepadButton button); // Asigna inputs a botones del mando + + auto checkInput(Uint8 input, bool repeat = true, int device = INPUT_USE_ANY, int index = 0) -> bool; // Comprueba si un input esta activo + auto checkAnyInput(int device = INPUT_USE_ANY, int index = 0) -> bool; // Comprueba si hay almenos un input activo + + auto discoverGameController() -> bool; // Busca si hay un mando conectado + + // Procesa un evento SDL_EVENT_GAMEPAD_ADDED. Devuelve true si el mando se ha añadido + // (no estaba ya registrado) y escribe el nombre visible en outName. + auto handleGamepadAdded(SDL_JoystickID jid, std::string &out_name) -> bool; + + // Procesa un evento SDL_EVENT_GAMEPAD_REMOVED. Devuelve true si se ha encontrado y + // eliminado, y escribe el nombre visible en outName. + auto handleGamepadRemoved(SDL_JoystickID jid, std::string &out_name) -> bool; + + [[nodiscard]] auto gameControllerFound() const -> bool; // Comprueba si hay algun mando conectado + [[nodiscard]] auto getNumControllers() const -> int; // Obten el numero de mandos conectados + auto getControllerName(int index) -> std::string; // Obten el nombre de un mando de juego + + void setVerbose(bool value); // Establece si ha de mostrar mensajes + void disableUntil(InputDisable value); // Deshabilita las entradas durante un periodo de tiempo + void enable(); // Hablita las entradas + private: struct KeyBindings { Uint8 scancode; // Scancode asociado @@ -63,78 +96,32 @@ class Input { }; // Objetos y punteros - std::vector connectedControllers; // Vector con todos los mandos conectados - std::vector connectedControllerIds; // Instance IDs paralelos para mapear eventos + std::vector connected_controllers_; // Vector con todos los mandos conectados + std::vector connected_controller_ids_; // Instance IDs paralelos para mapear eventos // Variables - std::vector keyBindings; // Vector con las teclas asociadas a los inputs predefinidos - std::vector gameControllerBindings; // Vector con las teclas asociadas a los inputs predefinidos - std::vector controllerNames; // Vector con los nombres de los mandos - int numGamepads{0}; // Numero de mandos conectados - std::string dbPath; // Ruta al archivo gamecontrollerdb.txt - bool verbose{true}; // Indica si ha de mostrar mensajes - InputDisable disabledUntil{d_notDisabled}; // Tiempo que esta deshabilitado - bool enabled{true}; // Indica si está habilitado + std::vector key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos + std::vector game_controller_bindings_; // Vector con las teclas asociadas a los inputs predefinidos + std::vector controller_names_; // Vector con los nombres de los mandos + int num_gamepads_{0}; // Numero de mandos conectados + std::string db_path_; // Ruta al archivo gamecontrollerdb.txt + bool verbose_{true}; // Indica si ha de mostrar mensajes + InputDisable disabled_until_{NOT_DISABLED}; // Tiempo que esta deshabilitado + bool enabled_{true}; // Indica si está habilitado + + static Input *instance; // Instancia única + + explicit Input(std::string file); // Constructor privado (usar Input::init) // Construye el nombre visible de un mando (name truncado + sufijo #N) - static auto buildControllerName(SDL_Gamepad *pad, int padIndex) -> std::string; + static auto buildControllerName(SDL_Gamepad *pad, int pad_index) -> std::string; - // Constructor privado (usar Input::init) - explicit Input(std::string file); + // Helpers de checkInput + auto checkKeyboardInput(Uint8 input, bool repeat) -> bool; + auto checkGameControllerInput(Uint8 input, bool repeat, int index) -> bool; - // Instancia única - static Input *instance; - - public: - // Singleton API - static void init(const std::string &gameControllerDbPath); // Crea la instancia - static void destroy(); // Libera la instancia - static auto get() -> Input *; // Obtiene el puntero a la instancia - - // Destructor - ~Input(); - - // Actualiza el estado del objeto - void update(); - - // Asigna inputs a teclas - void bindKey(Uint8 input, SDL_Scancode code); - - // Asigna inputs a botones del mando - void bindGameControllerButton(Uint8 input, SDL_GamepadButton button); - - // Comprueba si un input esta activo - auto checkInput(Uint8 input, bool repeat = true, int device = INPUT_USE_ANY, int index = 0) -> bool; - - // Comprueba si hay almenos un input activo - auto checkAnyInput(int device = INPUT_USE_ANY, int index = 0) -> bool; - - // Busca si hay un mando conectado - auto discoverGameController() -> bool; - - // Procesa un evento SDL_EVENT_GAMEPAD_ADDED. Devuelve true si el mando se ha añadido - // (no estaba ya registrado) y escribe el nombre visible en outName. - auto handleGamepadAdded(SDL_JoystickID jid, std::string &outName) -> bool; - - // Procesa un evento SDL_EVENT_GAMEPAD_REMOVED. Devuelve true si se ha encontrado y - // eliminado, y escribe el nombre visible en outName. - auto handleGamepadRemoved(SDL_JoystickID jid, std::string &outName) -> bool; - - // Comprueba si hay algun mando conectado - [[nodiscard]] auto gameControllerFound() const -> bool; - - // Obten el numero de mandos conectados - [[nodiscard]] auto getNumControllers() const -> int; - - // Obten el nombre de un mando de juego - auto getControllerName(int index) -> std::string; - - // Establece si ha de mostrar mensajes - void setVerbose(bool value); - - // Deshabilita las entradas durante un periodo de tiempo - void disableUntil(InputDisable value); - - // Hablita las entradas - void enable(); -}; \ No newline at end of file + // Helpers de discoverGameController + void resetGameControllerState(); + void ensureGamepadSubsystem(); + auto openGamepad(SDL_JoystickID joystick_id, int pad_index) -> bool; +}; diff --git a/source/core/input/mouse.cpp b/source/core/input/mouse.cpp index 38283b2..069015b 100644 --- a/source/core/input/mouse.cpp +++ b/source/core/input/mouse.cpp @@ -1,16 +1,16 @@ #include "core/input/mouse.hpp" namespace Mouse { - Uint32 cursorHideTime = 3000; // Tiempo en milisegundos para ocultar el cursor por inactividad - Uint32 lastMouseMoveTime = 0; // Última vez que el ratón se movió - bool cursorVisible = true; // Estado del cursor + Uint32 cursor_hide_time = 3000; // Tiempo en milisegundos para ocultar el cursor por inactividad + Uint32 last_mouse_move_time = 0; // Última vez que el ratón se movió + bool cursor_visible = true; // Estado del cursor void handleEvent(const SDL_Event &event, bool fullscreen) { if (event.type == SDL_EVENT_MOUSE_MOTION) { - lastMouseMoveTime = SDL_GetTicks(); - if (!cursorVisible && !fullscreen) { + last_mouse_move_time = SDL_GetTicks(); + if (!cursor_visible && !fullscreen) { SDL_ShowCursor(); - cursorVisible = true; + cursor_visible = true; } } } @@ -18,18 +18,18 @@ namespace Mouse { void updateCursorVisibility(bool fullscreen) { // En pantalla completa el cursor siempre está oculto if (fullscreen) { - if (cursorVisible) { + if (cursor_visible) { SDL_HideCursor(); - cursorVisible = false; + cursor_visible = false; } return; } // En modo ventana, lo oculta tras el periodo de inactividad - const Uint32 currentTime = SDL_GetTicks(); - if (cursorVisible && (currentTime - lastMouseMoveTime > cursorHideTime)) { + const Uint32 CURRENT_TIME = SDL_GetTicks(); + if (cursor_visible && (CURRENT_TIME - last_mouse_move_time > cursor_hide_time)) { SDL_HideCursor(); - cursorVisible = false; + cursor_visible = false; } } } // namespace Mouse diff --git a/source/core/input/mouse.hpp b/source/core/input/mouse.hpp index 1af8555..0d75573 100644 --- a/source/core/input/mouse.hpp +++ b/source/core/input/mouse.hpp @@ -3,9 +3,9 @@ #include namespace Mouse { - extern Uint32 cursorHideTime; // Tiempo en milisegundos para ocultar el cursor por inactividad - extern Uint32 lastMouseMoveTime; // Última vez que el ratón se movió - extern bool cursorVisible; // Estado del cursor + extern Uint32 cursor_hide_time; // Tiempo en milisegundos para ocultar el cursor por inactividad + extern Uint32 last_mouse_move_time; // Última vez que el ratón se movió + extern bool cursor_visible; // Estado del cursor // Procesa un evento de ratón. En pantalla completa ignora el movimiento // para no volver a mostrar el cursor. diff --git a/source/core/rendering/screen.cpp b/source/core/rendering/screen.cpp index f32955d..83ed118 100644 --- a/source/core/rendering/screen.cpp +++ b/source/core/rendering/screen.cpp @@ -340,11 +340,11 @@ void Screen::applyFullscreen(bool fullscreen) { SDL_SetWindowFullscreen(window, fullscreen); if (fullscreen) { SDL_HideCursor(); - Mouse::cursorVisible = false; + Mouse::cursor_visible = false; } else { SDL_ShowCursor(); - Mouse::cursorVisible = true; - Mouse::lastMouseMoveTime = SDL_GetTicks(); + Mouse::cursor_visible = true; + Mouse::last_mouse_move_time = SDL_GetTicks(); } } diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 99f2138..11fb3a8 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -210,44 +210,44 @@ void Director::initInput() { Input::get()->discoverGameController(); // Teclado - Movimiento del jugador - Input::get()->bindKey(input_up, SDL_SCANCODE_UP); - Input::get()->bindKey(input_down, SDL_SCANCODE_DOWN); - Input::get()->bindKey(input_left, SDL_SCANCODE_LEFT); - Input::get()->bindKey(input_right, SDL_SCANCODE_RIGHT); - Input::get()->bindKey(input_fire_left, SDL_SCANCODE_Q); - Input::get()->bindKey(input_fire_center, SDL_SCANCODE_W); - Input::get()->bindKey(input_fire_right, SDL_SCANCODE_E); + Input::get()->bindKey(UP, SDL_SCANCODE_UP); + Input::get()->bindKey(DOWN, SDL_SCANCODE_DOWN); + Input::get()->bindKey(LEFT, SDL_SCANCODE_LEFT); + Input::get()->bindKey(RIGHT, SDL_SCANCODE_RIGHT); + Input::get()->bindKey(FIRE_LEFT, SDL_SCANCODE_Q); + Input::get()->bindKey(FIRE_CENTER, SDL_SCANCODE_W); + Input::get()->bindKey(FIRE_RIGHT, SDL_SCANCODE_E); // Teclado - Otros - Input::get()->bindKey(input_accept, SDL_SCANCODE_RETURN); - Input::get()->bindKey(input_cancel, SDL_SCANCODE_ESCAPE); - Input::get()->bindKey(input_pause, SDL_SCANCODE_ESCAPE); - Input::get()->bindKey(input_exit, SDL_SCANCODE_ESCAPE); - Input::get()->bindKey(input_window_dec_size, SDL_SCANCODE_F1); - Input::get()->bindKey(input_window_inc_size, SDL_SCANCODE_F2); - Input::get()->bindKey(input_window_fullscreen, SDL_SCANCODE_F3); - Input::get()->bindKey(input_toggle_shader, SDL_SCANCODE_F4); - Input::get()->bindKey(input_toggle_shader_type, SDL_SCANCODE_F5); - Input::get()->bindKey(input_next_preset, SDL_SCANCODE_F6); + Input::get()->bindKey(ACCEPT, SDL_SCANCODE_RETURN); + Input::get()->bindKey(CANCEL, SDL_SCANCODE_ESCAPE); + Input::get()->bindKey(PAUSE, SDL_SCANCODE_ESCAPE); + Input::get()->bindKey(EXIT, SDL_SCANCODE_ESCAPE); + Input::get()->bindKey(WINDOW_DEC_ZOOM, SDL_SCANCODE_F1); + Input::get()->bindKey(WINDOW_INC_ZOOM, SDL_SCANCODE_F2); + Input::get()->bindKey(WINDOW_FULLSCREEN, SDL_SCANCODE_F3); + Input::get()->bindKey(TOGGLE_SHADER, SDL_SCANCODE_F4); + Input::get()->bindKey(TOGGLE_SHADER_TYPE, SDL_SCANCODE_F5); + Input::get()->bindKey(NEXT_SHADER_PRESET, SDL_SCANCODE_F6); // Mando - Movimiento del jugador - Input::get()->bindGameControllerButton(input_up, SDL_GAMEPAD_BUTTON_DPAD_UP); - Input::get()->bindGameControllerButton(input_down, SDL_GAMEPAD_BUTTON_DPAD_DOWN); - Input::get()->bindGameControllerButton(input_left, SDL_GAMEPAD_BUTTON_DPAD_LEFT); - Input::get()->bindGameControllerButton(input_right, SDL_GAMEPAD_BUTTON_DPAD_RIGHT); - Input::get()->bindGameControllerButton(input_fire_left, SDL_GAMEPAD_BUTTON_WEST); - Input::get()->bindGameControllerButton(input_fire_center, SDL_GAMEPAD_BUTTON_NORTH); - Input::get()->bindGameControllerButton(input_fire_right, SDL_GAMEPAD_BUTTON_EAST); + Input::get()->bindGameControllerButton(UP, SDL_GAMEPAD_BUTTON_DPAD_UP); + Input::get()->bindGameControllerButton(DOWN, SDL_GAMEPAD_BUTTON_DPAD_DOWN); + Input::get()->bindGameControllerButton(LEFT, SDL_GAMEPAD_BUTTON_DPAD_LEFT); + Input::get()->bindGameControllerButton(RIGHT, SDL_GAMEPAD_BUTTON_DPAD_RIGHT); + Input::get()->bindGameControllerButton(FIRE_LEFT, SDL_GAMEPAD_BUTTON_WEST); + Input::get()->bindGameControllerButton(FIRE_CENTER, SDL_GAMEPAD_BUTTON_NORTH); + Input::get()->bindGameControllerButton(FIRE_RIGHT, SDL_GAMEPAD_BUTTON_EAST); // Mando - Otros // SOUTH queda sin asignar para evitar salidas accidentales: pausa/cancel se hace con START/BACK. - Input::get()->bindGameControllerButton(input_accept, SDL_GAMEPAD_BUTTON_EAST); + Input::get()->bindGameControllerButton(ACCEPT, SDL_GAMEPAD_BUTTON_EAST); #ifdef GAME_CONSOLE Input::get()->bindGameControllerButton(input_pause, SDL_GAMEPAD_BUTTON_BACK); Input::get()->bindGameControllerButton(input_exit, SDL_GAMEPAD_BUTTON_START); #else - Input::get()->bindGameControllerButton(input_pause, SDL_GAMEPAD_BUTTON_START); - Input::get()->bindGameControllerButton(input_exit, SDL_GAMEPAD_BUTTON_BACK); + Input::get()->bindGameControllerButton(PAUSE, SDL_GAMEPAD_BUTTON_START); + Input::get()->bindGameControllerButton(EXIT, SDL_GAMEPAD_BUTTON_BACK); #endif } diff --git a/source/game/entities/player.cpp b/source/game/entities/player.cpp index 990ffe6..bcaeea2 100644 --- a/source/game/entities/player.cpp +++ b/source/game/entities/player.cpp @@ -97,25 +97,25 @@ void Player::init() { // Actua en consecuencia de la entrada recibida void Player::setInput(Uint8 input) { switch (input) { - case input_left: + case LEFT: vel_x_ = -base_speed_; setWalkingStatus(STATUS_WALKING_LEFT); break; - case input_right: + case RIGHT: vel_x_ = base_speed_; setWalkingStatus(STATUS_WALKING_RIGHT); break; - case input_fire_center: + case FIRE_CENTER: setFiringStatus(STATUS_FIRING_UP); break; - case input_fire_left: + case FIRE_LEFT: setFiringStatus(STATUS_FIRING_LEFT); break; - case input_fire_right: + case FIRE_RIGHT: setFiringStatus(STATUS_FIRING_RIGHT); break; diff --git a/source/game/game.cpp b/source/game/game.cpp index 177450b..1425613 100644 --- a/source/game/game.cpp +++ b/source/game/game.cpp @@ -29,6 +29,28 @@ #include "game/ui/menu.h" // for Menu struct JA_Sound_t; +namespace { + // Constantes geométricas y temporales compartidas por los helpers de initEnemyFormations + constexpr int Y4 = (PLAY_AREA_TOP - BLOCK); + constexpr int X4_0 = PLAY_AREA_LEFT; + constexpr int X4_100 = PLAY_AREA_RIGHT - Balloon::WIDTH_4; + + constexpr int Y3 = (PLAY_AREA_TOP - BLOCK); + constexpr int X3_0 = PLAY_AREA_LEFT; + constexpr int X3_100 = PLAY_AREA_RIGHT - Balloon::WIDTH_3; + + constexpr int Y2 = (PLAY_AREA_TOP - BLOCK); + constexpr int X2_0 = PLAY_AREA_LEFT; + constexpr int X2_100 = PLAY_AREA_RIGHT - Balloon::WIDTH_2; + + constexpr int Y1 = (PLAY_AREA_TOP - BLOCK); + constexpr int X1_0 = PLAY_AREA_LEFT; + constexpr int X1_50 = PLAY_AREA_CENTER_X - (Balloon::WIDTH_1 / 2); + constexpr int X1_100 = PLAY_AREA_RIGHT - Balloon::WIDTH_1; + + constexpr Uint16 CREATION_TIME = 300; +} // namespace + // Constructor Game::Game(int num_players, int current_stage, SDL_Renderer *renderer, bool demo, Section *section) : last_stage_reached_(current_stage) { @@ -45,8 +67,8 @@ Game::Game(int num_players, int current_stage, SDL_Renderer *renderer, bool demo this->current_stage_ = current_stage; #endif if (num_players == 1) { // Si solo juega un jugador, permite jugar tanto con teclado como con mando - player_one_control_ = Options::inputs[0].deviceType; - Options::inputs[0].deviceType = INPUT_USE_ANY; + player_one_control_ = Options::inputs[0].device_type; + Options::inputs[0].device_type = INPUT_USE_ANY; } difficulty_ = Options::settings.difficulty; @@ -93,7 +115,7 @@ Game::~Game() { // Restaura el metodo de control if (num_players_ == 1) { - Options::inputs[0].deviceType = player_one_control_; + Options::inputs[0].device_type = player_one_control_; } // Elimina todos los objetos contenidos en vectores (jugadores, balas, etc.) @@ -517,10 +539,10 @@ auto Game::loadDemoFile() -> bool { for (auto &i : demo_.data_file) { demo_.keys.left = 0; demo_.keys.right = 0; - demo_.keys.noInput = 0; + demo_.keys.no_input = 0; demo_.keys.fire = 0; - demo_.keys.fireLeft = 0; - demo_.keys.fireRight = 0; + demo_.keys.fire_left = 0; + demo_.keys.fire_right = 0; i = demo_.keys; } } @@ -583,24 +605,14 @@ auto Game::saveDemoFile() -> bool { // Inicializa las formaciones enemigas void Game::initEnemyFormations() { - const int Y4 = (PLAY_AREA_TOP - BLOCK); - const int X4_0 = PLAY_AREA_LEFT; - const int X4_100 = (PLAY_AREA_RIGHT)-Balloon::WIDTH_4; + initEnemyFormationsZero(); + initEnemyFormationsLinear(); + initEnemyFormationsSymmetric(); + initEnemyFormationsHexagonsAndTest(); +} - const int Y3 = (PLAY_AREA_TOP - BLOCK); - const int X3_0 = PLAY_AREA_LEFT; - const int X3_100 = (PLAY_AREA_RIGHT)-Balloon::WIDTH_3; - - const int Y2 = (PLAY_AREA_TOP - BLOCK); - const int X2_0 = PLAY_AREA_LEFT; - const int X2_100 = (PLAY_AREA_RIGHT)-Balloon::WIDTH_2; - - const int Y1 = (PLAY_AREA_TOP - BLOCK); - const int X1_0 = PLAY_AREA_LEFT; - const int X1_50 = PLAY_AREA_CENTER_X - (Balloon::WIDTH_1 / 2); - const int X1_100 = (PLAY_AREA_RIGHT)-Balloon::WIDTH_1; - - // Inicializa a cero las variables +// Pone a cero todas las formaciones +void Game::initEnemyFormationsZero() { for (auto &i : enemy_formation_) { i.number_of_enemies = 0; for (auto &j : i.init) { @@ -611,8 +623,10 @@ void Game::initEnemyFormations() { j.creation_counter = 0; } } +} - const Uint16 CREATION_TIME = 300; +// Formaciones 0..19: bucles lineales (todos los enemigos van en la misma dirección) +void Game::initEnemyFormationsLinear() { int inc_x = 0; Uint8 inc_time = 0; Uint8 j = 0; @@ -876,6 +890,13 @@ void Game::initEnemyFormations() { enemy_formation_[j].init[i].kind = Balloon::BALLOON_1; enemy_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i); } +} + +// Formaciones 20..25: simétricas (la primera mitad va hacia un lado, la segunda hacia el otro) +void Game::initEnemyFormationsSymmetric() { + int inc_x = 0; + Uint8 inc_time = 0; + Uint8 j = 0; // #20 - Dos enemigos BALLOON4 seguidos desde la izquierda/derecha. Simetricos j = 20; @@ -993,9 +1014,14 @@ void Game::initEnemyFormations() { enemy_formation_[j].init[i].y = Y1; enemy_formation_[j].init[i].kind = Balloon::BALLOON_1; } +} + +// Duplica las formaciones 0..25 como hexágonos en el rango 50..75, y configura la formación 99 (TEST) +void Game::initEnemyFormationsHexagonsAndTest() { + constexpr Uint8 LAST_SYMMETRIC = 25; // Crea las mismas formaciones pero con hexagonos a partir de la posición 50 del vector - for (int k = 0; k < j + 1; k++) { + for (int k = 0; k < LAST_SYMMETRIC + 1; k++) { enemy_formation_[k + 50].number_of_enemies = enemy_formation_[k].number_of_enemies; for (int i = 0; i < enemy_formation_[k + 50].number_of_enemies; i++) { enemy_formation_[k + 50].init[i].x = enemy_formation_[k].init[i].x; @@ -1843,44 +1869,48 @@ void Game::checkPlayerItemCollision(Player *player) { void Game::checkBulletBalloonCollision() { for (auto *bullet : bullets_) { for (auto *balloon : balloons_) { - if (balloon->isEnabled() && (!balloon->isInvulnerable()) && bullet->isEnabled()) { - if (checkCollision(balloon->getCollider(), bullet->getCollider())) { - // Otorga los puntos correspondientes al globo al jugador que disparó la bala - int index = bullet->getOwner(); - players_[index]->incScoreMultiplier(); - players_[index]->addScore(Uint32(balloon->getScore() * players_[index]->getScoreMultiplier() * difficulty_score_multiplier_)); - updateHiScore(); - - // Explota el globo - popBalloon(balloon); - - // Si no es el modo demo, genera un sonido - if (!demo_.enabled) { - Audio::get()->playSound(balloon_sound_); - } - - // Deshabilita la bala - bullet->disable(); - - // Suelta el item en caso de que salga uno - const Item::Id droppeditem = dropItem(); - if ((droppeditem != Item::Id::NONE) && !(demo_.enabled) && !(demo_.recording)) { - if (droppeditem != Item::Id::COFFEE_MACHINE) { - createItem(droppeditem, balloon->getPosX(), balloon->getPosY()); - Audio::get()->playSound(item_drop_sound_); - } else { - createItem(droppeditem, players_[index]->getPosX(), 0); - coffee_machine_enabled_ = true; - } - } - - break; - } + if (!balloon->isEnabled() || balloon->isInvulnerable() || !bullet->isEnabled()) { + continue; + } + if (checkCollision(balloon->getCollider(), bullet->getCollider())) { + resolveBulletBalloonHit(bullet, balloon); + break; } } } } +// Resuelve un impacto bala-globo: puntos, sonido, explosión, drop de item +void Game::resolveBulletBalloonHit(Bullet *bullet, Balloon *balloon) { + // Otorga los puntos al jugador que disparó la bala + const int INDEX = bullet->getOwner(); + players_[INDEX]->incScoreMultiplier(); + players_[INDEX]->addScore(Uint32(balloon->getScore() * players_[INDEX]->getScoreMultiplier() * difficulty_score_multiplier_)); + updateHiScore(); + + popBalloon(balloon); + + if (!demo_.enabled) { + Audio::get()->playSound(balloon_sound_); + } + + bullet->disable(); + + // Suelta el item en caso de que salga uno + const Item::Id DROPPED_ITEM = dropItem(); + if ((DROPPED_ITEM == Item::Id::NONE) || demo_.enabled || demo_.recording) { + return; + } + + if (DROPPED_ITEM != Item::Id::COFFEE_MACHINE) { + createItem(DROPPED_ITEM, balloon->getPosX(), balloon->getPosY()); + Audio::get()->playSound(item_drop_sound_); + } else { + createItem(DROPPED_ITEM, players_[INDEX]->getPosX(), 0); + coffee_machine_enabled_ = true; + } +} + // Mueve las balas activas void Game::moveBullets() { for (auto *bullet : bullets_) { @@ -2422,145 +2452,136 @@ void Game::updateMenace() { void Game::checkGameInput() { demo_.keys.left = 0; demo_.keys.right = 0; - demo_.keys.noInput = 0; + demo_.keys.no_input = 0; demo_.keys.fire = 0; - demo_.keys.fireLeft = 0; - demo_.keys.fireRight = 0; + demo_.keys.fire_left = 0; + demo_.keys.fire_right = 0; // Atalls globals (zoom finestra, fullscreen, shaders, presets, ...) GlobalInputs::handle(); - // Modo Demo activo if (demo_.enabled) { - const int INDEX = 0; - if (demo_.data_file[demo_.counter].left == 1) { - players_[INDEX]->setInput(input_left); - } + processDemoInput(); + } else { + processLiveInput(); + } +} - if (demo_.data_file[demo_.counter].right == 1) { - players_[INDEX]->setInput(input_right); - } +// Rama de checkGameInput: reproduce el input grabado en data_file +void Game::processDemoInput() { + const int INDEX = 0; + const DemoKeys &keys = demo_.data_file[demo_.counter]; - if (demo_.data_file[demo_.counter].noInput == 1) { - players_[INDEX]->setInput(input_null); - } + if (keys.left == 1) { + players_[INDEX]->setInput(LEFT); + } + if (keys.right == 1) { + players_[INDEX]->setInput(RIGHT); + } + if (keys.no_input == 1) { + players_[INDEX]->setInput(INVALID); + } - if (demo_.data_file[demo_.counter].fire == 1) { - if (players_[INDEX]->canFire()) { - players_[INDEX]->setInput(input_fire_center); - createBullet(players_[INDEX]->getPosX() + (players_[INDEX]->getWidth() / 2) - 4, players_[INDEX]->getPosY() + (players_[INDEX]->getHeight() / 2), Bullet::Kind::UP, players_[INDEX]->isPowerUp(), INDEX); - players_[INDEX]->setFireCooldown(10); - } - } + if (keys.fire == 1 && players_[INDEX]->canFire()) { + players_[INDEX]->setInput(FIRE_CENTER); + createBullet(players_[INDEX]->getPosX() + (players_[INDEX]->getWidth() / 2) - 4, players_[INDEX]->getPosY() + (players_[INDEX]->getHeight() / 2), Bullet::Kind::UP, players_[INDEX]->isPowerUp(), INDEX); + players_[INDEX]->setFireCooldown(10); + } - if (demo_.data_file[demo_.counter].fireLeft == 1) { - if (players_[INDEX]->canFire()) { - players_[INDEX]->setInput(input_fire_left); - createBullet(players_[INDEX]->getPosX() + (players_[INDEX]->getWidth() / 2) - 4, players_[INDEX]->getPosY() + (players_[INDEX]->getHeight() / 2), Bullet::Kind::LEFT, players_[INDEX]->isPowerUp(), INDEX); - players_[INDEX]->setFireCooldown(10); - } - } + if (keys.fire_left == 1 && players_[INDEX]->canFire()) { + players_[INDEX]->setInput(FIRE_LEFT); + createBullet(players_[INDEX]->getPosX() + (players_[INDEX]->getWidth() / 2) - 4, players_[INDEX]->getPosY() + (players_[INDEX]->getHeight() / 2), Bullet::Kind::LEFT, players_[INDEX]->isPowerUp(), INDEX); + players_[INDEX]->setFireCooldown(10); + } - if (demo_.data_file[demo_.counter].fireRight == 1) { - if (players_[INDEX]->canFire()) { - players_[INDEX]->setInput(input_fire_right); - createBullet(players_[INDEX]->getPosX() + (players_[INDEX]->getWidth() / 2) - 4, players_[INDEX]->getPosY() + (players_[INDEX]->getHeight() / 2), Bullet::Kind::RIGHT, players_[INDEX]->isPowerUp(), INDEX); - players_[INDEX]->setFireCooldown(10); - } - } + if (keys.fire_right == 1 && players_[INDEX]->canFire()) { + players_[INDEX]->setInput(FIRE_RIGHT); + createBullet(players_[INDEX]->getPosX() + (players_[INDEX]->getWidth() / 2) - 4, players_[INDEX]->getPosY() + (players_[INDEX]->getHeight() / 2), Bullet::Kind::RIGHT, players_[INDEX]->isPowerUp(), INDEX); + players_[INDEX]->setFireCooldown(10); + } - // Si se pulsa cualquier tecla, se sale del modo demo - if (Input::get()->checkAnyInput()) { - section_->name = SECTION_PROG_TITLE; - } + // Si se pulsa cualquier tecla, se sale del modo demo + if (Input::get()->checkAnyInput()) { + section_->name = SECTION_PROG_TITLE; + } - // Incrementa el contador de la demo - if (demo_.counter < TOTAL_DEMO_DATA) { - demo_.counter++; - } else { - section_->name = SECTION_PROG_TITLE; - section_->subsection = SUBSECTION_TITLE_INSTRUCTIONS; + // Incrementa el contador de la demo + if (demo_.counter < TOTAL_DEMO_DATA) { + demo_.counter++; + } else { + section_->name = SECTION_PROG_TITLE; + section_->subsection = SUBSECTION_TITLE_INSTRUCTIONS; + } +} + +// Rama de checkGameInput: lee inputs reales del teclado/gamepad por jugador +void Game::processLiveInput() { + int i = 0; + for (auto *player : players_) { + if (player->isAlive()) { + processPlayerLiveInput(player, i); + i++; } } - // Modo Demo no activo - else { - int i = 0; - for (auto *player : players_) { - if (player->isAlive()) { - // Input a la izquierda - if (Input::get()->checkInput(input_left, REPEAT_TRUE, Options::inputs[i].deviceType, Options::inputs[i].id)) { - player->setInput(input_left); - demo_.keys.left = 1; - } else { - // Input a la derecha - if (Input::get()->checkInput(input_right, REPEAT_TRUE, Options::inputs[i].deviceType, Options::inputs[i].id)) { - player->setInput(input_right); - demo_.keys.right = 1; - } else { - // Ninguno de los dos inputs anteriores - player->setInput(input_null); - demo_.keys.noInput = 1; - } - } - // Comprueba el input de disparar al centro - if (Input::get()->checkInput(input_fire_center, REPEAT_TRUE, Options::inputs[i].deviceType, Options::inputs[i].id)) { - if (player->canFire()) { - player->setInput(input_fire_center); - createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), Bullet::Kind::UP, player->isPowerUp(), i); - player->setFireCooldown(10); +} - // Reproduce el sonido de disparo - Audio::get()->playSound(bullet_sound_); +// Cuerpo per-player de processLiveInput +void Game::processPlayerLiveInput(Player *player, int i) { + auto *input = Input::get(); + const auto &device = Options::inputs[i]; - demo_.keys.fire = 1; - } - } + // Movimiento izquierda / derecha / nada + if (input->checkInput(LEFT, REPEAT_TRUE, device.device_type, device.id)) { + player->setInput(LEFT); + demo_.keys.left = 1; + } else if (input->checkInput(RIGHT, REPEAT_TRUE, device.device_type, device.id)) { + player->setInput(RIGHT); + demo_.keys.right = 1; + } else { + player->setInput(INVALID); + demo_.keys.no_input = 1; + } - // Comprueba el input de disparar a la izquierda - if (Input::get()->checkInput(input_fire_left, REPEAT_TRUE, Options::inputs[i].deviceType, Options::inputs[i].id)) { - if (player->canFire()) { - player->setInput(input_fire_left); - createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), Bullet::Kind::LEFT, player->isPowerUp(), i); - player->setFireCooldown(10); + // Disparo al centro + if (input->checkInput(FIRE_CENTER, REPEAT_TRUE, device.device_type, device.id) && player->canFire()) { + player->setInput(FIRE_CENTER); + createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), Bullet::Kind::UP, player->isPowerUp(), i); + player->setFireCooldown(10); + Audio::get()->playSound(bullet_sound_); + demo_.keys.fire = 1; + } - // Reproduce el sonido de disparo - Audio::get()->playSound(bullet_sound_); + // Disparo a la izquierda + if (input->checkInput(FIRE_LEFT, REPEAT_TRUE, device.device_type, device.id) && player->canFire()) { + player->setInput(FIRE_LEFT); + createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), Bullet::Kind::LEFT, player->isPowerUp(), i); + player->setFireCooldown(10); + Audio::get()->playSound(bullet_sound_); + demo_.keys.fire_left = 1; + } - demo_.keys.fireLeft = 1; - } - } + // Disparo a la derecha + if (input->checkInput(FIRE_RIGHT, REPEAT_TRUE, device.device_type, device.id) && player->canFire()) { + player->setInput(FIRE_RIGHT); + createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), Bullet::Kind::RIGHT, player->isPowerUp(), i); + player->setFireCooldown(10); + Audio::get()->playSound(bullet_sound_); + demo_.keys.fire_right = 1; + } - // Comprueba el input de disparar a la derecha - if (Input::get()->checkInput(input_fire_right, REPEAT_TRUE, Options::inputs[i].deviceType, Options::inputs[i].id)) { - if (player->canFire()) { - player->setInput(input_fire_right); - createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), Bullet::Kind::RIGHT, player->isPowerUp(), i); - player->setFireCooldown(10); + // Pausa + if (input->checkInput(PAUSE, REPEAT_FALSE, device.device_type, device.id)) { + section_->subsection = SUBSECTION_GAME_PAUSE; + } - // Reproduce el sonido de disparo - Audio::get()->playSound(bullet_sound_); - - demo_.keys.fireRight = 1; - } - } - - // Comprueba el input de pausa - if (Input::get()->checkInput(input_pause, REPEAT_FALSE, Options::inputs[i].deviceType, Options::inputs[i].id)) { - section_->subsection = SUBSECTION_GAME_PAUSE; - } - - if (demo_.counter < TOTAL_DEMO_DATA) { - if (demo_.recording) { - demo_.data_file[demo_.counter] = demo_.keys; - } - demo_.counter++; - } else if (demo_.recording) { - section_->name = SECTION_PROG_QUIT; - } - - i++; - } + // Grabación de demo + if (demo_.counter < TOTAL_DEMO_DATA) { + if (demo_.recording) { + demo_.data_file[demo_.counter] = demo_.keys; } + demo_.counter++; + } else if (demo_.recording) { + section_->name = SECTION_PROG_QUIT; } } @@ -2767,60 +2788,67 @@ void Game::run() { // Actualiza las variables del menu de pausa del juego void Game::updatePausedGame() { - // Calcula la lógica de los objetos - if (SDL_GetTicks() - ticks_ > ticks_speed_) { - // Actualiza el contador de ticks - ticks_ = SDL_GetTicks(); + if (SDL_GetTicks() - ticks_ <= ticks_speed_) { + return; + } + ticks_ = SDL_GetTicks(); - // Atalls globals (zoom finestra, fullscreen, shaders, presets, ...) - GlobalInputs::handle(); + // Atalls globals (zoom finestra, fullscreen, shaders, presets, ...) + GlobalInputs::handle(); - if (leaving_pause_menu_) { - if (pause_counter_ > 0) { // El contador está descendiendo - const bool A = pause_counter_ == 90; - const bool B = pause_counter_ == 60; - const bool C = pause_counter_ == 30; - if (A || B || C) { - Audio::get()->playSound(clock_sound_); - } - pause_counter_--; - } else { // Ha finalizado el contador - section_->name = SECTION_PROG_GAME; - section_->subsection = num_players_ == 1 ? SUBSECTION_GAME_PLAY_1P : SUBSECTION_GAME_PLAY_2P; + if (leaving_pause_menu_) { + updateLeavingPauseMenu(); + } else { + updatePauseMenuUI(); + } +} - if (Audio::getRealMusicState() == Audio::MusicState::PAUSED) { - Audio::get()->resumeMusic(); - } - } - } else { // Actualiza la lógica del menu de pausa - pause_menu_->update(); - - // Comprueba las entradas para el menu - pause_menu_->checkInput(); - - // Comprueba si se ha seleccionado algún item del menú - switch (pause_menu_->getItemSelected()) { - case 1: - leaving_pause_menu_ = true; - break; - - case 2: - fade_->setFadeType(FADE_CENTER); - fade_->activateFade(); - break; - - default: - break; - } - - // Actualiza el fade - fade_->update(); - if (fade_->hasEnded()) { - section_->name = SECTION_PROG_TITLE; - section_->subsection = SUBSECTION_TITLE_1; - Audio::get()->stopMusic(); - } +// Rama de updatePausedGame: cuenta atrás de salida y vuelta al juego +void Game::updateLeavingPauseMenu() { + if (pause_counter_ > 0) { // El contador está descendiendo + const bool A = pause_counter_ == 90; + const bool B = pause_counter_ == 60; + const bool C = pause_counter_ == 30; + if (A || B || C) { + Audio::get()->playSound(clock_sound_); } + pause_counter_--; + return; + } + + // Ha finalizado el contador + section_->name = SECTION_PROG_GAME; + section_->subsection = num_players_ == 1 ? SUBSECTION_GAME_PLAY_1P : SUBSECTION_GAME_PLAY_2P; + + if (Audio::getRealMusicState() == Audio::MusicState::PAUSED) { + Audio::get()->resumeMusic(); + } +} + +// Rama de updatePausedGame: lógica del menú de pausa +void Game::updatePauseMenuUI() { + pause_menu_->update(); + pause_menu_->checkInput(); + + switch (pause_menu_->getItemSelected()) { + case 1: + leaving_pause_menu_ = true; + break; + + case 2: + fade_->setFadeType(FADE_CENTER); + fade_->activateFade(); + break; + + default: + break; + } + + fade_->update(); + if (fade_->hasEnded()) { + section_->name = SECTION_PROG_TITLE; + section_->subsection = SUBSECTION_TITLE_1; + Audio::get()->stopMusic(); } } @@ -3027,7 +3055,7 @@ void Game::initPaths() { // Letrero de STAGE # const int FIRST_PART = STAGE_COUNTER / 4; // 50 - const int SECOND_PART = FIRST_PART * 3; // 150 + const int SECOND_PART = FIRST_PART * 3; // 150 const int CENTER_POINT = PLAY_AREA_CENTER_Y - (BLOCK * 2); const int DISTANCE = (PLAY_AREA_BOTTOM) - (PLAY_AREA_CENTER_Y - 16); diff --git a/source/game/game.h b/source/game/game.h index 4241289..f42ef54 100644 --- a/source/game/game.h +++ b/source/game/game.h @@ -283,6 +283,12 @@ class Game { // Inicializa las formaciones enemigas void initEnemyFormations(); + // Helpers de initEnemyFormations + void initEnemyFormationsZero(); + void initEnemyFormationsLinear(); + void initEnemyFormationsSymmetric(); + void initEnemyFormationsHexagonsAndTest(); + // Inicializa los conjuntos de formaciones void initEnemyPools(); @@ -370,6 +376,9 @@ class Game { // Comprueba la colisión entre las balas y los globos void checkBulletBalloonCollision(); + // Resuelve un impacto bala-globo (helper de checkBulletBalloonCollision) + void resolveBulletBalloonHit(Bullet *bullet, Balloon *balloon); + // Mueve las balas activas void moveBullets(); @@ -457,6 +466,11 @@ class Game { // Gestiona la entrada durante el juego void checkGameInput(); + // Helpers de checkGameInput + void processDemoInput(); + void processLiveInput(); + void processPlayerLiveInput(Player *player, int i); + // Pinta diferentes mensajes en la pantalla void renderMessages(); @@ -481,6 +495,10 @@ class Game { // Actualiza las variables del menu de pausa del juego void updatePausedGame(); + // Helpers de updatePausedGame + void updateLeavingPauseMenu(); + void updatePauseMenuUI(); + // Dibuja el menu de pausa del juego void renderPausedGame(); diff --git a/source/game/options.cpp b/source/game/options.cpp index 532a567..b78abdd 100644 --- a/source/game/options.cpp +++ b/source/game/options.cpp @@ -161,9 +161,9 @@ namespace Options { size_t i = 0; for (const auto &entry : ins) { if (i >= inputs.size()) { break; } - int device_type_int = inputs[i].deviceType; + int device_type_int = inputs[i].device_type; if (tryGet(entry, "device_type", device_type_int)) { - inputs[i].deviceType = static_cast(device_type_int); + inputs[i].device_type = static_cast(device_type_int); } ++i; } @@ -200,13 +200,13 @@ namespace Options { InputDevice kb; kb.id = 0; kb.name = "KEYBOARD"; - kb.deviceType = INPUT_USE_KEYBOARD; + kb.device_type = INPUT_USE_KEYBOARD; inputs.push_back(kb); InputDevice gc; gc.id = 0; gc.name = "GAME CONTROLLER"; - gc.deviceType = INPUT_USE_GAMECONTROLLER; + gc.device_type = INPUT_USE_GAMECONTROLLER; inputs.push_back(gc); } @@ -328,7 +328,7 @@ namespace Options { file << "input:\n"; for (size_t i = 0; i < inputs.size(); ++i) { file << " - slot: " << i << "\n"; - file << " device_type: " << static_cast(inputs[i].deviceType) << "\n"; + file << " device_type: " << static_cast(inputs[i].device_type) << "\n"; } file.close(); diff --git a/source/game/scenes/instructions.cpp b/source/game/scenes/instructions.cpp index cd8bb4c..fc6a1d8 100644 --- a/source/game/scenes/instructions.cpp +++ b/source/game/scenes/instructions.cpp @@ -211,7 +211,7 @@ void Instructions::checkEvents() { // Comprueba las entradas void Instructions::checkInput() { #ifndef __EMSCRIPTEN__ - if (Input::get()->checkInput(input_exit, REPEAT_FALSE)) { + if (Input::get()->checkInput(EXIT, REPEAT_FALSE)) { quit_requested_ = true; finished_ = true; return; @@ -219,7 +219,7 @@ void Instructions::checkInput() { #endif if (GlobalInputs::handle()) { return; } - if (Input::get()->checkInput(input_pause, REPEAT_FALSE) || Input::get()->checkInput(input_accept, REPEAT_FALSE) || Input::get()->checkInput(input_fire_left, REPEAT_FALSE) || Input::get()->checkInput(input_fire_center, REPEAT_FALSE) || Input::get()->checkInput(input_fire_right, REPEAT_FALSE)) { + if (Input::get()->checkInput(PAUSE, REPEAT_FALSE) || Input::get()->checkInput(ACCEPT, REPEAT_FALSE) || Input::get()->checkInput(FIRE_LEFT, REPEAT_FALSE) || Input::get()->checkInput(FIRE_CENTER, REPEAT_FALSE) || Input::get()->checkInput(FIRE_RIGHT, REPEAT_FALSE)) { if (mode_ == Mode::AUTO) { finished_ = true; } else { diff --git a/source/game/scenes/intro.cpp b/source/game/scenes/intro.cpp index b0acd26..0959259 100644 --- a/source/game/scenes/intro.cpp +++ b/source/game/scenes/intro.cpp @@ -167,14 +167,14 @@ Intro::~Intro() { // Comprueba las entradas void Intro::checkInput() { #ifndef __EMSCRIPTEN__ - if (Input::get()->checkInput(input_exit, REPEAT_FALSE)) { + if (Input::get()->checkInput(EXIT, REPEAT_FALSE)) { section_->name = SECTION_PROG_QUIT; return; } #endif if (GlobalInputs::handle()) { return; } - if (Input::get()->checkInput(input_pause, REPEAT_FALSE) || Input::get()->checkInput(input_accept, REPEAT_FALSE) || Input::get()->checkInput(input_fire_left, REPEAT_FALSE) || Input::get()->checkInput(input_fire_center, REPEAT_FALSE) || Input::get()->checkInput(input_fire_right, REPEAT_FALSE)) { + if (Input::get()->checkInput(PAUSE, REPEAT_FALSE) || Input::get()->checkInput(ACCEPT, REPEAT_FALSE) || Input::get()->checkInput(FIRE_LEFT, REPEAT_FALSE) || Input::get()->checkInput(FIRE_CENTER, REPEAT_FALSE) || Input::get()->checkInput(FIRE_RIGHT, REPEAT_FALSE)) { Audio::get()->stopMusic(); section_->name = SECTION_PROG_TITLE; section_->subsection = SUBSECTION_TITLE_1; diff --git a/source/game/scenes/logo.cpp b/source/game/scenes/logo.cpp index 2379bfe..6a6666a 100644 --- a/source/game/scenes/logo.cpp +++ b/source/game/scenes/logo.cpp @@ -59,14 +59,14 @@ void Logo::checkLogoEnd() { // Comprueba las entradas void Logo::checkInput() { #ifndef __EMSCRIPTEN__ - if (Input::get()->checkInput(input_exit, REPEAT_FALSE)) { + if (Input::get()->checkInput(EXIT, REPEAT_FALSE)) { section_->name = SECTION_PROG_QUIT; return; } #endif if (GlobalInputs::handle()) { return; } - if (Input::get()->checkInput(input_pause, REPEAT_FALSE) || Input::get()->checkInput(input_accept, REPEAT_FALSE) || Input::get()->checkInput(input_fire_left, REPEAT_FALSE) || Input::get()->checkInput(input_fire_center, REPEAT_FALSE) || Input::get()->checkInput(input_fire_right, REPEAT_FALSE)) { + if (Input::get()->checkInput(PAUSE, REPEAT_FALSE) || Input::get()->checkInput(ACCEPT, REPEAT_FALSE) || Input::get()->checkInput(FIRE_LEFT, REPEAT_FALSE) || Input::get()->checkInput(FIRE_CENTER, REPEAT_FALSE) || Input::get()->checkInput(FIRE_RIGHT, REPEAT_FALSE)) { section_->name = SECTION_PROG_TITLE; section_->subsection = SUBSECTION_TITLE_1; } diff --git a/source/game/scenes/title.cpp b/source/game/scenes/title.cpp index dba6512..78576e3 100644 --- a/source/game/scenes/title.cpp +++ b/source/game/scenes/title.cpp @@ -115,12 +115,12 @@ void Title::init() { InputDevice inp; inp.id = 0; inp.name = "KEYBOARD"; - inp.deviceType = INPUT_USE_KEYBOARD; + inp.device_type = INPUT_USE_KEYBOARD; Options::inputs.push_back(inp); inp.id = 0; inp.name = "GAME CONTROLLER"; - inp.deviceType = INPUT_USE_GAMECONTROLLER; + inp.device_type = INPUT_USE_GAMECONTROLLER; Options::inputs.push_back(inp); // Comprueba si hay mandos conectados @@ -135,7 +135,7 @@ void Title::init() { if (Input::get()->gameControllerFound()) { Options::inputs[1].id = available_input_devices_[device_index_[1]].id; Options::inputs[1].name = available_input_devices_[device_index_[1]].name; - Options::inputs[1].deviceType = available_input_devices_[device_index_[1]].deviceType; + Options::inputs[1].device_type = available_input_devices_[device_index_[1]].device_type; } else { // Si no ha encontrado un mando, deshabilita la opción de jugar a 2 jugadores menu_.title->setSelectable(1, false); menu_.title->setGreyed(1, true); @@ -625,7 +625,7 @@ void Title::render() { // Comprueba las entradas void Title::checkInput() { #ifndef __EMSCRIPTEN__ - if (Input::get()->checkInput(input_exit, REPEAT_FALSE)) { + if (Input::get()->checkInput(EXIT, REPEAT_FALSE)) { section_->name = SECTION_PROG_QUIT; return; } @@ -678,7 +678,7 @@ void Title::updateMenuLabels() const { i++; // PLAYER 1 CONTROLS - OPTIONS - switch (Options::inputs[0].deviceType) { + switch (Options::inputs[0].device_type) { case INPUT_USE_KEYBOARD: menu_.options->setItemCaption(i, Lang::get()->getText(69)); // KEYBOARD menu_.options->setGreyed(i, false); @@ -705,7 +705,7 @@ void Title::updateMenuLabels() const { i++; // PLAYER 2 CONTROLS - OPTIONS - switch (Options::inputs[1].deviceType) { + switch (Options::inputs[1].device_type) { case INPUT_USE_KEYBOARD: menu_.options->setItemCaption(i, Lang::get()->getText(69)); // KEYBOARD menu_.options->setGreyed(i, false); @@ -966,11 +966,11 @@ auto Title::updatePlayerInputs(int num_player) -> bool { Options::inputs[0].id = -1; Options::inputs[0].name = "KEYBOARD"; - Options::inputs[0].deviceType = INPUT_USE_KEYBOARD; + Options::inputs[0].device_type = INPUT_USE_KEYBOARD; Options::inputs[1].id = 0; Options::inputs[1].name = "GAME CONTROLLER"; - Options::inputs[1].deviceType = INPUT_USE_GAMECONTROLLER; + Options::inputs[1].device_type = INPUT_USE_GAMECONTROLLER; return true; } // Si hay mas de un dispositivo, se recorre el vector @@ -1062,7 +1062,7 @@ void Title::checkInputDevices() { for (int i = 0; i < NUM_CONTROLLERS; ++i) { temp.id = i; temp.name = Input::get()->getControllerName(i); - temp.deviceType = INPUT_USE_GAMECONTROLLER; + temp.device_type = INPUT_USE_GAMECONTROLLER; available_input_devices_.push_back(temp); if (Options::settings.console) { std::cout << "Device " << (int)available_input_devices_.size() << " - " << temp.name.c_str() << '\n'; @@ -1073,7 +1073,7 @@ void Title::checkInputDevices() { // Añade el teclado al final temp.id = -1; temp.name = "KEYBOARD"; - temp.deviceType = INPUT_USE_KEYBOARD; + temp.device_type = INPUT_USE_KEYBOARD; available_input_devices_.push_back(temp); if (Options::settings.console) { std::cout << "Device " << (int)available_input_devices_.size() << " - " << temp.name.c_str() << '\n'; diff --git a/source/game/ui/menu.cpp b/source/game/ui/menu.cpp index d18caab..117da16 100644 --- a/source/game/ui/menu.cpp +++ b/source/game/ui/menu.cpp @@ -775,28 +775,28 @@ void Menu::setDefaultActionWhenCancel(int item) { // Gestiona la entrada de teclado y mando durante el menu void Menu::checkInput() { - if (Input::get()->checkInput(input_up, REPEAT_FALSE)) { + if (Input::get()->checkInput(UP, REPEAT_FALSE)) { decreaseSelectorIndex(); if (soundMove != nullptr) { Audio::get()->playSound(soundMove); } } - if (Input::get()->checkInput(input_down, REPEAT_FALSE)) { + if (Input::get()->checkInput(DOWN, REPEAT_FALSE)) { increaseSelectorIndex(); if (soundMove != nullptr) { Audio::get()->playSound(soundMove); } } - if (Input::get()->checkInput(input_accept, REPEAT_FALSE)) { + if (Input::get()->checkInput(ACCEPT, REPEAT_FALSE)) { itemSelected = selector.index; if (soundAccept != nullptr) { Audio::get()->playSound(soundAccept); } } - if (Input::get()->checkInput(input_cancel, REPEAT_FALSE)) { + if (Input::get()->checkInput(CANCEL, REPEAT_FALSE)) { itemSelected = defaultActionWhenCancel; if (soundCancel != nullptr) { Audio::get()->playSound(soundCancel); diff --git a/source/utils/utils.cpp b/source/utils/utils.cpp index 3ca79d8..2685afe 100644 --- a/source/utils/utils.cpp +++ b/source/utils/utils.cpp @@ -7,47 +7,47 @@ // Calcula el cuadrado de la distancia entre dos puntos auto distanceSquared(int x1, int y1, int x2, int y2) -> double { - const int deltaX = x2 - x1; - const int deltaY = y2 - y1; - return (deltaX * deltaX) + (deltaY * deltaY); + const int DELTA_X = x2 - x1; + const int DELTA_Y = y2 - y1; + return (DELTA_X * DELTA_X) + (DELTA_Y * DELTA_Y); } // Detector de colisiones entre dos circulos auto checkCollision(const Circle &a, const Circle &b) -> bool { // Calcula el radio total al cuadrado - int totalRadiusSquared = a.r + b.r; - totalRadiusSquared = totalRadiusSquared * totalRadiusSquared; + int total_radius_squared = a.r + b.r; + total_radius_squared = total_radius_squared * total_radius_squared; // Han colisionat si la distancia entre centres és inferior a la suma de radis - return distanceSquared(a.x, a.y, b.x, b.y) < totalRadiusSquared; + return distanceSquared(a.x, a.y, b.x, b.y) < total_radius_squared; } // Detector de colisiones entre un circulo y un rectangulo auto checkCollision(const Circle &a, const SDL_Rect &b) -> bool { // Closest point on collision box - int cX; - int cY; + int c_x; + int c_y; // Find closest x offset if (a.x < b.x) { - cX = b.x; + c_x = b.x; } else if (a.x > b.x + b.w) { - cX = b.x + b.w; + c_x = b.x + b.w; } else { - cX = a.x; + c_x = a.x; } // Find closest y offset if (a.y < b.y) { - cY = b.y; + c_y = b.y; } else if (a.y > b.y + b.h) { - cY = b.y + b.h; + c_y = b.y + b.h; } else { - cY = a.y; + c_y = a.y; } // If the closest point is inside the Circle - if (distanceSquared(a.x, a.y, cX, cY) < a.r * a.r) { + if (distanceSquared(a.x, a.y, c_x, c_y) < a.r * a.r) { // This box and the Circle have collided return true; } @@ -59,31 +59,31 @@ auto checkCollision(const Circle &a, const SDL_Rect &b) -> bool { // Detector de colisiones entre dos rectangulos auto checkCollision(const SDL_Rect &a, const SDL_Rect &b) -> bool { // Calcula las caras del rectangulo a - const int leftA = a.x; - const int rightA = a.x + a.w; - const int topA = a.y; - const int bottomA = a.y + a.h; + const int LEFT_A = a.x; + const int RIGHT_A = a.x + a.w; + const int TOP_A = a.y; + const int BOTTOM_A = a.y + a.h; // Calcula las caras del rectangulo b - const int leftB = b.x; - const int rightB = b.x + b.w; - const int topB = b.y; - const int bottomB = b.y + b.h; + const int LEFT_B = b.x; + const int RIGHT_B = b.x + b.w; + const int TOP_B = b.y; + const int BOTTOM_B = b.y + b.h; // Si cualquiera de las caras de a está fuera de b - if (bottomA <= topB) { + if (BOTTOM_A <= TOP_B) { return false; } - if (topA >= bottomB) { + if (TOP_A >= BOTTOM_B) { return false; } - if (rightA <= leftB) { + if (RIGHT_A <= LEFT_B) { return false; } - if (leftA >= rightB) { + if (LEFT_A >= RIGHT_B) { return false; } @@ -197,91 +197,69 @@ auto checkCollision(const HorizontalLine &l, const SDL_Point &p) -> bool { // Detector de colisiones entre dos lineas auto checkCollision(const Line &l1, const Line &l2) -> SDL_Point { - const float x1 = l1.x1; - const float y1 = l1.y1; - const float x2 = l1.x2; - const float y2 = l1.y2; + const float X1 = l1.x1; + const float Y1 = l1.y1; + const float X2 = l1.x2; + const float Y2 = l1.y2; - const float x3 = l2.x1; - const float y3 = l2.y1; - const float x4 = l2.x2; - const float y4 = l2.y2; + const float X3 = l2.x1; + const float Y3 = l2.y1; + const float X4 = l2.x2; + const float Y4 = l2.y2; // calculate the direction of the lines - float uA = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)); - float uB = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)); + float u_a = ((X4 - X3) * (Y1 - Y3) - (Y4 - Y3) * (X1 - X3)) / ((Y4 - Y3) * (X2 - X1) - (X4 - X3) * (Y2 - Y1)); + float u_b = ((X2 - X1) * (Y1 - Y3) - (Y2 - Y1) * (X1 - X3)) / ((Y4 - Y3) * (X2 - X1) - (X4 - X3) * (Y2 - Y1)); // if uA and uB are between 0-1, lines are colliding - if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) { + if (u_a >= 0 && u_a <= 1 && u_b >= 0 && u_b <= 1) { // Calcula la intersección - const float x = x1 + (uA * (x2 - x1)); - const float y = y1 + (uA * (y2 - y1)); + const float X = X1 + (u_a * (X2 - X1)); + const float Y = Y1 + (u_a * (Y2 - Y1)); - return {(int)std::round(x), (int)std::round(y)}; + return {(int)std::round(X), (int)std::round(Y)}; } return {-1, -1}; } // Detector de colisiones entre dos lineas auto checkCollision(const DiagonalLine &l1, const VerticalLine &l2) -> SDL_Point { - const float x1 = l1.x1; - const float y1 = l1.y1; - const float x2 = l1.x2; - const float y2 = l1.y2; + const float X1 = l1.x1; + const float Y1 = l1.y1; + const float X2 = l1.x2; + const float Y2 = l1.y2; - const float x3 = l2.x; - const float y3 = l2.y1; - const float x4 = l2.x; - const float y4 = l2.y2; + const float X3 = l2.x; + const float Y3 = l2.y1; + const float X4 = l2.x; + const float Y4 = l2.y2; // calculate the direction of the lines - float uA = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)); - float uB = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)); + float u_a = ((X4 - X3) * (Y1 - Y3) - (Y4 - Y3) * (X1 - X3)) / ((Y4 - Y3) * (X2 - X1) - (X4 - X3) * (Y2 - Y1)); + float u_b = ((X2 - X1) * (Y1 - Y3) - (Y2 - Y1) * (X1 - X3)) / ((Y4 - Y3) * (X2 - X1) - (X4 - X3) * (Y2 - Y1)); // if uA and uB are between 0-1, lines are colliding - if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) { + if (u_a >= 0 && u_a <= 1 && u_b >= 0 && u_b <= 1) { // Calcula la intersección - const float x = x1 + (uA * (x2 - x1)); - const float y = y1 + (uA * (y2 - y1)); + const float X = X1 + (u_a * (X2 - X1)); + const float Y = Y1 + (u_a * (Y2 - Y1)); - return {(int)x, (int)y}; + return {(int)X, (int)Y}; } return {-1, -1}; } -// Detector de colisiones entre una linea diagonal y una vertical -/*bool checkCollision(DiagonalLine &l1, VerticalLine &l2) -{ - // Normaliza la linea diagonal - normalizeLine(l1); - - // Comprueba si la linea vertical esta a la izquierda de la linea diagonal - if (l2.x < l1.x1) - { - return false; - } - - // Comprueba si la linea vertical esta a la derecha de la linea diagonal - if (l2.x > l1.x2) - { - return false; - } - - // Inacabada - return true; -}*/ - // Normaliza una linea diagonal void normalizeLine(DiagonalLine &l) { // Las lineas diagonales van de izquierda a derecha // x2 mayor que x1 if (l.x2 < l.x1) { - const int x = l.x1; - const int y = l.y1; + const int X = l.x1; + const int Y = l.y1; l.x1 = l.x2; l.y1 = l.y2; - l.x2 = x; - l.y2 = y; + l.x2 = X; + l.y2 = Y; } } diff --git a/source/utils/utils.h b/source/utils/utils.h index 71b73be..349a61a 100644 --- a/source/utils/utils.h +++ b/source/utils/utils.h @@ -3,7 +3,6 @@ #include #include // for string, basic_string -#include // for vector // Dificultad del juego constexpr int DIFFICULTY_EASY = 0; @@ -63,17 +62,17 @@ struct Section { struct DemoKeys { Uint8 left; Uint8 right; - Uint8 noInput; + Uint8 no_input; Uint8 fire; - Uint8 fireLeft; - Uint8 fireRight; + Uint8 fire_left; + Uint8 fire_right; }; // Estructura para albergar métodos de control struct InputDevice { int id; // Identificador en el vector de mandos std::string name; // Nombre del dispositivo - Uint8 deviceType; // Tipo de dispositivo (teclado o mando) + Uint8 device_type; // Tipo de dispositivo (teclado o mando) }; // Calcula el cuadrado de la distancia entre dos puntos