From 87cc58b5dd2b0d28b782aae1aa5b1b8da6a62658 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Wed, 8 Apr 2026 11:07:50 +0200 Subject: [PATCH] granera con sarna no pica --- data/console/commands.yaml | 9 ------ source/core/input/input.hpp | 4 +-- source/core/rendering/render_info.cpp | 2 +- source/game/defaults.hpp | 28 +++++++++++++---- source/game/editor/map_editor.cpp | 23 ++------------ source/game/editor/room_saver.cpp | 3 -- source/game/entities/enemy.cpp | 19 ++++++------ source/game/entities/enemy.hpp | 12 +++---- source/game/entities/item.cpp | 4 +-- source/game/entities/item.hpp | 1 + source/game/entities/player.cpp | 33 ++++---------------- source/game/entities/player.hpp | 3 -- source/game/game_control.hpp | 7 ----- source/game/gameplay/item_manager.cpp | 3 +- source/game/gameplay/room.cpp | 7 ----- source/game/gameplay/room.hpp | 10 +++--- source/game/gameplay/room_loader.cpp | 5 --- source/game/gameplay/tilemap_renderer.cpp | 16 +++++----- source/game/gameplay/tilemap_renderer.hpp | 4 ++- source/game/options.cpp | 28 ----------------- source/game/options.hpp | 6 ++-- source/game/scenes/game.cpp | 24 ++------------ source/game/scenes/title.cpp | 27 +++++----------- source/game/scenes/title.hpp | 4 +++ source/game/ui/console.cpp | 8 ++--- source/game/ui/console.hpp | 3 ++ source/game/ui/console_commands.cpp | 38 ----------------------- source/game/ui/notifier.cpp | 14 ++++----- source/game/ui/notifier.hpp | 3 ++ 29 files changed, 104 insertions(+), 244 deletions(-) diff --git a/data/console/commands.yaml b/data/console/commands.yaml index e694af3..1d313a5 100644 --- a/data/console/commands.yaml +++ b/data/console/commands.yaml @@ -115,15 +115,6 @@ categories: - name: GAME scope: game commands: - - keyword: PLAYER - handler: cmd_player - description: "Player skin and color" - usage: "PLAYER SKIN | PLAYER COLOR <0-15>|DEFAULT" - completions: - PLAYER: [SKIN, COLOR] - PLAYER SKIN: [DEFAULT, ABAD, BATMAN, CHIP, CONGO, JEANNINE, MUMMY, UPV_STUDENT] - PLAYER COLOR: [DEFAULT] - - keyword: RESTART handler: cmd_restart description: Restart from the beginning diff --git a/source/core/input/input.hpp b/source/core/input/input.hpp index 698137d..67f6a12 100644 --- a/source/core/input/input.hpp +++ b/source/core/input/input.hpp @@ -115,8 +115,8 @@ class Input { private: // --- Constantes --- - static constexpr Sint16 AXIS_THRESHOLD = 30000; // Umbral para ejes analógicos - static constexpr Sint16 TRIGGER_THRESHOLD = 16384; // Umbral para triggers (50% del rango) + static constexpr Sint16 AXIS_THRESHOLD = 20000; // Umbral on/off para ejes analógicos + static constexpr Sint16 TRIGGER_THRESHOLD = 20000; // Umbral on/off para triggers static constexpr std::array BUTTON_INPUTS = {Action::JUMP}; // Inputs que usan botones // --- Métodos --- diff --git a/source/core/rendering/render_info.cpp b/source/core/rendering/render_info.cpp index 1ce9a6c..6d8719f 100644 --- a/source/core/rendering/render_info.cpp +++ b/source/core/rendering/render_info.cpp @@ -108,7 +108,7 @@ void RenderInfo::render() const { // Constantes visuales static constexpr Uint8 MSG_COLOR = 9; // PaletteColor::BRIGHT_GREEN - static constexpr int TEXT_SIZE = 6; + static constexpr int TEXT_SIZE = Console::TEXT_SIZE; static constexpr int PADDING_V = (TEXT_SIZE / 2) - 1; // Fuente: preferir la de la consola si está disponible diff --git a/source/game/defaults.hpp b/source/game/defaults.hpp index 2934369..b72532f 100644 --- a/source/game/defaults.hpp +++ b/source/game/defaults.hpp @@ -32,7 +32,7 @@ namespace Defaults::Video { constexpr const char* PALETTE_NAME = "resurrect-64"; // Paleta por defecto constexpr const char* PALETTE_SORT = "original"; // Modo de ordenación de paleta por defecto constexpr bool LINEAR_UPSCALE = false; // Upscale NEAREST por defecto - constexpr int DOWNSCALE_ALGO = 1; // Downscale Lanczos2 por defecto + constexpr int DOWNSCALE_ALGO = 1; // Downscale por defecto (0=Bilinear, 1=Lanczos2, 2=Lanczos3) constexpr bool GPU_ACCELERATION = true; // Aceleración GPU activada por defecto } // namespace Defaults::Video @@ -50,11 +50,24 @@ namespace Defaults::Audio { namespace Defaults::Music { constexpr float VOLUME = 0.8F; // Volumen por defecto de la musica constexpr bool ENABLED = true; // Musica habilitada por defecto + + namespace Files { + constexpr const char* TITLE_TRACK = "574071_EA_DTV.ogg"; + constexpr const char* GAME_TRACK = "574070_KUVO_Farewell_to_school.ogg"; + } // namespace Files } // namespace Defaults::Music namespace Defaults::Sound { constexpr float VOLUME = 1.0F; // Volumen por defecto de los efectos de sonido constexpr bool ENABLED = true; // Sonido habilitado por defecto + + namespace Files { + constexpr const char* JUMP = "jump.wav"; + constexpr const char* LAND = "land.wav"; + constexpr const char* DEATH = "death.wav"; + constexpr const char* ITEM = "item.wav"; + constexpr const char* NOTIFY = "notify.wav"; + } // namespace Files } // namespace Defaults::Sound namespace Defaults::Cheat { @@ -75,6 +88,7 @@ namespace Defaults::Controls { constexpr int GAMEPAD_BUTTON_LEFT = SDL_GAMEPAD_BUTTON_DPAD_LEFT; // Botón izquierda por defecto constexpr int GAMEPAD_BUTTON_RIGHT = SDL_GAMEPAD_BUTTON_DPAD_RIGHT; // Botón derecha por defecto constexpr int GAMEPAD_BUTTON_JUMP = SDL_GAMEPAD_BUTTON_WEST; // Botón salto por defecto + constexpr Sint16 JOYSTICK_AXIS_THRESHOLD = 20000; // Umbral para ejes y triggers del gamepad } // namespace Defaults::Controls namespace Defaults::Kiosk { @@ -98,12 +112,14 @@ namespace Defaults::Localization { namespace Defaults::Game::Room { constexpr const char* INITIAL = "03.yaml"; // Habitación de inicio + constexpr Uint8 ITEM_COLOR1 = 12; // Color principal de los items por defecto + constexpr Uint8 ITEM_COLOR2 = 6; // Color secundario de los items por defecto } // namespace Defaults::Game::Room namespace Defaults::Game::Player { - constexpr int SPAWN_X = 25 * Tile::SIZE; // Posición X inicial - constexpr int SPAWN_Y = 13 * Tile::SIZE; // Posición Y inicial - constexpr SDL_FlipMode SPAWN_FLIP = Flip::LEFT; // Orientación inicial - constexpr const char* SKIN = "default"; // Skin del jugador por defecto - constexpr int COLOR = -1; // Color del jugador (-1 = automático según cheats) + constexpr int SPAWN_X = 25 * Tile::SIZE; // Posición X inicial + constexpr int SPAWN_Y = 13 * Tile::SIZE; // Posición Y inicial + constexpr SDL_FlipMode SPAWN_FLIP = Flip::LEFT; // Orientación inicial + constexpr const char* SKIN = "default"; // Skin del jugador por defecto + constexpr const char* DEFAULT_ANIMATION = "player.yaml"; // Animación del skin por defecto } // namespace Defaults::Game::Player diff --git a/source/game/editor/map_editor.cpp b/source/game/editor/map_editor.cpp index 007063c..15e3646 100644 --- a/source/game/editor/map_editor.cpp +++ b/source/game/editor/map_editor.cpp @@ -204,7 +204,6 @@ void MapEditor::enter(std::shared_ptr room, std::shared_ptr player // Forzar invencibilidad Options::cheats.invincible = Options::Cheat::State::ENABLED; - player_->setColor(); // Aplicar el setting de render_info del editor if (settings_.show_render_info != RenderInfo::get()->isActive()) { @@ -246,7 +245,6 @@ void MapEditor::exit() { if (!reenter_) { // Solo restaurar en el exit final (no en cambio de room) Options::cheats.invincible = invincible_before_editor_; - player_->setColor(); if (RenderInfo::get()->isActive() != render_info_before_editor_) { RenderInfo::get()->toggle(); @@ -969,7 +967,7 @@ void MapEditor::updateStatusBarInfo() { // NOLINT(readability-function-cognitiv auto dot = anim.rfind('.'); if (dot != std::string::npos) { anim = anim.substr(0, dot); } - line2 = "enemy " + std::to_string(selected_enemy_) + ": " + anim + " c:" + std::to_string(e.color); + line2 = "enemy " + std::to_string(selected_enemy_) + ": " + anim; line3 = "vx:" + std::to_string(static_cast(e.vx)) + " vy:" + std::to_string(static_cast(e.vy)); if (e.flip) { line3 += " flip"; } @@ -1032,7 +1030,7 @@ auto MapEditor::getSetCompletions() const -> std::vector { return {"TILE", "COUNTER"}; } // Room - return {"BGCOLOR", "ITEMCOLOR1", "ITEMCOLOR2", "CONVEYOR", "TILESET", "UP", "DOWN", "LEFT", "RIGHT"}; + return {"ITEMCOLOR1", "ITEMCOLOR2", "CONVEYOR", "TILESET", "UP", "DOWN", "LEFT", "RIGHT"}; } // Modifica una propiedad del enemigo seleccionado @@ -1062,21 +1060,7 @@ auto MapEditor::setEnemyProperty(const std::string& property, const std::string& } if (property == "COLOR") { - auto color = static_cast(safeStoi(value, 14)); - - // Intentar recrear el enemigo con el nuevo color - Uint8 old_color = enemy.color; - enemy.color = color; - try { - auto* enemy_mgr = room_->getEnemyManager(); - enemy_mgr->getEnemy(selected_enemy_) = std::make_shared(enemy); - } catch (const std::exception& e) { - enemy.color = old_color; - return std::string("Error: ") + e.what(); - } - - autosave(); - return "color: " + std::to_string(color); + return "color property removed (legacy)"; } if (property == "VX") { @@ -1154,7 +1138,6 @@ auto MapEditor::addEnemy() -> std::string { new_enemy.y1 = static_cast(CENTER_Y); new_enemy.x2 = static_cast(CENTER_X + ROUTE_HALF); new_enemy.y2 = static_cast(CENTER_Y); - new_enemy.color = 14; new_enemy.flip = true; new_enemy.frame = -1; diff --git a/source/game/editor/room_saver.cpp b/source/game/editor/room_saver.cpp index 3acc01e..b61cbf6 100644 --- a/source/game/editor/room_saver.cpp +++ b/source/game/editor/room_saver.cpp @@ -127,9 +127,6 @@ auto RoomSaver::buildYAML(const fkyaml::node& original_yaml, const Room::Data& r out << " position1: {x: " << b1_x << ", y: " << b1_y << "}\n"; out << " position2: {x: " << b2_x << ", y: " << b2_y << "}\n"; - if (enemy.color != 14) { - out << " color: " << static_cast(enemy.color) << "\n"; - } if (enemy.flip) { out << " flip: true\n"; } if (enemy.mirror) { out << " mirror: true\n"; } if (enemy.frame != -1) { out << " frame: " << enemy.frame << "\n"; } diff --git a/source/game/entities/enemy.cpp b/source/game/entities/enemy.cpp index c5488af..e7d36dc 100644 --- a/source/game/entities/enemy.cpp +++ b/source/game/entities/enemy.cpp @@ -23,21 +23,17 @@ Enemy::Enemy(const Data& enemy) sprite_->setVelX(enemy.vx); sprite_->setVelY(enemy.vy); - const int FLIP = (should_flip_ && enemy.vx < 0.0F) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; - const int MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE; - sprite_->setFlip(static_cast(FLIP | MIRROR)); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange) SDL flags are designed for bitwise OR + applyFlipMirror(enemy.vx); collider_ = getRect(); - color_ = enemy.color; - // Coloca un frame al azar o el designado sprite_->setCurrentAnimationFrame((enemy.frame == -1) ? (rand() % sprite_->getCurrentAnimationSize()) : enemy.frame); } // Pinta el enemigo en pantalla void Enemy::render() { - sprite_->render(1, color_); + sprite_->render(); } // Actualiza las variables del objeto @@ -60,9 +56,7 @@ void Enemy::resetToInitialPosition(const Data& data) { sprite_->setVelX(data.vx); sprite_->setVelY(data.vy); - const int FLIP = (should_flip_ && data.vx < 0.0F) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; - const int MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE; - sprite_->setFlip(static_cast(FLIP | MIRROR)); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange) + applyFlipMirror(data.vx); collider_ = getRect(); } @@ -105,6 +99,13 @@ void Enemy::checkPath() { // NOLINT(readability-make-member-function-const) } } +// Aplica flip horizontal y/o mirror vertical al sprite +void Enemy::applyFlipMirror(float vx) { + const int FLIP = (should_flip_ && vx < 0.0F) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; + const int MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE; + sprite_->setFlip(static_cast(FLIP | MIRROR)); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange) SDL flags are designed for bitwise OR +} + // Devuelve el rectangulo que contiene al enemigo auto Enemy::getRect() -> SDL_FRect { return sprite_->getRect(); diff --git a/source/game/entities/enemy.hpp b/source/game/entities/enemy.hpp index 6aa22a4..60a5279 100644 --- a/source/game/entities/enemy.hpp +++ b/source/game/entities/enemy.hpp @@ -2,9 +2,10 @@ #include -#include // Para shared_ptr -#include // Para string -class AnimatedSprite; // lines 7-7 +#include // Para shared_ptr +#include // Para string + +class AnimatedSprite; class Enemy { public: @@ -21,7 +22,6 @@ class Enemy { bool flip{false}; // Indica si el enemigo hace flip al terminar su ruta bool mirror{false}; // Indica si el enemigo está volteado verticalmente int frame{0}; // Frame inicial para la animación del enemigo - Uint8 color{14}; // Color del enemigo (default: white=14) }; explicit Enemy(const Data& enemy); // Constructor @@ -38,12 +38,12 @@ class Enemy { auto getCollider() -> SDL_FRect&; // Obtiene el rectangulo de colision del enemigo private: - void checkPath(); // Comprueba si ha llegado al limite del recorrido para darse media vuelta + void applyFlipMirror(float vx); // Aplica flip horizontal y/o mirror vertical al sprite + void checkPath(); // Comprueba si ha llegado al limite del recorrido para darse media vuelta std::shared_ptr sprite_; // Sprite del enemigo // Variables - Uint8 color_{0}; // Color del enemigo int x1_{0}; // Limite izquierdo de la ruta en el eje X int x2_{0}; // Limite derecho de la ruta en el eje X int y1_{0}; // Limite superior de la ruta en el eje Y diff --git a/source/game/entities/item.cpp b/source/game/entities/item.cpp index ce31205..ffef84a 100644 --- a/source/game/entities/item.cpp +++ b/source/game/entities/item.cpp @@ -8,7 +8,7 @@ Item::Item(const Data& item) : sprite_(std::make_shared(Resource::Cache::get()->getSurface(item.tile_set_file), item.x, item.y, ITEM_SIZE, ITEM_SIZE)), time_accumulator_(static_cast(item.counter) * COLOR_CHANGE_INTERVAL) { // Inicia variables - sprite_->setClip((item.tile % 10) * ITEM_SIZE, (item.tile / 10) * ITEM_SIZE, ITEM_SIZE, ITEM_SIZE); + sprite_->setClip((item.tile % TILESET_COLUMNS) * ITEM_SIZE, (item.tile / TILESET_COLUMNS) * ITEM_SIZE, ITEM_SIZE, ITEM_SIZE); collider_ = sprite_->getRect(); // Inicializa los colores @@ -52,7 +52,7 @@ void Item::setPosition(float x, float y) { #ifdef _DEBUG // Cambia el tile del item (para editor) void Item::setTile(int tile) { - sprite_->setClip((tile % 10) * ITEM_SIZE, (tile / 10) * ITEM_SIZE, ITEM_SIZE, ITEM_SIZE); + sprite_->setClip((tile % TILESET_COLUMNS) * ITEM_SIZE, (tile / TILESET_COLUMNS) * ITEM_SIZE, ITEM_SIZE, ITEM_SIZE); } #endif diff --git a/source/game/entities/item.hpp b/source/game/entities/item.hpp index 2ec933c..7a25c5c 100644 --- a/source/game/entities/item.hpp +++ b/source/game/entities/item.hpp @@ -36,6 +36,7 @@ class Item { private: static constexpr float ITEM_SIZE = 8.0F; // Tamaño del item en pixels + static constexpr int TILESET_COLUMNS = 10; // Columnas en la textura del tileset de items static constexpr float COLOR_CHANGE_INTERVAL = 0.06F; // Intervalo de cambio de color en segundos (4 frames a 66.67fps) std::shared_ptr sprite_; // SSprite del objeto diff --git a/source/game/entities/player.cpp b/source/game/entities/player.cpp index 3df6f6e..ffb3b14 100644 --- a/source/game/entities/player.cpp +++ b/source/game/entities/player.cpp @@ -8,6 +8,7 @@ #include "core/input/input.hpp" // Para Input, InputAction #include "core/rendering/sprite/animated_sprite.hpp" // Para AnimatedSprite #include "core/resources/resource_cache.hpp" // Para Resource +#include "game/defaults.hpp" // Para Defaults::Game::Player, Defaults::Sound::Files #include "game/gameplay/room.hpp" // Para Room #include "game/gameplay/tile_collider.hpp" // Para TileCollider #include "game/options.hpp" // Para Cheat, Options @@ -24,7 +25,6 @@ Player::Player(const Data& player) : room_(player.room) { initSprite(player.animations_path); - setColor(); applySpawnValues(player.spawn_data); placeSprite(); initSounds(); @@ -36,7 +36,7 @@ Player::Player(const Data& player) // ============================================================================ void Player::render() { - sprite_->render(1, color_); + sprite_->render(); } // ============================================================================ @@ -560,35 +560,14 @@ void Player::animate(float delta_time) { // NOLINT(readability-make-member-func } // ============================================================================ -// Color y skin +// Skin // ============================================================================ -void Player::setColor(Uint8 color) { - if (color != 0) { - color_ = color; - return; - } - if (Options::game.player_color >= 0) { - color_ = static_cast(Options::game.player_color); - } else { - color_ = 14; - } - if (room_ != nullptr && color_ == room_->getBGColor()) { - color_ = (room_->getBGColor() != 14) ? 14 : 1; - } -} - auto Player::skinToAnimationPath(const std::string& skin_name) -> std::string { - if (skin_name == "default") { return "player.yaml"; } + if (skin_name == Defaults::Game::Player::SKIN) { return Defaults::Game::Player::DEFAULT_ANIMATION; } return skin_name + ".yaml"; } -void Player::setSkin(const std::string& skin_name) { - const auto FLIP = sprite_->getFlip(); - initSprite(skinToAnimationPath(skin_name)); - sprite_->setFlip(FLIP); -} - // ============================================================================ // Inicialización // ============================================================================ @@ -602,8 +581,8 @@ void Player::initSprite(const std::string& animations_path) { // NOLINT(readabi } void Player::initSounds() { // NOLINT(readability-convert-member-functions-to-static) - jump_sound_ = Resource::Cache::get()->getSound("jump.wav"); - land_sound_ = Resource::Cache::get()->getSound("land.wav"); + jump_sound_ = Resource::Cache::get()->getSound(Defaults::Sound::Files::JUMP); + land_sound_ = Resource::Cache::get()->getSound(Defaults::Sound::Files::LAND); } void Player::applySpawnValues(const SpawnData& spawn) { diff --git a/source/game/entities/player.hpp b/source/game/entities/player.hpp index 2b1f3b9..953cbc4 100644 --- a/source/game/entities/player.hpp +++ b/source/game/entities/player.hpp @@ -67,8 +67,6 @@ class Player { auto getRect() -> SDL_FRect { return {.x = x_, .y = y_, .w = WIDTH, .h = HEIGHT}; } auto getCollider() -> SDL_FRect& { return collider_box_; } auto getSpawnParams() -> SpawnData { return {.x = x_, .y = y_, .vx = vx_, .vy = vy_, .last_grounded_position = last_grounded_position_, .state = state_, .flip = sprite_->getFlip()}; } - void setColor(Uint8 color = 0); - void setSkin(const std::string& skin_name); static auto skinToAnimationPath(const std::string& skin_name) -> std::string; void setRoom(std::shared_ptr room) { room_ = std::move(room); } void setAdjacentRoom(std::shared_ptr room, Room::Border direction); @@ -134,7 +132,6 @@ class Player { int last_grounded_position_ = 0; // --- Renderizado y sonido --- - Uint8 color_ = 0; JA_Sound_t* jump_sound_ = nullptr; JA_Sound_t* land_sound_ = nullptr; diff --git a/source/game/game_control.hpp b/source/game/game_control.hpp index 5da6911..c00a0fb 100644 --- a/source/game/game_control.hpp +++ b/source/game/game_control.hpp @@ -2,13 +2,6 @@ #include #include -namespace GameControl { - // Disponible en todos los builds — cambia la skin del jugador ("default" o nombre de enemigo) - inline std::function change_player_skin; - // Disponible en todos los builds — cambia el color del jugador (-1 = automático, 0-15 = color fijo) - inline std::function change_player_color; -} // namespace GameControl - #ifdef _DEBUG namespace GameControl { // Registrada por Game::Game() — cambia la habitación activa diff --git a/source/game/gameplay/item_manager.cpp b/source/game/gameplay/item_manager.cpp index 84b8456..79e94ce 100644 --- a/source/game/gameplay/item_manager.cpp +++ b/source/game/gameplay/item_manager.cpp @@ -1,6 +1,7 @@ #include "item_manager.hpp" #include "core/audio/audio.hpp" // Para Audio +#include "game/defaults.hpp" // Para Defaults::Sound::Files #include "game/entities/item.hpp" // Para Item #include "game/options.hpp" // Para Options #include "item_tracker.hpp" // Para ItemTracker @@ -55,7 +56,7 @@ auto ItemManager::checkCollision(SDL_FRect& rect) -> bool { // NOLINT(readabili items_.erase(items_.begin() + i); // Reproduce el sonido de pickup - Audio::get()->playSound("item.wav", Audio::Group::GAME); + Audio::get()->playSound(Defaults::Sound::Files::ITEM, Audio::Group::GAME); // Actualiza el scoreboard y estadísticas data_->items++; diff --git a/source/game/gameplay/room.cpp b/source/game/gameplay/room.cpp index 7a1ca20..d3f150d 100644 --- a/source/game/gameplay/room.cpp +++ b/source/game/gameplay/room.cpp @@ -115,13 +115,6 @@ void Room::setTile(int index, int tile_value) { } } -// Cambia color de fondo y redibuja el mapa (para editor) -void Room::setBgColor(Uint8 color) { - bg_color_ = color; - tilemap_renderer_->setBgColor(color); - tilemap_renderer_->redrawMap(collision_map_->getCollisionTileMap()); -} - // Cambia colores de items en vivo (para editor) void Room::setItemColors(Uint8 color1, Uint8 color2) { item_color1_ = color1; diff --git a/source/game/gameplay/room.hpp b/source/game/gameplay/room.hpp index 194042e..60a0eff 100644 --- a/source/game/gameplay/room.hpp +++ b/source/game/gameplay/room.hpp @@ -6,6 +6,7 @@ #include // Para string #include // Para vector +#include "game/defaults.hpp" // Para Defaults::Game::Room #include "game/entities/enemy.hpp" // Para EnemyData #include "game/entities/item.hpp" // Para ItemData #include "game/gameplay/scoreboard.hpp" // Para Scoreboard::Data @@ -31,8 +32,8 @@ class Room { struct Data { std::string number; Uint8 bg_color{0}; - Uint8 item_color1{12}; - Uint8 item_color2{6}; + Uint8 item_color1{Defaults::Game::Room::ITEM_COLOR1}; + Uint8 item_color2{Defaults::Game::Room::ITEM_COLOR2}; std::string upper_room; std::string lower_room; std::string left_room; @@ -61,7 +62,6 @@ class Room { void resetEnemyPositions(const std::vector& enemy_data); auto getEnemyManager() -> EnemyManager* { return enemy_manager_.get(); } auto getItemManager() -> ItemManager* { return item_manager_.get(); } - void setBgColor(Uint8 color); void setItemColors(Uint8 color1, Uint8 color2); void setTile(int index, int tile_value); [[nodiscard]] auto getTileSetFile() const -> const std::string& { return tile_set_file_; } @@ -92,8 +92,8 @@ class Room { std::string number_; Uint8 bg_color_{0}; - Uint8 item_color1_{12}; - Uint8 item_color2_{6}; + Uint8 item_color1_{Defaults::Game::Room::ITEM_COLOR1}; + Uint8 item_color2_{Defaults::Game::Room::ITEM_COLOR2}; std::string upper_room_; std::string lower_room_; std::string left_room_; diff --git a/source/game/gameplay/room_loader.cpp b/source/game/gameplay/room_loader.cpp index a76626c..9e2140e 100644 --- a/source/game/gameplay/room_loader.cpp +++ b/source/game/gameplay/room_loader.cpp @@ -236,11 +236,6 @@ auto RoomLoader::parseEnemyData(const fkyaml::node& enemy_node) -> Enemy::Data { parseEnemyBoundaries(enemy_node["boundaries"], enemy); } - // Color - if (enemy_node.contains("color")) { - enemy.color = readColorNode(enemy_node["color"]); - } - // Optional fields enemy.flip = enemy_node.contains("flip") ? enemy_node["flip"].get_value_or(false) diff --git a/source/game/gameplay/tilemap_renderer.cpp b/source/game/gameplay/tilemap_renderer.cpp index af77d46..e382f11 100644 --- a/source/game/gameplay/tilemap_renderer.cpp +++ b/source/game/gameplay/tilemap_renderer.cpp @@ -62,8 +62,7 @@ void TilemapRenderer::setTile(int index, int tile_value) { map_surface_->fillRect(&cell, bg_color_); if (tile_value > -1) { - const bool IS_ANIMATED = (tile_value >= 18 * tile_set_width_) && (tile_value < 19 * tile_set_width_); - if (!IS_ANIMATED) { + if (!isAnimatedTile(tile_value)) { SDL_FRect clip = {.x = static_cast((tile_value % tile_set_width_) * TILE_SIZE), .y = static_cast((tile_value / tile_set_width_) * TILE_SIZE), .w = static_cast(TILE_SIZE), @@ -107,11 +106,10 @@ void TilemapRenderer::fillMapTexture(const std::vector& collision_tile_map) for (int y = 0; y < MAP_HEIGHT; ++y) { for (int x = 0; x < MAP_WIDTH; ++x) { const int INDEX = (y * MAP_WIDTH) + x; - // Los tiles animados (fila 18 del tileset) no se pintan en la textura estática - const bool IS_ANIMATED = (tile_map_[INDEX] >= 18 * tile_set_width_) && (tile_map_[INDEX] < 19 * tile_set_width_); + // Los tiles animados no se pintan en la textura estática const bool HAS_TILE = tile_map_[INDEX] > -1; - if (HAS_TILE && !IS_ANIMATED) { + if (HAS_TILE && !isAnimatedTile(tile_map_[INDEX])) { clip.x = (tile_map_[INDEX] % tile_set_width_) * TILE_SIZE; clip.y = (tile_map_[INDEX] / tile_set_width_) * TILE_SIZE; #ifdef _DEBUG @@ -145,8 +143,8 @@ void TilemapRenderer::setAnimatedTiles(const std::vector& collision_tile_ma const int YC = (tile_map_[i] / tile_set_width_) * TILE_SIZE; AnimatedTile at; - at.sprite = std::make_shared(tileset_surface_, X, Y, 8, 8); - at.sprite->setClip(XC, YC, 8, 8); + at.sprite = std::make_shared(tileset_surface_, X, Y, TILE_SIZE, TILE_SIZE); + at.sprite->setClip(XC, YC, TILE_SIZE, TILE_SIZE); at.x_orig = XC; animated_tiles_.push_back(at); } @@ -176,3 +174,7 @@ void TilemapRenderer::renderAnimatedTiles() { a.sprite->render(); } } + +auto TilemapRenderer::isAnimatedTile(int tile_value) const -> bool { + return (tile_value >= ANIMATED_TILE_ROW * tile_set_width_) && (tile_value < (ANIMATED_TILE_ROW + 1) * tile_set_width_); +} diff --git a/source/game/gameplay/tilemap_renderer.hpp b/source/game/gameplay/tilemap_renderer.hpp index fb8ade8..c873d80 100644 --- a/source/game/gameplay/tilemap_renderer.hpp +++ b/source/game/gameplay/tilemap_renderer.hpp @@ -26,7 +26,6 @@ class TilemapRenderer { #ifdef _DEBUG void redrawMap(const std::vector& collision_tile_map); - void setBgColor(Uint8 color) { bg_color_ = color; } void setTile(int index, int tile_value); #endif @@ -46,6 +45,9 @@ class TilemapRenderer { static constexpr int PLAY_AREA_HEIGHT = PlayArea::HEIGHT; static constexpr float CONVEYOR_FRAME_DURATION = 0.05F; static constexpr int COLLISION_ANIMATED = 6; // Valor del tile de conveyor en el collision tilemap + static constexpr int ANIMATED_TILE_ROW = 18; // Fila del tileset que contiene los tiles animados + + [[nodiscard]] auto isAnimatedTile(int tile_value) const -> bool; std::vector tile_map_; int tile_set_width_; diff --git a/source/game/options.cpp b/source/game/options.cpp index 8cd8e53..921602c 100644 --- a/source/game/options.cpp +++ b/source/game/options.cpp @@ -512,28 +512,6 @@ namespace Options { } } - // Carga configuración del jugador desde YAML - void loadPlayerConfigFromYaml(const fkyaml::node& yaml) { - if (yaml.contains("player")) { - const auto& player_node = yaml["player"]; - if (player_node.contains("skin")) { - try { - game.player_skin = player_node["skin"].get_value(); - } catch (...) { - game.player_skin = Defaults::Game::Player::SKIN; - } - } - if (player_node.contains("color")) { - try { - int color = player_node["color"].get_value(); - game.player_color = (color >= 0 && color <= 15) ? color : Defaults::Game::Player::COLOR; - } catch (...) { - game.player_color = Defaults::Game::Player::COLOR; - } - } - } - } - // Carga configuración del modo kiosko desde YAML void loadKioskConfigFromYaml(const fkyaml::node& yaml) { if (yaml.contains("kiosk")) { @@ -670,7 +648,6 @@ namespace Options { loadAudioConfigFromYaml(yaml); loadKeyboardControlsFromYaml(yaml); loadGamepadControlsFromYaml(yaml); - loadPlayerConfigFromYaml(yaml); loadKioskConfigFromYaml(yaml); loadLocalizationFromYaml(yaml); @@ -792,11 +769,6 @@ namespace Options { // KIOSK file << "\n"; - file << "# PLAYER\n"; - file << "player:\n"; - file << " skin: \"" << game.player_skin << "\"\n"; - file << " color: " << game.player_color << "\n"; - file << "\n"; file << "# KIOSK MODE\n"; file << "kiosk:\n"; diff --git a/source/game/options.hpp b/source/game/options.hpp index 9a33361..e202613 100644 --- a/source/game/options.hpp +++ b/source/game/options.hpp @@ -134,10 +134,8 @@ namespace Options { // Estructura para las opciones de juego struct Game { - float width{Defaults::Canvas::WIDTH}; // Ancho de la resolucion del juego - float height{Defaults::Canvas::HEIGHT}; // Alto de la resolucion del juego - std::string player_skin{Defaults::Game::Player::SKIN}; // Skin del jugador ("default" o nombre de enemigo) - int player_color{Defaults::Game::Player::COLOR}; // Color del jugador (-1 = automático, 0-15 = color fijo) + float width{Defaults::Canvas::WIDTH}; // Ancho de la resolucion del juego + float height{Defaults::Canvas::HEIGHT}; // Alto de la resolucion del juego }; // Estructura para un preset de PostFX diff --git a/source/game/scenes/game.cpp b/source/game/scenes/game.cpp index b94be1b..38c6e0e 100644 --- a/source/game/scenes/game.cpp +++ b/source/game/scenes/game.cpp @@ -80,15 +80,6 @@ Game::Game(Mode mode) Console::get()->on_toggle = [this](bool open) { player_->setIgnoreInput(open); }; if (Console::get()->isActive()) { player_->setIgnoreInput(true); } } - GameControl::change_player_skin = [this](const std::string& skin_name) -> void { - Options::game.player_skin = skin_name; - player_->setSkin(skin_name); - }; - GameControl::change_player_color = [this](int color) -> void { - Options::game.player_color = color; - player_->setColor(); - }; - #ifdef _DEBUG GameControl::change_room = [this](const std::string& r) -> bool { return this->changeRoom(r); }; GameControl::get_current_room = [this]() -> std::string { return current_room_; }; @@ -108,7 +99,6 @@ Game::Game(Mode mode) } else { Options::cheats.invincible = invincible_before_debug_ ? Options::Cheat::State::ENABLED : Options::Cheat::State::DISABLED; } - player_->setColor(); scoreboard_data_->music = !Debug::get()->isEnabled(); scoreboard_data_->music ? Audio::get()->resumeMusic() : Audio::get()->pauseMusic(); }; @@ -172,8 +162,6 @@ Game::~Game() { ItemTracker::destroy(); - GameControl::change_player_skin = nullptr; - GameControl::change_player_color = nullptr; if (Console::get() != nullptr) { Console::get()->on_toggle = nullptr; } #ifdef _DEBUG @@ -646,12 +634,10 @@ void Game::handleDebugEvents(const SDL_Event& event) { // NOLINT(readability-co case SDLK_1: toggleCheat(Options::cheats.infinite_lives, Locale::get()->get("game.cheat_infinite_lives")); // NOLINT(readability-static-accessed-through-instance) - player_->setColor(); break; case SDLK_2: toggleCheat(Options::cheats.invincible, Locale::get()->get("game.cheat_invincible")); // NOLINT(readability-static-accessed-through-instance) - player_->setColor(); break; case SDLK_7: @@ -671,7 +657,6 @@ void Game::handleDebugEvents(const SDL_Event& event) { // NOLINT(readability-co } else { Options::cheats.invincible = invincible_before_debug_ ? Options::Cheat::State::ENABLED : Options::Cheat::State::DISABLED; } - player_->setColor(); scoreboard_data_->music = !Debug::get()->isEnabled(); scoreboard_data_->music ? Audio::get()->resumeMusic() : Audio::get()->pauseMusic(); break; @@ -779,9 +764,6 @@ auto Game::changeRoom(const std::string& room_path) -> bool { // Pasa la nueva habitación al jugador player_->setRoom(room_); - // Recalcula el color del jugador (evita coincidir con el fondo) - player_->setColor(); - // Cambia la habitación actual current_room_ = room_path; @@ -938,7 +920,7 @@ void Game::killPlayer() { } // Sonido - Audio::get()->playSound("death.wav", Audio::Group::GAME); + Audio::get()->playSound(Defaults::Sound::Files::DEATH, Audio::Group::GAME); // Transicionar al estado BLACK_SCREEN (el respawn ocurre en transitionToState) transitionToState(State::BLACK_SCREEN); @@ -956,7 +938,7 @@ void Game::togglePause() { // Inicializa al jugador void Game::initPlayer(const Player::SpawnData& spawn_point, std::shared_ptr room) { // NOLINT(readability-convert-member-functions-to-static) const bool IGNORE_INPUT = player_ != nullptr && player_->getIgnoreInput(); - std::string player_animations = Player::skinToAnimationPath(Options::game.player_skin); + std::string player_animations = Player::skinToAnimationPath(Defaults::Game::Player::SKIN); const Player::Data PLAYER{.spawn_data = spawn_point, .animations_path = player_animations, .room = std::move(room)}; player_ = std::make_shared(PLAYER); if (IGNORE_INPUT) { player_->setIgnoreInput(true); } @@ -964,7 +946,7 @@ void Game::initPlayer(const Player::SpawnData& spawn_point, std::shared_ptrgetMusicState() == Audio::MusicState::STOPPED) { diff --git a/source/game/scenes/title.cpp b/source/game/scenes/title.cpp index c9468b1..1b1fd34 100644 --- a/source/game/scenes/title.cpp +++ b/source/game/scenes/title.cpp @@ -16,6 +16,7 @@ #include "core/resources/resource_list.hpp" // Para Asset #include "core/system/event_buffer.hpp" // Para EventBuffer #include "core/system/global_events.hpp" // Para check +#include "game/defaults.hpp" // Para Defaults::Music::Files #include "game/options.hpp" // Para Options, options, SectionState, Section #include "game/scene_manager.hpp" // Para SceneManager #include "game/ui/console.hpp" // Para Console @@ -41,8 +42,8 @@ Title::Title() SceneManager::options = SceneManager::Options::NONE; // Acciones iniciales - Screen::get()->setBorderColor(0); // Cambia el color del borde - Audio::get()->playMusic("574071_EA_DTV.ogg"); // Inicia la musica + Screen::get()->setBorderColor(0); // Cambia el color del borde + Audio::get()->playMusic(Defaults::Music::Files::TITLE_TRACK); // Inicia la musica } // Destructor @@ -260,10 +261,6 @@ void Title::renderMainMenu() { return; } - // Zona central del menu - constexpr int MENU_ZONE_Y = 73; - constexpr int MENU_ZONE_HEIGHT = 102; - // Menú principal normal con 3 opciones centradas verticalmente en la zona const Uint8 COLOR = 8; const int TEXT_SIZE = menu_text_->getCharacterSize(); @@ -394,9 +391,6 @@ void Title::applyKeyboardRemap() { // NOLINT(readability-convert-member-functio // Dibuja la pantalla de redefinir teclado void Title::renderKeyboardRemap() const { // Zona central del menu - constexpr int MENU_ZONE_Y = 73; - constexpr int MENU_ZONE_HEIGHT = 102; - const Uint8 COLOR = 8; const Uint8 ERROR_COLOR = 4; const int TEXT_SIZE = menu_text_->getCharacterSize(); @@ -441,10 +435,6 @@ void Title::renderKeyboardRemap() const { // Dibuja la pantalla de redefinir joystick void Title::renderJoystickRemap() const { - // Zona central del menu - constexpr int MENU_ZONE_Y = 73; - constexpr int MENU_ZONE_HEIGHT = 102; - const Uint8 COLOR = 8; const Uint8 ERROR_COLOR = 4; const int TEXT_SIZE = menu_text_->getCharacterSize(); @@ -502,23 +492,20 @@ void Title::handleJoystickRemap(const SDL_Event& event) { return; } - constexpr Sint16 TRIGGER_THRESHOLD = 20000; - constexpr Sint16 AXIS_THRESHOLD = 20000; - // Capturar triggers como botones (usando valores especiales 100/101) - if (event.gaxis.axis == SDL_GAMEPAD_AXIS_LEFT_TRIGGER && event.gaxis.value > TRIGGER_THRESHOLD) { + if (event.gaxis.axis == SDL_GAMEPAD_AXIS_LEFT_TRIGGER && event.gaxis.value > Defaults::Controls::JOYSTICK_AXIS_THRESHOLD) { captured_button = Input::TRIGGER_L2_AS_BUTTON; // 100 axis_cooldown_ = 0.5F; // Cooldown de medio segundo - } else if (event.gaxis.axis == SDL_GAMEPAD_AXIS_RIGHT_TRIGGER && event.gaxis.value > TRIGGER_THRESHOLD) { + } else if (event.gaxis.axis == SDL_GAMEPAD_AXIS_RIGHT_TRIGGER && event.gaxis.value > Defaults::Controls::JOYSTICK_AXIS_THRESHOLD) { captured_button = Input::TRIGGER_R2_AS_BUTTON; // 101 axis_cooldown_ = 0.5F; } // Capturar ejes del stick analógico (usando valores especiales 200+) else if (event.gaxis.axis == SDL_GAMEPAD_AXIS_LEFTX) { - if (event.gaxis.value < -AXIS_THRESHOLD) { + if (event.gaxis.value < -Defaults::Controls::JOYSTICK_AXIS_THRESHOLD) { captured_button = 200; // Left stick izquierda axis_cooldown_ = 0.5F; - } else if (event.gaxis.value > AXIS_THRESHOLD) { + } else if (event.gaxis.value > Defaults::Controls::JOYSTICK_AXIS_THRESHOLD) { captured_button = 201; // Left stick derecha axis_cooldown_ = 0.5F; } diff --git a/source/game/scenes/title.hpp b/source/game/scenes/title.hpp index dee9012..152c418 100644 --- a/source/game/scenes/title.hpp +++ b/source/game/scenes/title.hpp @@ -34,6 +34,10 @@ class Title { static constexpr float FADE_STEP_INTERVAL = 0.05F; // Intervalo entre pasos de fade (antes cada 4 frames) static constexpr float POST_FADE_DELAY = 1.0F; // Delay después del fade (pantalla en negro) static constexpr float KEYBOARD_REMAP_DISPLAY_DELAY = 2.0F; // Tiempo mostrando teclas definidas antes de guardar + + // --- Constantes de layout del menú --- + static constexpr int MENU_ZONE_Y = 73; // Coordenada Y de la zona de menú + static constexpr int MENU_ZONE_HEIGHT = 102; // Alto de la zona de menú // --- Métodos --- void handleEvents(); // Comprueba el manejador de eventos void handleMainMenuKeyPress(SDL_Keycode key); // Maneja las teclas del menu principal diff --git a/source/game/ui/console.cpp b/source/game/ui/console.cpp index 2aa87a7..f7caae5 100644 --- a/source/game/ui/console.cpp +++ b/source/game/ui/console.cpp @@ -42,14 +42,13 @@ static auto parseTokens(const std::string& input) -> std::vector { // Calcula la altura total de la consola para N líneas de mensaje (+ 1 línea de input) static auto calcTargetHeight(int num_msg_lines) -> float { - constexpr int TEXT_SIZE = 6; - constexpr int PADDING_IN_V = TEXT_SIZE / 2; - return static_cast((TEXT_SIZE * (num_msg_lines + 1)) + (PADDING_IN_V * 2)); + constexpr int PADDING_IN_V = Console::TEXT_SIZE / 2; + return static_cast((Console::TEXT_SIZE * (num_msg_lines + 1)) + (PADDING_IN_V * 2)); } // Divide text en líneas respetando los \n existentes y haciendo word-wrap por ancho en píxeles auto Console::wrapText(const std::string& text) const -> std::vector { - constexpr int PADDING_IN_H = 6; // TEXT_SIZE; simétrico a ambos lados + constexpr int PADDING_IN_H = TEXT_SIZE; // Simétrico a ambos lados const int MAX_PX = static_cast(Options::game.width) - (2 * PADDING_IN_H); std::vector result; @@ -132,7 +131,6 @@ void Console::buildSurface() { // Redibuja el texto dinámico sobre la surface (fondo + borde + líneas) void Console::redrawText() { const float WIDTH = Options::game.width; - constexpr int TEXT_SIZE = 6; constexpr int PADDING_IN_H = TEXT_SIZE; constexpr int PADDING_IN_V = TEXT_SIZE / 2; diff --git a/source/game/ui/console.hpp b/source/game/ui/console.hpp index 6847a32..ddac802 100644 --- a/source/game/ui/console.hpp +++ b/source/game/ui/console.hpp @@ -27,6 +27,9 @@ class Console { void toggle(); void handleEvent(const SDL_Event& event); + // Constantes públicas + static constexpr int TEXT_SIZE = 6; // Tamaño de carácter del font de la consola + // Consultas auto isActive() -> bool; // true si RISING, ACTIVE o VANISHING auto getVisibleHeight() -> int; // Píxeles visibles actuales (0 = oculta, height_ = totalmente visible) diff --git a/source/game/ui/console_commands.cpp b/source/game/ui/console_commands.cpp index d07a084..f6d531f 100644 --- a/source/game/ui/console_commands.cpp +++ b/source/game/ui/console_commands.cpp @@ -857,41 +857,6 @@ static auto cmdCheat(const std::vector& args) -> std::string { // return "usage: cheat [infinite lives|invincibility]"; } -// PLAYER SKIN / PLAYER COLOR -static auto cmdPlayer(const std::vector& args) -> std::string { - if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; } - - // PLAYER SKIN - if (args.size() >= 2 && args[0] == "SKIN") { - if (!GameControl::change_player_skin) { return "Game not initialized"; } - std::string skin_name = args[1]; - std::ranges::transform(skin_name, skin_name.begin(), ::tolower); - GameControl::change_player_skin(skin_name); - return "Player skin: " + skin_name; - } - - // PLAYER COLOR DEFAULT - if (args.size() >= 2 && args[0] == "COLOR" && args[1] == "DEFAULT") { - if (!GameControl::change_player_color) { return "Game not initialized"; } - GameControl::change_player_color(-1); - return "Player color: default"; - } - - // PLAYER COLOR <0-15> - if (args.size() >= 2 && args[0] == "COLOR") { - int color = -1; - try { - color = std::stoi(args[1]); - } catch (...) {} - if (color < 0 || color > 15) { return "usage: player color <0-15>|default"; } - if (!GameControl::change_player_color) { return "Game not initialized"; } - GameControl::change_player_color(color); - return "Player color: " + std::to_string(color); - } - - return "usage: player skin | player color <0-15>|default"; -} - // RESTART static auto cmdRestart(const std::vector& /*unused*/) -> std::string { SceneManager::current = SceneManager::Scene::LOGO; @@ -954,7 +919,6 @@ void CommandRegistry::registerHandlers() { // NOLINT(readability-function-cogni handlers_["cmd_show"] = cmdShow; handlers_["cmd_hide"] = cmdHide; handlers_["cmd_cheat"] = cmdCheat; - handlers_["cmd_player"] = cmdPlayer; handlers_["cmd_restart"] = cmdRestart; handlers_["cmd_kiosk"] = cmdKiosk; handlers_["cmd_exit"] = cmdExit; @@ -1006,8 +970,6 @@ void CommandRegistry::registerHandlers() { // NOLINT(readability-function-cogni } return result; }; - dynamic_providers_["SET COLOR"] = color_provider; - dynamic_providers_["SET BGCOLOR"] = color_provider; dynamic_providers_["EDIT MAPBG"] = color_provider; dynamic_providers_["EDIT MAPCONN"] = color_provider; diff --git a/source/game/ui/notifier.cpp b/source/game/ui/notifier.cpp index 9232b07..140d3d9 100644 --- a/source/game/ui/notifier.cpp +++ b/source/game/ui/notifier.cpp @@ -30,7 +30,7 @@ const Notifier::Style Notifier::Style::DEFAULT = { .shape = Notifier::Shape::SQUARED, .text_align = Notifier::TextAlign::CENTER, .duration = 2.0F, - .sound_file = "notify.wav", + .sound_file = Defaults::Sound::Files::NOTIFY, .play_sound = false}; const Notifier::Style Notifier::Style::CHEEVO = { @@ -40,7 +40,7 @@ const Notifier::Style Notifier::Style::CHEEVO = { .shape = Notifier::Shape::SQUARED, .text_align = Notifier::TextAlign::CENTER, .duration = 4.0F, - .sound_file = "notify.wav", + .sound_file = Defaults::Sound::Files::NOTIFY, .play_sound = true}; // [SINGLETON] Crearemos el objeto con esta función estática @@ -160,7 +160,7 @@ void Notifier::show(std::vector texts, const Style& style, int icon } // Inicializa variables - const int TEXT_SIZE = 6; + constexpr float TEXT_SIZE = LINE_HEIGHT; const auto PADDING_IN_H = TEXT_SIZE; const auto PADDING_IN_V = TEXT_SIZE / 2; const int ICON_SPACE = icon >= 0 ? ICON_SIZE + PADDING_IN_H : 0; @@ -205,16 +205,16 @@ void Notifier::show(std::vector texts, const Style& style, int icon // Dibuja el fondo de la notificación SDL_FRect rect; if (SHAPE == Shape::ROUNDED) { - rect = {.x = 4, .y = 0, .w = WIDTH - (4 * 2), .h = HEIGHT}; + rect = {.x = static_cast(CORNER_RADIUS), .y = 0, .w = WIDTH - (CORNER_RADIUS * 2), .h = HEIGHT}; n.surface->fillRect(&rect, style.bg_color); - rect = {.x = 4 / 2, .y = 1, .w = WIDTH - 4, .h = HEIGHT - 2}; + rect = {.x = static_cast(CORNER_RADIUS / 2), .y = static_cast(BORDER_INSET), .w = WIDTH - CORNER_RADIUS, .h = HEIGHT - (BORDER_INSET * 2)}; n.surface->fillRect(&rect, style.bg_color); - rect = {.x = 1, .y = 4 / 2, .w = WIDTH - 2, .h = HEIGHT - 4}; + rect = {.x = static_cast(BORDER_INSET), .y = static_cast(CORNER_RADIUS / 2), .w = WIDTH - (BORDER_INSET * 2), .h = HEIGHT - CORNER_RADIUS}; n.surface->fillRect(&rect, style.bg_color); - rect = {.x = 0, .y = 4, .w = WIDTH, .h = HEIGHT - (4 * 2)}; + rect = {.x = 0, .y = static_cast(CORNER_RADIUS), .w = WIDTH, .h = HEIGHT - (CORNER_RADIUS * 2)}; n.surface->fillRect(&rect, style.bg_color); } diff --git a/source/game/ui/notifier.hpp b/source/game/ui/notifier.hpp index 967007a..915a45d 100644 --- a/source/game/ui/notifier.hpp +++ b/source/game/ui/notifier.hpp @@ -92,6 +92,9 @@ class Notifier { static constexpr float ICON_SIZE = 16.0F; static constexpr float PADDING_OUT = 0.0F; static constexpr float SLIDE_SPEED = 120.0F; // Pixels per second for slide animations + static constexpr float LINE_HEIGHT = 6.0F; // Alto de línea fijo para el layout de notificaciones + static constexpr int CORNER_RADIUS = 4; // Radio de las esquinas redondeadas + static constexpr int BORDER_INSET = 1; // Inset del borde interior // [SINGLETON] Objeto notifier static Notifier* notifier;