From 81d486f2d39a566272b39868c05ab6274650151f Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 16 Aug 2025 10:29:30 +0200 Subject: [PATCH] afegit defaults.h amb els valors per defecte de Param --- source/defaults.h | 132 +++++++++++++++++++++++++++++++ source/param.cpp | 153 ++++++++++------------------------- source/param.h | 176 +++++++++++++++++++++++------------------ source/ui/notifier.cpp | 44 +++++------ source/ui/notifier.h | 33 +++++--- source/utils.h | 9 --- 6 files changed, 316 insertions(+), 231 deletions(-) create mode 100644 source/defaults.h diff --git a/source/defaults.h b/source/defaults.h new file mode 100644 index 0000000..c71ff78 --- /dev/null +++ b/source/defaults.h @@ -0,0 +1,132 @@ +#pragma once + +#include + +#include "color.h" +#include "ui/notifier.h" + +// Configuración centralizada con todos los valores por defecto del juego +namespace GameDefaults { + +// --- GAME --- +namespace Game { +constexpr float WIDTH = 320.0f; +constexpr float HEIGHT = 256.0f; +constexpr float ITEM_SIZE = 20.0f; +constexpr int NAME_ENTRY_IDLE_TIME = 10; +constexpr int NAME_ENTRY_TOTAL_TIME = 60; +constexpr bool HIT_STOP = false; +constexpr int HIT_STOP_MS = 500; + +// Play area por defecto +constexpr float PLAY_AREA_X = 0.0f; +constexpr float PLAY_AREA_Y = 0.0f; +constexpr float PLAY_AREA_W = 320.0f; +constexpr float PLAY_AREA_H = 216.0f; +} // namespace Game + +// --- FADE --- +namespace Fade { +constexpr const char* COLOR = "1F2B30"; +constexpr float NUM_SQUARES_WIDTH = 160.0f; +constexpr float NUM_SQUARES_HEIGHT = 128.0f; +constexpr int RANDOM_SQUARES_DELAY = 1; +constexpr int RANDOM_SQUARES_MULT = 500; +constexpr int POST_DURATION = 80; +constexpr float VENETIAN_SIZE = 12.0f; +} // namespace Fade + +// --- SCOREBOARD --- +namespace Scoreboard { +constexpr float RECT_X = 0.0f; +constexpr float RECT_Y = 216.0f; +constexpr float RECT_W = 320.0f; +constexpr float RECT_H = 40.0f; +constexpr bool SEPARATOR_AUTOCOLOR = true; +constexpr const char* SEPARATOR_COLOR = "0D1A2B"; +constexpr const char* EASY_COLOR = "4B692F"; +constexpr const char* NORMAL_COLOR = "2E3F47"; +constexpr const char* HARD_COLOR = "76428A"; +constexpr bool TEXT_AUTOCOLOR = true; +constexpr const char* TEXT_COLOR1 = "FFFFFF"; +constexpr const char* TEXT_COLOR2 = "FFFFFF"; +constexpr int SKIP_COUNTDOWN_VALUE = 8; +} // namespace Scoreboard + +// --- TITLE --- +namespace Title { +constexpr int PRESS_START_POSITION = 180; +constexpr int DURATION = 800; +constexpr int ARCADE_EDITION_POSITION = 123; +constexpr int TITLE_C_C_POSITION = 80; +constexpr const char* BG_COLOR = "41526F"; +} // namespace Title + +// --- BACKGROUND --- +namespace Background { +constexpr const char* ATTENUATE_COLOR = "FFFFFF00"; +} + +// --- BALLOONS --- +namespace Balloon { +// Configuración de física para cada nivel de globo +struct BalloonSettings { + float vel; + float grav; + constexpr BalloonSettings(float v, float g) : vel(v), grav(g) {} +}; + +constexpr std::array SETTINGS = {{ + BalloonSettings(2.75f, 0.09f), // Globo 0 + BalloonSettings(3.70f, 0.10f), // Globo 1 + BalloonSettings(4.70f, 0.10f), // Globo 2 + BalloonSettings(5.45f, 0.10f) // Globo 3 +}}; + +constexpr std::array COLORS = { + "blue", "orange", "red", "green"}; + +constexpr bool BOUNCING_SOUND = false; +} // namespace Balloon + +// --- NOTIFICATION --- +namespace Notification { +constexpr Notifier::Position POS_V = Notifier::Position::TOP; +constexpr Notifier::Position POS_H = Notifier::Position::LEFT; +constexpr bool SOUND = false; +constexpr const char* COLOR = "303030"; +} // namespace Notification + +// --- SERVICE MENU --- +namespace ServiceMenu { +constexpr const char* TITLE_COLOR = "99FF62"; +constexpr const char* TEXT_COLOR = "FFFFFF"; +constexpr const char* SELECTED_COLOR = "FFDC44"; +constexpr const char* BG_COLOR = "000F00F5"; +constexpr bool DROP_SHADOW = false; +} // namespace ServiceMenu + +// --- INTRO --- +namespace Intro { +constexpr const char* BG_COLOR = "4664BD"; +constexpr const char* CARD_COLOR = "CBDBFC"; +constexpr const char* SHADOW_COLOR = "00000080"; +constexpr int TEXT_DISTANCE_FROM_BOTTOM = 48; +} // namespace Intro + +// --- DEBUG --- +namespace Debug { +constexpr const char* COLOR = "00FFFF"; +} + +// --- RESOURCE --- +namespace Resource { +constexpr const char* COLOR = "FFFFFF"; +} + +// --- TABE --- +namespace Tabe { +constexpr float MIN_SPAWN_TIME = 2.0f; +constexpr float MAX_SPAWN_TIME = 3.0f; +} // namespace Tabe +} // namespace GameDefaults \ No newline at end of file diff --git a/source/param.cpp b/source/param.cpp index 8cd4f80..4b3abe7 100644 --- a/source/param.cpp +++ b/source/param.cpp @@ -12,95 +12,39 @@ #include "color.h" #include "utils.h" +// Variable global - ahora se inicializa automáticamente con valores por defecto Param param; -// Calcula variables a partir de otras variables -void precalculateZones(); - -// Asigna variables a partir de dos cadenas +// Declaraciones de funciones privadas +namespace { auto setParams(const std::string& var, const std::string& value) -> bool; +} -// Establece valores por defecto a las variables -void initParam() { - // GAME - param.game.width = 320; - param.game.height = 256; - param.game.item_size = 20; - param.game.game_area.rect = {0, 0, param.game.width, param.game.height}; - param.game.play_area.rect = {0, 0, param.game.width, 216}; - param.game.name_entry_idle_time = 10; - param.game.name_entry_total_time = 60; - param.game.speed = 15; - param.game.hit_stop = true; - param.game.hit_stop_ms = 300; - precalculateZones(); +// Implementación del método privado de Param +void Param::precalculateZones() { + // playArea - cálculos basados en el rectángulo actual + game.play_area.center_x = game.play_area.rect.w / 2; + game.play_area.first_quarter_x = game.play_area.rect.w / 4; + game.play_area.third_quarter_x = game.play_area.rect.w / 4 * 3; + game.play_area.center_y = game.play_area.rect.h / 2; + game.play_area.first_quarter_y = game.play_area.rect.h / 4; + game.play_area.third_quarter_y = game.play_area.rect.h / 4 * 3; - // SCOREBOARD - param.scoreboard.rect = {0, 216, param.game.width, 40}; - param.scoreboard.separator_autocolor = false; - param.scoreboard.separator_color = Color(); - param.scoreboard.easy_color = Color(); - param.scoreboard.normal_color = Color(); - param.scoreboard.hard_color = Color(); - param.scoreboard.text_autocolor = false; - param.scoreboard.text_color1 = Color(); - param.scoreboard.text_color2 = Color(); - param.scoreboard.skip_countdown_value = 8; - - // FADE - param.fade.num_squares_width = param.game.width / 2; - param.fade.num_squares_height = param.game.height / 2; - param.fade.random_squares_delay = 1; - param.fade.random_squares_mult = 500; - param.fade.post_duration = 80; - param.fade.venetian_size = 16; - - // TITLE - param.title.press_start_position = 160; - param.title.title_duration = 800; - param.title.arcade_edition_position = 123; - param.title.title_c_c_position = 11; - param.title.bg_color = Color(255, 255, 255); - - // BACKGROUND - param.background.attenuate_color = Color(255, 255, 255, 0); - - // BALLOONS - param.balloon.settings.at(0) = ParamBalloon::Settings(0.09F, 2.60F); - param.balloon.settings.at(1) = ParamBalloon::Settings(0.10F, 3.50F); - param.balloon.settings.at(2) = ParamBalloon::Settings(0.10F, 4.50F); - param.balloon.settings.at(3) = ParamBalloon::Settings(0.10F, 4.95F); - - param.balloon.color.at(0) = "blue"; - param.balloon.color.at(1) = "orange"; - param.balloon.color.at(2) = "red"; - param.balloon.color.at(3) = "green"; - - param.balloon.bouncing_sound = false; - - // NOTIFICATION - param.notification.pos_v = NotifyPosition::TOP; - param.notification.pos_h = NotifyPosition::LEFT; - param.notification.sound = false; - param.notification.color = Color(48, 48, 48); - - // INTRO - param.intro.bg_color = Color::fromHex("543149"); - param.intro.card_color = Color::fromHex("CBDBFC"); - param.intro.shadow_color = Color::fromHex("00000080"); - param.intro.text_distance_from_bottom = 48; - - // TABE - param.tabe.min_spawn_time = 2.0F; - param.tabe.max_spawn_time = 3.0F; + // gameArea - cálculos basados en width y height actuales + game.game_area.rect = {0, 0, game.width, game.height}; + game.game_area.center_x = game.game_area.rect.w / 2; + game.game_area.first_quarter_x = game.game_area.rect.w / 4; + game.game_area.third_quarter_x = game.game_area.rect.w / 4 * 3; + game.game_area.center_y = game.game_area.rect.h / 2; + game.game_area.first_quarter_y = game.game_area.rect.h / 4; + game.game_area.third_quarter_y = game.game_area.rect.h / 4 * 3; } // Carga los parámetros desde un archivo void loadParamsFromFile(const std::string& file_path) { - // Inicializa los parámetros con valores por defecto - initParam(); + // Los parámetros ya están inicializados con valores por defecto + // Solo necesitamos abrir el archivo y sobrescribir los valores que aparezcan - // Abre el archivo std::ifstream file(file_path); if (!file.is_open()) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: No se pudo abrir el archivo %s", file_path.c_str()); @@ -110,8 +54,9 @@ void loadParamsFromFile(const std::string& file_path) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\nReading file: %s", getFileName(file_path).c_str()); std::string line; - std::string param1; - std::string param2; + std::string param_name; + std::string param_value; + while (std::getline(file, line)) { // Elimina comentarios auto comment_pos = line.find('#'); @@ -121,21 +66,23 @@ void loadParamsFromFile(const std::string& file_path) { // Usa un stream para separar palabras std::istringstream iss(line); - if (iss >> param1 >> param2) { - if (!setParams(param1, param2)) { - SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Parámetro desconocido: %s", param1.c_str()); + if (iss >> param_name >> param_value) { + if (!setParams(param_name, param_value)) { + SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Parámetro desconocido: %s", param_name.c_str()); } } } - // Cierra el archivo file.close(); - // Realiza cálculos adicionales después de cargar los parámetros - precalculateZones(); + // Recalcula las zonas después de cargar todos los parámetros + param.precalculateZones(); } +// Implementación local de setParams +namespace { auto setParams(const std::string& var, const std::string& value) -> bool { + // Mapas estáticos para diferentes tipos de parámetros static const std::unordered_map> INT_PARAMS = { {"game.width", [](const std::string& v) { param.game.width = std::stoi(v); }}, {"game.height", [](const std::string& v) { param.game.height = std::stoi(v); }}, @@ -211,7 +158,7 @@ auto setParams(const std::string& var, const std::string& value) -> bool { {"balloon.color[2]", [](const std::string& v) { param.balloon.color.at(2) = v; }}, {"balloon.color[3]", [](const std::string& v) { param.balloon.color.at(3) = v; }}}; - // Intentar cada mapa de parámetros + // Lambda para intentar cada mapa de parámetros auto try_map = [&](const auto& param_map) -> bool { auto it = param_map.find(var); if (it != param_map.end()) { @@ -221,6 +168,7 @@ auto setParams(const std::string& var, const std::string& value) -> bool { return false; }; + // Intentar con todos los mapas if (try_map(INT_PARAMS) || try_map(COLOR_PARAMS) || try_map(BOOL_PARAMS) || try_map(FLOAT_PARAMS) || try_map(STRING_PARAMS)) { return true; @@ -229,39 +177,20 @@ auto setParams(const std::string& var, const std::string& value) -> bool { // Casos especiales que necesitan lógica personalizada if (var == "notification.pos_h") { if (value == "LEFT") { - param.notification.pos_h = NotifyPosition::LEFT; + param.notification.pos_h = Notifier::Position::LEFT; } else if (value == "MIDDLE") { - param.notification.pos_h = NotifyPosition::MIDDLE; + param.notification.pos_h = Notifier::Position::MIDDLE; } else { - param.notification.pos_h = NotifyPosition::RIGHT; + param.notification.pos_h = Notifier::Position::RIGHT; } return true; } if (var == "notification.pos_v") { - param.notification.pos_v = value == "TOP" ? NotifyPosition::TOP : NotifyPosition::BOTTOM; + param.notification.pos_v = value == "TOP" ? Notifier::Position::TOP : Notifier::Position::BOTTOM; return true; } return false; // Parámetro no encontrado } - -// Calcula variables a partir de otras variables -void precalculateZones() { - // playArea - param.game.play_area.center_x = param.game.play_area.rect.w / 2; - param.game.play_area.first_quarter_x = param.game.play_area.rect.w / 4; - param.game.play_area.third_quarter_x = param.game.play_area.rect.w / 4 * 3; - param.game.play_area.center_y = param.game.play_area.rect.h / 2; - param.game.play_area.first_quarter_y = param.game.play_area.rect.h / 4; - param.game.play_area.third_quarter_y = param.game.play_area.rect.h / 4 * 3; - - // gameArea - param.game.game_area.rect = {0, 0, param.game.width, param.game.height}; - param.game.game_area.center_x = param.game.game_area.rect.w / 2; - param.game.game_area.first_quarter_x = param.game.game_area.rect.w / 4; - param.game.game_area.third_quarter_x = param.game.game_area.rect.w / 4 * 3; - param.game.game_area.center_y = param.game.game_area.rect.h / 2; - param.game.game_area.first_quarter_y = param.game.game_area.rect.h / 4; - param.game.game_area.third_quarter_y = param.game.game_area.rect.h / 4 * 3; -} \ No newline at end of file +} // namespace \ No newline at end of file diff --git a/source/param.h b/source/param.h index 7c9bb54..15c2b8e 100644 --- a/source/param.h +++ b/source/param.h @@ -5,141 +5,167 @@ #include // Para array #include // Para basic_string, string -#include "color.h" // Para Color, NotifyPosition (ptr only), Zone -#include "utils.h" +#include "color.h" // Para Color +#include "defaults.h" // Para los valores por defecto +#include "utils.h" // Para NotifyPosition, Zone // --- Parámetros del juego --- struct ParamGame { - float width; // Ancho de la resolución nativa del juego - float height; // Alto de la resolución nativa del juego - float item_size; // Tamaño de los ítems del juego - Zone play_area; // Rectángulo con la posición de la zona de juego - Zone game_area; // Rectángulo con las dimensiones del juego - int name_entry_idle_time; // Segundos para introducir el nombre al finalizar la partida si no se pulsa nada - int name_entry_total_time; // Segundos totales para introducir el nombre al finalizar la partida - Uint32 speed; // Velocidad a la que transcurre el juego - bool hit_stop; // Indica si debe haber un paro cuando el jugador es golpeado por un globo - Uint32 hit_stop_ms; // Cantidad de milisegundos que dura el hit_stop + float width = GameDefaults::Game::WIDTH; + float height = GameDefaults::Game::HEIGHT; + float item_size = GameDefaults::Game::ITEM_SIZE; + Zone play_area{}; // Se inicializa en el constructor de Param + Zone game_area{}; // Se inicializa en el constructor de Param + int name_entry_idle_time = GameDefaults::Game::NAME_ENTRY_IDLE_TIME; + int name_entry_total_time = GameDefaults::Game::NAME_ENTRY_TOTAL_TIME; + Uint32 speed = 15; // Este valor no estaba en el archivo de configuración + bool hit_stop = GameDefaults::Game::HIT_STOP; + Uint32 hit_stop_ms = GameDefaults::Game::HIT_STOP_MS; }; // --- Parámetros del fade --- struct ParamFade { - Color color; // Color del fade - float num_squares_width; // Cantidad total de cuadraditos en horizontal para el FadeType::RANDOM_SQUARE - float num_squares_height; // Cantidad total de cuadraditos en vertical para el FadeType::RANDOM_SQUARE - int random_squares_delay; // Duración entre cada pintado de cuadrados - int random_squares_mult; // Cantidad de cuadrados que se pintarán cada vez - int post_duration; // Duración final del fade - float venetian_size; // Altura de los rectángulos para FadeType::VENETIAN + Color color = Color::fromHex(GameDefaults::Fade::COLOR); + float num_squares_width = GameDefaults::Fade::NUM_SQUARES_WIDTH; + float num_squares_height = GameDefaults::Fade::NUM_SQUARES_HEIGHT; + int random_squares_delay = GameDefaults::Fade::RANDOM_SQUARES_DELAY; + int random_squares_mult = GameDefaults::Fade::RANDOM_SQUARES_MULT; + int post_duration = GameDefaults::Fade::POST_DURATION; + float venetian_size = GameDefaults::Fade::VENETIAN_SIZE; }; // --- Parámetros de la pantalla de título --- struct ParamTitle { - int press_start_position; // Posición del texto para empezar a jugar - int title_duration; // Tiempo de inactividad del título - int arcade_edition_position; // Posición del bitmap "Arcade Edition" - int title_c_c_position; // Posición del bitmap "Coffee Crisis" - Color bg_color; // Color para los tiles de fondo + int press_start_position = GameDefaults::Title::PRESS_START_POSITION; + int title_duration = GameDefaults::Title::DURATION; + int arcade_edition_position = GameDefaults::Title::ARCADE_EDITION_POSITION; + int title_c_c_position = GameDefaults::Title::TITLE_C_C_POSITION; + Color bg_color = Color::fromHex(GameDefaults::Title::BG_COLOR); }; // --- Parámetros del fondo --- struct ParamBackground { - Color attenuate_color; // Color para atenuar el fondo + Color attenuate_color = Color::fromHex(GameDefaults::Background::ATTENUATE_COLOR); }; // --- Parámetros de los globos --- struct ParamBalloon { struct Settings { - float grav; // Aceleración en el eje Y. Modifica la velocidad - float vel; // Velocidad inicial al rebotar contra el suelo + float grav; + float vel; - // Constructor - explicit Settings(float grav_val = 0.0F, float vel_val = 0.0F) + // Constructor por defecto + constexpr Settings(float grav_val = 0.0f, float vel_val = 0.0f) : grav(grav_val), vel(vel_val) {} }; - std::array settings; - std::array color; - bool bouncing_sound; // Indica si los globos hacer sonido al rebotar + // Inicialización con los valores por defecto desde GameDefaults + std::array settings = {{Settings(GameDefaults::Balloon::SETTINGS[0].grav, GameDefaults::Balloon::SETTINGS[0].vel), + Settings(GameDefaults::Balloon::SETTINGS[1].grav, GameDefaults::Balloon::SETTINGS[1].vel), + Settings(GameDefaults::Balloon::SETTINGS[2].grav, GameDefaults::Balloon::SETTINGS[2].vel), + Settings(GameDefaults::Balloon::SETTINGS[3].grav, GameDefaults::Balloon::SETTINGS[3].vel)}}; + + std::array color = {{GameDefaults::Balloon::COLORS[0], + GameDefaults::Balloon::COLORS[1], + GameDefaults::Balloon::COLORS[2], + GameDefaults::Balloon::COLORS[3]}}; + + bool bouncing_sound = GameDefaults::Balloon::BOUNCING_SOUND; }; // --- Parámetros de las notificaciones --- struct ParamNotification { - NotifyPosition pos_h; // Ubicación horizontal de las notificaciones en pantalla - NotifyPosition pos_v; // Ubicación vertical de las notificaciones en pantalla - bool sound; // Indica si las notificaciones suenan - Color color; // Color de las notificaciones + Notifier::Position pos_h = GameDefaults::Notification::POS_H; + Notifier::Position pos_v = GameDefaults::Notification::POS_V; + bool sound = GameDefaults::Notification::SOUND; + Color color = Color::fromHex(GameDefaults::Notification::COLOR); }; // --- Parámetros del marcador --- struct ParamScoreboard { - SDL_FRect rect; // Posición y tamaño del marcador - bool separator_autocolor; // El separado establece su color de forma automatica - Color separator_color; // Color del separador si se pone de forma manual - Color easy_color; // Color del marcador segun la dificultad - Color normal_color; // Color del marcador segun la dificultad - Color hard_color; // Color del marcador segun la dificultad - bool text_autocolor; // El texto establece su color de forma automatica - Color text_color1; // Color del texto - Color text_color2; // Color del texto - int skip_countdown_value; // Valor a partir del cual se puede saltar la cuenta atras + SDL_FRect rect = { + GameDefaults::Scoreboard::RECT_X, + GameDefaults::Scoreboard::RECT_Y, + GameDefaults::Scoreboard::RECT_W, + GameDefaults::Scoreboard::RECT_H}; + bool separator_autocolor = GameDefaults::Scoreboard::SEPARATOR_AUTOCOLOR; + Color separator_color = Color::fromHex(GameDefaults::Scoreboard::SEPARATOR_COLOR); + Color easy_color = Color::fromHex(GameDefaults::Scoreboard::EASY_COLOR); + Color normal_color = Color::fromHex(GameDefaults::Scoreboard::NORMAL_COLOR); + Color hard_color = Color::fromHex(GameDefaults::Scoreboard::HARD_COLOR); + bool text_autocolor = GameDefaults::Scoreboard::TEXT_AUTOCOLOR; + Color text_color1 = Color::fromHex(GameDefaults::Scoreboard::TEXT_COLOR1); + Color text_color2 = Color::fromHex(GameDefaults::Scoreboard::TEXT_COLOR2); + int skip_countdown_value = GameDefaults::Scoreboard::SKIP_COUNTDOWN_VALUE; }; // --- Parámetros del menú de servicio --- struct ParamServiceMenu { - Color title_color; - Color text_color; - Color selected_color; - Color bg_color; - bool drop_shadow; + Color title_color = Color::fromHex(GameDefaults::ServiceMenu::TITLE_COLOR); + Color text_color = Color::fromHex(GameDefaults::ServiceMenu::TEXT_COLOR); + Color selected_color = Color::fromHex(GameDefaults::ServiceMenu::SELECTED_COLOR); + Color bg_color = Color::fromHex(GameDefaults::ServiceMenu::BG_COLOR); + bool drop_shadow = GameDefaults::ServiceMenu::DROP_SHADOW; }; // --- Parámetros de la intro --- struct ParamIntro { - Color bg_color; - Color card_color; - Color shadow_color; - int text_distance_from_bottom; + Color bg_color = Color::fromHex(GameDefaults::Intro::BG_COLOR); + Color card_color = Color::fromHex(GameDefaults::Intro::CARD_COLOR); + Color shadow_color = Color::fromHex(GameDefaults::Intro::SHADOW_COLOR); + int text_distance_from_bottom = GameDefaults::Intro::TEXT_DISTANCE_FROM_BOTTOM; }; // --- Parámetros para Debug --- struct ParamDebug { - Color color; + Color color = Color::fromHex(GameDefaults::Debug::COLOR); }; // --- Parámetros para Resource --- struct ParamResource { - Color color; + Color color = Color::fromHex(GameDefaults::Resource::COLOR); }; // --- Parámetros para Tabe --- struct ParamTabe { - float min_spawn_time; - float max_spawn_time; + float min_spawn_time = GameDefaults::Tabe::MIN_SPAWN_TIME; + float max_spawn_time = GameDefaults::Tabe::MAX_SPAWN_TIME; }; // --- Estructura principal para almacenar todos los parámetros del juego --- struct Param { - ParamGame game; // Parámetros del juego - ParamFade fade; // Parámetros del fade - ParamScoreboard scoreboard; // Rectángulo del marcador - ParamTitle title; // Parámetros de la pantalla de título - ParamBackground background; // Parámetros del fondo - ParamBalloon balloon; // Parámetros de los globos - ParamNotification notification; // Parámetros de las notificaciones - ParamServiceMenu service_menu; // Parámetros del menú de servicio - ParamIntro intro; // Parámetros de la intro - ParamDebug debug; // Parámetros para Debug - ParamResource resource; // Parámetros para Resource - ParamTabe tabe; // Parametros para Tabe + ParamGame game; + ParamFade fade; + ParamScoreboard scoreboard; + ParamTitle title; + ParamBackground background; + ParamBalloon balloon; + ParamNotification notification; + ParamServiceMenu service_menu; + ParamIntro intro; + ParamDebug debug; + ParamResource resource; + ParamTabe tabe; - // Constructor - Param() - : game(), fade(), scoreboard(), title(), background(), balloon(), notification(), service_menu(), intro(), debug(), resource() {} + // Constructor que inicializa las zonas que dependen de otros valores + Param() { + // Inicializar play_area usando los valores por defecto + game.play_area.rect = { + GameDefaults::Game::PLAY_AREA_X, + GameDefaults::Game::PLAY_AREA_Y, + GameDefaults::Game::PLAY_AREA_W, + GameDefaults::Game::PLAY_AREA_H}; + + // Las zonas calculadas se inicializarán en precalculateZones() + precalculateZones(); + } + + // Función pública para recalcular zonas (necesaria después de cambiar parámetros) + void precalculateZones(); }; // --- Variable global con los parámetros del juego --- extern Param param; // --- Funciones globales --- -void loadParamsFromFile(const std::string &file_path); // Establece valores para los parámetros a partir de un fichero de texto \ No newline at end of file +void loadParamsFromFile(const std::string& file_path); \ No newline at end of file diff --git a/source/ui/notifier.cpp b/source/ui/notifier.cpp index dda6c96..536f9cf 100644 --- a/source/ui/notifier.cpp +++ b/source/ui/notifier.cpp @@ -49,16 +49,14 @@ void Notifier::update() { if (!shouldProcessNotification(i)) { break; } - processNotification(i); } - clearFinishedNotifications(); } auto Notifier::shouldProcessNotification(int index) const -> bool { // Si la notificación anterior está "saliendo", no hagas nada - return index <= 0 || notifications_[index - 1].state != NotificationStatus::RISING; + return index <= 0 || notifications_[index - 1].state != State::RISING; } void Notifier::processNotification(int index) { @@ -74,7 +72,7 @@ void Notifier::playNotificationSoundIfNeeded(const Notification& notification) { // Hace sonar la notificación en el primer frame if (notification.counter == 1 && param.notification.sound && - notification.state == NotificationStatus::RISING) { + notification.state == State::RISING) { Audio::get()->playSound("notify.wav", Audio::Group::INTERFACE); } } @@ -83,13 +81,13 @@ void Notifier::updateNotificationState(int index) { auto& notification = notifications_[index]; switch (notification.state) { - case NotificationStatus::RISING: + case State::RISING: handleRisingState(index); break; - case NotificationStatus::STAY: + case State::STAY: handleStayState(index); break; - case NotificationStatus::VANISHING: + case State::VANISHING: handleVanishingState(index); break; default: @@ -103,7 +101,7 @@ void Notifier::handleRisingState(int index) { const float STEP = (float)notification.counter / notification.travel_dist; const int ALPHA = 255 * STEP; - moveNotificationVertically(notification, param.notification.pos_v == NotifyPosition::TOP ? 1 : -1); + moveNotificationVertically(notification, param.notification.pos_v == Position::TOP ? 1 : -1); notification.texture->setAlpha(ALPHA); if (notification.rect.y == notification.y) { @@ -115,7 +113,7 @@ void Notifier::handleStayState(int index) { auto& notification = notifications_[index]; if (notification.counter == wait_time_) { - notification.state = NotificationStatus::VANISHING; + notification.state = State::VANISHING; notification.counter = 0; } } @@ -126,11 +124,11 @@ void Notifier::handleVanishingState(int index) { const float STEP = notification.counter / (float)notification.travel_dist; const int ALPHA = 255 * (1 - STEP); - moveNotificationVertically(notification, param.notification.pos_v == NotifyPosition::TOP ? -1 : 1); + moveNotificationVertically(notification, param.notification.pos_v == Position::TOP ? -1 : 1); notification.texture->setAlpha(ALPHA); if (notification.rect.y == notification.y - notification.travel_dist) { - notification.state = NotificationStatus::FINISHED; + notification.state = State::FINISHED; } } @@ -140,7 +138,7 @@ void Notifier::moveNotificationVertically(Notification& notification, int direct void Notifier::transitionToStayState(int index) { auto& notification = notifications_[index]; - notification.state = NotificationStatus::STAY; + notification.state = State::STAY; notification.texture->setAlpha(255); notification.counter = 0; } @@ -148,7 +146,7 @@ void Notifier::transitionToStayState(int index) { // Elimina las notificaciones finalizadas void Notifier::clearFinishedNotifications() { for (int i = (int)notifications_.size() - 1; i >= 0; --i) { - if (notifications_[i].state == NotificationStatus::FINISHED) { + if (notifications_[i].state == State::FINISHED) { notifications_.erase(notifications_.begin() + i); } } @@ -185,20 +183,20 @@ void Notifier::show(std::vector texts, int icon, const std::string& const int ICON_SPACE = icon >= 0 ? ICON_SIZE + PADDING_IN_H : 0; const float WIDTH = text_->length(longest) + (PADDING_IN_H * 2) + ICON_SPACE; const float HEIGHT = (text_->getCharacterSize() * texts.size()) + (PADDING_IN_V * 2); - const auto SHAPE = NotificationShape::SQUARED; + const auto SHAPE = Shape::SQUARED; // Posición horizontal float desp_h = 0; switch (param.notification.pos_h) { - case NotifyPosition::LEFT: + case Position::LEFT: desp_h = PADDING_OUT; break; - case NotifyPosition::MIDDLE: + case Position::MIDDLE: desp_h = ((param.game.width / 2) - (WIDTH / 2)); break; - case NotifyPosition::RIGHT: + case Position::RIGHT: desp_h = param.game.width - WIDTH - PADDING_OUT; break; @@ -208,13 +206,13 @@ void Notifier::show(std::vector texts, int icon, const std::string& } // Posición vertical - const int DESP_V = (param.notification.pos_v == NotifyPosition::TOP) ? PADDING_OUT : (param.game.height - HEIGHT - PADDING_OUT); + const int DESP_V = (param.notification.pos_v == Position::TOP) ? PADDING_OUT : (param.game.height - HEIGHT - PADDING_OUT); // Offset const auto TRAVEL_DIST = HEIGHT + PADDING_OUT; auto offset = notifications_.empty() ? DESP_V - : notifications_.back().y + (param.notification.pos_v == NotifyPosition::TOP ? TRAVEL_DIST : -TRAVEL_DIST); + : notifications_.back().y + (param.notification.pos_v == Position::TOP ? TRAVEL_DIST : -TRAVEL_DIST); // Crea la notificacion Notification n; @@ -225,7 +223,7 @@ void Notifier::show(std::vector texts, int icon, const std::string& n.travel_dist = TRAVEL_DIST; n.texts = texts; n.shape = SHAPE; - const float POS_Y = offset + (param.notification.pos_v == NotifyPosition::TOP ? -TRAVEL_DIST : TRAVEL_DIST); + const float POS_Y = offset + (param.notification.pos_v == Position::TOP ? -TRAVEL_DIST : TRAVEL_DIST); n.rect = {desp_h, POS_Y, WIDTH, HEIGHT}; // Crea la textura @@ -239,7 +237,7 @@ void Notifier::show(std::vector texts, int icon, const std::string& // Dibuja el fondo de la notificación SDL_SetRenderDrawColor(renderer_, bg_color_.r, bg_color_.g, bg_color_.b, 255); SDL_FRect rect; - if (SHAPE == NotificationShape::ROUNDED) { + if (SHAPE == Shape::ROUNDED) { rect = {4, 0, WIDTH - (4 * 2), HEIGHT}; SDL_RenderFillRect(renderer_, &rect); @@ -253,7 +251,7 @@ void Notifier::show(std::vector texts, int icon, const std::string& SDL_RenderFillRect(renderer_, &rect); } - else if (SHAPE == NotificationShape::SQUARED) { + else if (SHAPE == Shape::SQUARED) { SDL_RenderClear(renderer_); } @@ -293,7 +291,7 @@ void Notifier::show(std::vector texts, int icon, const std::string& // Finaliza y elimnina todas las notificaciones activas void Notifier::clearAllNotifications() { for (auto& notification : notifications_) { - notification.state = NotificationStatus::FINISHED; + notification.state = State::FINISHED; } clearFinishedNotifications(); diff --git a/source/ui/notifier.h b/source/ui/notifier.h index eb5179e..8072ca9 100644 --- a/source/ui/notifier.h +++ b/source/ui/notifier.h @@ -16,6 +16,15 @@ class Texture; // --- Clase Notifier: gestiona las notificaciones en pantalla (singleton) --- class Notifier { public: + // Posiciones de las notificaciones + enum class Position { + TOP, + BOTTOM, + LEFT, + MIDDLE, + RIGHT, + }; + // --- Métodos de singleton --- static void init(const std::string &icon_file, std::shared_ptr text); // Inicializa el singleton static void destroy(); // Libera el singleton @@ -33,30 +42,30 @@ class Notifier { private: // --- Tipos internos --- - enum class NotificationStatus { + enum class State { RISING, STAY, VANISHING, FINISHED, }; - enum class NotificationShape { + enum class Shape { ROUNDED, SQUARED, }; // --- Estructura Notification --- struct Notification { - std::shared_ptr texture; // Textura de la notificación - std::shared_ptr sprite; // Sprite asociado - std::vector texts; // Textos a mostrar - int counter{0}; // Contador de tiempo - NotificationStatus state{NotificationStatus::RISING}; // Estado de la notificación - NotificationShape shape{NotificationShape::SQUARED}; // Forma de la notificación - SDL_FRect rect; // Rectángulo de la notificación - int y{0}; // Posición vertical - int travel_dist{0}; // Distancia a recorrer - std::string code; // Código identificador de la notificación + std::shared_ptr texture; // Textura de la notificación + std::shared_ptr sprite; // Sprite asociado + std::vector texts; // Textos a mostrar + int counter{0}; // Contador de tiempo + State state{State::RISING}; // Estado de la notificación + Shape shape{Shape::SQUARED}; // Forma de la notificación + SDL_FRect rect; // Rectángulo de la notificación + int y{0}; // Posición vertical + int travel_dist{0}; // Distancia a recorrer + std::string code; // Código identificador de la notificación // Constructor explicit Notification() diff --git a/source/utils.h b/source/utils.h index 872133b..b59effe 100644 --- a/source/utils.h +++ b/source/utils.h @@ -29,15 +29,6 @@ struct Circle { : x(x_coord), y(y_coord), r(radius) {} }; -// Posiciones de las notificaciones -enum class NotifyPosition { - TOP, - BOTTOM, - LEFT, - MIDDLE, - RIGHT, -}; - // Estructura para datos de la demo struct DemoKeys { Uint8 left;