diff --git a/source/core/defaults/effects.hpp b/source/core/defaults/effects.hpp index 83ffb14..cfe7e17 100644 --- a/source/core/defaults/effects.hpp +++ b/source/core/defaults/effects.hpp @@ -9,8 +9,8 @@ namespace Defaults::FX::Glow { // Neon glow per outline gruixut, aplicat automàticament per renderShape. // Els gruixos d'halo són RÀTIOS del bounding_radius de la shape (escalat - // per scale), de manera que un pentàgon (radi 20) té halo gros i una bala - // (radi 3) té halo subtil. El core (últim pass) usa el gruix de línia + // per scale), de manera que un pentàgon (radius 20) té halo gros i una bala + // (radius 3) té halo subtil. El core (últim pass) usa el gruix de línia // global (1.5px) — no escala amb la shape. // // Cap superior: si la shape és molt gran (logos del títol, intro), el diff --git a/source/core/defaults/game.hpp b/source/core/defaults/game.hpp index 5c08046..a7299c2 100644 --- a/source/core/defaults/game.hpp +++ b/source/core/defaults/game.hpp @@ -59,7 +59,7 @@ namespace Defaults::Game { constexpr float INIT_HUD_SHIP2_RATIO_INIT = 0.20F; constexpr float INIT_HUD_SHIP2_RATIO_END = 1.0F; - // Posición inicial de la nave en INIT_HUD (75% de altura de zona de juego) + // Posición inicial de la nave en INIT_HUD (75% de altura de zone de juego) constexpr float INIT_HUD_SHIP_START_Y_RATIO = 0.75F; // 75% desde el top de PLAYAREA // Spawn positions (distribución horizontal para 2 jugadores) diff --git a/source/core/defaults/title.hpp b/source/core/defaults/title.hpp index 02c1af8..8f5c3ff 100644 --- a/source/core/defaults/title.hpp +++ b/source/core/defaults/title.hpp @@ -68,7 +68,7 @@ namespace Defaults::Title { constexpr float FLOATING_SCALE = 1.0F * SHIP_BASE_SCALE; // Flotante: scale base // Offset de entrada (ajustat automáticoament a l'scale) - // Fórmula: (radi màxim de la ship * scale de entrada) + margen + // Fórmula: (radius màxim de la ship * scale de entrada) + margen constexpr float ENTRY_OFFSET = (SHIP_MAX_RADIUS * ENTRY_SCALE_START) + ENTRY_OFFSET_MARGIN; // Vec2 de fuga (centro para l'animación de salida) diff --git a/source/core/graphics/border.cpp b/source/core/graphics/border.cpp index 1c67aac..ccc7f08 100644 --- a/source/core/graphics/border.cpp +++ b/source/core/graphics/border.cpp @@ -23,12 +23,12 @@ namespace Graphics { } void Border::bumpAt(Vec2 contact_point, float strength) { - const SDL_FRect& zona = Defaults::Zones::PLAYAREA; + const SDL_FRect& zone = Defaults::Zones::PLAYAREA; const std::array DISTANCES = { - /* TOP */ std::abs(contact_point.y - zona.y), - /* RIGHT */ std::abs((zona.x + zona.w) - contact_point.x), - /* BOTTOM */ std::abs((zona.y + zona.h) - contact_point.y), - /* LEFT */ std::abs(contact_point.x - zona.x)}; + /* TOP */ std::abs(contact_point.y - zone.y), + /* RIGHT */ std::abs((zone.x + zone.w) - contact_point.x), + /* BOTTOM */ std::abs((zone.y + zone.h) - contact_point.y), + /* LEFT */ std::abs(contact_point.x - zone.x)}; int closest_idx = 0; float closest_dist = DISTANCES[0]; @@ -71,11 +71,11 @@ namespace Graphics { } // namespace void Border::draw() const { - const SDL_FRect& zona = Defaults::Zones::PLAYAREA; - const int X1 = static_cast(zona.x); - const int Y1 = static_cast(zona.y); - const int X2 = static_cast(zona.x + zona.w); - const int Y2 = static_cast(zona.y + zona.h); + const SDL_FRect& zone = Defaults::Zones::PLAYAREA; + 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 OFF_TOP = static_cast(sides_[SIDE_TOP].displacement_px); const int OFF_RIGHT = static_cast(sides_[SIDE_RIGHT].displacement_px); diff --git a/source/core/graphics/playfield.cpp b/source/core/graphics/playfield.cpp index 4358cb5..2c87e60 100644 --- a/source/core/graphics/playfield.cpp +++ b/source/core/graphics/playfield.cpp @@ -141,9 +141,9 @@ namespace Graphics { } void Playfield::buildLines() { - const SDL_FRect& zona = Defaults::Zones::PLAYAREA; - const float CELL_W = zona.w / static_cast(Defaults::Playfield::COLUMNS); - const float CELL_H = zona.h / static_cast(Defaults::Playfield::ROWS); + const SDL_FRect& zone = Defaults::Zones::PLAYAREA; + const float CELL_W = zone.w / static_cast(Defaults::Playfield::COLUMNS); + const float CELL_H = zone.h / static_cast(Defaults::Playfield::ROWS); const float SUB_W = CELL_W / static_cast(Defaults::Playfield::SUBDIVISIONS); const float SUB_H = CELL_H / static_cast(Defaults::Playfield::SUBDIVISIONS); const int SUB_VERTS = Defaults::Playfield::COLUMNS * Defaults::Playfield::SUBDIVISIONS; @@ -154,14 +154,14 @@ namespace Graphics { // Verticals: posicions i ∈ [1, SUB_VERTS-1]. for (int i = 1; i < SUB_VERTS; i++) { - const float X = zona.x + (static_cast(i) * SUB_W); + const float X = zone.x + (static_cast(i) * SUB_W); const bool IS_MAIN = (i % Defaults::Playfield::SUBDIVISIONS) == 0; const float BRIGHTNESS = IS_MAIN ? Defaults::Playfield::GRID_BRIGHTNESS : Defaults::Playfield::SUBGRID_BRIGHTNESS; verticals.push_back(Line{ - .start = {.x = X, .y = zona.y}, - .end = {.x = X, .y = zona.y + zona.h}, + .start = {.x = X, .y = zone.y}, + .end = {.x = X, .y = zone.y + zone.h}, .brightness = BRIGHTNESS, .spawn_time_s = 0.0F, .is_vertical = true}); @@ -169,14 +169,14 @@ namespace Graphics { // Horitzontals: posicions j ∈ [1, SUB_HORIZ-1]. for (int j = 1; j < SUB_HORIZ; j++) { - const float Y = zona.y + (static_cast(j) * SUB_H); + const float Y = zone.y + (static_cast(j) * SUB_H); const bool IS_MAIN = (j % Defaults::Playfield::SUBDIVISIONS) == 0; const float BRIGHTNESS = IS_MAIN ? Defaults::Playfield::GRID_BRIGHTNESS : Defaults::Playfield::SUBGRID_BRIGHTNESS; horizontals.push_back(Line{ - .start = {.x = zona.x, .y = Y}, - .end = {.x = zona.x + zona.w, .y = Y}, + .start = {.x = zone.x, .y = Y}, + .end = {.x = zone.x + zone.w, .y = Y}, .brightness = BRIGHTNESS, .spawn_time_s = 0.0F, .is_vertical = false}); diff --git a/source/core/graphics/starfield_parallax.cpp b/source/core/graphics/starfield_parallax.cpp index 8735ace..c6b0813 100644 --- a/source/core/graphics/starfield_parallax.cpp +++ b/source/core/graphics/starfield_parallax.cpp @@ -25,11 +25,11 @@ namespace Graphics { } void StarfieldParallax::buildStars() { - const SDL_FRect& zona = Defaults::Zones::PLAYAREA; - const float MIN_X = zona.x; - const float MAX_X = zona.x + zona.w; - const float MIN_Y = zona.y; - const float MAX_Y = zona.y + zona.h; + const SDL_FRect& zone = Defaults::Zones::PLAYAREA; + const float MIN_X = zone.x; + const float MAX_X = zone.x + zone.w; + const float MIN_Y = zone.y; + const float MAX_Y = zone.y + zone.h; // Color únic per a totes les estrelles: el mateix blanc-blau gel // del starfield del títol (Defaults::Title::Colors::STARFIELD). @@ -89,13 +89,13 @@ namespace Graphics { } void StarfieldParallax::update(float delta_time, Vec2 world_velocity) { - const SDL_FRect& zona = Defaults::Zones::PLAYAREA; - const float MIN_X = zona.x; - const float MAX_X = zona.x + zona.w; - const float MIN_Y = zona.y; - const float MAX_Y = zona.y + zona.h; - const float W = zona.w; - const float H = zona.h; + const SDL_FRect& zone = Defaults::Zones::PLAYAREA; + const float MIN_X = zone.x; + const float MAX_X = zone.x + zone.w; + const float MIN_Y = zone.y; + const float MAX_Y = zone.y + zone.h; + const float W = zone.w; + const float H = zone.h; for (auto& star : stars_) { const float FACTOR = layerParallax(star.layer); diff --git a/source/core/physics/collision.hpp b/source/core/physics/collision.hpp index 9f5adea..55c0ac3 100644 --- a/source/core/physics/collision.hpp +++ b/source/core/physics/collision.hpp @@ -17,7 +17,7 @@ namespace Physics { return false; } - // Calcular radi combinat (con amplificador per hitbox generós) + // Calcular radius combinat (con amplificador per hitbox generós) float suma_radis = (a.getCollisionRadius() + b.getCollisionRadius()) * amplifier; float suma_radis_sq = suma_radis * suma_radis; @@ -31,8 +31,8 @@ namespace Physics { return dist_sq <= suma_radis_sq; } - // Swept collision: una entitat mòbil (radi r_a) s'ha desplaçat de p0 a p1 aquest - // frame. Comprova si el segment expandit pel radi conjunt (r_a + radi de b, amb + // Swept collision: una entitat mòbil (radius r_a) s'ha desplaçat de p0 a p1 aquest + // frame. Comprova si el segment expandit pel radius conjunt (r_a + radius de b, amb // amplificador) toca el cercle de l'entity b. Equival al check discrete quan // p0 == p1 (sense moviment). Evita tunneling a velocitats altes. inline auto checkCollisionSwept(const Vec2& p0, const Vec2& p1, float r_a, const Entities::Entity& b, float amplifier = 1.0F) -> bool { diff --git a/source/core/system/game_config.hpp b/source/core/system/game_config.hpp index 5517b5c..25f26f6 100644 --- a/source/core/system/game_config.hpp +++ b/source/core/system/game_config.hpp @@ -4,52 +4,52 @@ namespace GameConfig { -// Mode de juego -enum class Mode : std::uint8_t { - NORMAL, // Partida normal - DEMO // Mode demostració (futur) -}; + // Mode de juego + enum class Mode : std::uint8_t { + NORMAL, // Partida normal + DEMO // Mode demostració (futur) + }; -// Configuración de una match -struct MatchConfig { - bool jugador1_actiu{false}; // Es active el player 1? - bool jugador2_actiu{false}; // Es active el player 2? + // Configuración de una match + struct MatchConfig { + bool player1_active{false}; // Es active el player 1? + bool player2_active{false}; // Es active el player 2? Mode mode{Mode::NORMAL}; // Mode de juego // Métodos auxiliars // Retorna true si solo hay un player active [[nodiscard]] auto isSinglePlayer() const -> bool { - return (jugador1_actiu && !jugador2_actiu) || - (!jugador1_actiu && jugador2_actiu); + return (player1_active && !player2_active) || + (!player1_active && player2_active); } // Retorna true si hay dos jugadors active [[nodiscard]] auto isCoop() const -> bool { - return jugador1_actiu && jugador2_actiu; + return player1_active && player2_active; } // Retorna true si no hay sin player active [[nodiscard]] auto hasNoPlayers() const -> bool { - return !jugador1_actiu && !jugador2_actiu; + return !player1_active && !player2_active; } // Compte de jugadors active (0, 1 o 2) [[nodiscard]] auto getPlayerCount() const -> uint8_t { - return (jugador1_actiu ? 1 : 0) + (jugador2_actiu ? 1 : 0); + return (player1_active ? 1 : 0) + (player2_active ? 1 : 0); } // Retorna l'ID de l'únic player active (0 o 1) // Solo vàlid si es_un_jugador() retorna true [[nodiscard]] auto getSinglePlayerId() const -> uint8_t { - if (jugador1_actiu && !jugador2_actiu) { + if (player1_active && !player2_active) { return 0; } - if (!jugador1_actiu && jugador2_actiu) { + if (!player1_active && player2_active) { return 1; } return 0; // Fallback (necesario comprovar es_un_jugador() primer) } -}; + }; } // namespace GameConfig diff --git a/source/game/constants.hpp b/source/game/constants.hpp index d6df236..c86f17d 100644 --- a/source/game/constants.hpp +++ b/source/game/constants.hpp @@ -12,35 +12,35 @@ namespace Constants { // Matemàtiques constexpr float PI = Defaults::Math::PI; - // Helpers per comprovar límits de zona + // Helpers per comprovar límits de zone inline auto isInPlayArea(float x, float y) -> bool { const SDL_FPoint POINT = {x, y}; return SDL_PointInRectFloat(&POINT, &Defaults::Zones::PLAYAREA); } inline void getPlayAreaBounds(float& min_x, float& max_x, float& min_y, float& max_y) { - const auto& zona = Defaults::Zones::PLAYAREA; - min_x = zona.x; - max_x = zona.x + zona.w; - min_y = zona.y; - max_y = zona.y + zona.h; + const auto& zone = Defaults::Zones::PLAYAREA; + min_x = zone.x; + max_x = zone.x + zone.w; + min_y = zone.y; + max_y = zone.y + zone.h; } - // Obtenir límits segurs (compensant radi de l'entidad) - inline void getSafePlayAreaBounds(float radi, float& min_x, float& max_x, float& min_y, float& max_y) { - const auto& zona = Defaults::Zones::PLAYAREA; - constexpr float MARGE_SEGURETAT = 10.0F; // Safety margin + // Obtenir límits segurs (compensant radius de l'entidad) + inline void getSafePlayAreaBounds(float radius, float& min_x, float& max_x, float& min_y, float& max_y) { + const auto& zone = Defaults::Zones::PLAYAREA; + constexpr float SAFETY_MARGIN = 10.0F; // Safety margin - min_x = zona.x + radi + MARGE_SEGURETAT; - max_x = zona.x + zona.w - radi - MARGE_SEGURETAT; - min_y = zona.y + radi + MARGE_SEGURETAT; - max_y = zona.y + zona.h - radi - MARGE_SEGURETAT; + min_x = zone.x + radius + SAFETY_MARGIN; + max_x = zone.x + zone.w - radius - SAFETY_MARGIN; + min_y = zone.y + radius + SAFETY_MARGIN; + max_y = zone.y + zone.h - radius - SAFETY_MARGIN; } // Obtenir centro de l'àrea de juego - inline void getPlayAreaCenter(float& centre_x, float& centre_y) { - const auto& zona = Defaults::Zones::PLAYAREA; - centre_x = zona.x + (zona.w / 2.0F); - centre_y = zona.y + (zona.h / 2.0F); + inline void getPlayAreaCenter(float& center_x, float& center_y) { + const auto& zone = Defaults::Zones::PLAYAREA; + center_x = zone.x + (zone.w / 2.0F); + center_y = zone.y + (zone.h / 2.0F); } } // namespace Constants diff --git a/source/game/effects/firework_manager.cpp b/source/game/effects/firework_manager.cpp index e9dd91d..70f1dba 100644 --- a/source/game/effects/firework_manager.cpp +++ b/source/game/effects/firework_manager.cpp @@ -61,7 +61,7 @@ namespace Effects { } } - void FireworkManager::spawn(const Vec2& origen, + void FireworkManager::spawn(const Vec2& origin, SDL_Color color, float initial_speed, int n_points, @@ -74,7 +74,7 @@ namespace Effects { // Notificar als subscriptors (playfield pulses, etc.). if (spawn_callback_) { - spawn_callback_(origen); + spawn_callback_(origin); } const float ANGLE_STEP = 2.0F * Defaults::Math::PI / static_cast(n_points); @@ -94,7 +94,7 @@ namespace Effects { const float SPEED = initial_speed + (randSigned() * Defaults::FX::Firework::SPEED_VARIATION); - fw->head = origen; + fw->head = origin; fw->velocity = {.x = std::cos(ANGLE) * SPEED, .y = std::sin(ANGLE) * SPEED}; fw->acceleration = Defaults::FX::Firework::FRICTION; diff --git a/source/game/effects/firework_manager.hpp b/source/game/effects/firework_manager.hpp index 9fd031b..fb06179 100644 --- a/source/game/effects/firework_manager.hpp +++ b/source/game/effects/firework_manager.hpp @@ -21,7 +21,7 @@ namespace Effects { class FireworkManager { public: // Notificació opcional cada vegada que es genera un burst. - using SpawnCallback = std::function; + using SpawnCallback = std::function; explicit FireworkManager(Rendering::Renderer* renderer); @@ -37,7 +37,7 @@ namespace Effects { // initial_brightness: 0..1. // glow: si true, cada partícula es renderitza amb halo neon. // glow_color: color del halo. Si alpha==0, agafa el color de la línia. - void spawn(const Vec2& origen, + void spawn(const Vec2& origin, SDL_Color color = Defaults::FX::Firework::DEFAULT_COLOR, float initial_speed = Defaults::FX::Firework::SPEED, int n_points = Defaults::FX::Firework::N_POINTS, diff --git a/source/game/entities/bullet.cpp b/source/game/entities/bullet.cpp index cc661bd..99187d3 100644 --- a/source/game/entities/bullet.cpp +++ b/source/game/entities/bullet.cpp @@ -80,7 +80,7 @@ void Bullet::fire(const Vec2& position, float angle, uint8_t owner_id) { } void Bullet::update(float /*delta_time*/) { - // No-op: la desactivació per fora-de-zona viu a + // No-op: la desactivació per fora-de-zone viu a // Systems::Collision::desactivateOutOfBoundsBullets() perquè així té accés // al DebrisManager i pot generar el "trencament" visual de la bala alhora. // El moviment l'integra PhysicsWorld; postUpdate sincronitza center_ i prev_position_. diff --git a/source/game/entities/enemy.cpp b/source/game/entities/enemy.cpp index 18917a7..3cd8948 100644 --- a/source/game/entities/enemy.cpp +++ b/source/game/entities/enemy.cpp @@ -131,7 +131,7 @@ void Enemy::init(EnemyType type, const Vec2* ship_pos) { const int RANGE_Y = static_cast(max_y - min_y); center_.x = static_cast((std::rand() % RANGE_X) + static_cast(min_x)); center_.y = static_cast((std::rand() % RANGE_Y) + static_cast(min_y)); - std::cout << "[Enemy] Advertencia: spawn sin zona segura tras " + std::cout << "[Enemy] Advertencia: spawn sin zone segura tras " << Defaults::Enemies::Spawn::MAX_SPAWN_ATTEMPTS << " intentos\n"; } } else { diff --git a/source/game/entities/ship.cpp b/source/game/entities/ship.cpp index 1b98dbf..4313b01 100644 --- a/source/game/entities/ship.cpp +++ b/source/game/entities/ship.cpp @@ -44,10 +44,10 @@ void Ship::init(const Vec2* spawn_point, bool activar_invulnerabilitat) { if (spawn_point != nullptr) { center_ = *spawn_point; } else { - float centre_x; - float centre_y; - Constants::getPlayAreaCenter(centre_x, centre_y); - center_ = {.x = centre_x, .y = centre_y}; + float center_x; + float center_y; + Constants::getPlayAreaCenter(center_x, center_y); + center_ = {.x = center_x, .y = center_y}; } // Reset orientación diff --git a/source/game/scenes/game_scene.cpp b/source/game/scenes/game_scene.cpp index 31e5556..0ce0e0c 100644 --- a/source/game/scenes/game_scene.cpp +++ b/source/game/scenes/game_scene.cpp @@ -38,9 +38,9 @@ GameScene::GameScene(SDLManager& sdl, SceneContext& context) // Debug output de la configuración std::cout << "[GameScene] Configuración de match - P1: " - << (match_config_.jugador1_actiu ? "ACTIU" : "INACTIU") + << (match_config_.player1_active ? "ACTIU" : "INACTIU") << ", P2: " - << (match_config_.jugador2_actiu ? "ACTIU" : "INACTIU") + << (match_config_.player2_active ? "ACTIU" : "INACTIU") << '\n'; // Consumir opciones (preparació per MODE_DEMO futur) @@ -61,7 +61,7 @@ GameScene::GameScene(SDLManager& sdl, SceneContext& context) // Basat en el codi Pascal original: line 376 std::srand(static_cast(std::time(nullptr))); - // Configurar el mundo físico con los límites de la zona de juego. + // Configurar el mundo físico con los límites de la zone de juego. physics_world_.clear(); physics_world_.setBounds(Defaults::Zones::PLAYAREA); @@ -77,17 +77,17 @@ GameScene::GameScene(SDLManager& sdl, SceneContext& context) }); // Fireworks generen una ripple gran al playfield (ona d'aigua centrada al burst). - firework_manager_.setSpawnCallback([this](Vec2 origen) { - playfield_.notifyExplosion(origen); + firework_manager_.setSpawnCallback([this](Vec2 origin) { + playfield_.notifyExplosion(origin); }); // Explosions properes a una paret també generen bump (falloff lineal amb la distància). debris_manager_.setExplosionCallback([this](Vec2 center) { - const SDL_FRect& zona = Defaults::Zones::PLAYAREA; - const float DIST_LEFT = std::abs(center.x - zona.x); - const float DIST_RIGHT = std::abs((zona.x + zona.w) - center.x); - const float DIST_TOP = std::abs(center.y - zona.y); - const float DIST_BOTTOM = std::abs((zona.y + zona.h) - center.y); + const SDL_FRect& zone = Defaults::Zones::PLAYAREA; + const float DIST_LEFT = std::abs(center.x - zone.x); + const float DIST_RIGHT = std::abs((zone.x + zone.w) - center.x); + const float DIST_TOP = std::abs(center.y - zone.y); + const float DIST_BOTTOM = std::abs((zone.y + zone.h) - center.y); const float MIN_DIST = std::min({DIST_LEFT, DIST_RIGHT, DIST_TOP, DIST_BOTTOM}); if (MIN_DIST > Defaults::Border::EXPLOSION_FALLOFF_PX) { return; @@ -130,9 +130,9 @@ GameScene::GameScene(SDLManager& sdl, SceneContext& context) // Inicialitzar naves segons configuración (solo jugadors active) for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; + bool player_active = (i == 0) ? match_config_.player1_active : match_config_.player2_active; - if (jugador_actiu) { + if (player_active) { // Jugador active: init normalment Vec2 spawn_pos = getSpawnPoint(i); ships_[i].init(&spawn_pos, false); // No invulnerability at start @@ -248,11 +248,11 @@ void GameScene::stepPhysics(float delta_time) { void GameScene::stepShootingInput() { auto* input = Input::get(); - if (match_config_.jugador1_actiu && + if (match_config_.player1_active && input->checkActionPlayer1(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) { fireBullet(0); } - if (match_config_.jugador2_actiu && + if (match_config_.player2_active && input->checkActionPlayer2(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) { fireBullet(1); } @@ -267,16 +267,16 @@ 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] != Defaults::Game::HIT_TIMER_INACTIVE_PLAYER) || - (match_config_.jugador2_actiu && hit_timer_per_player_[1] != Defaults::Game::HIT_TIMER_INACTIVE_PLAYER); + (match_config_.player1_active && hit_timer_per_player_[0] != Defaults::Game::HIT_TIMER_INACTIVE_PLAYER) || + (match_config_.player2_active && hit_timer_per_player_[1] != Defaults::Game::HIT_TIMER_INACTIVE_PLAYER); if (!ALGU_VIU) { return; } auto* input = Input::get(); for (uint8_t pid = 0; pid < 2; pid++) { - const bool ACTIU = (pid == 0) ? match_config_.jugador1_actiu - : match_config_.jugador2_actiu; + const bool ACTIU = (pid == 0) ? match_config_.player1_active + : match_config_.player2_active; 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 @@ -375,8 +375,8 @@ void GameScene::stepDeathSequence(float delta_time) { // Sin vidas: marcar definitivamente muerto y comprobar transición a CONTINUE. 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; + const bool P1_DEAD = !match_config_.player1_active || lives_per_player_[0] <= 0; + const bool P2_DEAD = !match_config_.player2_active || lives_per_player_[1] <= 0; if (P1_DEAD && P2_DEAD) { game_over_state_ = GameOverState::CONTINUE; continue_counter_ = Defaults::Game::CONTINUE_COUNT_START; @@ -440,10 +440,10 @@ void GameScene::runStageInitHud(float delta_time) { Defaults::Game::INIT_HUD_SHIP2_RATIO_INIT, Defaults::Game::INIT_HUD_SHIP2_RATIO_END); - if (match_config_.jugador1_actiu && SHIP1_P < 1.0F) { + if (match_config_.player1_active && SHIP1_P < 1.0F) { ships_[0].setCenter(Systems::InitHud::computeShipPosition(SHIP1_P, getSpawnPoint(0))); } - if (match_config_.jugador2_actiu && SHIP2_P < 1.0F) { + if (match_config_.player2_active && SHIP2_P < 1.0F) { ships_[1].setCenter(Systems::InitHud::computeShipPosition(SHIP2_P, getSpawnPoint(1))); } } @@ -453,7 +453,7 @@ void GameScene::runStageLevelStart(float delta_time) { // Ambas naves pueden moverse y disparar durante el intro. for (uint8_t i = 0; i < 2; i++) { - const bool ACTIU = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; + const bool ACTIU = (i == 0) ? match_config_.player1_active : match_config_.player2_active; if (ACTIU && hit_timer_per_player_[i] == 0.0F) { ships_[i].processInput(delta_time, i); ships_[i].update(delta_time); @@ -481,7 +481,7 @@ void GameScene::runStagePlaying(float delta_time) { // Gameplay normal: ships activos + entidades + colisiones + efectos. for (uint8_t i = 0; i < 2; i++) { - const bool ACTIU = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; + const bool ACTIU = (i == 0) ? match_config_.player1_active : match_config_.player2_active; if (ACTIU && hit_timer_per_player_[i] == 0.0F) { ships_[i].processInput(delta_time, i); ships_[i].update(delta_time); @@ -491,7 +491,7 @@ void GameScene::runStagePlaying(float delta_time) { enemy.update(delta_time); } - // Col·lisions primer, després desactivació per fora-de-zona: així una bala que + // Col·lisions primer, després desactivació per fora-de-zone: així una bala que // el mateix frame xoca amb un enemic i alhora surt del PLAYAREA es compta com a // impacte abans no se la trenqui per sortir. runCollisionDetections(); @@ -507,7 +507,7 @@ void GameScene::runStagePlaying(float delta_time) { void GameScene::runStageLevelCompleted(float delta_time) { stage_manager_->update(delta_time); for (uint8_t i = 0; i < 2; i++) { - const bool ACTIU = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; + const bool ACTIU = (i == 0) ? match_config_.player1_active : match_config_.player2_active; if (ACTIU && hit_timer_per_player_[i] == 0.0F) { ships_[i].processInput(delta_time, i); ships_[i].update(delta_time); @@ -580,8 +580,8 @@ void GameScene::drawBullets() const { void GameScene::drawActiveShipsAlive() const { for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; - if (jugador_actiu && hit_timer_per_player_[i] == 0.0F) { + bool player_active = (i == 0) ? match_config_.player1_active : match_config_.player2_active; + if (player_active && hit_timer_per_player_[i] == 0.0F) { ships_[i].draw(); } } @@ -613,10 +613,10 @@ void GameScene::drawGameOverState() { constexpr float SPACING = Defaults::Game::GameOverScreen::TEXT_SPACING; const SDL_FRect& play_area = Defaults::Zones::PLAYAREA; - float centre_x = play_area.x + (play_area.w / 2.0F); - float centre_y = play_area.y + (play_area.h / 2.0F); + float center_x = play_area.x + (play_area.w / 2.0F); + float center_y = play_area.y + (play_area.h / 2.0F); - text_.renderCentered(GAME_OVER_TEXT, {.x = centre_x, .y = centre_y}, SCALE, SPACING); + text_.renderCentered(GAME_OVER_TEXT, {.x = center_x, .y = center_y}, SCALE, SPACING); drawScoreboard(); } @@ -663,11 +663,11 @@ void GameScene::drawInitHudState() { Systems::InitHud::drawScoreboardAnimated(text_, buildScoreboard(), score_progress); } - if (ship1_progress > 0.0F && match_config_.jugador1_actiu && ships_[0].isActive()) { + if (ship1_progress > 0.0F && match_config_.player1_active && ships_[0].isActive()) { ships_[0].draw(); } - if (ship2_progress > 0.0F && match_config_.jugador2_actiu && ships_[1].isActive()) { + if (ship2_progress > 0.0F && match_config_.player2_active && ships_[1].isActive()) { ships_[1].draw(); } } @@ -769,20 +769,20 @@ void GameScene::drawScoreboard() { const float SCALE = Defaults::Hud::SCOREBOARD_TEXT_SCALE; const float SPACING = Defaults::Hud::SCOREBOARD_TEXT_SPACING; - // Calcular centro de la zona del marcador + // Calcular centro de la zone del marcador const SDL_FRect& scoreboard_zone = Defaults::Zones::SCOREBOARD; - float centre_x = scoreboard_zone.w / 2.0F; - float centre_y = scoreboard_zone.y + (scoreboard_zone.h / 2.0F); + float center_x = scoreboard_zone.w / 2.0F; + float center_y = scoreboard_zone.y + (scoreboard_zone.h / 2.0F); // Renderizar centrat - text_.renderCentered(text, {.x = centre_x, .y = centre_y}, SCALE, SPACING); + text_.renderCentered(text, {.x = center_x, .y = center_y}, SCALE, SPACING); } auto GameScene::buildScoreboard() const -> std::string { // Puntuación P1 (6 dígits) - mostrar zeros si inactiu std::string score_p1; std::string vides_p1; - if (match_config_.jugador1_actiu) { + if (match_config_.player1_active) { score_p1 = std::to_string(score_per_player_[0]); score_p1 = std::string(6 - std::min(6, static_cast(score_p1.length())), '0') + score_p1; vides_p1 = (lives_per_player_[0] < 10) @@ -801,7 +801,7 @@ auto GameScene::buildScoreboard() const -> std::string { // Puntuación P2 (6 dígits) - mostrar zeros si inactiu std::string score_p2; std::string vides_p2; - if (match_config_.jugador2_actiu) { + if (match_config_.player2_active) { score_p2 = std::to_string(score_per_player_[1]); score_p2 = std::string(6 - std::min(6, static_cast(score_p2.length())), '0') + score_p2; vides_p2 = (lives_per_player_[1] < 10) @@ -890,7 +890,7 @@ void GameScene::drawStageMessage(const std::string& message) { // ======================================== auto GameScene::getSpawnPoint(uint8_t player_id) const -> Vec2 { - const SDL_FRect& zona = Defaults::Zones::PLAYAREA; + const SDL_FRect& zone = Defaults::Zones::PLAYAREA; float x_ratio; if (match_config_.isSinglePlayer()) { @@ -904,8 +904,8 @@ auto GameScene::getSpawnPoint(uint8_t player_id) const -> Vec2 { } return { - .x = zona.x + (zona.w * x_ratio), - .y = zona.y + (zona.h * Defaults::Game::SPAWN_Y_RATIO)}; + .x = zone.x + (zone.w * x_ratio), + .y = zone.y + (zone.h * Defaults::Game::SPAWN_Y_RATIO)}; } void GameScene::fireBullet(uint8_t player_id) { @@ -950,10 +950,10 @@ void GameScene::drawContinue() { float escala_continue = Defaults::Game::ContinueScreen::CONTINUE_TEXT_SCALE; float y_ratio_continue = Defaults::Game::ContinueScreen::CONTINUE_TEXT_Y_RATIO; - float centre_x = play_area.x + (play_area.w / 2.0F); + float center_x = play_area.x + (play_area.w / 2.0F); float centre_y_continue = play_area.y + (play_area.h * y_ratio_continue); - text_.renderCentered(CONTINUE_TEXT, {.x = centre_x, .y = centre_y_continue}, escala_continue, SPACING); + text_.renderCentered(CONTINUE_TEXT, {.x = center_x, .y = centre_y_continue}, escala_continue, SPACING); // Countdown number (using constants) const std::string COUNTER_STR = std::to_string(continue_counter_); @@ -962,7 +962,7 @@ void GameScene::drawContinue() { float centre_y_counter = play_area.y + (play_area.h * y_ratio_counter); - text_.renderCentered(COUNTER_STR, {.x = centre_x, .y = centre_y_counter}, escala_counter, SPACING); + text_.renderCentered(COUNTER_STR, {.x = center_x, .y = centre_y_counter}, escala_counter, SPACING); // "CONTINUES LEFT" (conditional + using constants) if (!Defaults::Game::INFINITE_CONTINUES) { @@ -972,16 +972,16 @@ void GameScene::drawContinue() { float centre_y_info = play_area.y + (play_area.h * y_ratio_info); - text_.renderCentered(CONTINUES_TEXT, {.x = centre_x, .y = centre_y_info}, escala_info, SPACING); + text_.renderCentered(CONTINUES_TEXT, {.x = center_x, .y = centre_y_info}, escala_info, SPACING); } } void GameScene::joinPlayer(uint8_t player_id) { // Activate player if (player_id == 0) { - match_config_.jugador1_actiu = true; + match_config_.player1_active = true; } else { - match_config_.jugador2_actiu = true; + match_config_.player2_active = true; } // Reset stats diff --git a/source/game/scenes/logo_scene.cpp b/source/game/scenes/logo_scene.cpp index ce7f51c..ea1d787 100644 --- a/source/game/scenes/logo_scene.cpp +++ b/source/game/scenes/logo_scene.cpp @@ -22,16 +22,16 @@ using Option = SceneContext::Option; // Helper: calcular el progrés individual de una letter // en función del progrés global (efecte seqüencial) -static auto computeLetterProgress(size_t letra_index, size_t num_letras, float global_progress, float threshold) -> float { - if (num_letras == 0) { +static auto computeLetterProgress(size_t letter_index, size_t num_letters, float global_progress, float threshold) -> float { + if (num_letters == 0) { return 1.0F; } // Calcular time per letter - float duration_per_letra = 1.0F / static_cast(num_letras); - float step = threshold * duration_per_letra; - float start = static_cast(letra_index) * step; - float end = start + duration_per_letra; + float duration_per_letter = 1.0F / static_cast(num_letters); + float step = threshold * duration_per_letter; + float start = static_cast(letter_index) * step; + float end = start + duration_per_letter; // Interpolar progrés if (global_progress < start) { @@ -179,7 +179,7 @@ void LogoScene::changeState(AnimationState nou_estat) { } auto LogoScene::allLettersComplete() const -> bool { - // Cuando global_progress = 1.0, todas las lletres tenen letra_progress = 1.0 + // Cuando global_progress = 1.0, todas las lletres tenen letter_progress = 1.0 return temps_current_state_ >= DURATION_ZOOM; } @@ -231,14 +231,14 @@ void LogoScene::update(float delta_time) { for (size_t i = 0; i < letters_.size() && i < sound_played_.size(); i++) { if (!sound_played_[i]) { - float letra_progress = computeLetterProgress( + float letter_progress = computeLetterProgress( i, letters_.size(), global_progress, LETTER_THRESHOLD); // Reproduir so cuando la letter comença a aparèixer (progress > 0) - if (letra_progress > 0.0F) { + if (letter_progress > 0.0F) { Audio::get()->playSound(Defaults::Sound::LOGO, Audio::Group::GAME); sound_played_[i] = true; } @@ -294,28 +294,28 @@ void LogoScene::draw() { ? std::min(temps_current_state_ / DURATION_ZOOM, 1.0F) : 1.0F; // POST: mantenir al 100% - const Vec2 ORIGEN_ZOOM = {.x = ORIGEN_ZOOM_X, .y = ORIGEN_ZOOM_Y}; + const Vec2 ZOOM_ORIGIN = {.x = ZOOM_ORIGIN_X, .y = ZOOM_ORIGIN_Y}; for (size_t i = 0; i < letters_.size(); i++) { const auto& letter = letters_[i]; - float letra_progress = computeLetterProgress( + float letter_progress = computeLetterProgress( i, letters_.size(), global_progress, LETTER_THRESHOLD); - if (letra_progress <= 0.0F) { + if (letter_progress <= 0.0F) { continue; } Vec2 pos_actual; pos_actual.x = - ORIGEN_ZOOM.x + ((letter.position.x - ORIGEN_ZOOM.x) * letra_progress); + ZOOM_ORIGIN.x + ((letter.position.x - ZOOM_ORIGIN.x) * letter_progress); pos_actual.y = - ORIGEN_ZOOM.y + ((letter.position.y - ORIGEN_ZOOM.y) * letra_progress); + ZOOM_ORIGIN.y + ((letter.position.y - ZOOM_ORIGIN.y) * letter_progress); - float t = letra_progress; + float t = letter_progress; float ease_factor = 1.0F - ((1.0F - t) * (1.0F - t)); float current_scale = INITIAL_SCALE + ((FINAL_SCALE - INITIAL_SCALE) * ease_factor); diff --git a/source/game/scenes/logo_scene.hpp b/source/game/scenes/logo_scene.hpp index ffe40dd..ca75643 100644 --- a/source/game/scenes/logo_scene.hpp +++ b/source/game/scenes/logo_scene.hpp @@ -80,8 +80,8 @@ class LogoScene final : public Scene { // Constants de animación seqüencial static constexpr float LETTER_THRESHOLD = 0.6F; // Umbral per activar següent letter (0.0-1.0) - static constexpr float ORIGEN_ZOOM_X = Defaults::Game::WIDTH * 0.5F; // Vec2 inicial X del zoom - static constexpr float ORIGEN_ZOOM_Y = Defaults::Game::HEIGHT * 0.4F; // Vec2 inicial Y del zoom + static constexpr float ZOOM_ORIGIN_X = Defaults::Game::WIDTH * 0.5F; // Vec2 inicial X del zoom + static constexpr float ZOOM_ORIGIN_Y = Defaults::Game::HEIGHT * 0.4F; // Vec2 inicial Y del zoom // Métodos privats void initLetters(); diff --git a/source/game/scenes/title_scene.cpp b/source/game/scenes/title_scene.cpp index bf43a5b..b755e96 100644 --- a/source/game/scenes/title_scene.cpp +++ b/source/game/scenes/title_scene.cpp @@ -36,8 +36,8 @@ TitleScene::TitleScene(SDLManager& sdl, SceneContext& context) text_(sdl.getRenderer()) { std::cout << "SceneType Titol: Inicialitzant...\n"; - match_config_.jugador1_actiu = false; - match_config_.jugador2_actiu = false; + match_config_.player1_active = false; + match_config_.player2_active = false; match_config_.mode = GameConfig::Mode::NORMAL; auto option = context_.consumeOption(); @@ -404,8 +404,8 @@ void TitleScene::updatePlayerJoinPhaseState(float delta_time) { temps_acumulat_ += delta_time; updateLogoAnimation(delta_time); - const bool P1_ABANS = match_config_.jugador1_actiu; - const bool P2_ABANS = match_config_.jugador2_actiu; + const bool P1_ABANS = match_config_.player1_active; + const bool P2_ABANS = match_config_.player2_active; if (checkStartGameButtonPressed()) { context_.setMatchConfig(match_config_); @@ -466,8 +466,8 @@ void TitleScene::handleStartInput() { if (!press_start_visible_) { return; } - const bool P1_ABANS = match_config_.jugador1_actiu; - const bool P2_ABANS = match_config_.jugador2_actiu; + const bool P1_ABANS = match_config_.player1_active; + const bool P2_ABANS = match_config_.player2_active; if (!checkStartGameButtonPressed()) { return; @@ -492,11 +492,11 @@ void TitleScene::triggerExitForJoinedPlayers(bool p1_was_active, bool p2_was_act if (ship_animator_ == nullptr) { return; } - if (match_config_.jugador1_actiu && !p1_was_active) { + if (match_config_.player1_active && !p1_was_active) { ship_animator_->triggerExitAnimationForPlayer(1); std::cout << "[TitleScene] P1 " << log_prefix << "ship exiting\n"; } - if (match_config_.jugador2_actiu && !p2_was_active) { + if (match_config_.player2_active && !p2_was_active) { ship_animator_->triggerExitAnimationForPlayer(2); std::cout << "[TitleScene] P2 " << log_prefix << "ship exiting\n"; } @@ -622,14 +622,14 @@ auto TitleScene::checkStartGameButtonPressed() -> bool { bool any_pressed = false; for (auto action : START_GAME_BUTTONS) { if (input->checkActionPlayer1(action, Input::DO_NOT_ALLOW_REPEAT)) { - if (!match_config_.jugador1_actiu) { - match_config_.jugador1_actiu = true; + if (!match_config_.player1_active) { + match_config_.player1_active = true; any_pressed = true; } } if (input->checkActionPlayer2(action, Input::DO_NOT_ALLOW_REPEAT)) { - if (!match_config_.jugador2_actiu) { - match_config_.jugador2_actiu = true; + if (!match_config_.player2_active) { + match_config_.player2_active = true; any_pressed = true; } } diff --git a/source/game/systems/collision_system.cpp b/source/game/systems/collision_system.cpp index 0d5b1ff..3a6bbac 100644 --- a/source/game/systems/collision_system.cpp +++ b/source/game/systems/collision_system.cpp @@ -262,8 +262,8 @@ namespace Systems::Collision { continue; } const bool JUGADOR_ACTIU = (player_id == 0) - ? ctx.match_config.jugador1_actiu - : ctx.match_config.jugador2_actiu; + ? ctx.match_config.player1_active + : ctx.match_config.player2_active; if (!JUGADOR_ACTIU) { continue; } diff --git a/source/game/systems/continue_system.cpp b/source/game/systems/continue_system.cpp index f9a6dd4..ffe94a0 100644 --- a/source/game/systems/continue_system.cpp +++ b/source/game/systems/continue_system.cpp @@ -11,99 +11,99 @@ #include "game/scenes/game_scene.hpp" // GameOverState (definición completa) namespace Systems::ContinueScreen { -namespace { + namespace { -// Si el countdown ha bajado de 0, transiciona a GAME_OVER con su timer. -void checkAndApplyTimeout(Context& ctx) { - if (ctx.counter < 0) { - ctx.state = GameOverState::GAME_OVER; - ctx.game_over_timer = Defaults::Game::GAME_OVER_DURATION; - } -} + // Si el countdown ha bajado de 0, transiciona a GAME_OVER con su timer. + void checkAndApplyTimeout(Context& ctx) { + if (ctx.counter < 0) { + ctx.state = GameOverState::GAME_OVER; + ctx.game_over_timer = Defaults::Game::GAME_OVER_DURATION; + } + } -void revivePlayer(Context& ctx, uint8_t player_id) { - ctx.score_per_player[player_id] = 0; - ctx.lives_per_player[player_id] = Defaults::Game::STARTING_LIVES; - ctx.hit_timer_per_player[player_id] = 0.0F; + void revivePlayer(Context& ctx, uint8_t player_id) { + ctx.score_per_player[player_id] = 0; + ctx.lives_per_player[player_id] = Defaults::Game::STARTING_LIVES; + ctx.hit_timer_per_player[player_id] = 0.0F; - if (player_id == 0) { - ctx.match_config.jugador1_actiu = true; - } else { - ctx.match_config.jugador2_actiu = true; - } + if (player_id == 0) { + ctx.match_config.player1_active = true; + } else { + ctx.match_config.player2_active = true; + } - const Vec2 SPAWN = ctx.get_spawn_point(player_id); - ctx.ships[player_id].init(&SPAWN, /*activar_invulnerabilitat=*/true); -} + const Vec2 SPAWN = ctx.get_spawn_point(player_id); + ctx.ships[player_id].init(&SPAWN, /*activar_invulnerabilitat=*/true); + } -} // namespace + } // namespace -void update(Context& ctx, float delta_time) { - ctx.tick_timer -= delta_time; - if (ctx.tick_timer > 0.0F) { - return; - } - ctx.counter--; - ctx.tick_timer = Defaults::Game::CONTINUE_TICK_DURATION; - - checkAndApplyTimeout(ctx); - - // Solo pita el tick si seguimos en CONTINUE (no transitamos a GAME_OVER) - if (ctx.state == GameOverState::CONTINUE) { - Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME); - } -} - -void processInput(Context& ctx) { - auto* input = Input::get(); - - const bool P1_START = input->checkActionPlayer1(InputAction::START, Input::DO_NOT_ALLOW_REPEAT); - const bool P2_START = input->checkActionPlayer2(InputAction::START, Input::DO_NOT_ALLOW_REPEAT); - - if (P1_START || P2_START) { - // ¿Quedan continues? - if (!Defaults::Game::INFINITE_CONTINUES && - ctx.continues_used >= Defaults::Game::MAX_CONTINUES) { - ctx.state = GameOverState::GAME_OVER; - ctx.game_over_timer = Defaults::Game::GAME_OVER_DURATION; + void update(Context& ctx, float delta_time) { + ctx.tick_timer -= delta_time; + if (ctx.tick_timer > 0.0F) { return; } - if (!Defaults::Game::INFINITE_CONTINUES) { - ctx.continues_used++; - } - - const uint8_t PRIMARY = P1_START ? 0 : 1; - revivePlayer(ctx, PRIMARY); - // Si ambos pulsan START, revivimos a los dos. - if (P1_START && P2_START) { - revivePlayer(ctx, 1); - } - - // Reanudar partida. - ctx.state = GameOverState::NONE; - ctx.counter = 0; - ctx.tick_timer = 0.0F; - - Audio::get()->playSound(Defaults::Sound::START, Audio::Group::GAME); - return; - } - - // THRUST/SHOOT acelera el countdown manualmente. - const bool ACCEL = input->checkActionPlayer1(InputAction::THRUST, Input::DO_NOT_ALLOW_REPEAT) || - input->checkActionPlayer2(InputAction::THRUST, Input::DO_NOT_ALLOW_REPEAT) || - input->checkActionPlayer1(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT) || - input->checkActionPlayer2(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT); - - if (ACCEL) { ctx.counter--; + ctx.tick_timer = Defaults::Game::CONTINUE_TICK_DURATION; + checkAndApplyTimeout(ctx); + // Solo pita el tick si seguimos en CONTINUE (no transitamos a GAME_OVER) if (ctx.state == GameOverState::CONTINUE) { Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME); } - - ctx.tick_timer = Defaults::Game::CONTINUE_TICK_DURATION; } -} + + void processInput(Context& ctx) { + auto* input = Input::get(); + + const bool P1_START = input->checkActionPlayer1(InputAction::START, Input::DO_NOT_ALLOW_REPEAT); + const bool P2_START = input->checkActionPlayer2(InputAction::START, Input::DO_NOT_ALLOW_REPEAT); + + if (P1_START || P2_START) { + // ¿Quedan continues? + if (!Defaults::Game::INFINITE_CONTINUES && + ctx.continues_used >= Defaults::Game::MAX_CONTINUES) { + ctx.state = GameOverState::GAME_OVER; + ctx.game_over_timer = Defaults::Game::GAME_OVER_DURATION; + return; + } + if (!Defaults::Game::INFINITE_CONTINUES) { + ctx.continues_used++; + } + + const uint8_t PRIMARY = P1_START ? 0 : 1; + revivePlayer(ctx, PRIMARY); + // Si ambos pulsan START, revivimos a los dos. + if (P1_START && P2_START) { + revivePlayer(ctx, 1); + } + + // Reanudar partida. + ctx.state = GameOverState::NONE; + ctx.counter = 0; + ctx.tick_timer = 0.0F; + + Audio::get()->playSound(Defaults::Sound::START, Audio::Group::GAME); + return; + } + + // THRUST/SHOOT acelera el countdown manualmente. + const bool ACCEL = input->checkActionPlayer1(InputAction::THRUST, Input::DO_NOT_ALLOW_REPEAT) || + input->checkActionPlayer2(InputAction::THRUST, Input::DO_NOT_ALLOW_REPEAT) || + input->checkActionPlayer1(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT) || + input->checkActionPlayer2(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT); + + if (ACCEL) { + ctx.counter--; + checkAndApplyTimeout(ctx); + + if (ctx.state == GameOverState::CONTINUE) { + Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME); + } + + ctx.tick_timer = Defaults::Game::CONTINUE_TICK_DURATION; + } + } } // namespace Systems::ContinueScreen diff --git a/source/game/systems/init_hud_animator.cpp b/source/game/systems/init_hud_animator.cpp index 75e81eb..9e2011c 100644 --- a/source/game/systems/init_hud_animator.cpp +++ b/source/game/systems/init_hud_animator.cpp @@ -31,7 +31,7 @@ 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: bajo la zona de juego (sale desde fuera). + // Y inicial: bajo la zone 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}; diff --git a/source/game/systems/init_hud_animator.hpp b/source/game/systems/init_hud_animator.hpp index 668f180..1775816 100644 --- a/source/game/systems/init_hud_animator.hpp +++ b/source/game/systems/init_hud_animator.hpp @@ -4,7 +4,7 @@ // Cubre la animación INIT_HUD del comienzo de cada partida/stage: // 1. Crecimiento de los marcos del PLAYAREA con efecto pincel en 3 fases. // 2. Marcador subiendo desde abajo. -// 3. Naves entrando desde la zona inferior hacia su spawn. +// 3. Naves entrando desde la zone inferior hacia su spawn. // // Todas las funciones son puras (sin estado interno propio). GameScene aporta // el contexto que necesitan: posiciones finales, texto del scoreboard y el @@ -21,29 +21,29 @@ namespace Systems::InitHud { -// Convierte un progreso global 0..1 al sub-progreso de un elemento que solo -// se anima en la ventana [ratio_init, ratio_end]. -// < ratio_init → 0.0 (no empezó) -// > ratio_end → 1.0 (terminó) -// en rango → interpolación lineal 0..1 -[[nodiscard]] auto computeRangeProgress(float global_progress, - float ratio_init, - float ratio_end) -> float; + // Convierte un progreso global 0..1 al sub-progreso de un elemento que solo + // se anima en la ventana [ratio_init, ratio_end]. + // < ratio_init → 0.0 (no empezó) + // > ratio_end → 1.0 (terminó) + // en rango → interpolación lineal 0..1 + [[nodiscard]] auto computeRangeProgress(float global_progress, + float ratio_init, + float ratio_end) -> float; -// Calcula posición Y animada de una nave durante INIT_HUD. La nave sube -// desde 50 px bajo el PLAYAREA hasta `final_position` con easing. -[[nodiscard]] auto computeShipPosition(float progress, const Vec2& final_position) -> Vec2; + // Calcula posición Y animada de una nave durante INIT_HUD. La nave sube + // desde 50 px bajo el PLAYAREA hasta `final_position` con easing. + [[nodiscard]] auto computeShipPosition(float progress, const Vec2& final_position) -> Vec2; -// Dibuja los 4 lados del PLAYAREA con efecto pincel en 3 fases: -// 0..33% → línea superior crece desde el centro hacia los lados. -// 33..66% → líneas verticales bajan por los laterales. -// 66..100% → línea inferior crece desde los lados hacia el centro. -void drawBordersAnimated(Rendering::Renderer* renderer, float progress); + // Dibuja los 4 lados del PLAYAREA con efecto pincel en 3 fases: + // 0..33% → línea superior crece desde el centro hacia los lados. + // 33..66% → líneas verticales bajan por los laterales. + // 66..100% → línea inferior crece desde los lados hacia el centro. + void drawBordersAnimated(Rendering::Renderer* renderer, float progress); -// Dibuja el scoreboard centrado, subiendo desde fuera de la pantalla -// hasta su posición final con easing. -void drawScoreboardAnimated(const Graphics::VectorText& text, - const std::string& scoreboard_text, - float progress); + // Dibuja el scoreboard centrado, subiendo desde fuera de la pantalla + // hasta su posición final con easing. + void drawScoreboardAnimated(const Graphics::VectorText& text, + const std::string& scoreboard_text, + float progress); } // namespace Systems::InitHud