From 08100f60e8336844adfd8e412accdabcb698ec69 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Thu, 21 May 2026 09:39:36 +0200 Subject: [PATCH 1/3] refactor(defaults): centralitza constants de bullet, ship, enemy, hud i notifier --- source/core/defaults.hpp | 2 + source/core/defaults/enemies.hpp | 22 +++- source/core/defaults/game.hpp | 1 + source/core/defaults/hud.hpp | 13 ++ source/core/defaults/notifier.hpp | 31 +++++ source/core/defaults/ship.hpp | 11 ++ source/core/system/notifier.cpp | 69 ++++------ source/game/entities/bullet.cpp | 8 +- source/game/entities/enemy.cpp | 23 ++-- source/game/entities/ship.cpp | 14 +- source/game/scenes/game_scene.cpp | 4 +- source/game/systems/init_hud_animator.cpp | 149 +++++++++++----------- 12 files changed, 197 insertions(+), 150 deletions(-) create mode 100644 source/core/defaults/hud.hpp create mode 100644 source/core/defaults/notifier.hpp diff --git a/source/core/defaults.hpp b/source/core/defaults.hpp index a2c7670..04b752a 100644 --- a/source/core/defaults.hpp +++ b/source/core/defaults.hpp @@ -16,7 +16,9 @@ #include "core/defaults/entities.hpp" #include "core/defaults/floating_score.hpp" #include "core/defaults/game.hpp" +#include "core/defaults/hud.hpp" #include "core/defaults/math.hpp" +#include "core/defaults/notifier.hpp" #include "core/defaults/palette.hpp" #include "core/defaults/physics.hpp" #include "core/defaults/rendering.hpp" diff --git a/source/core/defaults/enemies.hpp b/source/core/defaults/enemies.hpp index b4c81ee..d321966 100644 --- a/source/core/defaults/enemies.hpp +++ b/source/core/defaults/enemies.hpp @@ -7,19 +7,30 @@ namespace Defaults::Enemies { + // Cuerpo físico común (valores por defecto del constructor) + namespace Body { + constexpr float DEFAULT_MASS = 5.0F; // Más liviano que la nave (10.0) + constexpr float RESTITUTION = 1.0F; // Rebote elástico perfecto contra paredes + constexpr float LINEAR_DAMPING = 0.0F; // Sin fricción: mantienen velocidad + constexpr float ANGULAR_DAMPING = 0.0F; + } // namespace Body + // Pentagon (esquivador - zigzag evasion) namespace Pentagon { - constexpr float VELOCITAT = 35.0F; // px/s (slightly slower) - constexpr float CANVI_ANGLE_PROB = 0.20F; // 20% per wall hit (frequent zigzag) - constexpr float CANVI_ANGLE_MAX = 1.0F; // Max random angle change (rad) - constexpr float DROTACIO_MIN = 0.75F; // Min visual rotation (rad/s) [+50%] - constexpr float DROTACIO_MAX = 3.75F; // Max visual rotation (rad/s) [+50%] + constexpr float VELOCITAT = 35.0F; // px/s (slightly slower) + constexpr float MASS = 5.0F; // Masa estándar + constexpr float CANVI_ANGLE_PROB = 0.20F; // 20% per wall hit (frequent zigzag) + constexpr float CANVI_ANGLE_MAX = 1.0F; // Max random angle change (rad) + constexpr float ZIGZAG_PROB_PER_SECOND = 0.8F; // Probabilidad de zigzag por segundo + constexpr float DROTACIO_MIN = 0.75F; // Min visual rotation (rad/s) [+50%] + constexpr float DROTACIO_MAX = 3.75F; // Max visual rotation (rad/s) [+50%] constexpr const char* SHAPE_FILE = "enemy_pentagon.shp"; } // namespace Pentagon // Cuadrado (perseguidor - tracks player) namespace Cuadrado { constexpr float VELOCITAT = 40.0F; // px/s (medium speed) + constexpr float MASS = 8.0F; // Más pesado, "tanque" constexpr float TRACKING_STRENGTH = 0.5F; // Interpolation toward player (0.0-1.0) constexpr float TRACKING_INTERVAL = 1.0F; // Seconds between angle updates constexpr float DROTACIO_MIN = 0.3F; // Slow rotation [+50%] @@ -30,6 +41,7 @@ namespace Defaults::Enemies { // Molinillo (agressiu - fast straight lines, proximity spin-up) namespace Molinillo { constexpr float VELOCITAT = 50.0F; // px/s (fastest) + constexpr float MASS = 4.0F; // Más liviano, ágil constexpr float CANVI_ANGLE_PROB = 0.05F; // 5% per wall hit (rare direction change) constexpr float CANVI_ANGLE_MAX = 0.3F; // Small angle adjustments constexpr float DROTACIO_MIN = 3.0F; // Base rotation (rad/s) [+50%] diff --git a/source/core/defaults/game.hpp b/source/core/defaults/game.hpp index e5f4c9d..64d86ab 100644 --- a/source/core/defaults/game.hpp +++ b/source/core/defaults/game.hpp @@ -20,6 +20,7 @@ namespace Defaults::Game { constexpr bool FRIENDLY_FIRE_ENABLED = true; // Activar friendly fire constexpr float COLLISION_BULLET_PLAYER_AMPLIFIER = 1.0F; // Hitbox exacto (100%) constexpr float BULLET_GRACE_PERIOD = 0.2F; // Inmunidad post-disparo (s) + constexpr float BULLET_SPEED = 140.0F; // Velocidad escalar (px/s). Pascal: 7 px/frame × 20 FPS // Transición LEVEL_START (mensajes aleatorios PRE-level) constexpr float LEVEL_START_DURATION = 3.0F; // Duración total diff --git a/source/core/defaults/hud.hpp b/source/core/defaults/hud.hpp new file mode 100644 index 0000000..f97843c --- /dev/null +++ b/source/core/defaults/hud.hpp @@ -0,0 +1,13 @@ +// hud.hpp - Configuració visual del HUD (marcador, etc.) +// © 2026 JailDesigner + +#pragma once + +namespace Defaults::Hud { + + // Marcador (scoreboard inferior). Usado por GameScene::drawScoreboard() + // y por la animación de entrada en init_hud_animator. + constexpr float SCOREBOARD_TEXT_SCALE = 0.85F; + constexpr float SCOREBOARD_TEXT_SPACING = 0.0F; + +} // namespace Defaults::Hud diff --git a/source/core/defaults/notifier.hpp b/source/core/defaults/notifier.hpp new file mode 100644 index 0000000..a3938df --- /dev/null +++ b/source/core/defaults/notifier.hpp @@ -0,0 +1,31 @@ +// notifier.hpp - Configuració del cuadre de notificacions toast (System::Notifier) +// © 2026 JailDesigner + +#pragma once + +#include + +namespace Defaults::Notifier { + + // Geometria del cuadre en coordenades lògiques (1280×720). + constexpr float CANVAS_WIDTH = 1280.0F; + constexpr float MARGIN_TOP = 40.0F; + constexpr float PADDING_H = 16.0F; + constexpr float PADDING_V = 10.0F; + constexpr float BORDER_THICKNESS = 2.0F; + constexpr float TEXT_SCALE = 0.55F; + constexpr float TEXT_SPACING = 2.0F; + constexpr float BORDER_BRIGHTNESS = 1.0F; + + // Cinemàtica del slide. + constexpr float SLIDE_DURATION_S = 0.30F; + + // Presets per als atajos semàntics. + constexpr SDL_Color COLOR_INFO{.r = 80, .g = 230, .b = 255, .a = 255}; + constexpr SDL_Color COLOR_WARN{.r = 255, .g = 180, .b = 40, .a = 255}; + constexpr SDL_Color COLOR_EXIT{.r = 255, .g = 80, .b = 80, .a = 255}; + constexpr float DURATION_INFO = 2.0F; + constexpr float DURATION_WARN = 3.0F; + constexpr float DURATION_EXIT = 3.0F; + +} // namespace Defaults::Notifier diff --git a/source/core/defaults/ship.hpp b/source/core/defaults/ship.hpp index 6156a3d..75e07b9 100644 --- a/source/core/defaults/ship.hpp +++ b/source/core/defaults/ship.hpp @@ -13,4 +13,15 @@ namespace Defaults::Ship { constexpr float BLINK_INVISIBLE_TIME = 0.1F; // Tiempo invisible (segundos) // Frecuencia total: 0.2s/ciclo = 5 Hz (~15 parpadeos en 3s) + // Cuerpo físico + constexpr float MASS = 10.0F; // Masa de referencia para choques + constexpr float RESTITUTION = 0.6F; // Rebote moderado contra paredes + constexpr float LINEAR_DAMPING = 1.5F; // Fricción exponencial (s⁻¹) + constexpr float ANGULAR_DAMPING = 0.0F; // Rotación 100% por input (no inercial) + + // Empuje visual: escala proporcional a la velocidad (0..200 px/s → 1.0..1.5) + // Mantiene la sensación del Pascal original. + constexpr float VISUAL_PUSH_DIVISOR = 33.33F; // SPEED / DIVISOR = empuje visual + constexpr float VISUAL_SCALE_DIVISOR = 12.0F; // SCALE = 1 + (PUSH / DIVISOR) + } // namespace Defaults::Ship diff --git a/source/core/system/notifier.cpp b/source/core/system/notifier.cpp index b44f756..ccf390d 100644 --- a/source/core/system/notifier.cpp +++ b/source/core/system/notifier.cpp @@ -2,24 +2,15 @@ #include "core/system/notifier.hpp" +#include "core/defaults.hpp" #include "core/rendering/gpu/gpu_frame_renderer.hpp" #include "core/utils/easing.hpp" namespace System { namespace { - // Geometria del cuadre en coordenades lògiques (1280×720). - constexpr float CANVAS_WIDTH = 1280.0F; - constexpr float MARGIN_TOP = 40.0F; - constexpr float PADDING_H = 16.0F; - constexpr float PADDING_V = 10.0F; - constexpr float BORDER_THICKNESS = 2.0F; - constexpr float TEXT_SCALE = 0.55F; - constexpr float TEXT_SPACING = 2.0F; - constexpr float BORDER_BRIGHTNESS = 1.0F; - - // Cinemàtica del slide. - constexpr float SLIDE_DURATION_S = 0.30F; + // Alias d'àmbit local per accedir compactament als defaults del notifier. + namespace Cfg = Defaults::Notifier; // Conversió color SDL → float [0,1]. constexpr auto toUnit(Uint8 v) -> float { @@ -47,14 +38,6 @@ namespace System { .b = toUnit(c.b) * DARKEN, .a = BG_ALPHA}; } - - // Presets per als atajos semàntics. - constexpr SDL_Color COLOR_INFO{.r = 80, .g = 230, .b = 255, .a = 255}; - constexpr SDL_Color COLOR_WARN{.r = 255, .g = 180, .b = 40, .a = 255}; - constexpr SDL_Color COLOR_EXIT{.r = 255, .g = 80, .b = 80, .a = 255}; - constexpr float DURATION_INFO = 2.0F; - constexpr float DURATION_WARN = 3.0F; - constexpr float DURATION_EXIT = 3.0F; } // namespace std::unique_ptr Notifier::instance; @@ -79,15 +62,15 @@ namespace System { hold_remaining_s_ = duration_s; current_is_exit_ = false; - const float TEXT_W = Graphics::VectorText::getTextWidth(text, TEXT_SCALE, TEXT_SPACING); - const float TEXT_H = Graphics::VectorText::getTextHeight(TEXT_SCALE); + const float TEXT_W = Graphics::VectorText::getTextWidth(text, Cfg::TEXT_SCALE, Cfg::TEXT_SPACING); + const float TEXT_H = Graphics::VectorText::getTextHeight(Cfg::TEXT_SCALE); - box_w_ = TEXT_W + (PADDING_H * 2.0F); - box_h_ = TEXT_H + (PADDING_V * 2.0F); - text_x_ = (CANVAS_WIDTH - TEXT_W) * 0.5F; + box_w_ = TEXT_W + (Cfg::PADDING_H * 2.0F); + box_h_ = TEXT_H + (Cfg::PADDING_V * 2.0F); + text_x_ = (Cfg::CANVAS_WIDTH - TEXT_W) * 0.5F; - y_on_ = MARGIN_TOP; - y_off_ = -(box_h_ + BORDER_THICKNESS); + y_on_ = Cfg::MARGIN_TOP; + y_off_ = -(box_h_ + Cfg::BORDER_THICKNESS); // Si ja es veu, reseteja el slide-in des de la posició actual perquè // la transició sembli continua. Si està amagat, arrenc des de fora. @@ -96,13 +79,13 @@ namespace System { } status_ = Status::ENTERING; slide_elapsed_s_ = 0.0F; - text_scale_ = TEXT_SCALE; + text_scale_ = Cfg::TEXT_SCALE; } - void Notifier::notifyInfo(const std::string& text) { notify(text, COLOR_INFO, DURATION_INFO); } - void Notifier::notifyWarn(const std::string& text) { notify(text, COLOR_WARN, DURATION_WARN); } + void Notifier::notifyInfo(const std::string& text) { notify(text, Cfg::COLOR_INFO, Cfg::DURATION_INFO); } + void Notifier::notifyWarn(const std::string& text) { notify(text, Cfg::COLOR_WARN, Cfg::DURATION_WARN); } void Notifier::notifyExit(const std::string& text) { - notify(text, COLOR_EXIT, DURATION_EXIT); + notify(text, Cfg::COLOR_EXIT, Cfg::DURATION_EXIT); current_is_exit_ = true; // notify() ho ha posat a false; restaurem. } @@ -110,12 +93,12 @@ namespace System { switch (status_) { case Status::ENTERING: { slide_elapsed_s_ += delta_time; - if (slide_elapsed_s_ >= SLIDE_DURATION_S) { + if (slide_elapsed_s_ >= Cfg::SLIDE_DURATION_S) { y_current_ = y_on_; status_ = Status::HOLDING; slide_elapsed_s_ = 0.0F; } else { - const float T = slide_elapsed_s_ / SLIDE_DURATION_S; + const float T = slide_elapsed_s_ / Cfg::SLIDE_DURATION_S; const float K = Utils::Easing::outCubic(T); y_current_ = y_off_ + ((y_on_ - y_off_) * K); } @@ -131,11 +114,11 @@ namespace System { } case Status::EXITING: { slide_elapsed_s_ += delta_time; - if (slide_elapsed_s_ >= SLIDE_DURATION_S) { + if (slide_elapsed_s_ >= Cfg::SLIDE_DURATION_S) { y_current_ = y_off_; status_ = Status::HIDDEN; } else { - const float T = slide_elapsed_s_ / SLIDE_DURATION_S; + const float T = slide_elapsed_s_ / Cfg::SLIDE_DURATION_S; const float K = Utils::Easing::inCubic(T); y_current_ = y_on_ + ((y_off_ - y_on_) * K); } @@ -152,7 +135,7 @@ namespace System { return; } - const float BOX_X = (CANVAS_WIDTH - box_w_) * 0.5F; + const float BOX_X = (Cfg::CANVAS_WIDTH - box_w_) * 0.5F; const float BOX_Y = y_current_; const UnitRGBA TC = textColorFloat(current_color_); const UnitRGBA BG = bgColorFloat(current_color_); @@ -167,19 +150,19 @@ namespace System { const float Y1 = BOX_Y; const float X2 = BOX_X + box_w_; const float Y2 = BOX_Y + box_h_; - gpu->pushLine(X1, Y1, X2, Y1, BORDER_THICKNESS, TC.r, TC.g, TC.b, TC.a); // top - gpu->pushLine(X1, Y2, X2, Y2, BORDER_THICKNESS, TC.r, TC.g, TC.b, TC.a); // bottom - gpu->pushLine(X1, Y1, X1, Y2, BORDER_THICKNESS, TC.r, TC.g, TC.b, TC.a); // left - gpu->pushLine(X2, Y1, X2, Y2, BORDER_THICKNESS, TC.r, TC.g, TC.b, TC.a); // right + gpu->pushLine(X1, Y1, X2, Y1, Cfg::BORDER_THICKNESS, TC.r, TC.g, TC.b, TC.a); // top + gpu->pushLine(X1, Y2, X2, Y2, Cfg::BORDER_THICKNESS, TC.r, TC.g, TC.b, TC.a); // bottom + gpu->pushLine(X1, Y1, X1, Y2, Cfg::BORDER_THICKNESS, TC.r, TC.g, TC.b, TC.a); // left + gpu->pushLine(X2, Y1, X2, Y2, Cfg::BORDER_THICKNESS, TC.r, TC.g, TC.b, TC.a); // right // 3. Text centrat dins la caixa, amb color explícit (l'alpha != 0 // li diu al renderShape que no agafe l'oscil·lador global de color). - const float TEXT_Y = BOX_Y + PADDING_V; + const float TEXT_Y = BOX_Y + Cfg::PADDING_V; text_.render(current_text_, Vec2{.x = text_x_, .y = TEXT_Y}, text_scale_, - TEXT_SPACING, - BORDER_BRIGHTNESS, + Cfg::TEXT_SPACING, + Cfg::BORDER_BRIGHTNESS, current_color_); } diff --git a/source/game/entities/bullet.cpp b/source/game/entities/bullet.cpp index 6434263..32186b4 100644 --- a/source/game/entities/bullet.cpp +++ b/source/game/entities/bullet.cpp @@ -16,12 +16,6 @@ #include "core/types.hpp" #include "game/constants.hpp" -namespace { - // Velocidad escalar de las balas (px/s). Conserva el feel del Pascal original - // (7 px/frame × 20 FPS = 140 px/s). - constexpr float BULLET_SPEED = 140.0F; -} // namespace - Bullet::Bullet(Rendering::Renderer* renderer) : Entity(renderer) { // Brightness específico para balas @@ -80,7 +74,7 @@ void Bullet::disparar(const Vec2& position, float angle, uint8_t owner_id) { body_.angle = angle; const float DIR_X = std::cos(angle - (Constants::PI / 2.0F)); const float DIR_Y = std::sin(angle - (Constants::PI / 2.0F)); - body_.velocity = Vec2{.x = DIR_X * BULLET_SPEED, .y = DIR_Y * BULLET_SPEED}; + body_.velocity = Vec2{.x = DIR_X * Defaults::Game::BULLET_SPEED, .y = DIR_Y * Defaults::Game::BULLET_SPEED}; body_.angular_velocity = 0.0F; body_.clearAccumulators(); diff --git a/source/game/entities/enemy.cpp b/source/game/entities/enemy.cpp index 1617366..033b942 100644 --- a/source/game/entities/enemy.cpp +++ b/source/game/entities/enemy.cpp @@ -41,16 +41,16 @@ namespace { Enemy::Enemy(Rendering::Renderer* renderer) : Entity(renderer), - tracking_strength_(0.5F) { + tracking_strength_(Defaults::Enemies::Cuadrado::TRACKING_STRENGTH) { brightness_ = Defaults::Brightness::ENEMIC; // Configuración del cuerpo físico — defaults para enemy genérico. // init() ajusta velocidad y masa según el tipo (Pentagon/Quadrat/Molinillo). - body_.setMass(5.0F); // Más liviano que la nave (10.0) - body_.radius = 0.0F; // 0 hasta spawn (no colisiona inactivo) - body_.restitution = 1.0F; // Rebote elástico perfecto contra paredes - body_.linear_damping = 0.0F; // Sin fricción: mantienen velocidad - body_.angular_damping = 0.0F; // Idem + body_.setMass(Defaults::Enemies::Body::DEFAULT_MASS); + body_.radius = 0.0F; // 0 hasta spawn (no colisiona inactivo) + body_.restitution = Defaults::Enemies::Body::RESTITUTION; + body_.linear_damping = Defaults::Enemies::Body::LINEAR_DAMPING; + body_.angular_damping = Defaults::Enemies::Body::ANGULAR_DAMPING; } void Enemy::init(EnemyType type, const Vec2* ship_pos) { @@ -60,7 +60,7 @@ void Enemy::init(EnemyType type, const Vec2* ship_pos) { float base_speed = 0.0F; float drotacio_min = 0.0F; float drotacio_max = 0.0F; - float type_mass = 5.0F; + float type_mass = Defaults::Enemies::Body::DEFAULT_MASS; switch (type_) { case EnemyType::PENTAGON: @@ -68,7 +68,7 @@ void Enemy::init(EnemyType type, const Vec2* ship_pos) { base_speed = Defaults::Enemies::Pentagon::VELOCITAT; drotacio_min = Defaults::Enemies::Pentagon::DROTACIO_MIN; drotacio_max = Defaults::Enemies::Pentagon::DROTACIO_MAX; - type_mass = 5.0F; + type_mass = Defaults::Enemies::Pentagon::MASS; break; case EnemyType::QUADRAT: @@ -76,7 +76,7 @@ void Enemy::init(EnemyType type, const Vec2* ship_pos) { base_speed = Defaults::Enemies::Cuadrado::VELOCITAT; drotacio_min = Defaults::Enemies::Cuadrado::DROTACIO_MIN; drotacio_max = Defaults::Enemies::Cuadrado::DROTACIO_MAX; - type_mass = 8.0F; // Más pesado, "tanque" + type_mass = Defaults::Enemies::Cuadrado::MASS; tracking_timer_ = 0.0F; break; @@ -85,7 +85,7 @@ void Enemy::init(EnemyType type, const Vec2* ship_pos) { base_speed = Defaults::Enemies::Molinillo::VELOCITAT; drotacio_min = Defaults::Enemies::Molinillo::DROTACIO_MIN; drotacio_max = Defaults::Enemies::Molinillo::DROTACIO_MAX; - type_mass = 4.0F; // Más liviano, ágil + type_mass = Defaults::Enemies::Molinillo::MASS; break; default: @@ -268,9 +268,8 @@ void Enemy::behaviorPentagon(float delta_time) { // Probabilidad de zigzag por segundo (calibrada para sensación equivalente // a la versión vieja que disparaba en cada toque de pared). - constexpr float ZIGZAG_PROB_PER_SECOND = 0.8F; const float RAND_VAL = static_cast(std::rand()) / static_cast(RAND_MAX); - if (RAND_VAL < ZIGZAG_PROB_PER_SECOND * delta_time) { + if (RAND_VAL < Defaults::Enemies::Pentagon::ZIGZAG_PROB_PER_SECOND * delta_time) { const float CURRENT_ANGLE = velocityToAngle(body_.velocity); const float DELTA = (static_cast(std::rand()) / static_cast(RAND_MAX)) * Defaults::Enemies::Pentagon::CANVI_ANGLE_MAX; diff --git a/source/game/entities/ship.cpp b/source/game/entities/ship.cpp index f4b129e..f021eb4 100644 --- a/source/game/entities/ship.cpp +++ b/source/game/entities/ship.cpp @@ -25,11 +25,11 @@ Ship::Ship(Rendering::Renderer* renderer, const char* shape_file) brightness_ = Defaults::Brightness::NAU; // Configuración del cuerpo físico - body_.setMass(10.0F); // Masa de referencia para choques - body_.radius = Defaults::Entities::SHIP_RADIUS; // Radio de colisión - body_.restitution = 0.6F; // Rebote moderado contra paredes - body_.linear_damping = 1.5F; // Fricción exponencial (s⁻¹) - body_.angular_damping = 0.0F; // La rotación es 100% por input, no inercial + body_.setMass(Defaults::Ship::MASS); + body_.radius = Defaults::Entities::SHIP_RADIUS; + body_.restitution = Defaults::Ship::RESTITUTION; + body_.linear_damping = Defaults::Ship::LINEAR_DAMPING; + body_.angular_damping = Defaults::Ship::ANGULAR_DAMPING; // Cargar shape compartida desde archivo shape_ = Graphics::ShapeLoader::load(shape_file); @@ -154,8 +154,8 @@ void Ship::draw() const { // Efecto visual de empuje: escala proporcional a la velocidad. // 0..200 px/s → escala 1.0..1.5 (manteniendo la sensación del Pascal original). const float SPEED = getSpeed(); - const float VISUAL_PUSH = SPEED / 33.33F; - const float SCALE = 1.0F + (VISUAL_PUSH / 12.0F); + const float VISUAL_PUSH = SPEED / Defaults::Ship::VISUAL_PUSH_DIVISOR; + const float SCALE = 1.0F + (VISUAL_PUSH / Defaults::Ship::VISUAL_SCALE_DIVISOR); Rendering::renderShape(renderer_, shape_, center_, angle_, SCALE, 1.0F, brightness_, Defaults::Palette::SHIP); } diff --git a/source/game/scenes/game_scene.cpp b/source/game/scenes/game_scene.cpp index 2c7170c..136b833 100644 --- a/source/game/scenes/game_scene.cpp +++ b/source/game/scenes/game_scene.cpp @@ -674,8 +674,8 @@ void GameScene::drawScoreboard() { std::string text = buildScoreboard(); // Parámetros de renderització - const float SCALE = 0.85F; - const float SPACING = 0.0F; + const float SCALE = Defaults::Hud::SCOREBOARD_TEXT_SCALE; + const float SPACING = Defaults::Hud::SCOREBOARD_TEXT_SPACING; // Calcular centro de la zona del marcador const SDL_FRect& scoreboard_zone = Defaults::Zones::SCOREBOARD; diff --git a/source/game/systems/init_hud_animator.cpp b/source/game/systems/init_hud_animator.cpp index a5e9c04..480315a 100644 --- a/source/game/systems/init_hud_animator.cpp +++ b/source/game/systems/init_hud_animator.cpp @@ -13,87 +13,88 @@ namespace Systems::InitHud { -auto computeRangeProgress(float global_progress, - float ratio_init, - float ratio_end) -> float { - if (ratio_init >= ratio_end) { - return (global_progress >= ratio_end) ? 1.0F : 0.0F; - } - if (global_progress < ratio_init) { - return 0.0F; - } - if (global_progress > ratio_end) { - return 1.0F; - } - return (global_progress - ratio_init) / (ratio_end - ratio_init); -} - -auto computeShipPosition(float progress, const Vec2& final_position) -> Vec2 { - const float EASED = Easing::easeOutQuad(progress); - const SDL_FRect& zone = Defaults::Zones::PLAYAREA; - // Y inicial: 50 px bajo la zona de juego. - const float Y_INI = zone.y + zone.h + 50.0F; - const float Y_ANIM = Y_INI + ((final_position.y - Y_INI) * EASED); - return Vec2{.x = final_position.x, .y = Y_ANIM}; -} - -void drawBordersAnimated(Rendering::Renderer* renderer, float progress) { - const SDL_FRect& zone = Defaults::Zones::PLAYAREA; - const float EASED = Easing::easeOutQuad(progress); - - const int X1 = static_cast(zone.x); - const int Y1 = static_cast(zone.y); - const int X2 = static_cast(zone.x + zone.w); - const int Y2 = static_cast(zone.y + zone.h); - const int CX = (X1 + X2) / 2; - - constexpr float PHASE_1_END = 0.33F; - constexpr float PHASE_2_END = 0.66F; - - // Fase 1: línea superior crece desde el centro hacia los lados. - if (EASED > 0.0F) { - const float P = std::min(EASED / PHASE_1_END, 1.0F); - const int X_LEFT = static_cast(CX - ((CX - X1) * P)); - const int X_RIGHT = static_cast(CX + ((X2 - CX) * P)); - Rendering::linea(renderer, CX, Y1, X_LEFT, Y1); - Rendering::linea(renderer, CX, Y1, X_RIGHT, Y1); + auto computeRangeProgress(float global_progress, + float ratio_init, + float ratio_end) -> float { + if (ratio_init >= ratio_end) { + return (global_progress >= ratio_end) ? 1.0F : 0.0F; + } + if (global_progress < ratio_init) { + return 0.0F; + } + if (global_progress > ratio_end) { + return 1.0F; + } + return (global_progress - ratio_init) / (ratio_end - ratio_init); } - // Fase 2: laterales bajan. - if (EASED > PHASE_1_END) { - const float P = std::min((EASED - PHASE_1_END) / (PHASE_2_END - PHASE_1_END), 1.0F); - const int Y_BOTTOM = static_cast(Y1 + ((Y2 - Y1) * P)); - Rendering::linea(renderer, X1, Y1, X1, Y_BOTTOM); - Rendering::linea(renderer, X2, Y1, X2, Y_BOTTOM); + auto computeShipPosition(float progress, const Vec2& final_position) -> Vec2 { + const float EASED = Easing::easeOutQuad(progress); + const SDL_FRect& zone = Defaults::Zones::PLAYAREA; + // Y inicial: 50 px bajo la zona de juego. + const float Y_INI = zone.y + zone.h + 50.0F; + const float Y_ANIM = Y_INI + ((final_position.y - Y_INI) * EASED); + return Vec2{.x = final_position.x, .y = Y_ANIM}; } - // Fase 3: línea inferior crece desde los lados hacia el centro. - if (EASED > PHASE_2_END) { - const float P = (EASED - PHASE_2_END) / (1.0F - PHASE_2_END); - const int X_LEFT = static_cast(X1 + ((CX - X1) * P)); - const int X_RIGHT = static_cast(X2 - ((X2 - CX) * P)); - Rendering::linea(renderer, X1, Y2, X_LEFT, Y2); - Rendering::linea(renderer, X2, Y2, X_RIGHT, Y2); + void drawBordersAnimated(Rendering::Renderer* renderer, float progress) { + const SDL_FRect& zone = Defaults::Zones::PLAYAREA; + const float EASED = Easing::easeOutQuad(progress); + + const int X1 = static_cast(zone.x); + const int Y1 = static_cast(zone.y); + const int X2 = static_cast(zone.x + zone.w); + const int Y2 = static_cast(zone.y + zone.h); + const int CX = (X1 + X2) / 2; + + constexpr float PHASE_1_END = 0.33F; + constexpr float PHASE_2_END = 0.66F; + + // Fase 1: línea superior crece desde el centro hacia los lados. + if (EASED > 0.0F) { + const float P = std::min(EASED / PHASE_1_END, 1.0F); + const int X_LEFT = static_cast(CX - ((CX - X1) * P)); + const int X_RIGHT = static_cast(CX + ((X2 - CX) * P)); + Rendering::linea(renderer, CX, Y1, X_LEFT, Y1); + Rendering::linea(renderer, CX, Y1, X_RIGHT, Y1); + } + + // Fase 2: laterales bajan. + if (EASED > PHASE_1_END) { + const float P = std::min((EASED - PHASE_1_END) / (PHASE_2_END - PHASE_1_END), 1.0F); + const int Y_BOTTOM = static_cast(Y1 + ((Y2 - Y1) * P)); + Rendering::linea(renderer, X1, Y1, X1, Y_BOTTOM); + Rendering::linea(renderer, X2, Y1, X2, Y_BOTTOM); + } + + // Fase 3: línea inferior crece desde los lados hacia el centro. + if (EASED > PHASE_2_END) { + const float P = (EASED - PHASE_2_END) / (1.0F - PHASE_2_END); + const int X_LEFT = static_cast(X1 + ((CX - X1) * P)); + const int X_RIGHT = static_cast(X2 - ((X2 - CX) * P)); + Rendering::linea(renderer, X1, Y2, X_LEFT, Y2); + Rendering::linea(renderer, X2, Y2, X_RIGHT, Y2); + } } -} -void drawScoreboardAnimated(const Graphics::VectorText& text, - const std::string& scoreboard_text, - float progress) { - const float EASED = Easing::easeOutQuad(progress); + void drawScoreboardAnimated(const Graphics::VectorText& text, + const std::string& scoreboard_text, + float progress) { + const float EASED = Easing::easeOutQuad(progress); - constexpr float SCALE = 0.85F; - constexpr float SPACING = 0.0F; - const SDL_FRect& scoreboard_zone = Defaults::Zones::SCOREBOARD; - const float CENTRE_X = scoreboard_zone.w / 2.0F; - const float Y_FINAL = scoreboard_zone.y + (scoreboard_zone.h / 2.0F); - // Posición inicial: fuera de la pantalla por debajo. - const auto Y_INI = static_cast(Defaults::Game::HEIGHT); - const float Y_ANIM = Y_INI + ((Y_FINAL - Y_INI) * EASED); + constexpr float SCALE = Defaults::Hud::SCOREBOARD_TEXT_SCALE; + constexpr float SPACING = Defaults::Hud::SCOREBOARD_TEXT_SPACING; + const SDL_FRect& scoreboard_zone = Defaults::Zones::SCOREBOARD; + const float CENTRE_X = scoreboard_zone.w / 2.0F; + const float Y_FINAL = scoreboard_zone.y + (scoreboard_zone.h / 2.0F); + // Posición inicial: fuera de la pantalla por debajo. + const auto Y_INI = static_cast(Defaults::Game::HEIGHT); + const float Y_ANIM = Y_INI + ((Y_FINAL - Y_INI) * EASED); - text.renderCentered(scoreboard_text, - Vec2{.x = CENTRE_X, .y = Y_ANIM}, - SCALE, SPACING); -} + text.renderCentered(scoreboard_text, + Vec2{.x = CENTRE_X, .y = Y_ANIM}, + SCALE, + SPACING); + } } // namespace Systems::InitHud From 7139dea7f6412c61e0b22fc7b36b547bb3524c57 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Thu, 21 May 2026 09:45:55 +0200 Subject: [PATCH 2/3] refactor(defaults): centralitza init hud, tips, hit timer, line thickness i debug overlay --- source/core/defaults/game.hpp | 10 ++- source/core/defaults/hud.hpp | 28 ++++++++ source/core/defaults/physics.hpp | 3 + source/core/defaults/rendering.hpp | 4 ++ source/core/rendering/line_renderer.cpp | 80 ++++++++++++----------- source/core/system/debug_overlay.cpp | 38 +++++------ source/game/scenes/game_scene.cpp | 15 +++-- source/game/systems/init_hud_animator.cpp | 8 +-- 8 files changed, 111 insertions(+), 75 deletions(-) diff --git a/source/core/defaults/game.hpp b/source/core/defaults/game.hpp index 64d86ab..bc85c45 100644 --- a/source/core/defaults/game.hpp +++ b/source/core/defaults/game.hpp @@ -10,9 +10,13 @@ namespace Defaults::Game { constexpr int HEIGHT = 720; // Regles de partida - constexpr int STARTING_LIVES = 3; // Initial lives - constexpr float DEATH_DURATION = 3.0F; // Seconds of death animation - constexpr float GAME_OVER_DURATION = 5.0F; // Seconds to display game over + constexpr int STARTING_LIVES = 3; // Initial lives + constexpr float DEATH_DURATION = 3.0F; // Seconds of death animation + constexpr float GAME_OVER_DURATION = 5.0F; // Seconds to display game over + + // Valores centinela del temporitzador de mort per-jugador. + constexpr float HIT_TIMER_INACTIVE_PLAYER = 999.0F; // Jugador permanentment inactiu + constexpr float HIT_TIMER_TRIGGER_DEATH = 0.001F; // Trigger inicial post-impacte (>0 sense disparar regla) constexpr float COLLISION_SHIP_ENEMY_AMPLIFIER = 0.80F; // 80% hitbox (generous) constexpr float COLLISION_BULLET_ENEMY_AMPLIFIER = 1.15F; // 115% hitbox (generous) diff --git a/source/core/defaults/hud.hpp b/source/core/defaults/hud.hpp index f97843c..072a536 100644 --- a/source/core/defaults/hud.hpp +++ b/source/core/defaults/hud.hpp @@ -10,4 +10,32 @@ namespace Defaults::Hud { constexpr float SCOREBOARD_TEXT_SCALE = 0.85F; constexpr float SCOREBOARD_TEXT_SPACING = 0.0F; + // Animación de entrada del HUD (init_hud_animator). + namespace InitAnim { + // Spawn vertical de la nave: 50 px bajo la PLAYAREA (sale desde fuera). + constexpr float SHIP_SPAWN_Y_OFFSET = 50.0F; + + // Bordes: ratios de las tres fases (top → laterales → bottom). + constexpr float BORDER_PHASE_1_END = 0.33F; // Fin de la fase top + constexpr float BORDER_PHASE_2_END = 0.66F; // Fin de la fase laterales + } // namespace InitAnim + + // Indicadores ("tips") sobre los enemigos enganchados a la nave. + // Offset local al frame de la nave (apunta hacia delante, eje Y negativo). + namespace Tips { + constexpr float LOCAL_X = 0.0F; + constexpr float LOCAL_Y = -12.0F; + } // namespace Tips + + // Overlay de debug (FPS, métriques) en coordenades lògiques (1280×720). + namespace DebugOverlay { + constexpr float X = 12.0F; + constexpr float Y_FPS = 12.0F; + constexpr float LINE_HEIGHT = 18.0F; // separació entre línies (scale 0.4 → ~16 px alt) + constexpr float TEXT_SCALE = 0.4F; + constexpr float TEXT_SPACING = 2.0F; + constexpr float BRIGHTNESS = 1.0F; + constexpr float FPS_UPDATE_INTERVAL = 0.5F; // Cadencia d'actualització del FPS visible + } // namespace DebugOverlay + } // namespace Defaults::Hud diff --git a/source/core/defaults/physics.hpp b/source/core/defaults/physics.hpp index 77704f5..7a204ba 100644 --- a/source/core/defaults/physics.hpp +++ b/source/core/defaults/physics.hpp @@ -26,6 +26,9 @@ namespace Defaults::Physics { constexpr float FACTOR_HERENCIA_MAX = 1.0F; // Màxim 100% del drotacio heredat constexpr float FRICCIO_ANGULAR = 0.5F; // Desacceleració angular (rad/s²) + // Velocity heredada de la nau a l'explosió (80% del feel original). + constexpr float SHIP_VELOCITY_INHERITANCE = 0.8F; + // Angular velocity sin for trajectory inheritance // Excess above this threshold is converted to tangential linear velocity // Prevents "vortex trap" problem with high-rotation enemies diff --git a/source/core/defaults/rendering.hpp b/source/core/defaults/rendering.hpp index 0480516..c87d119 100644 --- a/source/core/defaults/rendering.hpp +++ b/source/core/defaults/rendering.hpp @@ -11,6 +11,10 @@ namespace Defaults::Rendering { constexpr int VSYNC_DEFAULT = 1; // 0=disabled, 1=enabled constexpr int ANTIALIAS_DEFAULT = 1; // 0=disabled, 1=enabled (AA geomètric a les línies) + // Grosor global per defecte de les línies. 1.5 dóna línia visible i crujent; + // 1.0 es veu massa fi en pantalles grans. Configurable via setLineThickness. + constexpr float LINE_THICKNESS_DEFAULT = 1.5F; + // Resolució del render target offscreen. El tamany lògic del joc roman a // 1280×720 (coordenades dels objectes); aquesta és la resolució física a // la qual es rasteritzen les línies abans de la composició final. diff --git a/source/core/rendering/line_renderer.cpp b/source/core/rendering/line_renderer.cpp index 1e27e94..1f079b3 100644 --- a/source/core/rendering/line_renderer.cpp +++ b/source/core/rendering/line_renderer.cpp @@ -3,52 +3,56 @@ #include "core/rendering/line_renderer.hpp" +#include "core/defaults.hpp" + namespace Rendering { -// Color global compartido para líneas sin paleta propia (HUD, debug, texto -// genérico). Equivale al "color máximo" de la antigua oscilación CPU: verde -// fósforo CRT. El pulso de brillo lo aplica ahora el shader de postpro. -SDL_Color g_current_line_color = {100, 255, 100, 255}; + // Color global compartido para líneas sin paleta propia (HUD, debug, texto + // genérico). Equivale al "color máximo" de la antigua oscilación CPU: verde + // fósforo CRT. El pulso de brillo lo aplica ahora el shader de postpro. + SDL_Color g_current_line_color = {100, 255, 100, 255}; -// Grosor global por defecto. Configurable via setLineThickness. -// 1.5 da una línea visible y crujiente; 1.0 se ve demasiado fino en pantallas grandes. -float g_current_line_thickness = 1.5F; + // Grosor global por defecto. Configurable via setLineThickness. + float g_current_line_thickness = Defaults::Rendering::LINE_THICKNESS_DEFAULT; -void linea(Renderer* renderer, - int x1, int y1, int x2, int y2, - float brightness, - float thickness, - SDL_Color color) { - if (renderer == nullptr) { - return; + void linea(Renderer* renderer, + int x1, + int y1, + int x2, + int y2, + float brightness, + float thickness, + SDL_Color color) { + if (renderer == nullptr) { + return; + } + + // Coords lógicas (1280×720). El shader hace el mapeo a NDC; el viewport + // del SDLManager hace el letterbox a píxeles físicos. + const auto FX1 = static_cast(x1); + const auto FY1 = static_cast(y1); + const auto FX2 = static_cast(x2); + const auto FY2 = static_cast(y2); + + // color.alpha==0 → usar color global (verde fósforo). alpha>0 → color directo. + const SDL_Color SOURCE = (color.a > 0) ? color : g_current_line_color; + const float R = (static_cast(SOURCE.r) * brightness) / 255.0F; + const float G = (static_cast(SOURCE.g) * brightness) / 255.0F; + const float B = (static_cast(SOURCE.b) * brightness) / 255.0F; + + const float W = (thickness > 0.0F) ? thickness : g_current_line_thickness; + + renderer->pushLine(FX1, FY1, FX2, FY2, W, R, G, B, 1.0F); } - // Coords lógicas (1280×720). El shader hace el mapeo a NDC; el viewport - // del SDLManager hace el letterbox a píxeles físicos. - const auto FX1 = static_cast(x1); - const auto FY1 = static_cast(y1); - const auto FX2 = static_cast(x2); - const auto FY2 = static_cast(y2); + void setLineColor(SDL_Color color) { g_current_line_color = color; } - // color.alpha==0 → usar color global (verde fósforo). alpha>0 → color directo. - const SDL_Color SOURCE = (color.a > 0) ? color : g_current_line_color; - const float R = (static_cast(SOURCE.r) * brightness) / 255.0F; - const float G = (static_cast(SOURCE.g) * brightness) / 255.0F; - const float B = (static_cast(SOURCE.b) * brightness) / 255.0F; - - const float W = (thickness > 0.0F) ? thickness : g_current_line_thickness; - - renderer->pushLine(FX1, FY1, FX2, FY2, W, R, G, B, 1.0F); -} - -void setLineColor(SDL_Color color) { g_current_line_color = color; } - -void setLineThickness(float thickness) { - if (thickness > 0.0F) { - g_current_line_thickness = thickness; + void setLineThickness(float thickness) { + if (thickness > 0.0F) { + g_current_line_thickness = thickness; + } } -} -auto getLineThickness() -> float { return g_current_line_thickness; } + auto getLineThickness() -> float { return g_current_line_thickness; } } // namespace Rendering diff --git a/source/core/system/debug_overlay.cpp b/source/core/system/debug_overlay.cpp index e8f2577..5434143 100644 --- a/source/core/system/debug_overlay.cpp +++ b/source/core/system/debug_overlay.cpp @@ -4,21 +4,13 @@ #include +#include "core/defaults.hpp" #include "core/types.hpp" namespace System { namespace { - // Posición y tamaño del overlay en coordenadas lógicas (1280×720). - constexpr float OVERLAY_X = 12.0F; - constexpr float OVERLAY_Y_FPS = 12.0F; - constexpr float OVERLAY_LINE_HEIGHT = 18.0F; // separación entre líneas (scale 0.4 → ~16 px alto) - constexpr float OVERLAY_SCALE = 0.4F; - constexpr float OVERLAY_SPACING = 2.0F; - constexpr float OVERLAY_BRIGHTNESS = 1.0F; - - // Cadencia de actualización del valor de FPS mostrado. - constexpr float FPS_UPDATE_INTERVAL = 0.5F; + namespace Cfg = Defaults::Hud::DebugOverlay; } // namespace DebugOverlay::DebugOverlay(Rendering::Renderer* renderer, @@ -30,7 +22,7 @@ namespace System { fps_accumulator_ += delta_time; fps_frame_count_++; - if (fps_accumulator_ >= FPS_UPDATE_INTERVAL) { + if (fps_accumulator_ >= Cfg::FPS_UPDATE_INTERVAL) { fps_display_ = static_cast(fps_frame_count_ / fps_accumulator_); fps_frame_count_ = 0; fps_accumulator_ = 0.0F; @@ -47,20 +39,20 @@ namespace System { const std::string AA_TEXT = std::string("AA: ") + (rendering_cfg_->antialias == 1 ? "ON" : "OFF"); text_.render(FPS_TEXT, - Vec2{.x = OVERLAY_X, .y = OVERLAY_Y_FPS}, - OVERLAY_SCALE, - OVERLAY_SPACING, - OVERLAY_BRIGHTNESS); + Vec2{.x = Cfg::X, .y = Cfg::Y_FPS}, + Cfg::TEXT_SCALE, + Cfg::TEXT_SPACING, + Cfg::BRIGHTNESS); text_.render(VSYNC_TEXT, - Vec2{.x = OVERLAY_X, .y = OVERLAY_Y_FPS + OVERLAY_LINE_HEIGHT}, - OVERLAY_SCALE, - OVERLAY_SPACING, - OVERLAY_BRIGHTNESS); + Vec2{.x = Cfg::X, .y = Cfg::Y_FPS + Cfg::LINE_HEIGHT}, + Cfg::TEXT_SCALE, + Cfg::TEXT_SPACING, + Cfg::BRIGHTNESS); text_.render(AA_TEXT, - Vec2{.x = OVERLAY_X, .y = OVERLAY_Y_FPS + (2.0F * OVERLAY_LINE_HEIGHT)}, - OVERLAY_SCALE, - OVERLAY_SPACING, - OVERLAY_BRIGHTNESS); + Vec2{.x = Cfg::X, .y = Cfg::Y_FPS + (2.0F * Cfg::LINE_HEIGHT)}, + Cfg::TEXT_SCALE, + Cfg::TEXT_SPACING, + Cfg::BRIGHTNESS); } } // namespace System diff --git a/source/game/scenes/game_scene.cpp b/source/game/scenes/game_scene.cpp index 136b833..9bdb281 100644 --- a/source/game/scenes/game_scene.cpp +++ b/source/game/scenes/game_scene.cpp @@ -107,8 +107,8 @@ GameScene::GameScene(SDLManager& sdl, SceneContext& context) } else { // Jugador inactiu: marcar como a mort permanent ships_[i].markHit(); - hit_timer_per_player_[i] = 999.0F; // Valor sentinella (permanent inactiu) - lives_per_player_[i] = 0; // Sin vides + hit_timer_per_player_[i] = Defaults::Game::HIT_TIMER_INACTIVE_PLAYER; + lives_per_player_[i] = 0; // Sin vides std::cout << "[GameScene] Jugador " << (i + 1) << " inactiu\n"; } } @@ -628,8 +628,9 @@ void GameScene::tocado(uint8_t player_id) { const Vec2& ship_pos = ships_[player_id].getCenter(); float ship_angle = ships_[player_id].getAngle(); Vec2 vel_nau = ships_[player_id].getVelocityVector(); - // Reduir a 80% la velocity heretada per la ship (més realista) - Vec2 vel_nau_80 = {.x = vel_nau.x * 0.8F, .y = vel_nau.y * 0.8F}; + // Reduir la velocity heretada per la ship segons defaults (més realista) + constexpr float INHERIT = Defaults::Physics::Debris::SHIP_VELOCITY_INHERITANCE; + Vec2 vel_nau_80 = {.x = vel_nau.x * INHERIT, .y = vel_nau.y * INHERIT}; debris_manager_.explode( ships_[player_id].getShape(), // Ship shape (3 lines) @@ -646,7 +647,7 @@ void GameScene::tocado(uint8_t player_id) { ); // Start death timer (non-zero to avoid re-triggering) - hit_timer_per_player_[player_id] = 0.001F; + hit_timer_per_player_[player_id] = Defaults::Game::HIT_TIMER_TRIGGER_DEATH; } // Phase 2 is automatic (debris updates in update()) // Phase 3 is handled in update() when hit_timer_per_player_ >= DEATH_DURATION @@ -828,8 +829,8 @@ void GameScene::fireBullet(uint8_t player_id) { const Vec2& ship_centre = ships_[player_id].getCenter(); float ship_angle = ships_[player_id].getAngle(); - constexpr float LOCAL_TIP_X = 0.0F; - constexpr float LOCAL_TIP_Y = -12.0F; + constexpr float LOCAL_TIP_X = Defaults::Hud::Tips::LOCAL_X; + constexpr float LOCAL_TIP_Y = Defaults::Hud::Tips::LOCAL_Y; float cos_a = std::cos(ship_angle); float sin_a = std::sin(ship_angle); float tip_x = (LOCAL_TIP_X * cos_a) - (LOCAL_TIP_Y * sin_a) + ship_centre.x; diff --git a/source/game/systems/init_hud_animator.cpp b/source/game/systems/init_hud_animator.cpp index 480315a..75e81eb 100644 --- a/source/game/systems/init_hud_animator.cpp +++ b/source/game/systems/init_hud_animator.cpp @@ -31,8 +31,8 @@ namespace Systems::InitHud { auto computeShipPosition(float progress, const Vec2& final_position) -> Vec2 { const float EASED = Easing::easeOutQuad(progress); const SDL_FRect& zone = Defaults::Zones::PLAYAREA; - // Y inicial: 50 px bajo la zona de juego. - const float Y_INI = zone.y + zone.h + 50.0F; + // Y inicial: bajo la zona de juego (sale desde fuera). + const float Y_INI = zone.y + zone.h + Defaults::Hud::InitAnim::SHIP_SPAWN_Y_OFFSET; const float Y_ANIM = Y_INI + ((final_position.y - Y_INI) * EASED); return Vec2{.x = final_position.x, .y = Y_ANIM}; } @@ -47,8 +47,8 @@ namespace Systems::InitHud { const int Y2 = static_cast(zone.y + zone.h); const int CX = (X1 + X2) / 2; - constexpr float PHASE_1_END = 0.33F; - constexpr float PHASE_2_END = 0.66F; + constexpr float PHASE_1_END = Defaults::Hud::InitAnim::BORDER_PHASE_1_END; + constexpr float PHASE_2_END = Defaults::Hud::InitAnim::BORDER_PHASE_2_END; // Fase 1: línea superior crece desde el centro hacia los lados. if (EASED > 0.0F) { From bb21191c5b4e7122275ce7d9e17b64dffc158d4e Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Thu, 21 May 2026 09:48:20 +0200 Subject: [PATCH 3/3] refactor(defaults): substitueix els 999.0F restants per HIT_TIMER_INACTIVE_PLAYER --- source/game/scenes/game_scene.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/game/scenes/game_scene.cpp b/source/game/scenes/game_scene.cpp index 9bdb281..f7cc050 100644 --- a/source/game/scenes/game_scene.cpp +++ b/source/game/scenes/game_scene.cpp @@ -201,8 +201,8 @@ void GameScene::stepMidGameJoin() { // Solo se permite join si hay al menos un jugador vivo (no se puede // hacer join en pantalla vacía). const bool ALGU_VIU = - (match_config_.jugador1_actiu && hit_timer_per_player_[0] != 999.0F) || - (match_config_.jugador2_actiu && hit_timer_per_player_[1] != 999.0F); + (match_config_.jugador1_actiu && hit_timer_per_player_[0] != Defaults::Game::HIT_TIMER_INACTIVE_PLAYER) || + (match_config_.jugador2_actiu && hit_timer_per_player_[1] != Defaults::Game::HIT_TIMER_INACTIVE_PLAYER); if (!ALGU_VIU) { return; } @@ -211,7 +211,7 @@ void GameScene::stepMidGameJoin() { for (uint8_t pid = 0; pid < 2; pid++) { const bool ACTIU = (pid == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; - const bool MUERTO_SIN_VIDAS = hit_timer_per_player_[pid] == 999.0F; + const bool MUERTO_SIN_VIDAS = hit_timer_per_player_[pid] == Defaults::Game::HIT_TIMER_INACTIVE_PLAYER; if (ACTIU && !MUERTO_SIN_VIDAS) { continue; // jugador ya está jugando } @@ -284,7 +284,7 @@ auto GameScene::stepGameOver(float delta_time) -> bool { void GameScene::stepDeathSequence(float delta_time) { bool algun_mort = false; for (uint8_t i = 0; i < 2; i++) { - if (hit_timer_per_player_[i] <= 0.0F || hit_timer_per_player_[i] >= 999.0F) { + if (hit_timer_per_player_[i] <= 0.0F || hit_timer_per_player_[i] >= Defaults::Game::HIT_TIMER_INACTIVE_PLAYER) { continue; } algun_mort = true; @@ -304,7 +304,7 @@ void GameScene::stepDeathSequence(float delta_time) { } // Sin vidas: marcar definitivamente muerto y comprobar transición a CONTINUE. - hit_timer_per_player_[i] = 999.0F; + hit_timer_per_player_[i] = Defaults::Game::HIT_TIMER_INACTIVE_PLAYER; const bool P1_DEAD = !match_config_.jugador1_actiu || lives_per_player_[0] <= 0; const bool P2_DEAD = !match_config_.jugador2_actiu || lives_per_player_[1] <= 0; if (P1_DEAD && P2_DEAD) {