desacoplament de Player i Options
Player: canviat id de int a enum migrant input: eliminat Device, keyboard separat de la llista de mandos, llig i guarda configuracions de mandos falta: definir botons, asignar mandos a jugadors i guardar la asignació
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
#include "resource.h" // Para Resource
|
#include "resource.h" // Para Resource
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Bullet::Bullet(float x, float y, BulletType bullet_type, bool powered, int owner)
|
Bullet::Bullet(float x, float y, BulletType bullet_type, bool powered, Player::Id owner)
|
||||||
: sprite_(std::make_unique<AnimatedSprite>(Resource::get()->getTexture("bullet.png"), Resource::get()->getAnimation("bullet.ani"))),
|
: sprite_(std::make_unique<AnimatedSprite>(Resource::get()->getTexture("bullet.png"), Resource::get()->getAnimation("bullet.ani"))),
|
||||||
pos_x_(x),
|
pos_x_(x),
|
||||||
pos_y_(y),
|
pos_y_(y),
|
||||||
@@ -94,7 +94,7 @@ void Bullet::disable() {
|
|||||||
bullet_type_ = BulletType::NONE;
|
bullet_type_ = BulletType::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Bullet::getOwner() const -> int {
|
auto Bullet::getOwner() const -> Player::Id {
|
||||||
return owner_;
|
return owner_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
|
|
||||||
#include "animated_sprite.h" // Para AnimatedSprite
|
#include "animated_sprite.h" // Para AnimatedSprite
|
||||||
|
#include "player.h" // Para Player
|
||||||
#include "utils.h" // Para Circle
|
#include "utils.h" // Para Circle
|
||||||
|
|
||||||
// Tipos de balas
|
// Tipos de balas
|
||||||
@@ -30,7 +31,7 @@ class Bullet {
|
|||||||
static constexpr float HEIGHT = 12.0F;
|
static constexpr float HEIGHT = 12.0F;
|
||||||
|
|
||||||
// Constructor y Destructor
|
// Constructor y Destructor
|
||||||
Bullet(float x, float y, BulletType bullet_type, bool powered, int owner);
|
Bullet(float x, float y, BulletType bullet_type, bool powered, Player::Id owner);
|
||||||
~Bullet() = default;
|
~Bullet() = default;
|
||||||
|
|
||||||
// Métodos principales
|
// Métodos principales
|
||||||
@@ -42,7 +43,7 @@ class Bullet {
|
|||||||
void disable(); // Desactiva la bala
|
void disable(); // Desactiva la bala
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
[[nodiscard]] auto getOwner() const -> int; // Devuelve el identificador del dueño
|
[[nodiscard]] auto getOwner() const -> Player::Id; // Devuelve el identificador del dueño
|
||||||
auto getCollider() -> Circle &; // Devuelve el círculo de colisión
|
auto getCollider() -> Circle &; // Devuelve el círculo de colisión
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -60,7 +61,7 @@ class Bullet {
|
|||||||
float vel_x_; // Velocidad en el eje X
|
float vel_x_; // Velocidad en el eje X
|
||||||
|
|
||||||
BulletType bullet_type_; // Tipo de bala
|
BulletType bullet_type_; // Tipo de bala
|
||||||
int owner_; // Identificador del dueño
|
Player::Id owner_; // Identificador del dueño
|
||||||
Circle collider_; // Círculo de colisión
|
Circle collider_; // Círculo de colisión
|
||||||
|
|
||||||
// Métodos internos
|
// Métodos internos
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ DefineButtons::DefineButtons()
|
|||||||
|
|
||||||
clearButtons();
|
clearButtons();
|
||||||
|
|
||||||
for (int i = 0; i < input_->getNumControllers(); ++i) {
|
auto gamepads = input_->getGamepads();
|
||||||
// controller_names_.emplace_back(input_->getControllerName(i));
|
for (auto gamepad : gamepads) {
|
||||||
|
controller_names_.emplace_back(input_->getControllerName(gamepad));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,9 +29,9 @@ DefineButtons::DefineButtons()
|
|||||||
void DefineButtons::render() {
|
void DefineButtons::render() {
|
||||||
static auto text = Resource::get()->getText("8bithud");
|
static auto text = Resource::get()->getText("8bithud");
|
||||||
if (enabled_) {
|
if (enabled_) {
|
||||||
// text->writeCentered(x_, y_ - 10, Lang::getText("[DEFINE_BUTTONS] PLAYER") + std::to_string(Options::controllers.at(index_controller_).player_id));
|
text->writeCentered(x_, y_ - 10, Lang::getText("[DEFINE_BUTTONS] PLAYER") + std::to_string(static_cast<int>(gamepad_options_->player_id)));
|
||||||
// text->writeCentered(x_, y_, controller_names_.at(index_controller_));
|
text->writeCentered(x_, y_, gamepad_options_->instance->name);
|
||||||
// text->writeCentered(x_, y_ + 10, buttons_.at(index_button_).label);
|
text->writeCentered(x_, y_ + 10, buttons_.at(index_button_).label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,15 +77,15 @@ void DefineButtons::checkEvents(const SDL_Event &event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Habilita el objeto
|
// Habilita el objeto
|
||||||
auto DefineButtons::enable(int index) -> bool {
|
auto DefineButtons::enable(std::shared_ptr<Options::Gamepad> gamepad_options) -> bool {
|
||||||
if (index < input_->getNumControllers()) {
|
if (gamepad_options != nullptr) {
|
||||||
|
gamepad_options_ = gamepad_options;
|
||||||
enabled_ = true;
|
enabled_ = true;
|
||||||
finished_ = false;
|
finished_ = false;
|
||||||
index_button_ = 0;
|
index_button_ = 0;
|
||||||
clearButtons();
|
clearButtons();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
// Clase DefineButtons
|
// Clase DefineButtons
|
||||||
class DefineButtons {
|
class DefineButtons {
|
||||||
@@ -28,7 +29,7 @@ class DefineButtons {
|
|||||||
|
|
||||||
void render(); // Dibuja el objeto en pantalla
|
void render(); // Dibuja el objeto en pantalla
|
||||||
void checkEvents(const SDL_Event &event); // Procesa los eventos
|
void checkEvents(const SDL_Event &event); // Procesa los eventos
|
||||||
auto enable(int index_controller) -> bool; // Habilita la redefinición de botones
|
auto enable(std::shared_ptr<Options::Gamepad> gamepad_options) -> bool; // Habilita la redefinición de botones
|
||||||
[[nodiscard]] auto isEnabled() const -> bool { return enabled_; }; // Comprueba si está habilitado
|
[[nodiscard]] auto isEnabled() const -> bool { return enabled_; }; // Comprueba si está habilitado
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -42,6 +43,7 @@ class DefineButtons {
|
|||||||
size_t index_button_ = 0; // Índice del botón en proceso
|
size_t index_button_ = 0; // Índice del botón en proceso
|
||||||
std::vector<std::string> controller_names_; // Nombres de los mandos
|
std::vector<std::string> controller_names_; // Nombres de los mandos
|
||||||
bool finished_ = false;
|
bool finished_ = false;
|
||||||
|
std::shared_ptr<Options::Gamepad> gamepad_options_;
|
||||||
|
|
||||||
// Métodos internos
|
// Métodos internos
|
||||||
void incIndexButton(); // Incrementa el índice de botones
|
void incIndexButton(); // Incrementa el índice de botones
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ void Director::init() {
|
|||||||
|
|
||||||
auto gamepads = Input::get()->getGamepads();
|
auto gamepads = Input::get()->getGamepads();
|
||||||
if (!gamepads.empty())
|
if (!gamepads.empty())
|
||||||
Options::controllers.front().gamepad = gamepads.front();
|
Options::gamepads.front()->instance = gamepads.front();
|
||||||
|
|
||||||
ServiceMenu::init(); // Inicializa el menú de servicio
|
ServiceMenu::init(); // Inicializa el menú de servicio
|
||||||
Notifier::init(std::string(), Resource::get()->getText("8bithud")); // Inicialización del sistema de notificaciones
|
Notifier::init(std::string(), Resource::get()->getText("8bithud")); // Inicialización del sistema de notificaciones
|
||||||
@@ -543,23 +543,19 @@ void Director::runTitle() {
|
|||||||
|
|
||||||
// Ejecuta la sección donde se juega al juego
|
// Ejecuta la sección donde se juega al juego
|
||||||
void Director::runGame() {
|
void Director::runGame() {
|
||||||
int player_id = 1;
|
Player::Id player_id = Player::Id::PLAYER1;
|
||||||
|
|
||||||
switch (Section::options) {
|
switch (Section::options) {
|
||||||
case Section::Options::GAME_PLAY_1P:
|
case Section::Options::GAME_PLAY_1P:
|
||||||
player_id = 1;
|
player_id = Player::Id::PLAYER1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Section::Options::GAME_PLAY_2P:
|
case Section::Options::GAME_PLAY_2P:
|
||||||
player_id = 2;
|
player_id = Player::Id::PLAYER2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Section::Options::GAME_PLAY_BOTH:
|
case Section::Options::GAME_PLAY_BOTH:
|
||||||
player_id = 0;
|
player_id = Player::Id::BOTH_PLAYERS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
player_id = 1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,7 +564,7 @@ void Director::runGame() {
|
|||||||
#else
|
#else
|
||||||
constexpr int CURRENT_STAGE = 0;
|
constexpr int CURRENT_STAGE = 0;
|
||||||
#endif
|
#endif
|
||||||
auto game = std::make_unique<Game>(player_id, CURRENT_STAGE, GAME_MODE_DEMO_OFF);
|
auto game = std::make_unique<Game>(player_id, CURRENT_STAGE, Game::DEMO_OFF);
|
||||||
game->run();
|
game->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,9 +588,9 @@ void Director::runHiScoreTable() {
|
|||||||
|
|
||||||
// Ejecuta el juego en modo demo
|
// Ejecuta el juego en modo demo
|
||||||
void Director::runDemoGame() {
|
void Director::runDemoGame() {
|
||||||
const auto PLAYER_ID = (rand() % 2) + 1;
|
const auto PLAYER_ID = static_cast<Player::Id>((rand() % 2) + 1);
|
||||||
constexpr auto CURRENT_STAGE = 0;
|
constexpr auto CURRENT_STAGE = 0;
|
||||||
auto game = std::make_unique<Game>(PLAYER_ID, CURRENT_STAGE, GAME_MODE_DEMO_ON);
|
auto game = std::make_unique<Game>(PLAYER_ID, CURRENT_STAGE, Game::DEMO_ON);
|
||||||
game->run();
|
game->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ auto Input::get() -> Input * { return Input::instance; }
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Input::Input(std::string game_controller_db_path, std::string gamepad_configs_file)
|
Input::Input(std::string game_controller_db_path, std::string gamepad_configs_file)
|
||||||
: game_controller_db_path_(std::move(game_controller_db_path)),
|
: gamepad_mappings_file_(std::move(game_controller_db_path)),
|
||||||
gamepad_configs_file_(std::move(gamepad_configs_file)) {
|
gamepad_configs_file_(std::move(gamepad_configs_file)) {
|
||||||
// Inicializa el subsistema SDL_INIT_GAMEPAD
|
// Inicializa el subsistema SDL_INIT_GAMEPAD
|
||||||
initSDLGamePad();
|
initSDLGamePad();
|
||||||
@@ -139,7 +139,7 @@ auto Input::gameControllerFound() const -> bool { return !gamepads_.empty(); }
|
|||||||
auto Input::getControllerName(std::shared_ptr<Gamepad> gamepad) const -> std::string { return gamepad == nullptr ? std::string() : gamepad->name; }
|
auto Input::getControllerName(std::shared_ptr<Gamepad> gamepad) const -> std::string { return gamepad == nullptr ? std::string() : gamepad->name; }
|
||||||
|
|
||||||
// Obten el número de mandos conectados
|
// Obten el número de mandos conectados
|
||||||
auto Input::getNumControllers() const -> int { return gamepads_.size(); }
|
auto Input::getNumGamepads() const -> int { return gamepads_.size(); }
|
||||||
|
|
||||||
// Obtiene el indice del controlador a partir de un event.id
|
// Obtiene el indice del controlador a partir de un event.id
|
||||||
auto Input::getJoyIndex(SDL_JoystickID id) const -> int {
|
auto Input::getJoyIndex(SDL_JoystickID id) const -> int {
|
||||||
@@ -230,8 +230,8 @@ auto Input::checkAxisInput(Action input, std::shared_ptr<Gamepad> gamepad, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Input::addGamepadMappingsFromFile() {
|
void Input::addGamepadMappingsFromFile() {
|
||||||
if (SDL_AddGamepadMappingsFromFile(game_controller_db_path_.c_str()) < 0) {
|
if (SDL_AddGamepadMappingsFromFile(gamepad_mappings_file_.c_str()) < 0) {
|
||||||
std::cout << "Error, could not load " << game_controller_db_path_.c_str() << " file: " << SDL_GetError() << std::endl;
|
std::cout << "Error, could not load " << gamepad_mappings_file_.c_str() << " file: " << SDL_GetError() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,14 +362,13 @@ void Input::applyGamepadConfig(std::shared_ptr<Gamepad> gamepad) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Buscar configuración por nombre del gamepad
|
// Buscar configuración por nombre del gamepad
|
||||||
auto configIt = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(),
|
auto configIt = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), [&gamepad](const GamepadConfig &config) {
|
||||||
[&gamepad](const GamepadConfig& config) {
|
|
||||||
return config.name == gamepad->name;
|
return config.name == gamepad->name;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (configIt != gamepad_configs_.end()) {
|
if (configIt != gamepad_configs_.end()) {
|
||||||
// Aplicar la configuración encontrada al gamepad
|
// Aplicar la configuración encontrada al gamepad
|
||||||
for (const auto& [action, button] : configIt->bindings) {
|
for (const auto &[action, button] : configIt->bindings) {
|
||||||
if (gamepad->bindings.find(action) != gamepad->bindings.end()) {
|
if (gamepad->bindings.find(action) != gamepad->bindings.end()) {
|
||||||
gamepad->bindings[action].button = button;
|
gamepad->bindings[action].button = button;
|
||||||
}
|
}
|
||||||
@@ -383,8 +382,7 @@ void Input::saveGamepadConfigFromGamepad(std::shared_ptr<Gamepad> gamepad) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Buscar si ya existe una configuración con este nombre
|
// Buscar si ya existe una configuración con este nombre
|
||||||
auto configIt = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(),
|
auto configIt = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), [&gamepad](const GamepadConfig &config) {
|
||||||
[&gamepad](const GamepadConfig& config) {
|
|
||||||
return config.name == gamepad->name;
|
return config.name == gamepad->name;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -393,7 +391,7 @@ void Input::saveGamepadConfigFromGamepad(std::shared_ptr<Gamepad> gamepad) {
|
|||||||
newConfig.bindings.clear(); // Limpiar bindings por defecto
|
newConfig.bindings.clear(); // Limpiar bindings por defecto
|
||||||
|
|
||||||
// Copiar todos los bindings del gamepad
|
// Copiar todos los bindings del gamepad
|
||||||
for (const auto& [action, buttonState] : gamepad->bindings) {
|
for (const auto &[action, buttonState] : gamepad->bindings) {
|
||||||
newConfig.bindings[action] = buttonState.button;
|
newConfig.bindings[action] = buttonState.button;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,15 +408,14 @@ void Input::saveGamepadConfigFromGamepad(std::shared_ptr<Gamepad> gamepad) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Método para establecer el archivo de configuración (opcional)
|
// Método para establecer el archivo de configuración (opcional)
|
||||||
void Input::setGamepadConfigsFile(const std::string& filename) {
|
void Input::setGamepadConfigsFile(const std::string &filename) {
|
||||||
gamepad_configs_file_ = filename;
|
gamepad_configs_file_ = filename;
|
||||||
loadGamepadConfigs(); // Recargar con el nuevo archivo
|
loadGamepadConfigs(); // Recargar con el nuevo archivo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Método para obtener configuración de un gamepad específico (opcional)
|
// Método para obtener configuración de un gamepad específico (opcional)
|
||||||
GamepadConfig* Input::getGamepadConfig(const std::string& gamepadName) {
|
GamepadConfig *Input::getGamepadConfig(const std::string &gamepadName) {
|
||||||
auto configIt = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(),
|
auto configIt = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), [&gamepadName](const GamepadConfig &config) {
|
||||||
[&gamepadName](const GamepadConfig& config) {
|
|
||||||
return config.name == gamepadName;
|
return config.name == gamepadName;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -426,9 +423,8 @@ GamepadConfig* Input::getGamepadConfig(const std::string& gamepadName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Método para eliminar configuración de gamepad (opcional)
|
// Método para eliminar configuración de gamepad (opcional)
|
||||||
bool Input::removeGamepadConfig(const std::string& gamepadName) {
|
bool Input::removeGamepadConfig(const std::string &gamepadName) {
|
||||||
auto configIt = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(),
|
auto configIt = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), [&gamepadName](const GamepadConfig &config) {
|
||||||
[&gamepadName](const GamepadConfig& config) {
|
|
||||||
return config.name == gamepadName;
|
return config.name == gamepadName;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -49,54 +49,54 @@ class Input {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Keyboard {
|
struct Keyboard {
|
||||||
std::unordered_map<InputAction, KeyState> bindings;
|
std::unordered_map<Action, KeyState> bindings;
|
||||||
|
|
||||||
Keyboard()
|
Keyboard()
|
||||||
: bindings{
|
: bindings{
|
||||||
// Teclado - Movimiento del jugador
|
// Teclado - Movimiento del jugador
|
||||||
{InputAction::UP, KeyState(SDL_SCANCODE_UP)},
|
{Action::UP, KeyState(SDL_SCANCODE_UP)},
|
||||||
{InputAction::DOWN, KeyState(SDL_SCANCODE_DOWN)},
|
{Action::DOWN, KeyState(SDL_SCANCODE_DOWN)},
|
||||||
{InputAction::LEFT, KeyState(SDL_SCANCODE_LEFT)},
|
{Action::LEFT, KeyState(SDL_SCANCODE_LEFT)},
|
||||||
{InputAction::RIGHT, KeyState(SDL_SCANCODE_RIGHT)},
|
{Action::RIGHT, KeyState(SDL_SCANCODE_RIGHT)},
|
||||||
|
|
||||||
// Teclado - Disparo del jugador
|
// Teclado - Disparo del jugador
|
||||||
{InputAction::FIRE_LEFT, KeyState(SDL_SCANCODE_Q)},
|
{Action::FIRE_LEFT, KeyState(SDL_SCANCODE_Q)},
|
||||||
{InputAction::FIRE_CENTER, KeyState(SDL_SCANCODE_W)},
|
{Action::FIRE_CENTER, KeyState(SDL_SCANCODE_W)},
|
||||||
{InputAction::FIRE_RIGHT, KeyState(SDL_SCANCODE_E)},
|
{Action::FIRE_RIGHT, KeyState(SDL_SCANCODE_E)},
|
||||||
|
|
||||||
// Teclado - Interfaz
|
// Teclado - Interfaz
|
||||||
{InputAction::START, KeyState(SDL_SCANCODE_RETURN)},
|
{Action::START, KeyState(SDL_SCANCODE_RETURN)},
|
||||||
|
|
||||||
// Teclado - Menu de servicio
|
// Teclado - Menu de servicio
|
||||||
{InputAction::SERVICE, KeyState(SDL_SCANCODE_0)},
|
{Action::SERVICE, KeyState(SDL_SCANCODE_0)},
|
||||||
{InputAction::SM_SELECT, KeyState(SDL_SCANCODE_RETURN)},
|
{Action::SM_SELECT, KeyState(SDL_SCANCODE_RETURN)},
|
||||||
{InputAction::SM_BACK, KeyState(SDL_SCANCODE_BACKSPACE)},
|
{Action::SM_BACK, KeyState(SDL_SCANCODE_BACKSPACE)},
|
||||||
|
|
||||||
// Teclado - Control del programa
|
// Teclado - Control del programa
|
||||||
{InputAction::EXIT, KeyState(SDL_SCANCODE_ESCAPE)},
|
{Action::EXIT, KeyState(SDL_SCANCODE_ESCAPE)},
|
||||||
{InputAction::PAUSE, KeyState(SDL_SCANCODE_P)},
|
{Action::PAUSE, KeyState(SDL_SCANCODE_P)},
|
||||||
{InputAction::BACK, KeyState(SDL_SCANCODE_BACKSPACE)},
|
{Action::BACK, KeyState(SDL_SCANCODE_BACKSPACE)},
|
||||||
|
|
||||||
{InputAction::WINDOW_DEC_SIZE, KeyState(SDL_SCANCODE_F1)},
|
{Action::WINDOW_DEC_SIZE, KeyState(SDL_SCANCODE_F1)},
|
||||||
{InputAction::WINDOW_INC_SIZE, KeyState(SDL_SCANCODE_F2)},
|
{Action::WINDOW_INC_SIZE, KeyState(SDL_SCANCODE_F2)},
|
||||||
{InputAction::WINDOW_FULLSCREEN, KeyState(SDL_SCANCODE_F3)},
|
{Action::WINDOW_FULLSCREEN, KeyState(SDL_SCANCODE_F3)},
|
||||||
{InputAction::TOGGLE_VIDEO_SHADERS, KeyState(SDL_SCANCODE_F4)},
|
{Action::TOGGLE_VIDEO_SHADERS, KeyState(SDL_SCANCODE_F4)},
|
||||||
{InputAction::TOGGLE_VIDEO_INTEGER_SCALE, KeyState(SDL_SCANCODE_F5)},
|
{Action::TOGGLE_VIDEO_INTEGER_SCALE, KeyState(SDL_SCANCODE_F5)},
|
||||||
{InputAction::TOGGLE_VIDEO_VSYNC, KeyState(SDL_SCANCODE_F6)},
|
{Action::TOGGLE_VIDEO_VSYNC, KeyState(SDL_SCANCODE_F6)},
|
||||||
|
|
||||||
{InputAction::TOGGLE_AUDIO, KeyState(SDL_SCANCODE_F7)},
|
{Action::TOGGLE_AUDIO, KeyState(SDL_SCANCODE_F7)},
|
||||||
{InputAction::TOGGLE_AUTO_FIRE, KeyState(SDL_SCANCODE_F8)},
|
{Action::TOGGLE_AUTO_FIRE, KeyState(SDL_SCANCODE_F8)},
|
||||||
{InputAction::CHANGE_LANG, KeyState(SDL_SCANCODE_F9)},
|
{Action::CHANGE_LANG, KeyState(SDL_SCANCODE_F9)},
|
||||||
|
|
||||||
{InputAction::RESET, KeyState(SDL_SCANCODE_F10)},
|
{Action::RESET, KeyState(SDL_SCANCODE_F10)},
|
||||||
{InputAction::SHOW_INFO, KeyState(SDL_SCANCODE_F12)}} {}
|
{Action::SHOW_INFO, KeyState(SDL_SCANCODE_F12)}} {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Gamepad {
|
struct Gamepad {
|
||||||
SDL_Gamepad *pad;
|
SDL_Gamepad *pad;
|
||||||
SDL_JoystickID instance_id;
|
SDL_JoystickID instance_id;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::unordered_map<InputAction, ButtonState> bindings;
|
std::unordered_map<Action, ButtonState> bindings;
|
||||||
|
|
||||||
Gamepad(SDL_Gamepad *gamepad)
|
Gamepad(SDL_Gamepad *gamepad)
|
||||||
: pad(gamepad),
|
: pad(gamepad),
|
||||||
@@ -104,19 +104,19 @@ class Input {
|
|||||||
name(std::string(SDL_GetGamepadName(gamepad))),
|
name(std::string(SDL_GetGamepadName(gamepad))),
|
||||||
bindings{
|
bindings{
|
||||||
// Mando - Movimiento del jugador
|
// Mando - Movimiento del jugador
|
||||||
{InputAction::UP, ButtonState(SDL_GAMEPAD_BUTTON_DPAD_UP)},
|
{Action::UP, ButtonState(SDL_GAMEPAD_BUTTON_DPAD_UP)},
|
||||||
{InputAction::DOWN, ButtonState(SDL_GAMEPAD_BUTTON_DPAD_DOWN)},
|
{Action::DOWN, ButtonState(SDL_GAMEPAD_BUTTON_DPAD_DOWN)},
|
||||||
{InputAction::LEFT, ButtonState(SDL_GAMEPAD_BUTTON_DPAD_LEFT)},
|
{Action::LEFT, ButtonState(SDL_GAMEPAD_BUTTON_DPAD_LEFT)},
|
||||||
{InputAction::RIGHT, ButtonState(SDL_GAMEPAD_BUTTON_DPAD_RIGHT)},
|
{Action::RIGHT, ButtonState(SDL_GAMEPAD_BUTTON_DPAD_RIGHT)},
|
||||||
|
|
||||||
// Mando - Disparo del jugador
|
// Mando - Disparo del jugador
|
||||||
{InputAction::FIRE_LEFT, ButtonState(SDL_GAMEPAD_BUTTON_WEST)},
|
{Action::FIRE_LEFT, ButtonState(SDL_GAMEPAD_BUTTON_WEST)},
|
||||||
{InputAction::FIRE_CENTER, ButtonState(SDL_GAMEPAD_BUTTON_NORTH)},
|
{Action::FIRE_CENTER, ButtonState(SDL_GAMEPAD_BUTTON_NORTH)},
|
||||||
{InputAction::FIRE_RIGHT, ButtonState(SDL_GAMEPAD_BUTTON_EAST)},
|
{Action::FIRE_RIGHT, ButtonState(SDL_GAMEPAD_BUTTON_EAST)},
|
||||||
|
|
||||||
// Mando - Interfaz
|
// Mando - Interfaz
|
||||||
{InputAction::START, ButtonState(SDL_GAMEPAD_BUTTON_START)},
|
{Action::START, ButtonState(SDL_GAMEPAD_BUTTON_START)},
|
||||||
{InputAction::SERVICE, ButtonState(SDL_GAMEPAD_BUTTON_BACK)}} {}
|
{Action::SERVICE, ButtonState(SDL_GAMEPAD_BUTTON_BACK)}} {}
|
||||||
|
|
||||||
~Gamepad() {
|
~Gamepad() {
|
||||||
if (pad) {
|
if (pad) {
|
||||||
@@ -125,7 +125,7 @@ class Input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reasigna un botón a una acción
|
// Reasigna un botón a una acción
|
||||||
void rebindAction(InputAction action, SDL_GamepadButton new_button) {
|
void rebindAction(Action action, SDL_GamepadButton new_button) {
|
||||||
bindings[action] = new_button;
|
bindings[action] = new_button;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -149,7 +149,7 @@ class Input {
|
|||||||
// --- Métodos de gestión de mandos ---
|
// --- Métodos de gestión de mandos ---
|
||||||
[[nodiscard]] auto gameControllerFound() const -> bool;
|
[[nodiscard]] auto gameControllerFound() const -> bool;
|
||||||
auto getControllerName(std::shared_ptr<Gamepad> gamepad) const -> std::string;
|
auto getControllerName(std::shared_ptr<Gamepad> gamepad) const -> std::string;
|
||||||
[[nodiscard]] auto getNumControllers() const -> int;
|
[[nodiscard]] auto getNumGamepads() const -> int;
|
||||||
[[nodiscard]] auto getJoyIndex(SDL_JoystickID id) const -> int;
|
[[nodiscard]] auto getJoyIndex(SDL_JoystickID id) const -> int;
|
||||||
|
|
||||||
// --- Métodos de consulta y utilidades ---
|
// --- Métodos de consulta y utilidades ---
|
||||||
@@ -175,7 +175,7 @@ class Input {
|
|||||||
std::vector<std::shared_ptr<Gamepad>> gamepads_;
|
std::vector<std::shared_ptr<Gamepad>> gamepads_;
|
||||||
Keyboard keyboard_;
|
Keyboard keyboard_;
|
||||||
std::vector<Action> button_inputs_;
|
std::vector<Action> button_inputs_;
|
||||||
std::string game_controller_db_path_;
|
std::string gamepad_mappings_file_;
|
||||||
std::string gamepad_configs_file_;
|
std::string gamepad_configs_file_;
|
||||||
GamepadConfigs gamepad_configs_;
|
GamepadConfigs gamepad_configs_;
|
||||||
|
|
||||||
@@ -194,9 +194,9 @@ class Input {
|
|||||||
void saveGamepadConfigFromGamepad(std::shared_ptr<Gamepad> gamepad);
|
void saveGamepadConfigFromGamepad(std::shared_ptr<Gamepad> gamepad);
|
||||||
|
|
||||||
// Métodos auxiliares opcionales
|
// Métodos auxiliares opcionales
|
||||||
void setGamepadConfigsFile(const std::string& filename);
|
void setGamepadConfigsFile(const std::string &filename);
|
||||||
GamepadConfig* getGamepadConfig(const std::string& gamepadName);
|
GamepadConfig *getGamepadConfig(const std::string &gamepadName);
|
||||||
bool removeGamepadConfig(const std::string& gamepadName);
|
bool removeGamepadConfig(const std::string &gamepadName);
|
||||||
|
|
||||||
// --- Constructor y destructor ---
|
// --- Constructor y destructor ---
|
||||||
explicit Input(std::string game_controller_db_path, std::string gamepad_configs_file);
|
explicit Input(std::string game_controller_db_path, std::string gamepad_configs_file);
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ auto ManageHiScoreTable::add(const HiScoreEntry &entry) -> int {
|
|||||||
|
|
||||||
// Si el nuevo elemento quedó fuera del top 10
|
// Si el nuevo elemento quedó fuera del top 10
|
||||||
if (position >= 10) {
|
if (position >= 10) {
|
||||||
position = -1; // No entró en el top 10
|
position = NO_ENTRY; // No entró en el top 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,32 +22,29 @@ struct HiScoreEntry {
|
|||||||
: name(n.substr(0, 6)), score(s), one_credit_complete(occ) {}
|
: name(n.substr(0, 6)), score(s), one_credit_complete(occ) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using Table = std::vector<HiScoreEntry>;
|
||||||
|
|
||||||
// --- Clase ManageHiScoreTable ---
|
// --- Clase ManageHiScoreTable ---
|
||||||
class ManageHiScoreTable {
|
class ManageHiScoreTable {
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// --- Constantes ---
|
||||||
explicit ManageHiScoreTable(std::vector<HiScoreEntry> &table)
|
static constexpr int NO_ENTRY = -1;
|
||||||
: table_(table) {}
|
|
||||||
|
|
||||||
// Destructor
|
// Constructor y destructor
|
||||||
|
explicit ManageHiScoreTable(Table &table)
|
||||||
|
: table_(table) {}
|
||||||
~ManageHiScoreTable() = default;
|
~ManageHiScoreTable() = default;
|
||||||
|
|
||||||
// Resetea la tabla a los valores por defecto
|
// --- Métodos públicos ---
|
||||||
void clear();
|
void clear(); // Resetea la tabla a los valores por defecto
|
||||||
|
auto add(const HiScoreEntry &entry) -> int; // Añade un elemento a la tabla (devuelve la posición en la que se inserta)
|
||||||
// Añade un elemento a la tabla (devuelve la posición en la que se inserta)
|
auto loadFromFile(const std::string &file_path) -> bool; // Carga la tabla con los datos de un fichero
|
||||||
auto add(const HiScoreEntry &entry) -> int;
|
auto saveToFile(const std::string &file_path) -> bool; // Guarda la tabla en un fichero
|
||||||
|
|
||||||
// Carga la tabla con los datos de un fichero
|
|
||||||
auto loadFromFile(const std::string &file_path) -> bool;
|
|
||||||
|
|
||||||
// Guarda la tabla en un fichero
|
|
||||||
auto saveToFile(const std::string &file_path) -> bool;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Referencia a la tabla con los records
|
// --- Variables privadas ---
|
||||||
std::vector<HiScoreEntry> &table_;
|
Table &table_; // Referencia a la tabla con los records
|
||||||
|
|
||||||
// Ordena la tabla internamente
|
// --- Métodos privados ---
|
||||||
void sort();
|
void sort(); // Ordena la tabla
|
||||||
};
|
};
|
||||||
@@ -19,13 +19,13 @@
|
|||||||
|
|
||||||
namespace Options {
|
namespace Options {
|
||||||
// --- Variables globales ---
|
// --- Variables globales ---
|
||||||
WindowOptions window; // Opciones de la ventana
|
Window window; // Opciones de la ventana
|
||||||
SettingsOptions settings; // Opciones del juego
|
Settings settings; // Opciones del juego
|
||||||
VideoOptions video; // Opciones de vídeo
|
Video video; // Opciones de vídeo
|
||||||
AudioOptions audio; // Opciones de audio
|
Audio audio; // Opciones de audio
|
||||||
std::vector<GamepadOptions> controllers; // Opciones de mando para cada jugador
|
std::vector<std::shared_ptr<Gamepad>> gamepads; // Opciones de mando para cada jugador
|
||||||
|
Keyboard keyboard; // Opciones para el teclado
|
||||||
PendingChanges pending_changes; // Opciones que se aplican al cerrar
|
PendingChanges pending_changes; // Opciones que se aplican al cerrar
|
||||||
// std::vector<GamepadConfig> gamepad_configs; // Lista con las configuraciones registradas para cada mando
|
|
||||||
|
|
||||||
// Declaraciones
|
// Declaraciones
|
||||||
auto set(const std::string& var, const std::string& value) -> bool;
|
auto set(const std::string& var, const std::string& value) -> bool;
|
||||||
@@ -42,10 +42,10 @@ void init() {
|
|||||||
Difficulty::init();
|
Difficulty::init();
|
||||||
|
|
||||||
// Opciones de control
|
// Opciones de control
|
||||||
controllers.clear();
|
gamepads.clear();
|
||||||
controllers.emplace_back(GamepadOptions(1));
|
gamepads.emplace_back(std::make_shared<Gamepad>(Player::Id::PLAYER1));
|
||||||
controllers.emplace_back(GamepadOptions(2));
|
gamepads.emplace_back(std::make_shared<Gamepad>(Player::Id::PLAYER2));
|
||||||
setKeyboardToPlayer(1);
|
setKeyboardToPlayer(Player::Id::PLAYER1);
|
||||||
|
|
||||||
// Opciones de cambios pendientes
|
// Opciones de cambios pendientes
|
||||||
pending_changes.new_language = settings.language;
|
pending_changes.new_language = settings.language;
|
||||||
@@ -154,15 +154,15 @@ auto saveToFile() -> bool {
|
|||||||
// Opciones de mandos
|
// Opciones de mandos
|
||||||
file << "\n\n## CONTROLLERS\n";
|
file << "\n\n## CONTROLLERS\n";
|
||||||
|
|
||||||
int controller_index = 0;
|
// int controller_index = 0;
|
||||||
for (const auto& controller : controllers) {
|
// for (const auto& controller : gamepads) {
|
||||||
file << "\n";
|
// file << "\n";
|
||||||
file << "controller." << controller_index << ".name=" << controller.name << "\n";
|
// file << "controller." << controller_index << ".name=" << controller->name << "\n";
|
||||||
file << "controller." << controller_index << ".player=" << controller.player_id << "\n";
|
// file << "controller." << controller_index << ".player=" << controller->player_id << "\n";
|
||||||
|
//
|
||||||
// Incrementa el índice
|
// // Incrementa el índice
|
||||||
++controller_index;
|
// ++controller_index;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Cierra el fichero
|
// Cierra el fichero
|
||||||
file.close();
|
file.close();
|
||||||
@@ -173,19 +173,19 @@ auto saveToFile() -> bool {
|
|||||||
// Función auxiliar para analizar la configuración del mando y reducir duplicación
|
// Función auxiliar para analizar la configuración del mando y reducir duplicación
|
||||||
void parseAndSetController(const std::string& var, const std::string& value) {
|
void parseAndSetController(const std::string& var, const std::string& value) {
|
||||||
// Lógica básica de análisis (puede hacerse más robusta)
|
// Lógica básica de análisis (puede hacerse más robusta)
|
||||||
size_t first_dot = var.find('.');
|
// size_t first_dot = var.find('.');
|
||||||
size_t second_dot = var.find('.', first_dot + 1);
|
// size_t second_dot = var.find('.', first_dot + 1);
|
||||||
|
//
|
||||||
int controller_index = std::stoi(var.substr(first_dot + 1, second_dot - first_dot - 1));
|
// int controller_index = std::stoi(var.substr(first_dot + 1, second_dot - first_dot - 1));
|
||||||
std::string setting_key = var.substr(second_dot + 1);
|
// std::string setting_key = var.substr(second_dot + 1);
|
||||||
|
//
|
||||||
auto& controller = controllers.at(controller_index);
|
// auto& controller = gamepads.at(controller_index);
|
||||||
|
//
|
||||||
if (setting_key == "name") {
|
// if (setting_key == "name") {
|
||||||
controller.name = value;
|
// controller.name = value;
|
||||||
} else if (setting_key == "player") {
|
// } else if (setting_key == "player") {
|
||||||
controller.player_id = std::clamp(std::stoi(value), 1, 2);
|
// controller.player_id = std::clamp(std::stoi(value), 1, 2);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
auto set(const std::string& var, const std::string& value) -> bool {
|
auto set(const std::string& var, const std::string& value) -> bool {
|
||||||
@@ -254,35 +254,23 @@ auto set(const std::string& var, const std::string& value) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Asigna el teclado al jugador
|
// Asigna el teclado al jugador
|
||||||
void setKeyboardToPlayer(int player_id) {
|
void setKeyboardToPlayer(Player::Id player_id) {
|
||||||
for (auto& controller : controllers) {
|
keyboard.player_id = player_id;
|
||||||
if (controller.player_id == player_id) {
|
|
||||||
// controller.type = Input::Device::ANY;
|
|
||||||
} else {
|
|
||||||
// controller.type = Input::Device::CONTROLLER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intercambia el teclado de jugador
|
// Intercambia el teclado de jugador
|
||||||
void swapKeyboard() {
|
void swapKeyboard() {
|
||||||
// std::swap(controllers.at(0).type, controllers.at(1).type);
|
keyboard.player_id = keyboard.player_id == Player::Id::PLAYER1 ? Player::Id::PLAYER2 : Player::Id::PLAYER1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intercambia los jugadores asignados a los dos primeros mandos
|
// Intercambia los jugadores asignados a los dos primeros mandos
|
||||||
void swapControllers() {
|
void swapControllers() {
|
||||||
std::swap(controllers.at(0).player_id, controllers.at(1).player_id);
|
std::swap(gamepads.at(0)->player_id, gamepads.at(1)->player_id);
|
||||||
// std::swap(controllers.at(0).type, controllers.at(1).type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Averigua quien está usando el teclado
|
// Averigua quien está usando el teclado
|
||||||
auto getPlayerWhoUsesKeyboard() -> int {
|
auto getPlayerWhoUsesKeyboard() -> Player::Id {
|
||||||
// for (const auto& controller : controllers) {
|
return keyboard.player_id;
|
||||||
// if (controller.type == Input::Device::ANY) {
|
|
||||||
// return controller.player_id;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aplica los cambios pendientes copiando los valores a sus variables
|
// Aplica los cambios pendientes copiando los valores a sus variables
|
||||||
|
|||||||
@@ -9,27 +9,25 @@
|
|||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "difficulty.h" // Para Code
|
#include "difficulty.h" // Para Code
|
||||||
// #include "gamepad_config_manager.h"
|
|
||||||
#include "input.h" // Para InputAction, InputDevice
|
#include "input.h" // Para InputAction, InputDevice
|
||||||
#include "lang.h" // Para Code
|
#include "lang.h" // Para Code
|
||||||
#include "manage_hiscore_table.h" // Para HiScoreEntry
|
#include "manage_hiscore_table.h" // Para HiScoreEntry
|
||||||
|
#include "player.h" // Para Player
|
||||||
static constexpr int INVALID_INDEX = -1;
|
|
||||||
|
|
||||||
namespace Options {
|
namespace Options {
|
||||||
// --- Opciones de ventana ---
|
// --- Opciones de ventana ---
|
||||||
struct WindowOptions {
|
struct Window {
|
||||||
std::string caption; // Texto que aparece en la barra de título de la ventana
|
std::string caption; // Texto que aparece en la barra de título de la ventana
|
||||||
int zoom{2}; // Valor por el que se multiplica el tamaño de la ventana
|
int zoom{2}; // Valor por el que se multiplica el tamaño de la ventana
|
||||||
int max_zoom{2}; // Tamaño máximo para que la ventana no sea mayor que la pantalla
|
int max_zoom{2}; // Tamaño máximo para que la ventana no sea mayor que la pantalla
|
||||||
|
|
||||||
// Constructor por defecto con valores iniciales
|
// Constructor por defecto con valores iniciales
|
||||||
WindowOptions()
|
Window()
|
||||||
: caption("Coffee Crisis Arcade Edition") {}
|
: caption("Coffee Crisis Arcade Edition") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Opciones de vídeo ---
|
// --- Opciones de vídeo ---
|
||||||
struct VideoOptions {
|
struct Video {
|
||||||
SDL_ScaleMode scale_mode{SDL_ScaleMode::SDL_SCALEMODE_NEAREST}; // Filtro usado para el escalado de la imagen
|
SDL_ScaleMode scale_mode{SDL_ScaleMode::SDL_SCALEMODE_NEAREST}; // Filtro usado para el escalado de la imagen
|
||||||
bool fullscreen{false}; // Indica si se usa pantalla completa
|
bool fullscreen{false}; // Indica si se usa pantalla completa
|
||||||
bool vsync{true}; // Indica si se usa vsync
|
bool vsync{true}; // Indica si se usa vsync
|
||||||
@@ -38,69 +36,73 @@ struct VideoOptions {
|
|||||||
std::string info; // Información sobre el modo de vídeo
|
std::string info; // Información sobre el modo de vídeo
|
||||||
|
|
||||||
// Constructor por defecto con valores iniciales
|
// Constructor por defecto con valores iniciales
|
||||||
VideoOptions() = default;
|
Video() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Opciones de música ---
|
// --- Opciones de música ---
|
||||||
struct MusicOptions {
|
struct Music {
|
||||||
bool enabled{true}; // Indica si la música suena o no
|
bool enabled{true}; // Indica si la música suena o no
|
||||||
int volume{100}; // Volumen de la música
|
int volume{100}; // Volumen de la música
|
||||||
|
|
||||||
// Constructor por defecto
|
// Constructor por defecto
|
||||||
MusicOptions() = default;
|
Music() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Opciones de sonido ---
|
// --- Opciones de sonido ---
|
||||||
struct SoundOptions {
|
struct Sound {
|
||||||
bool enabled{true}; // Indica si los sonidos suenan o no
|
bool enabled{true}; // Indica si los sonidos suenan o no
|
||||||
int volume{100}; // Volumen de los sonidos
|
int volume{100}; // Volumen de los sonidos
|
||||||
|
|
||||||
// Constructor por defecto
|
// Constructor por defecto
|
||||||
SoundOptions() = default;
|
Sound() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Opciones de audio ---
|
// --- Opciones de audio ---
|
||||||
struct AudioOptions {
|
struct Audio {
|
||||||
MusicOptions music; // Opciones para la música
|
Music music; // Opciones para la música
|
||||||
SoundOptions sound; // Opciones para los efectos de sonido
|
Sound sound; // Opciones para los efectos de sonido
|
||||||
bool enabled{true}; // Indica si el audio está activo o no
|
bool enabled{true}; // Indica si el audio está activo o no
|
||||||
int volume{100}; // Volumen general del audio
|
int volume{100}; // Volumen general del audio
|
||||||
|
|
||||||
// Constructor por defecto
|
// Constructor por defecto
|
||||||
AudioOptions() = default;
|
Audio() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Opciones de configuración ---
|
// --- Opciones de configuración ---
|
||||||
struct SettingsOptions {
|
struct Settings {
|
||||||
Difficulty::Code difficulty{Difficulty::Code::NORMAL}; // Dificultad del juego
|
Difficulty::Code difficulty{Difficulty::Code::NORMAL}; // Dificultad del juego
|
||||||
Lang::Code language{Lang::Code::VALENCIAN}; // Idioma usado en el juego
|
Lang::Code language{Lang::Code::VALENCIAN}; // Idioma usado en el juego
|
||||||
bool autofire{true}; // Indicador de autofire
|
bool autofire{true}; // Indicador de autofire
|
||||||
bool shutdown_enabled{false}; // Especifica si se puede apagar el sistema
|
bool shutdown_enabled{false}; // Especifica si se puede apagar el sistema
|
||||||
std::vector<HiScoreEntry> hi_score_table; // Tabla de mejores puntuaciones
|
Table hi_score_table; // Tabla de mejores puntuaciones
|
||||||
std::vector<int> last_hi_score_entry; // Últimas posiciones de entrada en la tabla
|
std::vector<int> glowing_entries; // Últimas posiciones de entrada en la tabla
|
||||||
std::string config_file; // Ruta al fichero donde guardar la configuración y las opciones del juego
|
std::string config_file; // Ruta al fichero donde guardar la configuración y las opciones del juego
|
||||||
std::string controllers_file; // Ruta al fichero con las configuraciones de los mandos
|
std::string controllers_file; // Ruta al fichero con las configuraciones de los mandos
|
||||||
|
|
||||||
// Constructor por defecto con valores iniciales
|
// Constructor por defecto con valores iniciales
|
||||||
SettingsOptions()
|
Settings()
|
||||||
: last_hi_score_entry({INVALID_INDEX, INVALID_INDEX}) {}
|
: glowing_entries({ManageHiScoreTable::NO_ENTRY, ManageHiScoreTable::NO_ENTRY}) {}
|
||||||
|
|
||||||
// Reinicia las últimas entradas de puntuación
|
// Reinicia las últimas entradas de puntuación
|
||||||
void clearLastHiScoreEntries() {
|
void clearLastHiScoreEntries() {
|
||||||
last_hi_score_entry.at(0) = INVALID_INDEX;
|
glowing_entries.at(0) = ManageHiScoreTable::NO_ENTRY;
|
||||||
last_hi_score_entry.at(1) = INVALID_INDEX;
|
glowing_entries.at(1) = ManageHiScoreTable::NO_ENTRY;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GamepadOptions {
|
struct Gamepad {
|
||||||
std::shared_ptr<Input::Gamepad> gamepad = nullptr; // Referencia al mando
|
std::shared_ptr<Input::Gamepad> instance = nullptr; // Referencia al mando
|
||||||
std::string name; // Nombre del mando
|
std::string name; // Nombre del mando
|
||||||
int player_id; // Jugador asociado al mando
|
Player::Id player_id; // Jugador asociado al mando
|
||||||
|
|
||||||
GamepadOptions(int custom_player_id = INVALID_INDEX)
|
Gamepad(Player::Id custom_player_id = Player::Id::NO_PLAYER)
|
||||||
: player_id(custom_player_id) {}
|
: player_id(custom_player_id) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Keyboard {
|
||||||
|
Player::Id player_id = Player::Id::PLAYER1; // Jugador asociado al teclado
|
||||||
|
};
|
||||||
|
|
||||||
// --- Opciones pendientes de aplicar ---
|
// --- Opciones pendientes de aplicar ---
|
||||||
struct PendingChanges {
|
struct PendingChanges {
|
||||||
Lang::Code new_language{Lang::Code::VALENCIAN}; // Idioma en espera de aplicar
|
Lang::Code new_language{Lang::Code::VALENCIAN}; // Idioma en espera de aplicar
|
||||||
@@ -112,11 +114,12 @@ struct PendingChanges {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// --- Variables globales ---
|
// --- Variables globales ---
|
||||||
extern WindowOptions window; // Opciones de la ventana
|
extern Window window; // Opciones de la ventana
|
||||||
extern SettingsOptions settings; // Opciones del juego
|
extern Settings settings; // Opciones del juego
|
||||||
extern VideoOptions video; // Opciones de vídeo
|
extern Video video; // Opciones de vídeo
|
||||||
extern AudioOptions audio; // Opciones de audio
|
extern Audio audio; // Opciones de audio
|
||||||
extern std::vector<GamepadOptions> controllers; // Opciones de mando para cada jugador
|
extern std::vector<std::shared_ptr<Gamepad>> gamepads; // Opciones de mando para cada jugador
|
||||||
|
extern Keyboard keyboard; // Opciones para el teclado
|
||||||
extern PendingChanges pending_changes; // Opciones que se aplican al cerrar
|
extern PendingChanges pending_changes; // Opciones que se aplican al cerrar
|
||||||
|
|
||||||
// --- Funciones de configuración ---
|
// --- Funciones de configuración ---
|
||||||
@@ -125,10 +128,10 @@ void setConfigFile(const std::string &file_path); // Establece el fichero
|
|||||||
void setControllersFile(const std::string &file_path); // Establece el fichero de configuración de mandos
|
void setControllersFile(const std::string &file_path); // Establece el fichero de configuración de mandos
|
||||||
auto loadFromFile() -> bool; // Carga el fichero de configuración
|
auto loadFromFile() -> bool; // Carga el fichero de configuración
|
||||||
auto saveToFile() -> bool; // Guarda el fichero de configuración
|
auto saveToFile() -> bool; // Guarda el fichero de configuración
|
||||||
void setKeyboardToPlayer(int player_id); // Asigna el teclado al jugador
|
void setKeyboardToPlayer(Player::Id player_id); // Asigna el teclado al jugador
|
||||||
void swapKeyboard(); // Intercambia el teclado de jugador
|
void swapKeyboard(); // Intercambia el teclado de jugador
|
||||||
void swapControllers(); // Intercambia los jugadores asignados a los dos primeros mandos
|
void swapControllers(); // Intercambia los jugadores asignados a los dos primeros mandos
|
||||||
auto getPlayerWhoUsesKeyboard() -> int; // Averigua quién está usando el teclado
|
auto getPlayerWhoUsesKeyboard() -> Player::Id; // Averigua quién está usando el teclado
|
||||||
void applyPendingChanges(); // Aplica los cambios pendientes copiando los valores a sus variables
|
void applyPendingChanges(); // Aplica los cambios pendientes copiando los valores a sus variables
|
||||||
void checkPendingChanges(); // Verifica si hay cambios pendientes
|
void checkPendingChanges(); // Verifica si hay cambios pendientes
|
||||||
|
|
||||||
|
|||||||
@@ -16,20 +16,22 @@
|
|||||||
#include "texture.h" // Para Texture
|
#include "texture.h" // Para Texture
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Player::Player(int id, float x, int y, bool demo, SDL_FRect &play_area, std::vector<std::shared_ptr<Texture>> texture, const std::vector<std::vector<std::string>> &animations)
|
Player::Player(const Config& config)
|
||||||
: player_sprite_(std::make_unique<AnimatedSprite>(texture.at(0), animations.at(0))),
|
: player_sprite_(std::make_unique<AnimatedSprite>(config.texture.at(0), config.animations.at(0))),
|
||||||
power_sprite_(std::make_unique<AnimatedSprite>(texture.at(1), animations.at(1))),
|
power_sprite_(std::make_unique<AnimatedSprite>(config.texture.at(1), config.animations.at(1))),
|
||||||
enter_name_(std::make_unique<EnterName>()),
|
enter_name_(std::make_unique<EnterName>()),
|
||||||
id_(id),
|
id_(config.id),
|
||||||
play_area_(play_area),
|
play_area_(*config.play_area),
|
||||||
default_pos_x_(x),
|
default_pos_x_(config.x),
|
||||||
default_pos_y_(y),
|
default_pos_y_(config.y),
|
||||||
demo_(demo) {
|
hi_score_table_(*config.hi_score_table),
|
||||||
|
glowing_entry_(*config.glowing_entry),
|
||||||
|
demo_(config.demo) {
|
||||||
// Configura objetos
|
// Configura objetos
|
||||||
player_sprite_->getTexture()->setPalette(coffees_);
|
player_sprite_->getTexture()->setPalette(coffees_);
|
||||||
power_sprite_->getTexture()->setAlpha(224);
|
power_sprite_->getTexture()->setAlpha(224);
|
||||||
power_up_x_offset_ = (power_sprite_->getWidth() - player_sprite_->getWidth()) / 2;
|
power_up_x_offset_ = (power_sprite_->getWidth() - player_sprite_->getWidth()) / 2;
|
||||||
power_sprite_->setPosY(y - (power_sprite_->getHeight() - player_sprite_->getHeight()));
|
power_sprite_->setPosY(default_pos_y_ - (power_sprite_->getHeight() - player_sprite_->getHeight()));
|
||||||
|
|
||||||
// Inicializa variables
|
// Inicializa variables
|
||||||
pos_x_ = default_pos_x_;
|
pos_x_ = default_pos_x_;
|
||||||
@@ -219,8 +221,8 @@ void Player::handleRollingGroundCollision() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Player::handleRollingStop() {
|
void Player::handleRollingStop() {
|
||||||
const auto NEXT_PLAYER_STATUS = isEligibleForHighScore() ? State::ENTERING_NAME : State::CONTINUE;
|
const auto NEXT_PLAYER_STATE = qualifiesForHighScore() ? State::ENTERING_NAME : State::CONTINUE;
|
||||||
const auto NEXT_STATE = demo_ ? State::LYING_ON_THE_FLOOR_FOREVER : NEXT_PLAYER_STATUS;
|
const auto NEXT_STATE = demo_ ? State::LYING_ON_THE_FLOOR_FOREVER : NEXT_PLAYER_STATE;
|
||||||
|
|
||||||
setPlayingState(NEXT_STATE);
|
setPlayingState(NEXT_STATE);
|
||||||
pos_x_ = player_sprite_->getPosX();
|
pos_x_ = player_sprite_->getPosX();
|
||||||
@@ -278,10 +280,15 @@ void Player::handleLeavingScreen() {
|
|||||||
void Player::handleEnteringScreen() {
|
void Player::handleEnteringScreen() {
|
||||||
updateStepCounter();
|
updateStepCounter();
|
||||||
|
|
||||||
if (id_ == 1) {
|
switch (id_) {
|
||||||
|
case Id::PLAYER1:
|
||||||
handlePlayer1Entering();
|
handlePlayer1Entering();
|
||||||
} else if (id_ == 2) {
|
break;
|
||||||
|
case Id::PLAYER2:
|
||||||
handlePlayer2Entering();
|
handlePlayer2Entering();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
shiftSprite();
|
shiftSprite();
|
||||||
@@ -350,10 +357,10 @@ void Player::updateWalkingStateForCredits() {
|
|||||||
|
|
||||||
void Player::setInputBasedOnPlayerId() {
|
void Player::setInputBasedOnPlayerId() {
|
||||||
switch (id_) {
|
switch (id_) {
|
||||||
case 1:
|
case Id::PLAYER1:
|
||||||
setInputPlaying(Input::Action::LEFT);
|
setInputPlaying(Input::Action::LEFT);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case Id::PLAYER2:
|
||||||
setInputPlaying(Input::Action::RIGHT);
|
setInputPlaying(Input::Action::RIGHT);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -552,9 +559,10 @@ void Player::update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Incrementa la puntuación del jugador
|
// Incrementa la puntuación del jugador
|
||||||
void Player::addScore(int score) {
|
void Player::addScore(int score, int last_hi_score_entry) {
|
||||||
if (isPlaying()) {
|
if (isPlaying()) {
|
||||||
score_ += score;
|
score_ += score;
|
||||||
|
qualifies_for_high_score_ = score_ > last_hi_score_entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,10 +619,10 @@ void Player::setPlayingState(State state) {
|
|||||||
}
|
}
|
||||||
case State::WAITING: {
|
case State::WAITING: {
|
||||||
switch (id_) {
|
switch (id_) {
|
||||||
case 1:
|
case Id::PLAYER1:
|
||||||
pos_x_ = param.game.game_area.rect.x;
|
pos_x_ = param.game.game_area.rect.x;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case Id::PLAYER2:
|
||||||
pos_x_ = param.game.game_area.rect.w - WIDTH;
|
pos_x_ = param.game.game_area.rect.w - WIDTH;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -698,11 +706,11 @@ void Player::setPlayingState(State state) {
|
|||||||
step_counter_ = 0;
|
step_counter_ = 0;
|
||||||
setScoreboardMode(Scoreboard::Mode::SCORE);
|
setScoreboardMode(Scoreboard::Mode::SCORE);
|
||||||
switch (id_) {
|
switch (id_) {
|
||||||
case 1:
|
case Id::PLAYER1:
|
||||||
pos_x_ = param.game.game_area.rect.x - WIDTH;
|
pos_x_ = param.game.game_area.rect.x - WIDTH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case Id::PLAYER2:
|
||||||
pos_x_ = param.game.game_area.rect.x + param.game.game_area.rect.w;
|
pos_x_ = param.game.game_area.rect.x + param.game.game_area.rect.w;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -898,7 +906,7 @@ auto Player::isRenderable() const -> bool {
|
|||||||
// Añade una puntuación a la tabla de records
|
// Añade una puntuación a la tabla de records
|
||||||
void Player::addScoreToScoreBoard() const {
|
void Player::addScoreToScoreBoard() const {
|
||||||
const auto ENTRY = HiScoreEntry(trim(getLastEnterName()), getScore(), get1CC());
|
const auto ENTRY = HiScoreEntry(trim(getLastEnterName()), getScore(), get1CC());
|
||||||
auto manager = std::make_unique<ManageHiScoreTable>(Options::settings.hi_score_table);
|
auto manager = std::make_unique<ManageHiScoreTable>(hi_score_table_);
|
||||||
Options::settings.last_hi_score_entry.at(getId() - 1) = manager->add(ENTRY);
|
glowing_entry_ = manager->add(ENTRY);
|
||||||
manager->saveToFile(Asset::get()->get("score.bin"));
|
manager->saveToFile(Asset::get()->get("score.bin"));
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,6 @@
|
|||||||
#include "enter_name.h" // Para EnterName
|
#include "enter_name.h" // Para EnterName
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "manage_hiscore_table.h" // Para HiScoreEntry
|
#include "manage_hiscore_table.h" // Para HiScoreEntry
|
||||||
#include "options.h" // Para SettingsOptions, settings
|
|
||||||
#include "scoreboard.h" // Para Scoreboard
|
#include "scoreboard.h" // Para Scoreboard
|
||||||
#include "utils.h" // Para Circle
|
#include "utils.h" // Para Circle
|
||||||
|
|
||||||
@@ -25,6 +24,14 @@ class Player {
|
|||||||
static constexpr int WIDTH = 32; // Anchura
|
static constexpr int WIDTH = 32; // Anchura
|
||||||
static constexpr int HEIGHT = 32; // Altura
|
static constexpr int HEIGHT = 32; // Altura
|
||||||
|
|
||||||
|
// --- Id para los jugadores ---
|
||||||
|
enum class Id : int {
|
||||||
|
NO_PLAYER = -1,
|
||||||
|
BOTH_PLAYERS = 0,
|
||||||
|
PLAYER1 = 1,
|
||||||
|
PLAYER2 = 2
|
||||||
|
};
|
||||||
|
|
||||||
// --- Estados posibles del jugador ---
|
// --- Estados posibles del jugador ---
|
||||||
enum class State {
|
enum class State {
|
||||||
// Estados de movimiento
|
// Estados de movimiento
|
||||||
@@ -68,8 +75,20 @@ class Player {
|
|||||||
RESPAWNING, // Tras continuar y volver al juego
|
RESPAWNING, // Tras continuar y volver al juego
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Config {
|
||||||
|
Id id;
|
||||||
|
float x;
|
||||||
|
int y;
|
||||||
|
bool demo;
|
||||||
|
SDL_FRect *play_area; // Usamos puntero para mantener la referencia
|
||||||
|
std::vector<std::shared_ptr<Texture>> texture;
|
||||||
|
std::vector<std::vector<std::string>> animations;
|
||||||
|
Table *hi_score_table; // También como puntero para referencia
|
||||||
|
int *glowing_entry; // Puntero para mantener la referencia
|
||||||
|
};
|
||||||
|
|
||||||
// --- Constructor y destructor ---
|
// --- Constructor y destructor ---
|
||||||
Player(int id, float x, int y, bool demo, SDL_FRect &play_area, std::vector<std::shared_ptr<Texture>> texture, const std::vector<std::vector<std::string>> &animations);
|
Player(const Config& config);
|
||||||
~Player() = default;
|
~Player() = default;
|
||||||
|
|
||||||
// --- Inicialización y ciclo de vida ---
|
// --- Inicialización y ciclo de vida ---
|
||||||
@@ -93,7 +112,7 @@ class Player {
|
|||||||
void updateCooldown(); // Actualiza el cooldown de disparo
|
void updateCooldown(); // Actualiza el cooldown de disparo
|
||||||
|
|
||||||
// --- Puntuación y marcador ---
|
// --- Puntuación y marcador ---
|
||||||
void addScore(int score); // Añade puntos
|
void addScore(int score, int last_hi_score_entry); // Añade puntos
|
||||||
void incScoreMultiplier(); // Incrementa el multiplicador
|
void incScoreMultiplier(); // Incrementa el multiplicador
|
||||||
void decScoreMultiplier(); // Decrementa el multiplicador
|
void decScoreMultiplier(); // Decrementa el multiplicador
|
||||||
|
|
||||||
@@ -128,7 +147,7 @@ class Player {
|
|||||||
[[nodiscard]] auto hasExtraHit() const -> bool { return extra_hit_; }
|
[[nodiscard]] auto hasExtraHit() const -> bool { return extra_hit_; }
|
||||||
[[nodiscard]] auto isCooling() const -> bool { return firing_state_ == State::COOLING_LEFT || firing_state_ == State::COOLING_UP || firing_state_ == State::COOLING_RIGHT; }
|
[[nodiscard]] auto isCooling() const -> bool { return firing_state_ == State::COOLING_LEFT || firing_state_ == State::COOLING_UP || firing_state_ == State::COOLING_RIGHT; }
|
||||||
[[nodiscard]] auto isRecoiling() const -> bool { return firing_state_ == State::RECOILING_LEFT || firing_state_ == State::RECOILING_UP || firing_state_ == State::RECOILING_RIGHT; }
|
[[nodiscard]] auto isRecoiling() const -> bool { return firing_state_ == State::RECOILING_LEFT || firing_state_ == State::RECOILING_UP || firing_state_ == State::RECOILING_RIGHT; }
|
||||||
[[nodiscard]] auto isEligibleForHighScore() const -> bool { return score_ > Options::settings.hi_score_table.back().score; }
|
[[nodiscard]] auto qualifiesForHighScore() const -> bool { return qualifies_for_high_score_; }
|
||||||
[[nodiscard]] auto isInvulnerable() const -> bool { return invulnerable_; }
|
[[nodiscard]] auto isInvulnerable() const -> bool { return invulnerable_; }
|
||||||
[[nodiscard]] auto isPowerUp() const -> bool { return power_up_; }
|
[[nodiscard]] auto isPowerUp() const -> bool { return power_up_; }
|
||||||
auto getCollider() -> Circle & { return collider_; }
|
auto getCollider() -> Circle & { return collider_; }
|
||||||
@@ -137,7 +156,7 @@ class Player {
|
|||||||
[[nodiscard]] auto getContinueCounter() const -> int { return continue_counter_; }
|
[[nodiscard]] auto getContinueCounter() const -> int { return continue_counter_; }
|
||||||
[[nodiscard]] auto getController() const -> int { return controller_index_; }
|
[[nodiscard]] auto getController() const -> int { return controller_index_; }
|
||||||
[[nodiscard]] static auto getHeight() -> int { return HEIGHT; }
|
[[nodiscard]] static auto getHeight() -> int { return HEIGHT; }
|
||||||
[[nodiscard]] auto getId() const -> int { return id_; }
|
[[nodiscard]] auto getId() const -> Player::Id { return id_; }
|
||||||
[[nodiscard]] auto getInvulnerableCounter() const -> int { return invulnerable_counter_; }
|
[[nodiscard]] auto getInvulnerableCounter() const -> int { return invulnerable_counter_; }
|
||||||
[[nodiscard]] auto getPosX() const -> int { return static_cast<int>(pos_x_); }
|
[[nodiscard]] auto getPosX() const -> int { return static_cast<int>(pos_x_); }
|
||||||
[[nodiscard]] auto getPosY() const -> int { return pos_y_; }
|
[[nodiscard]] auto getPosY() const -> int { return pos_y_; }
|
||||||
@@ -165,11 +184,13 @@ class Player {
|
|||||||
void setWalkingState(State state) { walking_state_ = state; }
|
void setWalkingState(State state) { walking_state_ = state; }
|
||||||
void addCredit() { ++credits_used_; }
|
void addCredit() { ++credits_used_; }
|
||||||
|
|
||||||
// Setter y getter para gamepad_
|
|
||||||
void setGamepad(std::shared_ptr<Input::Gamepad> gamepad) { gamepad_ = gamepad; }
|
void setGamepad(std::shared_ptr<Input::Gamepad> gamepad) { gamepad_ = gamepad; }
|
||||||
[[nodiscard]] std::shared_ptr<Input::Gamepad> getGamepad() const { return gamepad_; }
|
[[nodiscard]] std::shared_ptr<Input::Gamepad> getGamepad() const { return gamepad_; }
|
||||||
void setUsesKeyboard(bool value) { uses_keyboard_ = value; }
|
void setUsesKeyboard(bool value) { uses_keyboard_ = value; }
|
||||||
[[nodiscard]] bool getUsesKeyboard() const { return uses_keyboard_; }
|
[[nodiscard]] bool getUsesKeyboard() const { return uses_keyboard_; }
|
||||||
|
void setHiScoreTable(const Table &table) { hi_score_table_ = table; }
|
||||||
|
const Table &getHiScoreTable() const { return hi_score_table_; }
|
||||||
|
void setGlowingEntry(const int &entry) { glowing_entry_ = entry; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Constantes ---
|
// --- Constantes ---
|
||||||
@@ -186,7 +207,7 @@ class Player {
|
|||||||
std::unique_ptr<EnterName> enter_name_; // Clase utilizada para introducir el nombre
|
std::unique_ptr<EnterName> enter_name_; // Clase utilizada para introducir el nombre
|
||||||
|
|
||||||
// --- Variables de estado ---
|
// --- Variables de estado ---
|
||||||
int id_; // Número de identificación para el jugador. Player1 = 1, Player2 = 2
|
Id id_; // Identificador para el jugador
|
||||||
SDL_FRect play_area_; // Rectángulo con la zona de juego
|
SDL_FRect play_area_; // Rectángulo con la zona de juego
|
||||||
float pos_x_ = 0.0F; // Posición en el eje X
|
float pos_x_ = 0.0F; // Posición en el eje X
|
||||||
int pos_y_ = 0; // Posición en el eje Y
|
int pos_y_ = 0; // Posición en el eje Y
|
||||||
@@ -200,6 +221,9 @@ class Player {
|
|||||||
int cooling_state_counter_ = 0; // Contador para la animación del estado cooling
|
int cooling_state_counter_ = 0; // Contador para la animación del estado cooling
|
||||||
int score_ = 0; // Puntos del jugador
|
int score_ = 0; // Puntos del jugador
|
||||||
float score_multiplier_ = 1.0F; // Multiplicador de puntos
|
float score_multiplier_ = 1.0F; // Multiplicador de puntos
|
||||||
|
bool qualifies_for_high_score_ = false; // Indica si tiene una puntuación que le permite entrar en la tabla de records
|
||||||
|
Table &hi_score_table_; // Tabla de maximas puntuaciones
|
||||||
|
int &glowing_entry_; // Entrada de la tabla de puntuaciones para hacerla brillar
|
||||||
State walking_state_ = State::WALKING_STOP; // Estado del jugador al moverse
|
State walking_state_ = State::WALKING_STOP; // Estado del jugador al moverse
|
||||||
State firing_state_ = State::FIRING_NONE; // Estado del jugador al disparar
|
State firing_state_ = State::FIRING_NONE; // Estado del jugador al disparar
|
||||||
State playing_state_ = State::WAITING; // Estado del jugador en el juego
|
State playing_state_ = State::WAITING; // Estado del jugador en el juego
|
||||||
|
|||||||
@@ -353,11 +353,32 @@ void Credits::initPlayers() {
|
|||||||
const int Y = play_area_.y + play_area_.h - PLAYER_WIDTH;
|
const int Y = play_area_.y + play_area_.h - PLAYER_WIDTH;
|
||||||
constexpr bool DEMO = false;
|
constexpr bool DEMO = false;
|
||||||
constexpr int AWAY_DISTANCE = 700;
|
constexpr int AWAY_DISTANCE = 700;
|
||||||
players_.emplace_back(std::make_unique<Player>(1, play_area_.x - AWAY_DISTANCE - PLAYER_WIDTH, Y, DEMO, play_area_, player_textures.at(0), player_animations));
|
|
||||||
|
Player::Config config_player1;
|
||||||
|
config_player1.id = Player::Id::PLAYER1;
|
||||||
|
config_player1.x = play_area_.x - AWAY_DISTANCE - PLAYER_WIDTH;
|
||||||
|
config_player1.y = Y;
|
||||||
|
config_player1.demo = DEMO;
|
||||||
|
config_player1.play_area = &play_area_;
|
||||||
|
config_player1.texture = player_textures.at(0);
|
||||||
|
config_player1.animations = player_animations;
|
||||||
|
config_player1.hi_score_table = &Options::settings.hi_score_table;
|
||||||
|
config_player1.glowing_entry = &Options::settings.glowing_entries.at(static_cast<int>(Player::Id::PLAYER1) - 1);
|
||||||
|
players_.emplace_back(std::make_unique<Player>(config_player1));
|
||||||
players_.back()->setWalkingState(Player::State::WALKING_RIGHT);
|
players_.back()->setWalkingState(Player::State::WALKING_RIGHT);
|
||||||
players_.back()->setPlayingState(Player::State::CREDITS);
|
players_.back()->setPlayingState(Player::State::CREDITS);
|
||||||
|
|
||||||
players_.emplace_back(std::make_unique<Player>(2, play_area_.x + play_area_.w + AWAY_DISTANCE, Y, DEMO, play_area_, player_textures.at(1), player_animations));
|
Player::Config config_player2;
|
||||||
|
config_player2.id = Player::Id::PLAYER2;
|
||||||
|
config_player2.x = play_area_.x + play_area_.w + AWAY_DISTANCE;
|
||||||
|
config_player2.y = Y;
|
||||||
|
config_player2.demo = DEMO;
|
||||||
|
config_player2.play_area = &play_area_;
|
||||||
|
config_player2.texture = player_textures.at(1);
|
||||||
|
config_player2.animations = player_animations;
|
||||||
|
config_player2.hi_score_table = &Options::settings.hi_score_table;
|
||||||
|
config_player2.glowing_entry = &Options::settings.glowing_entries.at(static_cast<int>(Player::Id::PLAYER2) - 1);
|
||||||
|
players_.emplace_back(std::make_unique<Player>(config_player2));
|
||||||
players_.back()->setWalkingState(Player::State::WALKING_LEFT);
|
players_.back()->setWalkingState(Player::State::WALKING_LEFT);
|
||||||
players_.back()->setPlayingState(Player::State::CREDITS);
|
players_.back()->setPlayingState(Player::State::CREDITS);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
#include "ui/service_menu.h" // Para ServiceMenu
|
#include "ui/service_menu.h" // Para ServiceMenu
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Game::Game(int player_id, int current_stage, bool demo)
|
Game::Game(Player::Id player_id, int current_stage, bool demo)
|
||||||
: renderer_(Screen::get()->getRenderer()),
|
: renderer_(Screen::get()->getRenderer()),
|
||||||
screen_(Screen::get()),
|
screen_(Screen::get()),
|
||||||
input_(Input::get()),
|
input_(Input::get()),
|
||||||
@@ -365,7 +365,7 @@ void Game::updateGameStateCompleted() {
|
|||||||
|
|
||||||
for (auto &player : players_) {
|
for (auto &player : players_) {
|
||||||
if (player->isPlaying()) {
|
if (player->isPlaying()) {
|
||||||
player->addScore(1000000);
|
player->addScore(1000000, Options::settings.hi_score_table.back().score);
|
||||||
player->setPlayingState(Player::State::CELEBRATING);
|
player->setPlayingState(Player::State::CELEBRATING);
|
||||||
} else {
|
} else {
|
||||||
player->setPlayingState(Player::State::GAME_OVER);
|
player->setPlayingState(Player::State::GAME_OVER);
|
||||||
@@ -379,7 +379,7 @@ void Game::updateGameStateCompleted() {
|
|||||||
if (game_completed_counter_ == END_CELEBRATIONS) {
|
if (game_completed_counter_ == END_CELEBRATIONS) {
|
||||||
for (auto &player : players_) {
|
for (auto &player : players_) {
|
||||||
if (player->isCelebrating()) {
|
if (player->isCelebrating()) {
|
||||||
player->setPlayingState(player->isEligibleForHighScore() ? Player::State::ENTERING_NAME_GAME_COMPLETED : Player::State::LEAVING_SCREEN);
|
player->setPlayingState(player->qualifiesForHighScore() ? Player::State::ENTERING_NAME_GAME_COMPLETED : Player::State::LEAVING_SCREEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -435,28 +435,28 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player) {
|
|||||||
if (checkCollision(player->getCollider(), item->getCollider())) {
|
if (checkCollision(player->getCollider(), item->getCollider())) {
|
||||||
switch (item->getType()) {
|
switch (item->getType()) {
|
||||||
case ItemType::DISK: {
|
case ItemType::DISK: {
|
||||||
player->addScore(1000);
|
player->addScore(1000, Options::settings.hi_score_table.back().score);
|
||||||
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(0)->getWidth()) / 2;
|
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(0)->getWidth()) / 2;
|
||||||
createItemText(X, game_text_textures_.at(0));
|
createItemText(X, game_text_textures_.at(0));
|
||||||
playSound("item_pickup.wav");
|
playSound("item_pickup.wav");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ItemType::GAVINA: {
|
case ItemType::GAVINA: {
|
||||||
player->addScore(2500);
|
player->addScore(2500, Options::settings.hi_score_table.back().score);
|
||||||
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(1)->getWidth()) / 2;
|
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(1)->getWidth()) / 2;
|
||||||
createItemText(X, game_text_textures_.at(1));
|
createItemText(X, game_text_textures_.at(1));
|
||||||
playSound("item_pickup.wav");
|
playSound("item_pickup.wav");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ItemType::PACMAR: {
|
case ItemType::PACMAR: {
|
||||||
player->addScore(5000);
|
player->addScore(5000, Options::settings.hi_score_table.back().score);
|
||||||
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(2)->getWidth()) / 2;
|
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(2)->getWidth()) / 2;
|
||||||
createItemText(X, game_text_textures_.at(2));
|
createItemText(X, game_text_textures_.at(2));
|
||||||
playSound("item_pickup.wav");
|
playSound("item_pickup.wav");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ItemType::DEBIAN: {
|
case ItemType::DEBIAN: {
|
||||||
player->addScore(100000);
|
player->addScore(100000, Options::settings.hi_score_table.back().score);
|
||||||
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(6)->getWidth()) / 2;
|
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(6)->getWidth()) / 2;
|
||||||
createItemText(X, game_text_textures_.at(6));
|
createItemText(X, game_text_textures_.at(6));
|
||||||
playSound("debian_pickup.wav");
|
playSound("debian_pickup.wav");
|
||||||
@@ -471,7 +471,7 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player) {
|
|||||||
}
|
}
|
||||||
case ItemType::COFFEE: {
|
case ItemType::COFFEE: {
|
||||||
if (player->getCoffees() == 2) {
|
if (player->getCoffees() == 2) {
|
||||||
player->addScore(5000);
|
player->addScore(5000, Options::settings.hi_score_table.back().score);
|
||||||
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(2)->getWidth()) / 2;
|
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(2)->getWidth()) / 2;
|
||||||
createItemText(X, game_text_textures_.at(2));
|
createItemText(X, game_text_textures_.at(2));
|
||||||
} else {
|
} else {
|
||||||
@@ -594,11 +594,11 @@ void Game::handleItemDrop(std::shared_ptr<Balloon> balloon, std::shared_ptr<Play
|
|||||||
|
|
||||||
// Maneja la destrucción del globo y puntuación
|
// Maneja la destrucción del globo y puntuación
|
||||||
void Game::handleBalloonDestruction(std::shared_ptr<Balloon> balloon, std::shared_ptr<Player> player) {
|
void Game::handleBalloonDestruction(std::shared_ptr<Balloon> balloon, std::shared_ptr<Player> player) {
|
||||||
const auto SCORE = balloon_manager_->popBalloon(balloon);
|
|
||||||
evaluateAndSetMenace();
|
evaluateAndSetMenace();
|
||||||
|
|
||||||
if (player->isPlaying()) {
|
if (player->isPlaying()) {
|
||||||
player->addScore(SCORE * player->getScoreMultiplier() * difficulty_score_multiplier_);
|
auto const SCORE = balloon_manager_->popBalloon(balloon) * player->getScoreMultiplier() * difficulty_score_multiplier_;
|
||||||
|
player->addScore(SCORE, Options::settings.hi_score_table.back().score);
|
||||||
player->incScoreMultiplier();
|
player->incScoreMultiplier();
|
||||||
}
|
}
|
||||||
updateHiScore();
|
updateHiScore();
|
||||||
@@ -621,7 +621,7 @@ void Game::renderBullets() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Crea un objeto bala
|
// Crea un objeto bala
|
||||||
void Game::createBullet(int x, int y, BulletType kind, bool powered_up, int owner) {
|
void Game::createBullet(int x, int y, BulletType kind, bool powered_up, Player::Id owner) {
|
||||||
bullets_.emplace_back(std::make_shared<Bullet>(x, y, kind, powered_up, owner));
|
bullets_.emplace_back(std::make_shared<Bullet>(x, y, kind, powered_up, owner));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1174,7 +1174,7 @@ void Game::pause(bool value) {
|
|||||||
void Game::addScoreToScoreBoard(const std::shared_ptr<Player> &player) {
|
void Game::addScoreToScoreBoard(const std::shared_ptr<Player> &player) {
|
||||||
const auto ENTRY = HiScoreEntry(trim(player->getLastEnterName()), player->getScore(), player->get1CC());
|
const auto ENTRY = HiScoreEntry(trim(player->getLastEnterName()), player->getScore(), player->get1CC());
|
||||||
auto manager = std::make_unique<ManageHiScoreTable>(Options::settings.hi_score_table);
|
auto manager = std::make_unique<ManageHiScoreTable>(Options::settings.hi_score_table);
|
||||||
Options::settings.last_hi_score_entry.at(player->getId() - 1) = manager->add(ENTRY);
|
Options::settings.glowing_entries.at(static_cast<int>(player->getId()) - 1) = manager->add(ENTRY);
|
||||||
manager->saveToFile(Asset::get()->get("score.bin"));
|
manager->saveToFile(Asset::get()->get("score.bin"));
|
||||||
hi_score_.name = Options::settings.hi_score_table.front().name;
|
hi_score_.name = Options::settings.hi_score_table.front().name;
|
||||||
}
|
}
|
||||||
@@ -1206,7 +1206,7 @@ void Game::checkPlayersStatusPlaying() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene un jugador a partir de su "id"
|
// Obtiene un jugador a partir de su "id"
|
||||||
auto Game::getPlayer(int id) -> std::shared_ptr<Player> {
|
auto Game::getPlayer(Player::Id id) -> std::shared_ptr<Player> {
|
||||||
auto it = std::find_if(players_.begin(), players_.end(), [id](const auto &player) { return player->getId() == id; });
|
auto it = std::find_if(players_.begin(), players_.end(), [id](const auto &player) { return player->getId() == id; });
|
||||||
|
|
||||||
if (it != players_.end()) {
|
if (it != players_.end()) {
|
||||||
@@ -1216,11 +1216,11 @@ auto Game::getPlayer(int id) -> std::shared_ptr<Player> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene un controlador a partir del "id" del jugador
|
// Obtiene un controlador a partir del "id" del jugador
|
||||||
auto Game::getController(int player_id) -> int {
|
auto Game::getController(Player::Id player_id) -> int {
|
||||||
auto it = std::find_if(Options::controllers.begin(), Options::controllers.end(), [player_id](const auto &controller) { return controller.player_id == player_id; });
|
auto it = std::find_if(Options::gamepads.begin(), Options::gamepads.end(), [player_id](const auto &controller) { return controller->player_id == player_id; });
|
||||||
|
|
||||||
if (it != Options::controllers.end()) {
|
if (it != Options::gamepads.end()) {
|
||||||
return std::distance(Options::controllers.begin(), it);
|
return std::distance(Options::gamepads.begin(), it);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1286,7 +1286,7 @@ void Game::demoHandleInput() {
|
|||||||
|
|
||||||
// Procesa las entradas para un jugador específico durante el modo demo.
|
// Procesa las entradas para un jugador específico durante el modo demo.
|
||||||
void Game::demoHandlePlayerInput(const std::shared_ptr<Player> &player, int index) {
|
void Game::demoHandlePlayerInput(const std::shared_ptr<Player> &player, int index) {
|
||||||
const auto &demo_data = demo_.data[index][demo_.counter];
|
const auto &demo_data = demo_.data.at(index).at(demo_.counter);
|
||||||
|
|
||||||
if (demo_data.left == 1) {
|
if (demo_data.left == 1) {
|
||||||
player->setInput(Input::Action::LEFT);
|
player->setInput(Input::Action::LEFT);
|
||||||
@@ -1469,7 +1469,7 @@ void Game::handleNameInput(const std::shared_ptr<Player> &player) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Inicializa las variables para el modo DEMO
|
// Inicializa las variables para el modo DEMO
|
||||||
void Game::initDemo(int player_id) {
|
void Game::initDemo(Player::Id player_id) {
|
||||||
if (demo_.enabled) {
|
if (demo_.enabled) {
|
||||||
// Cambia el estado del juego
|
// Cambia el estado del juego
|
||||||
setState(State::PLAYING);
|
setState(State::PLAYING);
|
||||||
@@ -1497,7 +1497,7 @@ void Game::initDemo(int player_id) {
|
|||||||
|
|
||||||
// Activa o no al otro jugador
|
// Activa o no al otro jugador
|
||||||
if (rand() % 3 != 0) {
|
if (rand() % 3 != 0) {
|
||||||
const auto OTHER_PLAYER_ID = player_id == 1 ? 2 : 1;
|
const auto OTHER_PLAYER_ID = player_id == Player::Id::PLAYER1 ? Player::Id::PLAYER2 : Player::Id::PLAYER1;
|
||||||
auto other_player = getPlayer(OTHER_PLAYER_ID);
|
auto other_player = getPlayer(OTHER_PLAYER_ID);
|
||||||
other_player->setPlayingState(Player::State::PLAYING);
|
other_player->setPlayingState(Player::State::PLAYING);
|
||||||
}
|
}
|
||||||
@@ -1581,30 +1581,54 @@ void Game::initDifficultyVars() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Inicializa los jugadores
|
// Inicializa los jugadores
|
||||||
void Game::initPlayers(int player_id) {
|
void Game::initPlayers(Player::Id player_id) {
|
||||||
const int Y = param.game.play_area.rect.h - Player::HEIGHT + 1; // Se hunde un pixel para esconder el outline de los pies
|
const int Y = param.game.play_area.rect.h - Player::HEIGHT + 1; // Se hunde un pixel para esconder el outline de los pies
|
||||||
|
|
||||||
// Crea al jugador uno y lo pone en modo espera
|
// Crea al jugador uno y lo pone en modo espera
|
||||||
players_.emplace_back(std::make_unique<Player>(1, param.game.play_area.first_quarter_x - (Player::WIDTH / 2), Y, demo_.enabled, param.game.play_area.rect, player_textures_.at(0), player_animations_));
|
Player::Config config_player1;
|
||||||
players_.back()->setScoreBoardPanel(Scoreboard::Id::LEFT);
|
config_player1.id = Player::Id::PLAYER1;
|
||||||
players_.back()->setName(Lang::getText("[SCOREBOARD] 1"));
|
config_player1.x = param.game.play_area.first_quarter_x - (Player::WIDTH / 2);
|
||||||
//players_.back()->setController(getController(players_.back()->getId()));
|
config_player1.y = Y;
|
||||||
players_.back()->setGamepad(Options::controllers.front().gamepad);
|
config_player1.demo = demo_.enabled;
|
||||||
players_.back()->setUsesKeyboard(true);
|
config_player1.play_area = ¶m.game.play_area.rect;
|
||||||
players_.back()->setPlayingState(Player::State::WAITING);
|
config_player1.texture = player_textures_.at(0);
|
||||||
|
config_player1.animations = player_animations_;
|
||||||
|
config_player1.hi_score_table = &Options::settings.hi_score_table;
|
||||||
|
config_player1.glowing_entry = &Options::settings.glowing_entries.at(static_cast<int>(Player::Id::PLAYER1) - 1);
|
||||||
|
|
||||||
|
auto player1 = std::make_unique<Player>(config_player1);
|
||||||
|
player1->setScoreBoardPanel(Scoreboard::Id::LEFT);
|
||||||
|
player1->setName(Lang::getText("[SCOREBOARD] 1"));
|
||||||
|
player1->setGamepad(Options::gamepads.front()->instance);
|
||||||
|
player1->setUsesKeyboard(Player::Id::PLAYER1 == Options::keyboard.player_id);
|
||||||
|
player1->setPlayingState(Player::State::WAITING);
|
||||||
|
players_.push_back(std::move(player1));
|
||||||
|
|
||||||
// Crea al jugador dos y lo pone en modo espera
|
// Crea al jugador dos y lo pone en modo espera
|
||||||
players_.emplace_back(std::make_unique<Player>(2, param.game.play_area.third_quarter_x - (Player::WIDTH / 2), Y, demo_.enabled, param.game.play_area.rect, player_textures_.at(1), player_animations_));
|
Player::Config config_player2;
|
||||||
players_.back()->setScoreBoardPanel(Scoreboard::Id::RIGHT);
|
config_player2.id = Player::Id::PLAYER2;
|
||||||
players_.back()->setName(Lang::getText("[SCOREBOARD] 2"));
|
config_player2.x = param.game.play_area.third_quarter_x - (Player::WIDTH / 2);
|
||||||
//players_.back()->setController(getController(players_.back()->getId()));
|
config_player2.y = Y;
|
||||||
players_.back()->setPlayingState(Player::State::WAITING);
|
config_player2.demo = demo_.enabled;
|
||||||
|
config_player2.play_area = ¶m.game.play_area.rect;
|
||||||
|
config_player2.texture = player_textures_.at(1);
|
||||||
|
config_player2.animations = player_animations_;
|
||||||
|
config_player2.hi_score_table = &Options::settings.hi_score_table;
|
||||||
|
config_player2.glowing_entry = &Options::settings.glowing_entries.at(static_cast<int>(Player::Id::PLAYER2) - 1);
|
||||||
|
|
||||||
|
auto player2 = std::make_unique<Player>(config_player2);
|
||||||
|
player2->setScoreBoardPanel(Scoreboard::Id::RIGHT);
|
||||||
|
player2->setName(Lang::getText("[SCOREBOARD] 2"));
|
||||||
|
player2->setGamepad(Options::gamepads.back()->instance);
|
||||||
|
player2->setUsesKeyboard(Player::Id::PLAYER2 == Options::keyboard.player_id);
|
||||||
|
player2->setPlayingState(Player::State::WAITING);
|
||||||
|
players_.push_back(std::move(player2));
|
||||||
|
|
||||||
// Activa el jugador que coincide con el "player_id" o ambos si es "0"
|
// Activa el jugador que coincide con el "player_id" o ambos si es "0"
|
||||||
if (player_id == 0) {
|
if (player_id == Player::Id::BOTH_PLAYERS) {
|
||||||
// Activa ambos jugadores
|
// Activa ambos jugadores
|
||||||
getPlayer(1)->setPlayingState(demo_.enabled ? Player::State::PLAYING : Player::State::ENTERING_SCREEN);
|
getPlayer(Player::Id::PLAYER1)->setPlayingState(demo_.enabled ? Player::State::PLAYING : Player::State::ENTERING_SCREEN);
|
||||||
getPlayer(2)->setPlayingState(demo_.enabled ? Player::State::PLAYING : Player::State::ENTERING_SCREEN);
|
getPlayer(Player::Id::PLAYER2)->setPlayingState(demo_.enabled ? Player::State::PLAYING : Player::State::ENTERING_SCREEN);
|
||||||
} else {
|
} else {
|
||||||
// Activa el jugador elegido
|
// Activa el jugador elegido
|
||||||
auto player = getPlayer(player_id);
|
auto player = getPlayer(player_id);
|
||||||
|
|||||||
@@ -30,18 +30,15 @@ namespace Difficulty {
|
|||||||
enum class Code;
|
enum class Code;
|
||||||
} // namespace Difficulty
|
} // namespace Difficulty
|
||||||
|
|
||||||
// Modo demo
|
|
||||||
constexpr bool GAME_MODE_DEMO_OFF = false;
|
|
||||||
constexpr bool GAME_MODE_DEMO_ON = true;
|
|
||||||
|
|
||||||
// Cantidad de elementos a escribir en los ficheros de datos
|
|
||||||
constexpr int TOTAL_SCORE_DATA = 3;
|
|
||||||
|
|
||||||
// Clase Game
|
// Clase Game
|
||||||
class Game {
|
class Game {
|
||||||
public:
|
public:
|
||||||
|
// --- Constantes ---
|
||||||
|
static constexpr bool DEMO_OFF = false;
|
||||||
|
static constexpr bool DEMO_ON = true;
|
||||||
|
|
||||||
// --- Constructor y destructor ---
|
// --- Constructor y destructor ---
|
||||||
Game(int player_id, int current_stage, bool demo);
|
Game(Player::Id player_id, int current_stage, bool demo);
|
||||||
~Game();
|
~Game();
|
||||||
|
|
||||||
// --- Bucle principal ---
|
// --- Bucle principal ---
|
||||||
@@ -174,12 +171,12 @@ class Game {
|
|||||||
void updateGameStateGameOver(); // Gestiona el estado de fin de partida
|
void updateGameStateGameOver(); // Gestiona el estado de fin de partida
|
||||||
|
|
||||||
// --- Gestión de jugadores ---
|
// --- Gestión de jugadores ---
|
||||||
void initPlayers(int player_id); // Inicializa los datos de los jugadores
|
void initPlayers(Player::Id player_id); // Inicializa los datos de los jugadores
|
||||||
void updatePlayers(); // Actualiza las variables y estados de los jugadores
|
void updatePlayers(); // Actualiza las variables y estados de los jugadores
|
||||||
void renderPlayers(); // Renderiza todos los jugadores en pantalla
|
void renderPlayers(); // Renderiza todos los jugadores en pantalla
|
||||||
void sortPlayersByZOrder(); // Reorganiza el orden de dibujado de jugadores
|
void sortPlayersByZOrder(); // Reorganiza el orden de dibujado de jugadores
|
||||||
auto getPlayer(int id) -> std::shared_ptr<Player>; // Obtiene un jugador por su identificador
|
auto getPlayer(Player::Id id) -> std::shared_ptr<Player>; // Obtiene un jugador por su identificador
|
||||||
static auto getController(int player_id) -> int; // Obtiene el controlador asignado a un jugador
|
static auto getController(Player::Id player_id) -> int; // Obtiene el controlador asignado a un jugador
|
||||||
|
|
||||||
// --- Estado de jugadores ---
|
// --- Estado de jugadores ---
|
||||||
void checkAndUpdatePlayerStatus(int active_player_index, int inactive_player_index); // Actualiza estado entre jugadores
|
void checkAndUpdatePlayerStatus(int active_player_index, int inactive_player_index); // Actualiza estado entre jugadores
|
||||||
@@ -214,7 +211,7 @@ class Game {
|
|||||||
// --- Sistema de balas y proyectiles ---
|
// --- Sistema de balas y proyectiles ---
|
||||||
void updateBullets(); // Actualiza posición y estado de todas las balas
|
void updateBullets(); // Actualiza posición y estado de todas las balas
|
||||||
void renderBullets(); // Renderiza todas las balas activas
|
void renderBullets(); // Renderiza todas las balas activas
|
||||||
void createBullet(int x, int y, BulletType kind, bool powered_up, int owner); // Crea una nueva bala
|
void createBullet(int x, int y, BulletType kind, bool powered_up, Player::Id owner); // Crea una nueva bala
|
||||||
void checkBulletCollision(); // Verifica colisiones de todas las balas
|
void checkBulletCollision(); // Verifica colisiones de todas las balas
|
||||||
void freeBullets(); // Libera memoria del vector de balas
|
void freeBullets(); // Libera memoria del vector de balas
|
||||||
|
|
||||||
@@ -276,7 +273,7 @@ class Game {
|
|||||||
void initScoreboard(); // Inicializa el sistema de puntuación
|
void initScoreboard(); // Inicializa el sistema de puntuación
|
||||||
|
|
||||||
// --- Modo demostración ---
|
// --- Modo demostración ---
|
||||||
void initDemo(int player_id); // Inicializa variables para el modo demostración
|
void initDemo(Player::Id player_id); // Inicializa variables para el modo demostración
|
||||||
void updateDemo(); // Actualiza lógica específica del modo demo
|
void updateDemo(); // Actualiza lógica específica del modo demo
|
||||||
|
|
||||||
// --- Recursos y renderizado ---
|
// --- Recursos y renderizado ---
|
||||||
|
|||||||
@@ -348,7 +348,7 @@ void HiScoreTable::iniEntryColors() {
|
|||||||
// Hace brillar los nombres de la tabla de records
|
// Hace brillar los nombres de la tabla de records
|
||||||
void HiScoreTable::glowEntryNames() {
|
void HiScoreTable::glowEntryNames() {
|
||||||
const Color ENTRY_COLOR = getEntryColor(counter_ / 5);
|
const Color ENTRY_COLOR = getEntryColor(counter_ / 5);
|
||||||
for (const auto &entry_index : Options::settings.last_hi_score_entry) {
|
for (const auto &entry_index : Options::settings.glowing_entries) {
|
||||||
if (entry_index != -1) {
|
if (entry_index != -1) {
|
||||||
entry_names_.at(entry_index)->getTexture()->setColor(ENTRY_COLOR);
|
entry_names_.at(entry_index)->getTexture()->setColor(ENTRY_COLOR);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ Title::Title()
|
|||||||
game_logo_(std::make_unique<GameLogo>(param.game.game_area.center_x, param.title.title_c_c_position)),
|
game_logo_(std::make_unique<GameLogo>(param.game.game_area.center_x, param.title.title_c_c_position)),
|
||||||
mini_logo_sprite_(std::make_unique<Sprite>(Resource::get()->getTexture("logo_jailgames_mini.png"))),
|
mini_logo_sprite_(std::make_unique<Sprite>(Resource::get()->getTexture("logo_jailgames_mini.png"))),
|
||||||
define_buttons_(std::make_unique<DefineButtons>()),
|
define_buttons_(std::make_unique<DefineButtons>()),
|
||||||
num_controllers_(Input::get()->getNumControllers()),
|
num_controllers_(Input::get()->getNumGamepads()),
|
||||||
state_(TitleState::LOGO_ANIMATING) {
|
state_(TitleState::LOGO_ANIMATING) {
|
||||||
// Configura objetos
|
// Configura objetos
|
||||||
tiled_bg_->setColor(param.title.bg_color);
|
tiled_bg_->setColor(param.title.bg_color);
|
||||||
@@ -213,12 +213,12 @@ void Title::printColorValue(const Color& color) {
|
|||||||
void Title::handleControlKeys(SDL_Keycode key) {
|
void Title::handleControlKeys(SDL_Keycode key) {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case SDLK_1:
|
case SDLK_1:
|
||||||
define_buttons_->enable(0);
|
define_buttons_->enable(Options::gamepads.at(0));
|
||||||
resetCounter();
|
resetCounter();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_2:
|
case SDLK_2:
|
||||||
define_buttons_->enable(1);
|
define_buttons_->enable(Options::gamepads.at(1));
|
||||||
resetCounter();
|
resetCounter();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -262,29 +262,29 @@ auto Title::shouldSkipInputCheck() const -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Title::processControllerInputs() {
|
void Title::processControllerInputs() {
|
||||||
for (const auto& controller : Options::controllers) {
|
for (const auto& controller : Options::gamepads) {
|
||||||
if (isStartButtonPressed(controller)) {
|
if (isStartButtonPressed(controller)) {
|
||||||
handleStartButtonPress(controller);
|
handleStartButtonPress(controller);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Title::isStartButtonPressed(const Options::GamepadOptions& controller) -> bool {
|
auto Title::isStartButtonPressed(std::shared_ptr<Options::Gamepad> controller) -> bool {
|
||||||
return Input::get()->checkAction(
|
return Input::get()->checkAction(
|
||||||
Input::Action::START,
|
Input::Action::START,
|
||||||
Input::DO_NOT_ALLOW_REPEAT,
|
Input::DO_NOT_ALLOW_REPEAT,
|
||||||
Input::CHECK_KEYBOARD,
|
Input::CHECK_KEYBOARD,
|
||||||
controller.gamepad);
|
controller->instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Title::handleStartButtonPress(const Options::GamepadOptions& controller) {
|
void Title::handleStartButtonPress(std::shared_ptr<Options::Gamepad> controller) {
|
||||||
if (!canProcessStartButton()) {
|
if (!canProcessStartButton()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controller.player_id == 1) {
|
if (controller->player_id == Player::Id::PLAYER1) {
|
||||||
processPlayer1Start();
|
processPlayer1Start();
|
||||||
} else if (controller.player_id == 2) {
|
} else if (controller->player_id == Player::Id::PLAYER2) {
|
||||||
processPlayer2Start();
|
processPlayer2Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -296,18 +296,18 @@ auto Title::canProcessStartButton() const -> bool {
|
|||||||
void Title::processPlayer1Start() {
|
void Title::processPlayer1Start() {
|
||||||
if (!player1_start_pressed_) {
|
if (!player1_start_pressed_) {
|
||||||
player1_start_pressed_ = true;
|
player1_start_pressed_ = true;
|
||||||
activatePlayerAndSetState(1);
|
activatePlayerAndSetState(Player::Id::PLAYER1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Title::processPlayer2Start() {
|
void Title::processPlayer2Start() {
|
||||||
if (!player2_start_pressed_) {
|
if (!player2_start_pressed_) {
|
||||||
player2_start_pressed_ = true;
|
player2_start_pressed_ = true;
|
||||||
activatePlayerAndSetState(2);
|
activatePlayerAndSetState(Player::Id::PLAYER2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Title::activatePlayerAndSetState(int player_id) {
|
void Title::activatePlayerAndSetState(Player::Id player_id) {
|
||||||
getPlayer(player_id)->setPlayingState(Player::State::TITLE_ANIMATION);
|
getPlayer(player_id)->setPlayingState(Player::State::TITLE_ANIMATION);
|
||||||
setState(TitleState::START_HAS_BEEN_PRESSED);
|
setState(TitleState::START_HAS_BEEN_PRESSED);
|
||||||
counter_ = 0;
|
counter_ = 0;
|
||||||
@@ -328,7 +328,7 @@ void Title::resetCounter() { counter_ = 0; }
|
|||||||
|
|
||||||
// Intercambia la asignación de mandos a los jugadores
|
// Intercambia la asignación de mandos a los jugadores
|
||||||
void Title::swapControllers() {
|
void Title::swapControllers() {
|
||||||
if (Input::get()->getNumControllers() == 0) {
|
if (Input::get()->getNumGamepads() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,13 +339,13 @@ void Title::swapControllers() {
|
|||||||
// Intercambia el teclado de jugador
|
// Intercambia el teclado de jugador
|
||||||
void Title::swapKeyboard() {
|
void Title::swapKeyboard() {
|
||||||
Options::swapKeyboard();
|
Options::swapKeyboard();
|
||||||
std::string text = Lang::getText("[DEFINE_BUTTONS] PLAYER") + std::to_string(Options::getPlayerWhoUsesKeyboard()) + ": " + Lang::getText("[DEFINE_BUTTONS] KEYBOARD");
|
std::string text = Lang::getText("[DEFINE_BUTTONS] PLAYER") + std::to_string(static_cast<int>(Options::getPlayerWhoUsesKeyboard())) + ": " + Lang::getText("[DEFINE_BUTTONS] KEYBOARD");
|
||||||
Notifier::get()->show({text});
|
Notifier::get()->show({text});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Muestra información sobre los controles y los jugadores
|
// Muestra información sobre los controles y los jugadores
|
||||||
void Title::showControllers() {
|
void Title::showControllers() {
|
||||||
// Crea vectores de texto vacíos para un número máximo de mandos
|
/* // Crea vectores de texto vacíos para un número máximo de mandos
|
||||||
constexpr size_t NUM_CONTROLLERS = 2;
|
constexpr size_t NUM_CONTROLLERS = 2;
|
||||||
std::vector<std::string> text(NUM_CONTROLLERS);
|
std::vector<std::string> text(NUM_CONTROLLERS);
|
||||||
std::vector<int> player_controller_index(NUM_CONTROLLERS, -1);
|
std::vector<int> player_controller_index(NUM_CONTROLLERS, -1);
|
||||||
@@ -353,19 +353,20 @@ void Title::showControllers() {
|
|||||||
// Obtiene de cada jugador el índice del mando que tiene asignado
|
// Obtiene de cada jugador el índice del mando que tiene asignado
|
||||||
for (size_t i = 0; i < NUM_CONTROLLERS; ++i) {
|
for (size_t i = 0; i < NUM_CONTROLLERS; ++i) {
|
||||||
// Ejemplo: el jugador 1 tiene el mando 2
|
// Ejemplo: el jugador 1 tiene el mando 2
|
||||||
player_controller_index.at(Options::controllers.at(i).player_id - 1) = i;
|
player_controller_index.at(Options::controllers.at(i)->player_id - 1) = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Genera el texto correspondiente
|
// Genera el texto correspondiente
|
||||||
//for (size_t i = 0; i < NUM_CONTROLLERS; ++i) {
|
for (size_t i = 0; i < NUM_CONTROLLERS; ++i) {
|
||||||
// const size_t INDEX = player_controller_index.at(i);
|
const size_t INDEX = player_controller_index.at(i);
|
||||||
// if (Options::controllers.at(INDEX).plugged) {
|
if (Options::controllers.at(INDEX).plugged) {
|
||||||
// text.at(i) = Lang::getText("[DEFINE_BUTTONS] PLAYER") + std::to_string(i + 1) + ": " + Options::controllers.at(INDEX).name;
|
text.at(i) = Lang::getText("[DEFINE_BUTTONS] PLAYER") + std::to_string(i + 1) + ": " + Options::controllers.at(INDEX).name;
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
// Muestra la notificación
|
// Muestra la notificación
|
||||||
Notifier::get()->show({text.at(0), text.at(1)});
|
Notifier::get()->show({text.at(0), text.at(1)});
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza el fade
|
// Actualiza el fade
|
||||||
@@ -558,10 +559,31 @@ void Title::initPlayers() {
|
|||||||
constexpr int PLAYER_HEIGHT = 32;
|
constexpr int PLAYER_HEIGHT = 32;
|
||||||
const int Y = param.title.press_start_position - (PLAYER_HEIGHT / 2);
|
const int Y = param.title.press_start_position - (PLAYER_HEIGHT / 2);
|
||||||
constexpr bool DEMO = false;
|
constexpr bool DEMO = false;
|
||||||
players_.emplace_back(std::make_unique<Player>(1, param.game.game_area.center_x - (PLAYER_WIDTH / 2), Y, DEMO, param.game.play_area.rect, player_textures.at(0), player_animations));
|
|
||||||
|
Player::Config config_player1;
|
||||||
|
config_player1.id = Player::Id::PLAYER1;
|
||||||
|
config_player1.x = param.game.game_area.center_x - (PLAYER_WIDTH / 2);
|
||||||
|
config_player1.y = Y;
|
||||||
|
config_player1.demo = DEMO;
|
||||||
|
config_player1.play_area = ¶m.game.play_area.rect;
|
||||||
|
config_player1.texture = player_textures.at(0);
|
||||||
|
config_player1.animations = player_animations;
|
||||||
|
config_player1.hi_score_table = &Options::settings.hi_score_table;
|
||||||
|
config_player1.glowing_entry = &Options::settings.glowing_entries.at(static_cast<int>(Player::Id::PLAYER1) - 1);
|
||||||
|
players_.emplace_back(std::make_unique<Player>(config_player1));
|
||||||
players_.back()->setPlayingState(Player::State::TITLE_HIDDEN);
|
players_.back()->setPlayingState(Player::State::TITLE_HIDDEN);
|
||||||
|
|
||||||
players_.emplace_back(std::make_unique<Player>(2, param.game.game_area.center_x - (PLAYER_WIDTH / 2), Y, DEMO, param.game.play_area.rect, player_textures.at(1), player_animations));
|
Player::Config config_player2;
|
||||||
|
config_player2.id = Player::Id::PLAYER2;
|
||||||
|
config_player2.x = param.game.game_area.center_x - (PLAYER_WIDTH / 2);
|
||||||
|
config_player2.y = Y;
|
||||||
|
config_player2.demo = DEMO;
|
||||||
|
config_player2.play_area = ¶m.game.play_area.rect;
|
||||||
|
config_player2.texture = player_textures.at(1);
|
||||||
|
config_player2.animations = player_animations;
|
||||||
|
config_player2.hi_score_table = &Options::settings.hi_score_table;
|
||||||
|
config_player2.glowing_entry = &Options::settings.glowing_entries.at(static_cast<int>(Player::Id::PLAYER2) - 1);
|
||||||
|
players_.emplace_back(std::make_unique<Player>(config_player2));
|
||||||
players_.back()->setPlayingState(Player::State::TITLE_HIDDEN);
|
players_.back()->setPlayingState(Player::State::TITLE_HIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,7 +602,7 @@ void Title::renderPlayers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene un jugador a partir de su "id"
|
// Obtiene un jugador a partir de su "id"
|
||||||
auto Title::getPlayer(int id) -> std::shared_ptr<Player> {
|
auto Title::getPlayer(Player::Id id) -> std::shared_ptr<Player> {
|
||||||
auto it = std::find_if(players_.begin(), players_.end(), [id](const auto& player) { return player->getId() == id; });
|
auto it = std::find_if(players_.begin(), players_.end(), [id](const auto& player) { return player->getId() == id; });
|
||||||
|
|
||||||
if (it != players_.end()) {
|
if (it != players_.end()) {
|
||||||
|
|||||||
@@ -7,17 +7,17 @@
|
|||||||
#include <string_view> // Para string_view
|
#include <string_view> // Para string_view
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
|
#include "player.h" // Para Player
|
||||||
#include "section.hpp" // Para Options, Name (ptr only)
|
#include "section.hpp" // Para Options, Name (ptr only)
|
||||||
|
|
||||||
class DefineButtons;
|
class DefineButtons;
|
||||||
class Fade;
|
class Fade;
|
||||||
class GameLogo;
|
class GameLogo;
|
||||||
class Player;
|
|
||||||
class Sprite;
|
class Sprite;
|
||||||
class Text;
|
class Text;
|
||||||
class TiledBG;
|
class TiledBG;
|
||||||
namespace Options {
|
namespace Options {
|
||||||
struct GamepadOptions;
|
struct Gamepad;
|
||||||
} // namespace Options
|
} // namespace Options
|
||||||
struct Color;
|
struct Color;
|
||||||
|
|
||||||
@@ -93,18 +93,18 @@ class Title {
|
|||||||
void handleControlKeys(SDL_Keycode key); // Maneja las teclas de control específicas
|
void handleControlKeys(SDL_Keycode key); // Maneja las teclas de control específicas
|
||||||
[[nodiscard]] auto shouldSkipInputCheck() const -> bool; // Determina si se debe omitir la comprobación de entrada
|
[[nodiscard]] auto shouldSkipInputCheck() const -> bool; // Determina si se debe omitir la comprobación de entrada
|
||||||
void processControllerInputs(); // Procesa las entradas de los mandos
|
void processControllerInputs(); // Procesa las entradas de los mandos
|
||||||
[[nodiscard]] static auto isStartButtonPressed(const Options::GamepadOptions& controller) -> bool; // Comprueba si se ha pulsado el botón Start
|
[[nodiscard]] static auto isStartButtonPressed(std::shared_ptr<Options::Gamepad> controller) -> bool; // Comprueba si se ha pulsado el botón Start
|
||||||
void handleStartButtonPress(const Options::GamepadOptions& controller); // Maneja la pulsación del botón Start
|
void handleStartButtonPress(std::shared_ptr<Options::Gamepad> controller); // Maneja la pulsación del botón Start
|
||||||
[[nodiscard]] auto canProcessStartButton() const -> bool; // Verifica si se puede procesar la pulsación del botón Start
|
[[nodiscard]] auto canProcessStartButton() const -> bool; // Verifica si se puede procesar la pulsación del botón Start
|
||||||
void processPlayer1Start(); // Procesa el inicio del jugador 1
|
void processPlayer1Start(); // Procesa el inicio del jugador 1
|
||||||
void processPlayer2Start(); // Procesa el inicio del jugador 2
|
void processPlayer2Start(); // Procesa el inicio del jugador 2
|
||||||
void activatePlayerAndSetState(int player_id); // Activa al jugador y cambia el estado del título
|
void activatePlayerAndSetState(Player::Id player_id); // Activa al jugador y cambia el estado del título
|
||||||
|
|
||||||
// --- Gestión de jugadores ---
|
// --- Gestión de jugadores ---
|
||||||
void initPlayers(); // Inicializa los jugadores
|
void initPlayers(); // Inicializa los jugadores
|
||||||
void updatePlayers(); // Actualiza los jugadores
|
void updatePlayers(); // Actualiza los jugadores
|
||||||
void renderPlayers(); // Renderiza los jugadores
|
void renderPlayers(); // Renderiza los jugadores
|
||||||
auto getPlayer(int id) -> std::shared_ptr<Player>; // Obtiene un jugador a partir de su "id"
|
auto getPlayer(Player::Id id) -> std::shared_ptr<Player>; // Obtiene un jugador a partir de su "id"
|
||||||
|
|
||||||
// --- Visualización / Renderizado ---
|
// --- Visualización / Renderizado ---
|
||||||
void render(); // Dibuja el objeto en pantalla
|
void render(); // Dibuja el objeto en pantalla
|
||||||
|
|||||||
Reference in New Issue
Block a user