From 6cf990bc1d164629d1b3cefb962e9fcf2d011631 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 19 May 2026 11:10:42 +0200 Subject: [PATCH 01/27] Fase 0: eliminar tot el codi llegacy (polars + primitives + bool dibuixar) Aplicada la directiva "res llegacy" abans d'arrencar la migracio a fisica vectorial + SDL3 GPU. Cada bossa de cruft que arrossegava el port de Pascal queda eliminada. Borrats (huerfanos): - source/core/rendering/primitives.hpp/.cpp (modul/diferencia/angle_punt/ crear_poligon_regular) - source/core/rendering/polygon_renderer.hpp/.cpp (rota_tri/rota_pol) - core::types::Triangle, Poligon, IPunt - Defaults::Entities::MAX_IPUNTS i alias a constants.hpp - EscenaJoc::chatarra_cosmica_ (mai usat) - Bresenham comentat dins de Rendering::linea() Simplificat (parametre 'dibuixar' llegacy que sempre era true): - Rendering::linea(...): treta la signatura bool dibuixar, retorn void - Rendering::render_shape(...): treta la signatura bool dibuixar - 11 callsites de linea() actualitzats (escena_joc, debris_manager) - 12 callsites de render_shape() actualitzats Modernitzats: - 5 fitxers .shp netejats de comentaris polar->cartesia historics - types.hpp queda nomes amb Punt (l'unica coordenada del joc) - debris_manager.hpp afegit include explicit de defaults.hpp Net: 452 linies eliminades, 56 afegides. Compila i enllaca correctament. Co-Authored-By: Claude Opus 4.7 (1M context) --- data/shapes/bullet.shp | 18 +--- data/shapes/enemy_pentagon.shp | 16 +--- data/shapes/enemy_square.shp | 14 +-- data/shapes/ship.shp | 20 +--- data/shapes/ship2.shp | 25 +---- source/core/defaults.hpp | 1 - source/core/graphics/starfield.cpp | 1 - source/core/graphics/vector_text.cpp | 2 +- source/core/rendering/line_renderer.cpp | 102 ++++----------------- source/core/rendering/line_renderer.hpp | 11 ++- source/core/rendering/polygon_renderer.cpp | 86 ----------------- source/core/rendering/polygon_renderer.hpp | 22 ----- source/core/rendering/primitives.cpp | 66 ------------- source/core/rendering/primitives.hpp | 32 ------- source/core/rendering/shape_renderer.cpp | 7 +- source/core/rendering/shape_renderer.hpp | 2 - source/core/types.hpp | 39 +------- source/game/constants.hpp | 3 +- source/game/effects/debris_manager.cpp | 1 - source/game/effects/debris_manager.hpp | 1 + source/game/entities/bala.cpp | 2 +- source/game/entities/enemic.cpp | 2 +- source/game/entities/nau.cpp | 2 +- source/game/escenes/escena_joc.cpp | 20 ++-- source/game/escenes/escena_joc.hpp | 4 +- source/game/escenes/escena_logo.cpp | 2 - source/game/escenes/escena_titol.cpp | 4 - source/game/title/ship_animator.cpp | 1 - 28 files changed, 55 insertions(+), 451 deletions(-) delete mode 100644 source/core/rendering/polygon_renderer.cpp delete mode 100644 source/core/rendering/polygon_renderer.hpp delete mode 100644 source/core/rendering/primitives.cpp delete mode 100644 source/core/rendering/primitives.hpp diff --git a/data/shapes/bullet.shp b/data/shapes/bullet.shp index 1b3a353..ad9d4e2 100644 --- a/data/shapes/bullet.shp +++ b/data/shapes/bullet.shp @@ -1,23 +1,7 @@ -# bullet.shp - Projectil (petit pentàgon) -# © 1999 Visente i Sergi (versió Pascal) -# © 2025 Port a C++20 amb SDL3 +# bullet.shp - Projectil (octàgon, radi=3) name: bullet scale: 1.0 center: 0, 0 -# Cercle (octàgon regular radi=3) -# 8 punts equidistants (45° entre ells) per aproximar un cercle -# Començant a angle=-90° (amunt), rotant sentit horari -# -# Conversió polar→cartesià (radi=3, SDL: Y creix cap avall): -# angle=-90°: (0.00, -3.00) -# angle=-45°: (2.12, -2.12) -# angle=0°: (3.00, 0.00) -# angle=45°: (2.12, 2.12) -# angle=90°: (0.00, 3.00) -# angle=135°: (-2.12, 2.12) -# angle=180°: (-3.00, 0.00) -# angle=225°: (-2.12, -2.12) - polyline: 0,-3 2.12,-2.12 3,0 2.12,2.12 0,3 -2.12,2.12 -3,0 -2.12,-2.12 0,-3 diff --git a/data/shapes/enemy_pentagon.shp b/data/shapes/enemy_pentagon.shp index 8771dc2..23c84c9 100644 --- a/data/shapes/enemy_pentagon.shp +++ b/data/shapes/enemy_pentagon.shp @@ -1,21 +1,7 @@ -# enemy_pentagon.shp - ORNI enemic (pentàgon regular) -# © 1999 Visente i Sergi (versió Pascal) -# © 2025 Port a C++20 amb SDL3 +# enemy_pentagon.shp - ORNI enemic (pentàgon regular, radi=20) name: enemy_pentagon scale: 1.0 center: 0, 0 -# Pentàgon regular radi=20 -# 5 punts equidistants al voltant d'un cercle (72° entre ells) -# Començant a angle=-90° (amunt), rotant sentit antihorari -# -# Angles: -90°, -18°, 54°, 126°, 198° -# Conversió polar→cartesià (SDL: Y creix cap avall): -# angle=-90°: (0.00, -20.00) -# angle=-18°: (19.02, -6.18) -# angle=54°: (11.76, 16.18) -# angle=126°: (-11.76, 16.18) -# angle=198°: (-19.02, -6.18) - polyline: 0,-20 19.02,-6.18 11.76,16.18 -11.76,16.18 -19.02,-6.18 0,-20 diff --git a/data/shapes/enemy_square.shp b/data/shapes/enemy_square.shp index 2d6f16c..3c17405 100644 --- a/data/shapes/enemy_square.shp +++ b/data/shapes/enemy_square.shp @@ -1,19 +1,7 @@ -# enemy_square.shp - ORNI enemic (quadrat regular) -# © 2025 Port a C++20 amb SDL3 +# enemy_square.shp - ORNI enemic (quadrat regular, radi=20) name: enemy_square scale: 1.0 center: 0, 0 -# Quadrat regular radi=20 (circumscrit) -# 4 punts equidistants al voltant d'un cercle (90° entre ells) -# Començant a angle=-90° (amunt), rotant sentit horari -# -# Angles: -90°, 0°, 90°, 180° -# Conversió polar→cartesià (SDL: Y creix cap avall): -# angle=-90°: (0.00, -20.00) -# angle=0°: (20.00, 0.00) -# angle=90°: (0.00, 20.00) -# angle=180°: (-20.00, 0.00) - polyline: 0,-20 20,0 0,20 -20,0 0,-20 diff --git a/data/shapes/ship.shp b/data/shapes/ship.shp index f4f683e..aebcbe7 100644 --- a/data/shapes/ship.shp +++ b/data/shapes/ship.shp @@ -1,24 +1,8 @@ -# ship.shp - Nau del jugador 1 (triangle amb base còncava - punta de fletxa) -# © 1999 Visente i Sergi (versió Pascal) -# © 2025 Port a C++20 amb SDL3 +# ship.shp - Nau del jugador 1 +# Triangle amb base còncava (punta de fletxa) name: ship scale: 1.0 center: 0, 0 -# Triangle amb base còncava tipus "punta de fletxa" -# Punts originals (polar): -# p1: r=12, angle=270° (3π/2) → punta amunt -# p2: r=12, angle=45° (π/4) → base dreta-darrere -# p3: r=12, angle=135° (3π/4) → base esquerra-darrere -# -# MODIFICACIÓ: afegit p4 al mig de la base, desplaçat cap al centre -# p4: (0, 4) → punt central de la base, cap endins -# -# Conversió polar→cartesià (angle-90° perquè origen visual és amunt): -# p1: (0, -12) → punta -# p2: (8.49, 8.49) → base dreta -# p4: (0, 4) → base centre (cap endins) -# p3: (-8.49, 8.49) → base esquerra - polyline: 0,-12 8.49,8.49 0,4 -8.49,8.49 0,-12 diff --git a/data/shapes/ship2.shp b/data/shapes/ship2.shp index 9d6280c..4bf35d3 100644 --- a/data/shapes/ship2.shp +++ b/data/shapes/ship2.shp @@ -1,30 +1,11 @@ -# ship2.shp - Nau del jugador 2 (triangle amb circulito central) -# © 1999 Visente i Sergi (versió Pascal) -# © 2025 Port a C++20 amb SDL3 +# ship2.shp - Nau del jugador 2 +# Triangle amb cercle central (distintiu visual) name: ship2 scale: 1.0 center: 0, 0 -# Triangle amb base còncava tipus "punta de fletxa" -# (Mateix que ship.shp) -# Punts originals (polar): -# p1: r=12, angle=270° (3π/2) → punta amunt -# p2: r=12, angle=45° (π/4) → base dreta-darrere -# p3: r=12, angle=135° (3π/4) → base esquerra-darrere -# -# MODIFICACIÓ: afegit p4 al mig de la base, desplaçat cap al centre -# p4: (0, 4) → punt central de la base, cap endins -# -# Conversió polar→cartesià (angle-90° perquè origen visual és amunt): -# p1: (0, -12) → punta -# p2: (8.49, 8.49) → base dreta -# p4: (0, 4) → base centre (cap endins) -# p3: (-8.49, 8.49) → base esquerra - -#polyline: 0,-12 8.49,8.49 0,4 -8.49,8.49 0,-12 polyline: 0,-12 8.49,8.49 -8.49,8.49 0,-12 -# Circulito central (octàgon r=2.5) -# Distintiu visual del jugador 2 +# Octàgon central (radi=2.5) polyline: 0,-2.5 1.77,-1.77 2.5,0 1.77,1.77 0,2.5 -1.77,1.77 -2.5,0 -1.77,-1.77 0,-2.5 diff --git a/source/core/defaults.hpp b/source/core/defaults.hpp index 7f04d7a..361cad4 100644 --- a/source/core/defaults.hpp +++ b/source/core/defaults.hpp @@ -101,7 +101,6 @@ constexpr float SCOREBOARD_PADDING_H = 0.0F; // Game::WIDTH * 0.015f; namespace Entities { constexpr int MAX_ORNIS = 15; constexpr int MAX_BALES = 3; -constexpr int MAX_IPUNTS = 30; constexpr float SHIP_RADIUS = 12.0F; constexpr float ENEMY_RADIUS = 20.0F; diff --git a/source/core/graphics/starfield.cpp b/source/core/graphics/starfield.cpp index 945171f..34ac8c9 100644 --- a/source/core/graphics/starfield.cpp +++ b/source/core/graphics/starfield.cpp @@ -162,7 +162,6 @@ void Starfield::dibuixar() { estrella.posicio, 0.0F, // angle (les estrelles no giren) escala, // escala dinàmica - true, // dibuixar 1.0F, // progress (sempre visible) brightness // brightness dinàmica ); diff --git a/source/core/graphics/vector_text.cpp b/source/core/graphics/vector_text.cpp index 80ce303..7ac60b0 100644 --- a/source/core/graphics/vector_text.cpp +++ b/source/core/graphics/vector_text.cpp @@ -224,7 +224,7 @@ void VectorText::render(const std::string& text, const Punt& posicio, float esca // Ajustar X e Y para que posicio represente esquina superior izquierda // (render_shape espera el centro, así que sumamos la mitad de ancho y altura) Punt char_pos = {.x = current_x + (char_width_scaled / 2.0F), .y = posicio.y + (char_height_scaled / 2.0F)}; - Rendering::render_shape(renderer_, it->second, char_pos, 0.0F, escala, true, 1.0F, brightness); + Rendering::render_shape(renderer_, it->second, char_pos, 0.0F, escala, 1.0F, brightness); // Avanzar posición current_x += char_width_scaled + spacing_scaled; diff --git a/source/core/rendering/line_renderer.cpp b/source/core/rendering/line_renderer.cpp index c387288..956e499 100644 --- a/source/core/rendering/line_renderer.cpp +++ b/source/core/rendering/line_renderer.cpp @@ -4,99 +4,35 @@ #include "core/rendering/line_renderer.hpp" -#include - #include "core/rendering/coordinate_transform.hpp" namespace Rendering { -// [NUEVO] Color global compartit (actualitzat per ColorOscillator via -// SDLManager) -SDL_Color g_current_line_color = {255, 255, 255, 255}; // Blanc inicial +// Color global compartit (actualitzat per ColorOscillator via SDLManager) +SDL_Color g_current_line_color = {255, 255, 255, 255}; -bool linea(SDL_Renderer* renderer, int x1, int y1, int x2, int y2, bool dibuixar, float brightness) { - // Algorisme de Bresenham per dibuixar línies - // Basat en el codi Pascal original - - // Helper function: retorna el signe d'un nombre - auto sign = [](int x) -> int { - if (x < 0) { - return -1; - } - if (x > 0) { - return 1; - } - return 0; - }; - - // Variables per a l'algorisme (no utilitzades fins Fase 10 - detecció de - // col·lisions) int x = x1, y = y1; int xs = x2 - x1; int ys = y2 - y1; int - // xm = sign(xs); int ym = sign(ys); xs = std::abs(xs); ys = std::abs(ys); - - // Suprimir warning de variable no usada - (void)sign; - - // Detecció de col·lisió (TODO per Fase 10) - // El codi Pascal original llegia pixels del framebuffer bit-packed - // i comptava col·lisions. Per ara, usem SDL_RenderDrawLine i retornem false. - bool colisio = false; - - // Dibuixar amb SDL3 (més eficient que Bresenham píxel a píxel) - if (dibuixar && (renderer != nullptr)) { - // Transformar coordenades lògiques (640x480) a físiques (resolució real) - float scale = g_current_scale_factor; - int px1 = transform_x(x1, scale); - int py1 = transform_y(y1, scale); - int px2 = transform_x(x2, scale); - int py2 = transform_y(y2, scale); - - // Aplicar brightness al color oscil·lat global - SDL_Color color_final; - color_final.r = static_cast(g_current_line_color.r * brightness); - color_final.g = static_cast(g_current_line_color.g * brightness); - color_final.b = static_cast(g_current_line_color.b * brightness); - color_final.a = 255; - - SDL_SetRenderDrawColor(renderer, color_final.r, color_final.g, color_final.b, 255); - - // Renderitzar amb coordenades físiques - SDL_RenderLine(renderer, static_cast(px1), static_cast(py1), static_cast(px2), static_cast(py2)); +void linea(SDL_Renderer* renderer, int x1, int y1, int x2, int y2, float brightness) { + if (renderer == nullptr) { + return; } - // Algorisme de Bresenham original (conservat per a futura detecció de - // col·lisió) - /* - if (xs > ys) { - // Línia plana (<45 graus) - int count = -(xs / 2); - while (x != x2) { - count = count + ys; - x = x + xm; - if (count > 0) { - y = y + ym; - count = count - xs; - } - // Aquí aniria la detecció de col·lisió píxel a píxel - } - } else { - // Línia pronunciada (>=45 graus) - int count = -(ys / 2); - while (y != y2) { - count = count + xs; - y = y + ym; - if (count > 0) { - x = x + xm; - count = count - ys; - } - // Aquí aniria la detecció de col·lisió píxel a píxel - } - } - */ + // Transformar coordenades lògiques (640x480) a físiques (resolució real) + const float SCALE = g_current_scale_factor; + const int PX1 = transform_x(x1, SCALE); + const int PY1 = transform_y(y1, SCALE); + const int PX2 = transform_x(x2, SCALE); + const int PY2 = transform_y(y2, SCALE); - return colisio; + // Aplicar brightness al color oscil·lat global + const auto R = static_cast(g_current_line_color.r * brightness); + const auto G = static_cast(g_current_line_color.g * brightness); + const auto B = static_cast(g_current_line_color.b * brightness); + + SDL_SetRenderDrawColor(renderer, R, G, B, 255); + SDL_RenderLine(renderer, static_cast(PX1), static_cast(PY1), + static_cast(PX2), static_cast(PY2)); } -// [NUEVO] Establir el color global de les línies void setLineColor(SDL_Color color) { g_current_line_color = color; } } // namespace Rendering diff --git a/source/core/rendering/line_renderer.hpp b/source/core/rendering/line_renderer.hpp index cf154a0..5fba73c 100644 --- a/source/core/rendering/line_renderer.hpp +++ b/source/core/rendering/line_renderer.hpp @@ -6,11 +6,12 @@ #include namespace Rendering { -// Algorisme de Bresenham per dibuixar línies -// Retorna true si hi ha col·lisió (per Fase 10) -// brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor) -bool linea(SDL_Renderer* renderer, int x1, int y1, int x2, int y2, bool dibuixar, float brightness = 1.0F); -// [NUEVO] Establir el color global de les línies (oscil·lació) +// Dibuixa una línia entre dos punts en coordenades lògiques (640x480). +// brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor). +void linea(SDL_Renderer* renderer, int x1, int y1, int x2, int y2, float brightness = 1.0F); + +// Estableix el color global de les línies (utilitzat per ColorOscillator). void setLineColor(SDL_Color color); + } // namespace Rendering diff --git a/source/core/rendering/polygon_renderer.cpp b/source/core/rendering/polygon_renderer.cpp deleted file mode 100644 index f4ca471..0000000 --- a/source/core/rendering/polygon_renderer.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// polygon_renderer.cpp - Implementació de renderitzat de polígons -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 -// -// ============================================================================== -// DEPRECATED: Use core/rendering/shape_renderer.cpp instead -// ============================================================================== - -#include "core/rendering/polygon_renderer.hpp" - -#include -#include - -#include "core/defaults.hpp" -#include "core/rendering/line_renderer.hpp" - -namespace Rendering { - -void rota_tri(SDL_Renderer* renderer, const Triangle& tri, float angul, float velocitat, bool dibuixar) { - // Rotar i dibuixar triangle (nau) - // Conversió de coordenades polars a cartesianes amb rotació - // Basat en el codi Pascal original: lines 271-284 - - // Convertir cada punt polar a cartesià - // x = (r + velocitat) * cos(angle_punt + angle_nau) + centre.x - // y = (r + velocitat) * sin(angle_punt + angle_nau) + centre.y - - int x1 = static_cast(std::round((tri.p1.r + velocitat) * - std::cos(tri.p1.angle + angul))) + - tri.centre.x; - - int y1 = static_cast(std::round((tri.p1.r + velocitat) * - std::sin(tri.p1.angle + angul))) + - tri.centre.y; - - int x2 = static_cast(std::round((tri.p2.r + velocitat) * - std::cos(tri.p2.angle + angul))) + - tri.centre.x; - - int y2 = static_cast(std::round((tri.p2.r + velocitat) * - std::sin(tri.p2.angle + angul))) + - tri.centre.y; - - int x3 = static_cast(std::round((tri.p3.r + velocitat) * - std::cos(tri.p3.angle + angul))) + - tri.centre.x; - - int y3 = static_cast(std::round((tri.p3.r + velocitat) * - std::sin(tri.p3.angle + angul))) + - tri.centre.y; - - // Dibuixar les 3 línies que formen el triangle - linea(renderer, x1, y1, x2, y2, dibuixar); - linea(renderer, x1, y1, x3, y3, dibuixar); - linea(renderer, x3, y3, x2, y2, dibuixar); -} - -void rota_pol(SDL_Renderer* renderer, const Poligon& pol, float angul, bool dibuixar) { - // Rotar i dibuixar polígon (enemics i bales) - // Conversió de coordenades polars a cartesianes amb rotació - // Basat en el codi Pascal original: lines 286-296 - - // Array temporal per emmagatzemar punts convertits a cartesianes - std::array xy; - - // Convertir cada punt polar a cartesià - for (uint8_t i = 0; i < pol.n; i++) { - xy[i].x = static_cast(std::round( - pol.ipuntx[i].r * std::cos(pol.ipuntx[i].angle + angul))) + - pol.centre.x; - - xy[i].y = static_cast(std::round( - pol.ipuntx[i].r * std::sin(pol.ipuntx[i].angle + angul))) + - pol.centre.y; - } - - // Dibuixar línies entre punts consecutius - for (uint8_t i = 0; i < pol.n - 1; i++) { - linea(renderer, xy[i].x, xy[i].y, xy[i + 1].x, xy[i + 1].y, dibuixar); - } - - // Tancar el polígon (últim punt → primer punt) - linea(renderer, xy[pol.n - 1].x, xy[pol.n - 1].y, xy[0].x, xy[0].y, dibuixar); -} - -} // namespace Rendering diff --git a/source/core/rendering/polygon_renderer.hpp b/source/core/rendering/polygon_renderer.hpp deleted file mode 100644 index 703a25a..0000000 --- a/source/core/rendering/polygon_renderer.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// polygon_renderer.hpp - Renderitzat de polígons polars -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 -// -// ============================================================================== -// DEPRECATED: Use core/rendering/shape_renderer.hpp instead -// ============================================================================== -// This file is kept temporarily for chatarra_cosmica_ (Phase 10: explosions) -// TODO Phase 10: Replace with particle system or remove completely - -#pragma once -#include - -#include "core/types.hpp" - -namespace Rendering { -// Rotar i dibuixar triangle (nau) -void rota_tri(SDL_Renderer* renderer, const Triangle& tri, float angul, float velocitat, bool dibuixar); - -// Rotar i dibuixar polígon (enemics i bales) -void rota_pol(SDL_Renderer* renderer, const Poligon& pol, float angul, bool dibuixar); -} // namespace Rendering diff --git a/source/core/rendering/primitives.cpp b/source/core/rendering/primitives.cpp deleted file mode 100644 index dd19167..0000000 --- a/source/core/rendering/primitives.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// primitives.cpp - Implementació de funcions geomètriques -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 -// -// ============================================================================== -// DEPRECATED: Use Shape system instead (.shp files + ShapeLoader) -// ============================================================================== - -#include "primitives.hpp" - -#include - -#include "core/defaults.hpp" - -float modul(const Punt& p) { - // Càlcul de la magnitud d'un vector: sqrt(x² + y²) - return std::sqrt((p.x * p.x) + (p.y * p.y)); -} - -void diferencia(const Punt& o, const Punt& d, Punt& p) { - // Resta de vectors (origen - destí) - p.x = o.x - d.x; - p.y = o.y - d.y; -} - -int distancia(const Punt& o, const Punt& d) { - // Distància entre dos punts - Punt p; - diferencia(o, d, p); - return static_cast(std::round(modul(p))); -} - -float angle_punt(const Punt& p) { - // Càlcul de l'angle d'un punt (arctan) - if (p.y != 0) { - return std::atan(p.x / p.y); - } - return 0.0F; -} - -void crear_poligon_regular(Poligon& pol, uint8_t n, float r) { - // Crear un polígon regular amb n costats i radi r - // Distribueix els punts uniformement al voltant d'un cercle - - float interval = 2.0F * Defaults::Math::PI / n; - float act = 0.0F; - - for (uint8_t i = 0; i < n; i++) { - pol.ipuntx[i].r = r; - pol.ipuntx[i].angle = act; - act += interval; - } - - // Inicialitzar propietats del polígon - pol.centre.x = 320.0F; - pol.centre.y = 200.0F; - pol.angle = 0.0F; - // Convertir velocitat de px/frame a px/s: 2 px/frame × 20 FPS = 40 px/s - pol.velocitat = Defaults::Physics::ENEMY_SPEED * 20.0F; - pol.n = n; - // Convertir rotació de rad/frame a rad/s: 0.0785 rad/frame × 20 FPS = 1.57 - // rad/s (~90°/s) - pol.drotacio = 0.078539816F * 20.0F; - pol.rotacio = 0.0F; - pol.esta = true; -} diff --git a/source/core/rendering/primitives.hpp b/source/core/rendering/primitives.hpp deleted file mode 100644 index e97acb3..0000000 --- a/source/core/rendering/primitives.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// primitives.hpp - Funcions geomètriques bàsiques -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 -// -// ============================================================================== -// DEPRECATED: Use Shape system instead (.shp files + ShapeLoader) -// ============================================================================== -// This file is kept temporarily for chatarra_cosmica_ (Phase 10: explosions) -// TODO Phase 10: Replace with particle system or remove completely - -#pragma once - -#include - -#include "core/types.hpp" - -// Funcions matemàtiques geomètriques pures (sense dependències d'estat) - -// Càlcul de la magnitud d'un vector -float modul(const Punt& p); - -// Diferència entre dos punts (vector origen - destí) -void diferencia(const Punt& o, const Punt& d, Punt& p); - -// Distància entre dos punts -int distancia(const Punt& o, const Punt& d); - -// Càlcul de l'angle d'un punt -float angle_punt(const Punt& p); - -// Creació de polígons regulars -void crear_poligon_regular(Poligon& pol, uint8_t n, float r); diff --git a/source/core/rendering/shape_renderer.cpp b/source/core/rendering/shape_renderer.cpp index 5aec16b..bd8b3ad 100644 --- a/source/core/rendering/shape_renderer.cpp +++ b/source/core/rendering/shape_renderer.cpp @@ -77,7 +77,6 @@ void render_shape(SDL_Renderer* renderer, const Punt& posicio, float angle, float escala, - bool dibuixar, float progress, float brightness, const Rotation3D* rotation_3d) { @@ -102,7 +101,8 @@ void render_shape(SDL_Renderer* renderer, Punt p1 = transform_point(primitive.points[i], shape_centre, posicio, angle, escala, rotation_3d); Punt p2 = transform_point(primitive.points[i + 1], shape_centre, posicio, angle, escala, rotation_3d); - linea(renderer, static_cast(p1.x), static_cast(p1.y), static_cast(p2.x), static_cast(p2.y), dibuixar, brightness); + linea(renderer, static_cast(p1.x), static_cast(p1.y), + static_cast(p2.x), static_cast(p2.y), brightness); } } else { // PrimitiveType::LINE // LINE: exactament 2 punts @@ -110,7 +110,8 @@ void render_shape(SDL_Renderer* renderer, Punt p1 = transform_point(primitive.points[0], shape_centre, posicio, angle, escala, rotation_3d); Punt p2 = transform_point(primitive.points[1], shape_centre, posicio, angle, escala, rotation_3d); - linea(renderer, static_cast(p1.x), static_cast(p1.y), static_cast(p2.x), static_cast(p2.y), dibuixar, brightness); + linea(renderer, static_cast(p1.x), static_cast(p1.y), + static_cast(p2.x), static_cast(p2.y), brightness); } } } diff --git a/source/core/rendering/shape_renderer.hpp b/source/core/rendering/shape_renderer.hpp index 2eba582..c289f8d 100644 --- a/source/core/rendering/shape_renderer.hpp +++ b/source/core/rendering/shape_renderer.hpp @@ -38,7 +38,6 @@ struct Rotation3D { // - posicio: posició del centre en coordenades mundials // - angle: rotació en radians (0 = amunt, sentit horari) // - escala: factor d'escala (1.0 = mida original) -// - dibuixar: flag per dibuixar (false per col·lisions futures) // - progress: progrés de l'animació (0.0-1.0, default 1.0 = tot visible) // - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor) void render_shape(SDL_Renderer* renderer, @@ -46,7 +45,6 @@ void render_shape(SDL_Renderer* renderer, const Punt& posicio, float angle, float escala = 1.0F, - bool dibuixar = true, float progress = 1.0F, float brightness = 1.0F, const Rotation3D* rotation_3d = nullptr); diff --git a/source/core/types.hpp b/source/core/types.hpp index 1c75a3e..09698ee 100644 --- a/source/core/types.hpp +++ b/source/core/types.hpp @@ -1,43 +1,6 @@ #pragma once -#include -#include - -#include "core/defaults.hpp" - -// Punt polar (coordenades polars) -struct IPunt { - float r; // Radi - float angle; // Angle en radians -}; - -// Punt cartesià +// Punt cartesià - ÚNICA estructura de coordenades del joc struct Punt { float x, y; }; - -// ============================================================================== -// DEPRECATED: Legacy types (replaced by Shape system) -// ============================================================================== -// These types are kept temporarily for chatarra_cosmica_ (Phase 10: explosions) -// TODO Phase 10: Replace with particle system or remove completely - -// Nau (triangle) - DEPRECATED: Now using Shape system (ship.shp) -struct Triangle { - IPunt p1, p2, p3; - Punt centre; - float angle; - float velocitat; -}; - -// Polígon (enemics i bales) - DEPRECATED: Now using Shape system (.shp files) -struct Poligon { - std::array ipuntx; - Punt centre; - float angle; - float velocitat; - uint8_t n; - float drotacio; - float rotacio; - bool esta; -}; diff --git a/source/game/constants.hpp b/source/game/constants.hpp index 5b70523..c0d8c65 100644 --- a/source/game/constants.hpp +++ b/source/game/constants.hpp @@ -14,8 +14,7 @@ constexpr int MARGE_DALT = static_cast(Defaults::Zones::PLAYAREA.y); constexpr int MARGE_BAIX = static_cast(Defaults::Zones::PLAYAREA.y + Defaults::Zones::PLAYAREA.h); -// Límits de polígons i objectes -constexpr int MAX_IPUNTS = Defaults::Entities::MAX_IPUNTS; +// Límits d'objectes constexpr int MAX_ORNIS = Defaults::Entities::MAX_ORNIS; constexpr int MAX_BALES = Defaults::Entities::MAX_BALES; diff --git a/source/game/effects/debris_manager.cpp b/source/game/effects/debris_manager.cpp index 273d84b..97c2622 100644 --- a/source/game/effects/debris_manager.cpp +++ b/source/game/effects/debris_manager.cpp @@ -314,7 +314,6 @@ void DebrisManager::dibuixar() const { static_cast(debris.p1.y), static_cast(debris.p2.x), static_cast(debris.p2.y), - true, debris.brightness); } } diff --git a/source/game/effects/debris_manager.hpp b/source/game/effects/debris_manager.hpp index 147a49b..6dc7cc5 100644 --- a/source/game/effects/debris_manager.hpp +++ b/source/game/effects/debris_manager.hpp @@ -7,6 +7,7 @@ #include #include +#include "core/defaults.hpp" #include "core/graphics/shape.hpp" #include "core/types.hpp" #include "debris.hpp" diff --git a/source/game/entities/bala.cpp b/source/game/entities/bala.cpp index 17794cd..208ee4a 100644 --- a/source/game/entities/bala.cpp +++ b/source/game/entities/bala.cpp @@ -87,7 +87,7 @@ void Bala::dibuixar() const { if (esta_ && forma_) { // [NUEVO] Usar render_shape en lloc de rota_pol // Les bales roten segons l'angle de trajectòria - Rendering::render_shape(renderer_, forma_, centre_, angle_, 1.0F, true, 1.0F, brightness_); + Rendering::render_shape(renderer_, forma_, centre_, angle_, 1.0F, 1.0F, brightness_); } } diff --git a/source/game/entities/enemic.cpp b/source/game/entities/enemic.cpp index 022f688..98f3dcc 100644 --- a/source/game/entities/enemic.cpp +++ b/source/game/entities/enemic.cpp @@ -185,7 +185,7 @@ void Enemic::dibuixar() const { float escala = calcular_escala_actual(); // brightness_ is already updated in actualitzar() - Rendering::render_shape(renderer_, forma_, centre_, rotacio_, escala, true, 1.0F, brightness_); + Rendering::render_shape(renderer_, forma_, centre_, rotacio_, escala, 1.0F, brightness_); } } diff --git a/source/game/entities/nau.cpp b/source/game/entities/nau.cpp index de97759..bb8ee34 100644 --- a/source/game/entities/nau.cpp +++ b/source/game/entities/nau.cpp @@ -167,7 +167,7 @@ void Nau::dibuixar() const { float velocitat_visual = velocitat_ / 33.33F; float escala = 1.0F + (velocitat_visual / 12.0F); - Rendering::render_shape(renderer_, forma_, centre_, angle_, escala, true, 1.0F, brightness_); + Rendering::render_shape(renderer_, forma_, centre_, angle_, escala, 1.0F, brightness_); } void Nau::aplicar_fisica(float delta_time) { diff --git a/source/game/escenes/escena_joc.cpp b/source/game/escenes/escena_joc.cpp index be6d3a3..f59d2dc 100644 --- a/source/game/escenes/escena_joc.cpp +++ b/source/game/escenes/escena_joc.cpp @@ -745,10 +745,10 @@ void EscenaJoc::dibuixar_marges() const { int y2 = static_cast(zona.y + zona.h); // 4 línies per formar el rectangle - Rendering::linea(sdl_.obte_renderer(), x1, y1, x2, y1, true); // Top - Rendering::linea(sdl_.obte_renderer(), x1, y2, x2, y2, true); // Bottom - Rendering::linea(sdl_.obte_renderer(), x1, y1, x1, y2, true); // Left - Rendering::linea(sdl_.obte_renderer(), x2, y1, x2, y2, true); // Right + Rendering::linea(sdl_.obte_renderer(), x1, y1, x2, y1); // Top + Rendering::linea(sdl_.obte_renderer(), x1, y2, x2, y2); // Bottom + Rendering::linea(sdl_.obte_renderer(), x1, y1, x1, y2); // Left + Rendering::linea(sdl_.obte_renderer(), x2, y1, x2, y2); // Right } void EscenaJoc::dibuixar_marcador() { @@ -794,11 +794,11 @@ void EscenaJoc::dibuixar_marges_animat(float progress) const { // Línia esquerra: creix des del centre cap a l'esquerra int x1_phase1 = static_cast(cx - ((cx - x1) * phase1_progress)); - Rendering::linea(sdl_.obte_renderer(), cx, y1, x1_phase1, y1, true); + Rendering::linea(sdl_.obte_renderer(), cx, y1, x1_phase1, y1); // Línia dreta: creix des del centre cap a la dreta int x2_phase1 = static_cast(cx + ((x2 - cx) * phase1_progress)); - Rendering::linea(sdl_.obte_renderer(), cx, y1, x2_phase1, y1, true); + Rendering::linea(sdl_.obte_renderer(), cx, y1, x2_phase1, y1); } // --- FASE 2: Línies verticals laterals (33-66%) --- @@ -807,10 +807,10 @@ void EscenaJoc::dibuixar_marges_animat(float progress) const { // Línia esquerra: creix des de dalt cap a baix int y2_phase2 = static_cast(y1 + ((y2 - y1) * phase2_progress)); - Rendering::linea(sdl_.obte_renderer(), x1, y1, x1, y2_phase2, true); + Rendering::linea(sdl_.obte_renderer(), x1, y1, x1, y2_phase2); // Línia dreta: creix des de dalt cap a baix - Rendering::linea(sdl_.obte_renderer(), x2, y1, x2, y2_phase2, true); + Rendering::linea(sdl_.obte_renderer(), x2, y1, x2, y2_phase2); } // --- FASE 3: Línies horitzontals inferiors (66-100%) --- @@ -819,11 +819,11 @@ void EscenaJoc::dibuixar_marges_animat(float progress) const { // Línia esquerra: creix des de l'esquerra cap al centre int x_left_phase3 = static_cast(x1 + ((cx - x1) * phase3_progress)); - Rendering::linea(sdl_.obte_renderer(), x1, y2, x_left_phase3, y2, true); + Rendering::linea(sdl_.obte_renderer(), x1, y2, x_left_phase3, y2); // Línia dreta: creix des de la dreta cap al centre int x_right_phase3 = static_cast(x2 - ((x2 - cx) * phase3_progress)); - Rendering::linea(sdl_.obte_renderer(), x2, y2, x_right_phase3, y2, true); + Rendering::linea(sdl_.obte_renderer(), x2, y2, x_right_phase3, y2); } } diff --git a/source/game/escenes/escena_joc.hpp b/source/game/escenes/escena_joc.hpp index b9d6be3..0894328 100644 --- a/source/game/escenes/escena_joc.hpp +++ b/source/game/escenes/escena_joc.hpp @@ -55,7 +55,6 @@ class EscenaJoc { std::array naus_; // [0]=P1, [1]=P2 std::array orni_; std::array bales_; // 6 balas: P1=[0,1,2], P2=[3,4,5] - Poligon chatarra_cosmica_; std::array itocado_per_jugador_; // Death timers per player (seconds) // Lives and game over system @@ -65,8 +64,7 @@ class EscenaJoc { float continue_tick_timer_; // Timer for countdown tick (1.0s) int continues_usados_; // Continues used this game (0-3 max) float game_over_timer_; // Final GAME OVER timer before title screen - // Punt punt_spawn_; // DEPRECATED: usar obtenir_punt_spawn(player_id) - Punt punt_mort_; // Death position (for respawn, legacy) + Punt punt_mort_; // Death position (for respawn) std::array puntuacio_per_jugador_; // [0]=P1, [1]=P2 // Text vectorial diff --git a/source/game/escenes/escena_logo.cpp b/source/game/escenes/escena_logo.cpp index 30f7b7f..96453d2 100644 --- a/source/game/escenes/escena_logo.cpp +++ b/source/game/escenes/escena_logo.cpp @@ -379,7 +379,6 @@ void EscenaLogo::dibuixar() { pos_actual, 0.0F, escala_actual, - true, 1.0F); } } @@ -403,7 +402,6 @@ void EscenaLogo::dibuixar() { lletra.posicio, 0.0F, ESCALA_FINAL, - true, 1.0F); } } diff --git a/source/game/escenes/escena_titol.cpp b/source/game/escenes/escena_titol.cpp index 2e7d123..0e1de2a 100644 --- a/source/game/escenes/escena_titol.cpp +++ b/source/game/escenes/escena_titol.cpp @@ -593,7 +593,6 @@ void EscenaTitol::dibuixar() { pos_shadow, 0.0F, Defaults::Title::Layout::LOGO_SCALE, - true, 1.0F, // progress = 1.0 (totalment visible) SHADOW_BRIGHTNESS // brightness = 0.4 (brillantor reduïda) ); @@ -611,7 +610,6 @@ void EscenaTitol::dibuixar() { pos_shadow, 0.0F, Defaults::Title::Layout::LOGO_SCALE, - true, 1.0F, // progress = 1.0 (totalment visible) SHADOW_BRIGHTNESS); } @@ -627,7 +625,6 @@ void EscenaTitol::dibuixar() { lletra.posicio, 0.0F, Defaults::Title::Layout::LOGO_SCALE, - true, 1.0F // Brillantor completa ); } @@ -640,7 +637,6 @@ void EscenaTitol::dibuixar() { lletra.posicio, 0.0F, Defaults::Title::Layout::LOGO_SCALE, - true, 1.0F // Brillantor completa ); } diff --git a/source/game/title/ship_animator.cpp b/source/game/title/ship_animator.cpp index 4cdc770..bcc5c51 100644 --- a/source/game/title/ship_animator.cpp +++ b/source/game/title/ship_animator.cpp @@ -67,7 +67,6 @@ void ShipAnimator::dibuixar() const { nau.posicio_actual, 0.0F, // angle (rotació 2D no utilitzada) nau.escala_actual, - true, // dibuixar 1.0F, // progress (sempre visible) 1.0F // brightness (brillantor màxima) ); From cd38101f99d9e34d7675a12aa504c0bce0ff20f1 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 19 May 2026 11:33:27 +0200 Subject: [PATCH 02/27] Fase 1a: Punt -> Vec2 amb operadors moderns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Primera sub-fase del naming sweep. Punt era un struct sense operacions, conservat per compatibilitat amb el Pascal original. Substituit per Vec2, un aggregate amb operadors aritmetics, dot, length, normalized i length_squared (camelBack: lengthSquared) seguint les regles del .clang-tidy del projecte. Canvis: - core/types.hpp reescrit: nou struct Vec2 amb +=,-=,*=,/=, unary -, ==, dot, length, lengthSquared, normalized - Operadors fora de la classe: +, -, *, / (amb float per ambdues bandes), - unari, == - Vec2 segueix sent aggregate (sense constructors definits): els 'designated initializers' del codi existent funcionen igual: Vec2{.x = ..., .y = ...} - Sed global sobre 35 fitxers: tots els 'Punt' -> 'Vec2' Net: 35 fitxers tocats, +180 / -114. Compila i enllaça. Co-Authored-By: Claude Opus 4.7 (1M context) --- source/core/defaults.hpp | 2 +- source/core/entities/entitat.hpp | 4 +- source/core/graphics/shape.cpp | 4 +- source/core/graphics/shape.hpp | 8 +-- source/core/graphics/starfield.cpp | 2 +- source/core/graphics/starfield.hpp | 8 +-- source/core/graphics/vector_text.cpp | 8 +-- source/core/graphics/vector_text.hpp | 4 +- source/core/physics/collision.hpp | 4 +- source/core/rendering/shape_renderer.cpp | 18 ++--- source/core/rendering/shape_renderer.hpp | 2 +- source/core/types.hpp | 72 ++++++++++++++++++- source/game/effects/debris.hpp | 6 +- source/game/effects/debris_manager.cpp | 24 +++---- source/game/effects/debris_manager.hpp | 6 +- .../game/effects/gestor_puntuacio_flotant.cpp | 2 +- .../game/effects/gestor_puntuacio_flotant.hpp | 2 +- source/game/effects/puntuacio_flotant.hpp | 4 +- source/game/entities/bala.cpp | 2 +- source/game/entities/bala.hpp | 2 +- source/game/entities/enemic.cpp | 4 +- source/game/entities/enemic.hpp | 10 +-- source/game/entities/nau.cpp | 2 +- source/game/entities/nau.hpp | 6 +- source/game/escenes/escena_joc.cpp | 36 +++++----- source/game/escenes/escena_joc.hpp | 6 +- source/game/escenes/escena_logo.cpp | 4 +- source/game/escenes/escena_logo.hpp | 6 +- source/game/escenes/escena_titol.cpp | 6 +- source/game/escenes/escena_titol.hpp | 6 +- source/game/stage_system/spawn_controller.cpp | 2 +- source/game/stage_system/spawn_controller.hpp | 6 +- source/game/title/ship_animator.cpp | 6 +- source/game/title/ship_animator.hpp | 8 +-- source/main.cpp | 2 +- 35 files changed, 180 insertions(+), 114 deletions(-) diff --git a/source/core/defaults.hpp b/source/core/defaults.hpp index 361cad4..6c39e05 100644 --- a/source/core/defaults.hpp +++ b/source/core/defaults.hpp @@ -464,7 +464,7 @@ constexpr float FLOATING_SCALE = 1.0F * SHIP_BASE_SCALE; // Flotant: escala // Fórmula: (radi màxim de la nau * escala d'entrada) + marge constexpr float ENTRY_OFFSET = (SHIP_MAX_RADIUS * ENTRY_SCALE_START) + ENTRY_OFFSET_MARGIN; -// Punt de fuga (centre per a l'animació de sortida) +// Vec2 de fuga (centre per a l'animació de sortida) constexpr float VANISHING_POINT_X = CENTER_X; // 320.0f constexpr float VANISHING_POINT_Y = CENTER_Y; // 240.0f diff --git a/source/core/entities/entitat.hpp b/source/core/entities/entitat.hpp index 1210d32..a9882bb 100644 --- a/source/core/entities/entitat.hpp +++ b/source/core/entities/entitat.hpp @@ -27,7 +27,7 @@ class Entitat { [[nodiscard]] virtual bool es_collidable() const { return false; } // Getters comuns (inline, sense overhead) - [[nodiscard]] const Punt& get_centre() const { return centre_; } + [[nodiscard]] const Vec2& get_centre() const { return centre_; } [[nodiscard]] float get_angle() const { return angle_; } [[nodiscard]] float get_brightness() const { return brightness_; } [[nodiscard]] const std::shared_ptr& get_forma() const { return forma_; } @@ -36,7 +36,7 @@ class Entitat { // Estat comú (accés directe, sense overhead) SDL_Renderer* renderer_; std::shared_ptr forma_; - Punt centre_; + Vec2 centre_; float angle_{0.0F}; float brightness_{1.0F}; diff --git a/source/core/graphics/shape.cpp b/source/core/graphics/shape.cpp index dc218bb..c69ac70 100644 --- a/source/core/graphics/shape.cpp +++ b/source/core/graphics/shape.cpp @@ -134,8 +134,8 @@ void Shape::parse_center(const std::string& value) { } // Helper: parse points "x1,y1 x2,y2 x3,y3" -std::vector Shape::parse_points(const std::string& str) const { - std::vector points; +std::vector Shape::parse_points(const std::string& str) const { + std::vector points; std::istringstream iss(trim(str)); std::string pair; diff --git a/source/core/graphics/shape.hpp b/source/core/graphics/shape.hpp index 4f13f36..c206813 100644 --- a/source/core/graphics/shape.hpp +++ b/source/core/graphics/shape.hpp @@ -19,7 +19,7 @@ enum class PrimitiveType { // Primitiva individual (polyline o line) struct ShapePrimitive { PrimitiveType type; - std::vector points; // 2+ punts per polyline, exactament 2 per line + std::vector points; // 2+ punts per polyline, exactament 2 per line }; // Classe Shape - representa una forma vectorial carregada des de .shp @@ -39,7 +39,7 @@ class Shape { [[nodiscard]] const std::vector& get_primitives() const { return primitives_; } - [[nodiscard]] const Punt& get_centre() const { return centre_; } + [[nodiscard]] const Vec2& get_centre() const { return centre_; } [[nodiscard]] float get_escala_defecte() const { return escala_defecte_; } [[nodiscard]] bool es_valida() const { return !primitives_.empty(); } @@ -49,7 +49,7 @@ class Shape { private: std::vector primitives_; - Punt centre_; // Centre/origen de la forma + Vec2 centre_; // Centre/origen de la forma float escala_defecte_; // Escala per defecte (normalment 1.0) std::string nom_; // Nom de la forma (per depuració) @@ -58,7 +58,7 @@ class Shape { [[nodiscard]] bool starts_with(const std::string& str, const std::string& prefix) const; [[nodiscard]] std::string extract_value(const std::string& line) const; void parse_center(const std::string& value); - [[nodiscard]] std::vector parse_points(const std::string& str) const; + [[nodiscard]] std::vector parse_points(const std::string& str) const; }; } // namespace Graphics diff --git a/source/core/graphics/starfield.cpp b/source/core/graphics/starfield.cpp index 34ac8c9..6f5fa79 100644 --- a/source/core/graphics/starfield.cpp +++ b/source/core/graphics/starfield.cpp @@ -15,7 +15,7 @@ namespace Graphics { // Constructor Starfield::Starfield(SDL_Renderer* renderer, - const Punt& punt_fuga, + const Vec2& punt_fuga, const SDL_FRect& area, int densitat) : renderer_(renderer), diff --git a/source/core/graphics/starfield.hpp b/source/core/graphics/starfield.hpp index b74d2b1..34e71cf 100644 --- a/source/core/graphics/starfield.hpp +++ b/source/core/graphics/starfield.hpp @@ -30,7 +30,7 @@ class Starfield { // - area: rectangle on actuen les estrelles (SDL_FRect) // - densitat: nombre total d'estrelles (es divideix entre capes) Starfield(SDL_Renderer* renderer, - const Punt& punt_fuga, + const Vec2& punt_fuga, const SDL_FRect& area, int densitat = 150); @@ -41,13 +41,13 @@ class Starfield { void dibuixar(); // Setters per ajustar paràmetres en temps real - void set_punt_fuga(const Punt& punt) { punt_fuga_ = punt; } + void set_punt_fuga(const Vec2& punt) { punt_fuga_ = punt; } void set_brightness(float multiplier); private: // Estructura interna per cada estrella struct Estrella { - Punt posicio; // Posició actual + Vec2 posicio; // Posició actual float angle; // Angle de moviment (radians) float distancia_centre; // Distància normalitzada del centre (0.0-1.0) int capa; // Índex de capa (0=lluny, 1=mitjà, 2=prop) @@ -72,7 +72,7 @@ class Starfield { SDL_Renderer* renderer_; // Configuració - Punt punt_fuga_; // Punt d'origen de les estrelles + Vec2 punt_fuga_; // Vec2 d'origen de les estrelles SDL_FRect area_; // Àrea activa float radi_max_; // Distància màxima del centre al límit de pantalla int densitat_; // Nombre total d'estrelles diff --git a/source/core/graphics/vector_text.cpp b/source/core/graphics/vector_text.cpp index 7ac60b0..ceae3fe 100644 --- a/source/core/graphics/vector_text.cpp +++ b/source/core/graphics/vector_text.cpp @@ -182,7 +182,7 @@ bool VectorText::is_supported(char c) const { return chars_.contains(c); } -void VectorText::render(const std::string& text, const Punt& posicio, float escala, float spacing, float brightness) const { +void VectorText::render(const std::string& text, const Vec2& posicio, float escala, float spacing, float brightness) const { if (renderer_ == nullptr) { return; } @@ -223,7 +223,7 @@ void VectorText::render(const std::string& text, const Punt& posicio, float esca // Renderizar carácter // Ajustar X e Y para que posicio represente esquina superior izquierda // (render_shape espera el centro, así que sumamos la mitad de ancho y altura) - Punt char_pos = {.x = current_x + (char_width_scaled / 2.0F), .y = posicio.y + (char_height_scaled / 2.0F)}; + Vec2 char_pos = {.x = current_x + (char_width_scaled / 2.0F), .y = posicio.y + (char_height_scaled / 2.0F)}; Rendering::render_shape(renderer_, it->second, char_pos, 0.0F, escala, 1.0F, brightness); // Avanzar posición @@ -237,14 +237,14 @@ void VectorText::render(const std::string& text, const Punt& posicio, float esca } } -void VectorText::render_centered(const std::string& text, const Punt& centre_punt, float escala, float spacing, float brightness) const { +void VectorText::render_centered(const std::string& text, const Vec2& centre_punt, float escala, float spacing, float brightness) const { // Calcular dimensions del text float text_width = get_text_width(text, escala, spacing); float text_height = get_text_height(escala); // Calcular posició de l'esquina superior esquerra // restant la meitat de les dimensions del punt central - Punt posicio_esquerra = { + Vec2 posicio_esquerra = { .x = centre_punt.x - (text_width / 2.0F), .y = centre_punt.y - (text_height / 2.0F)}; diff --git a/source/core/graphics/vector_text.hpp b/source/core/graphics/vector_text.hpp index eacddb4..a88d9c0 100644 --- a/source/core/graphics/vector_text.hpp +++ b/source/core/graphics/vector_text.hpp @@ -25,7 +25,7 @@ class VectorText { // - escala: factor de escala (1.0 = 20×40 px por carácter) // - spacing: espacio entre caracteres en píxeles (a escala 1.0) // - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor) - void render(const std::string& text, const Punt& posicio, float escala = 1.0F, float spacing = 2.0F, float brightness = 1.0F) const; + void render(const std::string& text, const Vec2& posicio, float escala = 1.0F, float spacing = 2.0F, float brightness = 1.0F) const; // Renderizar string centrado en un punto // - text: cadena a renderizar @@ -33,7 +33,7 @@ class VectorText { // - escala: factor de escala (1.0 = 20×40 px por carácter) // - spacing: espacio entre caracteres en píxeles (a escala 1.0) // - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor) - void render_centered(const std::string& text, const Punt& centre_punt, float escala = 1.0F, float spacing = 2.0F, float brightness = 1.0F) const; + void render_centered(const std::string& text, const Vec2& centre_punt, float escala = 1.0F, float spacing = 2.0F, float brightness = 1.0F) const; // Calcular ancho total de un string (útil para centrado) [[nodiscard]] float get_text_width(const std::string& text, float escala = 1.0F, float spacing = 2.0F) const; diff --git a/source/core/physics/collision.hpp b/source/core/physics/collision.hpp index 4bc73af..2a67483 100644 --- a/source/core/physics/collision.hpp +++ b/source/core/physics/collision.hpp @@ -20,8 +20,8 @@ inline bool check_collision(const Entities::Entitat& a, const Entities::Entitat& float suma_radis_sq = suma_radis * suma_radis; // Comprovació distància al quadrat (sense sqrt) - const Punt& pos_a = a.get_centre(); - const Punt& pos_b = b.get_centre(); + const Vec2& pos_a = a.get_centre(); + const Vec2& pos_b = b.get_centre(); float dx = pos_a.x - pos_b.x; float dy = pos_a.y - pos_b.y; float dist_sq = (dx * dx) + (dy * dy); diff --git a/source/core/rendering/shape_renderer.cpp b/source/core/rendering/shape_renderer.cpp index bd8b3ad..a35a809 100644 --- a/source/core/rendering/shape_renderer.cpp +++ b/source/core/rendering/shape_renderer.cpp @@ -11,7 +11,7 @@ namespace Rendering { // Helper: aplicar rotació 3D a un punt 2D (assumeix Z=0) -static Punt apply_3d_rotation(float x, float y, const Rotation3D& rot) { +static Vec2 apply_3d_rotation(float x, float y, const Rotation3D& rot) { float z = 0.0F; // Tots els punts 2D comencen a Z=0 // Pitch (rotació eix X): cabeceo arriba/baix @@ -42,14 +42,14 @@ static Punt apply_3d_rotation(float x, float y, const Rotation3D& rot) { } // Helper: transformar un punt amb rotació, escala i trasllació -static Punt transform_point(const Punt& point, const Punt& shape_centre, const Punt& posicio, float angle, float escala, const Rotation3D* rotation_3d) { +static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const Vec2& posicio, float angle, float escala, const Rotation3D* rotation_3d) { // 1. Centrar el punt respecte al centre de la forma float centered_x = point.x - shape_centre.x; float centered_y = point.y - shape_centre.y; // 2. Aplicar rotació 3D (si es proporciona) if ((rotation_3d != nullptr) && rotation_3d->has_rotation()) { - Punt rotated_3d = apply_3d_rotation(centered_x, centered_y, *rotation_3d); + Vec2 rotated_3d = apply_3d_rotation(centered_x, centered_y, *rotation_3d); centered_x = rotated_3d.x; centered_y = rotated_3d.y; } @@ -74,7 +74,7 @@ static Punt transform_point(const Punt& point, const Punt& shape_centre, const P void render_shape(SDL_Renderer* renderer, const std::shared_ptr& shape, - const Punt& posicio, + const Vec2& posicio, float angle, float escala, float progress, @@ -91,15 +91,15 @@ void render_shape(SDL_Renderer* renderer, } // Obtenir el centre de la forma per a transformacions - const Punt& shape_centre = shape->get_centre(); + const Vec2& shape_centre = shape->get_centre(); // Iterar sobre totes les primitives for (const auto& primitive : shape->get_primitives()) { if (primitive.type == Graphics::PrimitiveType::POLYLINE) { // POLYLINE: connectar punts consecutius for (size_t i = 0; i < primitive.points.size() - 1; i++) { - Punt p1 = transform_point(primitive.points[i], shape_centre, posicio, angle, escala, rotation_3d); - Punt p2 = transform_point(primitive.points[i + 1], shape_centre, posicio, angle, escala, rotation_3d); + Vec2 p1 = transform_point(primitive.points[i], shape_centre, posicio, angle, escala, rotation_3d); + Vec2 p2 = transform_point(primitive.points[i + 1], shape_centre, posicio, angle, escala, rotation_3d); linea(renderer, static_cast(p1.x), static_cast(p1.y), static_cast(p2.x), static_cast(p2.y), brightness); @@ -107,8 +107,8 @@ void render_shape(SDL_Renderer* renderer, } else { // PrimitiveType::LINE // LINE: exactament 2 punts if (primitive.points.size() >= 2) { - Punt p1 = transform_point(primitive.points[0], shape_centre, posicio, angle, escala, rotation_3d); - Punt p2 = transform_point(primitive.points[1], shape_centre, posicio, angle, escala, rotation_3d); + Vec2 p1 = transform_point(primitive.points[0], shape_centre, posicio, angle, escala, rotation_3d); + Vec2 p2 = transform_point(primitive.points[1], shape_centre, posicio, angle, escala, rotation_3d); linea(renderer, static_cast(p1.x), static_cast(p1.y), static_cast(p2.x), static_cast(p2.y), brightness); diff --git a/source/core/rendering/shape_renderer.hpp b/source/core/rendering/shape_renderer.hpp index c289f8d..72f8242 100644 --- a/source/core/rendering/shape_renderer.hpp +++ b/source/core/rendering/shape_renderer.hpp @@ -42,7 +42,7 @@ struct Rotation3D { // - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor) void render_shape(SDL_Renderer* renderer, const std::shared_ptr& shape, - const Punt& posicio, + const Vec2& posicio, float angle, float escala = 1.0F, float progress = 1.0F, diff --git a/source/core/types.hpp b/source/core/types.hpp index 09698ee..c463496 100644 --- a/source/core/types.hpp +++ b/source/core/types.hpp @@ -1,6 +1,72 @@ +// types.hpp - Tipos básicos compartidos +// © 2025 Orni Attack + #pragma once -// Punt cartesià - ÚNICA estructura de coordenades del joc -struct Punt { - float x, y; +#include + +// Vector 2D cartesiano - única estructura de coordenadas del juego. +// Aggregate (sin constructores definidos) para soportar designated initializers: +// Vec2{.x = 1.0F, .y = 2.0F} +// y aggregate initialization clásica: +// Vec2{1.0F, 2.0F} +struct Vec2 { + float x{0.0F}; + float y{0.0F}; + + constexpr auto operator+=(const Vec2& o) -> Vec2& { + x += o.x; + y += o.y; + return *this; + } + constexpr auto operator-=(const Vec2& o) -> Vec2& { + x -= o.x; + y -= o.y; + return *this; + } + constexpr auto operator*=(float s) -> Vec2& { + x *= s; + y *= s; + return *this; + } + constexpr auto operator/=(float s) -> Vec2& { + x /= s; + y /= s; + return *this; + } + + [[nodiscard]] auto lengthSquared() const -> float { return (x * x) + (y * y); } + [[nodiscard]] auto length() const -> float { return std::sqrt(lengthSquared()); } + [[nodiscard]] auto dot(const Vec2& o) const -> float { return (x * o.x) + (y * o.y); } + + // Devuelve el vector normalizado; si la magnitud es 0 devuelve {0,0}. + [[nodiscard]] auto normalized() const -> Vec2 { + const float L = length(); + return L > 0.0F ? Vec2{.x = x / L, .y = y / L} : Vec2{}; + } }; + +constexpr auto operator+(Vec2 a, const Vec2& b) -> Vec2 { + a += b; + return a; +} +constexpr auto operator-(Vec2 a, const Vec2& b) -> Vec2 { + a -= b; + return a; +} +constexpr auto operator*(Vec2 v, float s) -> Vec2 { + v *= s; + return v; +} +constexpr auto operator*(float s, Vec2 v) -> Vec2 { + v *= s; + return v; +} +constexpr auto operator/(Vec2 v, float s) -> Vec2 { + v /= s; + return v; +} +constexpr auto operator-(const Vec2& v) -> Vec2 { return {.x = -v.x, .y = -v.y}; } +constexpr auto operator==(const Vec2& a, const Vec2& b) -> bool { + return a.x == b.x && a.y == b.y; +} diff --git a/source/game/effects/debris.hpp b/source/game/effects/debris.hpp index 0b2a0ec..f56fff5 100644 --- a/source/game/effects/debris.hpp +++ b/source/game/effects/debris.hpp @@ -10,11 +10,11 @@ namespace Effects { // Representa un fragment d'una forma destruïda (nau, enemic, bala) struct Debris { // Geometria del segment (2 punts en coordenades mundials) - Punt p1; // Punt inicial del segment - Punt p2; // Punt final del segment + Vec2 p1; // Vec2 inicial del segment + Vec2 p2; // Vec2 final del segment // Física - Punt velocitat; // Velocitat en px/s (components x, y) + Vec2 velocitat; // Velocitat en px/s (components x, y) float acceleracio; // Acceleració negativa (fricció) en px/s² // Rotació diff --git a/source/game/effects/debris_manager.cpp b/source/game/effects/debris_manager.cpp index 97c2622..10865c1 100644 --- a/source/game/effects/debris_manager.cpp +++ b/source/game/effects/debris_manager.cpp @@ -16,7 +16,7 @@ namespace Effects { // Helper: transformar punt amb rotació, escala i trasllació // (Copiat de shape_renderer.cpp:12-34) -static Punt transform_point(const Punt& point, const Punt& shape_centre, const Punt& posicio, float angle, float escala) { +static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const Vec2& posicio, float angle, float escala) { // 1. Centrar el punt respecte al centre de la forma float centered_x = point.x - shape_centre.x; float centered_y = point.y - shape_centre.y; @@ -45,12 +45,12 @@ DebrisManager::DebrisManager(SDL_Renderer* renderer) } void DebrisManager::explotar(const std::shared_ptr& shape, - const Punt& centre, + const Vec2& centre, float angle, float escala, float velocitat_base, float brightness, - const Punt& velocitat_objecte, + const Vec2& velocitat_objecte, float velocitat_angular, float factor_herencia_visual, const std::string& sound) { @@ -62,12 +62,12 @@ void DebrisManager::explotar(const std::shared_ptr& shape, Audio::get()->playSound(sound, Audio::Group::GAME); // Obtenir centre de la forma per a transformacions - const Punt& shape_centre = shape->get_centre(); + const Vec2& shape_centre = shape->get_centre(); // Iterar sobre totes les primitives de la forma for (const auto& primitive : shape->get_primitives()) { // Processar cada segment de línia - std::vector> segments; + std::vector> segments; if (primitive.type == Graphics::PrimitiveType::POLYLINE) { // Polyline: extreure segments consecutius @@ -84,9 +84,9 @@ void DebrisManager::explotar(const std::shared_ptr& shape, // Crear debris per a cada segment for (const auto& [local_p1, local_p2] : segments) { // 1. Transformar punts locals → coordenades mundials - Punt world_p1 = + Vec2 world_p1 = transform_point(local_p1, shape_centre, centre, angle, escala); - Punt world_p2 = + Vec2 world_p2 = transform_point(local_p2, shape_centre, centre, angle, escala); // 2. Trobar slot lliure @@ -101,7 +101,7 @@ void DebrisManager::explotar(const std::shared_ptr& shape, debris->p2 = world_p2; // 4. Calcular direcció d'explosió (radial, des del centre cap a fora) - Punt direccio = calcular_direccio_explosio(world_p1, world_p2, centre); + Vec2 direccio = calcular_direccio_explosio(world_p1, world_p2, centre); // 5. Velocitat inicial (base ± variació aleatòria + velocitat heretada) float speed = @@ -271,7 +271,7 @@ void DebrisManager::actualitzar(float delta_time) { } // 3. Calcular centre del segment - Punt centre = {.x = (debris.p1.x + debris.p2.x) / 2.0F, + Vec2 centre = {.x = (debris.p1.x + debris.p2.x) / 2.0F, .y = (debris.p1.y + debris.p2.y) / 2.0F}; // 4. Actualitzar posició del centre @@ -327,9 +327,9 @@ Debris* DebrisManager::trobar_slot_lliure() { return nullptr; // Pool ple } -Punt DebrisManager::calcular_direccio_explosio(const Punt& p1, - const Punt& p2, - const Punt& centre_objecte) const { +Vec2 DebrisManager::calcular_direccio_explosio(const Vec2& p1, + const Vec2& p2, + const Vec2& centre_objecte) const { // 1. Calcular centre del segment float centro_seg_x = (p1.x + p2.x) / 2.0F; float centro_seg_y = (p1.y + p2.y) / 2.0F; diff --git a/source/game/effects/debris_manager.hpp b/source/game/effects/debris_manager.hpp index 6dc7cc5..4020ab5 100644 --- a/source/game/effects/debris_manager.hpp +++ b/source/game/effects/debris_manager.hpp @@ -31,12 +31,12 @@ class DebrisManager { // - velocitat_angular: velocitat angular heretada (rad/s, per defecte 0) // - factor_herencia_visual: factor de herència rotació visual (0.0-1.0, per defecte 0.0) void explotar(const std::shared_ptr& shape, - const Punt& centre, + const Vec2& centre, float angle, float escala, float velocitat_base, float brightness = 1.0F, - const Punt& velocitat_objecte = {.x = 0.0F, .y = 0.0F}, + const Vec2& velocitat_objecte = {.x = 0.0F, .y = 0.0F}, float velocitat_angular = 0.0F, float factor_herencia_visual = 0.0F, const std::string& sound = Defaults::Sound::EXPLOSION); @@ -67,7 +67,7 @@ class DebrisManager { Debris* trobar_slot_lliure(); // Calcular direcció d'explosió (radial, des del centre cap al segment) - [[nodiscard]] Punt calcular_direccio_explosio(const Punt& p1, const Punt& p2, const Punt& centre_objecte) const; + [[nodiscard]] Vec2 calcular_direccio_explosio(const Vec2& p1, const Vec2& p2, const Vec2& centre_objecte) const; }; } // namespace Effects diff --git a/source/game/effects/gestor_puntuacio_flotant.cpp b/source/game/effects/gestor_puntuacio_flotant.cpp index 17c0bd4..4376f7a 100644 --- a/source/game/effects/gestor_puntuacio_flotant.cpp +++ b/source/game/effects/gestor_puntuacio_flotant.cpp @@ -15,7 +15,7 @@ GestorPuntuacioFlotant::GestorPuntuacioFlotant(SDL_Renderer* renderer) } } -void GestorPuntuacioFlotant::crear(int punts, const Punt& posicio) { +void GestorPuntuacioFlotant::crear(int punts, const Vec2& posicio) { // 1. Trobar slot lliure PuntuacioFlotant* pf = trobar_slot_lliure(); if (pf == nullptr) { diff --git a/source/game/effects/gestor_puntuacio_flotant.hpp b/source/game/effects/gestor_puntuacio_flotant.hpp index f3d4fe6..0b4b1b8 100644 --- a/source/game/effects/gestor_puntuacio_flotant.hpp +++ b/source/game/effects/gestor_puntuacio_flotant.hpp @@ -23,7 +23,7 @@ class GestorPuntuacioFlotant { // Crear número flotant // - punts: valor numèric (100, 150, 200) // - posicio: on apareix (normalment centre d'enemic destruït) - void crear(int punts, const Punt& posicio); + void crear(int punts, const Vec2& posicio); // Actualitzar tots els números actius void actualitzar(float delta_time); diff --git a/source/game/effects/puntuacio_flotant.hpp b/source/game/effects/puntuacio_flotant.hpp index 340e2a4..cd9daa0 100644 --- a/source/game/effects/puntuacio_flotant.hpp +++ b/source/game/effects/puntuacio_flotant.hpp @@ -16,10 +16,10 @@ struct PuntuacioFlotant { std::string text; // Posició actual (coordenades mundials) - Punt posicio; + Vec2 posicio; // Animació de moviment - Punt velocitat; // px/s (normalment cap amunt: {0.0f, -30.0f}) + Vec2 velocitat; // px/s (normalment cap amunt: {0.0f, -30.0f}) // Animació de fade float temps_vida; // Temps transcorregut (segons) diff --git a/source/game/entities/bala.cpp b/source/game/entities/bala.cpp index 208ee4a..b3d2bc7 100644 --- a/source/game/entities/bala.cpp +++ b/source/game/entities/bala.cpp @@ -43,7 +43,7 @@ void Bala::inicialitzar() { grace_timer_ = 0.0F; } -void Bala::disparar(const Punt& posicio, float angle, uint8_t owner_id) { +void Bala::disparar(const Vec2& posicio, float angle, uint8_t owner_id) { // Activar bala i posicionar-la a la nau // Basat en joc_asteroides.cpp línies 188-200 diff --git a/source/game/entities/bala.hpp b/source/game/entities/bala.hpp index de801bd..e83660d 100644 --- a/source/game/entities/bala.hpp +++ b/source/game/entities/bala.hpp @@ -18,7 +18,7 @@ class Bala : public Entities::Entitat { Bala(SDL_Renderer* renderer); void inicialitzar() override; - void disparar(const Punt& posicio, float angle, uint8_t owner_id); + void disparar(const Vec2& posicio, float angle, uint8_t owner_id); void actualitzar(float delta_time) override; void dibuixar() const override; diff --git a/source/game/entities/enemic.cpp b/source/game/entities/enemic.cpp index 98f3dcc..b21489c 100644 --- a/source/game/entities/enemic.cpp +++ b/source/game/entities/enemic.cpp @@ -34,7 +34,7 @@ Enemic::Enemic(SDL_Renderer* renderer) // Constructor no carrega forma per permetre tipus diferents } -void Enemic::inicialitzar(TipusEnemic tipus, const Punt* ship_pos) { +void Enemic::inicialitzar(TipusEnemic tipus, const Vec2* ship_pos) { // Guardar tipus tipus_ = tipus; @@ -523,7 +523,7 @@ void Enemic::set_tracking_strength(float strength) { } // [NEW] Safe spawn helper - checks if position is away from ship -bool Enemic::intent_spawn_safe(const Punt& ship_pos, float& out_x, float& out_y) { +bool Enemic::intent_spawn_safe(const Vec2& ship_pos, float& out_x, float& out_y) { // Generate random position within safe bounds float min_x; float max_x; diff --git a/source/game/entities/enemic.hpp b/source/game/entities/enemic.hpp index 5a8e14d..18c25b3 100644 --- a/source/game/entities/enemic.hpp +++ b/source/game/entities/enemic.hpp @@ -43,7 +43,7 @@ class Enemic : public Entities::Entitat { Enemic(SDL_Renderer* renderer); void inicialitzar() override { inicialitzar(TipusEnemic::PENTAGON, nullptr); } - void inicialitzar(TipusEnemic tipus, const Punt* ship_pos = nullptr); + void inicialitzar(TipusEnemic tipus, const Vec2* ship_pos = nullptr); void actualitzar(float delta_time) override; void dibuixar() const override; @@ -61,14 +61,14 @@ class Enemic : public Entities::Entitat { // Getters (API pública sense canvis) void destruir() { esta_ = false; } [[nodiscard]] float get_drotacio() const { return drotacio_; } - [[nodiscard]] Punt get_velocitat_vector() const { + [[nodiscard]] Vec2 get_velocitat_vector() const { return { .x = velocitat_ * std::cos(angle_ - (Constants::PI / 2.0F)), .y = velocitat_ * std::sin(angle_ - (Constants::PI / 2.0F))}; } // Set ship position reference for tracking behavior - void set_ship_position(const Punt* ship_pos) { ship_position_ = ship_pos; } + void set_ship_position(const Vec2* ship_pos) { ship_position_ = ship_pos; } // [NEW] Getters for stage system (base stats) [[nodiscard]] float get_base_velocity() const; @@ -102,7 +102,7 @@ class Enemic : public Entities::Entitat { // [NEW] Behavior state (type-specific) float tracking_timer_; // For Quadrat: time since last angle update - const Punt* ship_position_; // Pointer to ship position (for tracking) + const Vec2* ship_position_; // Pointer to ship position (for tracking) float tracking_strength_; // For Quadrat: tracking intensity (0.0-1.5), default 0.5 // [NEW] Invulnerability state @@ -119,5 +119,5 @@ class Enemic : public Entities::Entitat { void comportament_quadrat(float delta_time); void comportament_molinillo(float delta_time); [[nodiscard]] float calcular_escala_actual() const; // Returns scale with palpitation applied - bool intent_spawn_safe(const Punt& ship_pos, float& out_x, float& out_y); + bool intent_spawn_safe(const Vec2& ship_pos, float& out_x, float& out_y); }; diff --git a/source/game/entities/nau.cpp b/source/game/entities/nau.cpp index bb8ee34..de86098 100644 --- a/source/game/entities/nau.cpp +++ b/source/game/entities/nau.cpp @@ -36,7 +36,7 @@ Nau::Nau(SDL_Renderer* renderer, const char* shape_file) } } -void Nau::inicialitzar(const Punt* spawn_point, bool activar_invulnerabilitat) { +void Nau::inicialitzar(const Vec2* spawn_point, bool activar_invulnerabilitat) { // Inicialització de la nau (triangle) // Basat en el codi Pascal original: lines 380-384 // Copiat de joc_asteroides.cpp línies 30-44 diff --git a/source/game/entities/nau.hpp b/source/game/entities/nau.hpp index cc477fe..ca4dc91 100644 --- a/source/game/entities/nau.hpp +++ b/source/game/entities/nau.hpp @@ -20,7 +20,7 @@ class Nau : public Entities::Entitat { Nau(SDL_Renderer* renderer, const char* shape_file = "ship.shp"); void inicialitzar() override { inicialitzar(nullptr, false); } - void inicialitzar(const Punt* spawn_point, bool activar_invulnerabilitat = false); + void inicialitzar(const Vec2* spawn_point, bool activar_invulnerabilitat = false); void processar_input(float delta_time, uint8_t player_id); void actualitzar(float delta_time) override; void dibuixar() const override; @@ -40,14 +40,14 @@ class Nau : public Entities::Entitat { [[nodiscard]] bool esta_viva() const { return !esta_tocada_; } [[nodiscard]] bool esta_tocada() const { return esta_tocada_; } [[nodiscard]] bool es_invulnerable() const { return invulnerable_timer_ > 0.0F; } - [[nodiscard]] Punt get_velocitat_vector() const { + [[nodiscard]] Vec2 get_velocitat_vector() const { return { .x = velocitat_ * std::cos(angle_ - (Constants::PI / 2.0F)), .y = velocitat_ * std::sin(angle_ - (Constants::PI / 2.0F))}; } // Setters - void set_centre(const Punt& nou_centre) { centre_ = nou_centre; } + void set_centre(const Vec2& nou_centre) { centre_ = nou_centre; } // Col·lisions (Fase 10) void marcar_tocada() { esta_tocada_ = true; } diff --git a/source/game/escenes/escena_joc.cpp b/source/game/escenes/escena_joc.cpp index f59d2dc..7f2dbda 100644 --- a/source/game/escenes/escena_joc.cpp +++ b/source/game/escenes/escena_joc.cpp @@ -176,7 +176,7 @@ void EscenaJoc::inicialitzar() { if (jugador_actiu) { // Jugador actiu: inicialitzar normalment - Punt spawn_pos = obtenir_punt_spawn(i); + Vec2 spawn_pos = obtenir_punt_spawn(i); naus_[i].inicialitzar(&spawn_pos, false); // No invulnerability at start std::cout << "[EscenaJoc] Jugador " << (i + 1) << " inicialitzat\n"; } else { @@ -326,7 +326,7 @@ void EscenaJoc::actualitzar(float delta_time) { if (vides_per_jugador_[i] > 0) { // Respawn ship en spawn position con invulnerabilidad - Punt spawn_pos = obtenir_punt_spawn(i); + Vec2 spawn_pos = obtenir_punt_spawn(i); naus_[i].inicialitzar(&spawn_pos, true); itocado_per_jugador_[i] = 0.0F; } else { @@ -397,12 +397,12 @@ void EscenaJoc::actualitzar(float delta_time) { // [MODIFICAT] Animar AMBAS naus con sus progress respectivos if (config_partida_.jugador1_actiu && ship1_progress < 1.0F) { - Punt pos_p1 = calcular_posicio_nau_init_hud(ship1_progress, 0); + Vec2 pos_p1 = calcular_posicio_nau_init_hud(ship1_progress, 0); naus_[0].set_centre(pos_p1); } if (config_partida_.jugador2_actiu && ship2_progress < 1.0F) { - Punt pos_p2 = calcular_posicio_nau_init_hud(ship2_progress, 1); + Vec2 pos_p2 = calcular_posicio_nau_init_hud(ship2_progress, 1); naus_[1].set_centre(pos_p2); } @@ -708,11 +708,11 @@ void EscenaJoc::tocado(uint8_t player_id) { naus_[player_id].marcar_tocada(); // Create ship explosion - const Punt& ship_pos = naus_[player_id].get_centre(); + const Vec2& ship_pos = naus_[player_id].get_centre(); float ship_angle = naus_[player_id].get_angle(); - Punt vel_nau = naus_[player_id].get_velocitat_vector(); + Vec2 vel_nau = naus_[player_id].get_velocitat_vector(); // Reduir a 80% la velocitat heretada per la nau (més realista) - Punt vel_nau_80 = {.x = vel_nau.x * 0.8F, .y = vel_nau.y * 0.8F}; + Vec2 vel_nau_80 = {.x = vel_nau.x * 0.8F, .y = vel_nau.y * 0.8F}; debris_manager_.explotar( naus_[player_id].get_forma(), // Ship shape (3 lines) @@ -855,7 +855,7 @@ void EscenaJoc::dibuixar_marcador_animat(float progress) { text_.render_centered(text, {.x = centre_x, .y = centre_y_animada}, escala, spacing); } -Punt EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const { +Vec2 EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const { // Animació de la nau pujant des de baix amb easing // [MODIFICAT] Ambas naves usan ease_out_quad (desfase temporal via INIT/END) @@ -865,7 +865,7 @@ Punt EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const SDL_FRect& zona = Defaults::Zones::PLAYAREA; // Calcular posició final segons jugador (reutilitza obtenir_punt_spawn) - Punt spawn_final = obtenir_punt_spawn(player_id); + Vec2 spawn_final = obtenir_punt_spawn(player_id); float x_final = spawn_final.x; float y_final = spawn_final.y; @@ -957,7 +957,7 @@ void EscenaJoc::detectar_col·lisions_bales_enemics() { if (Physics::check_collision(bala, enemic, AMPLIFIER)) { // *** COL·LISIÓ DETECTADA *** - const Punt& pos_enemic = enemic.get_centre(); + const Vec2& pos_enemic = enemic.get_centre(); // 1. Calculate score for enemy type int punts = 0; @@ -984,7 +984,7 @@ void EscenaJoc::detectar_col·lisions_bales_enemics() { enemic.destruir(); // 2. Crear explosió de fragments - Punt vel_enemic = enemic.get_velocitat_vector(); + Vec2 vel_enemic = enemic.get_velocitat_vector(); debris_manager_.explotar( enemic.get_forma(), // Forma vectorial del pentàgon pos_enemic, // Posició central @@ -1174,7 +1174,7 @@ void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) { float y = play_area.y + (play_area.h * Defaults::Game::STAGE_MESSAGE_Y_RATIO) - (text_height / 2.0F); // Render only the partial message (typewriter effect) - Punt pos = {.x = x, .y = y}; + Vec2 pos = {.x = x, .y = y}; text_.render(partial_message, pos, escala, spacing); } @@ -1182,7 +1182,7 @@ void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) { // Helper methods for 2-player support // ======================================== -Punt EscenaJoc::obtenir_punt_spawn(uint8_t player_id) const { +Vec2 EscenaJoc::obtenir_punt_spawn(uint8_t player_id) const { const SDL_FRect& zona = Defaults::Zones::PLAYAREA; float x_ratio; @@ -1211,7 +1211,7 @@ void EscenaJoc::disparar_bala(uint8_t player_id) { } // Calcular posición en la punta de la nave - const Punt& ship_centre = naus_[player_id].get_centre(); + const Vec2& ship_centre = naus_[player_id].get_centre(); float ship_angle = naus_[player_id].get_angle(); constexpr float LOCAL_TIP_X = 0.0F; @@ -1220,7 +1220,7 @@ void EscenaJoc::disparar_bala(uint8_t player_id) { float sin_a = std::sin(ship_angle); float tip_x = (LOCAL_TIP_X * cos_a) - (LOCAL_TIP_Y * sin_a) + ship_centre.x; float tip_y = (LOCAL_TIP_X * sin_a) + (LOCAL_TIP_Y * cos_a) + ship_centre.y; - Punt posicio_dispar = {.x = tip_x, .y = tip_y}; + Vec2 posicio_dispar = {.x = tip_x, .y = tip_y}; // Buscar primera bala inactiva en el pool del jugador int start_idx = player_id * 3; // P1=[0,1,2], P2=[3,4,5] @@ -1295,7 +1295,7 @@ void EscenaJoc::processar_input_continue() { } // Spawn with invulnerability - Punt spawn_pos = obtenir_punt_spawn(player_to_revive); + Vec2 spawn_pos = obtenir_punt_spawn(player_to_revive); naus_[player_to_revive].inicialitzar(&spawn_pos, true); // Check if other player wants to continue too @@ -1305,7 +1305,7 @@ void EscenaJoc::processar_input_continue() { vides_per_jugador_[other_player] = Defaults::Game::STARTING_LIVES; itocado_per_jugador_[other_player] = 0.0F; config_partida_.jugador2_actiu = true; - Punt spawn_pos2 = obtenir_punt_spawn(other_player); + Vec2 spawn_pos2 = obtenir_punt_spawn(other_player); naus_[other_player].inicialitzar(&spawn_pos2, true); } @@ -1391,7 +1391,7 @@ void EscenaJoc::unir_jugador(uint8_t player_id) { itocado_per_jugador_[player_id] = 0.0F; // Spawn with invulnerability - Punt spawn_pos = obtenir_punt_spawn(player_id); + Vec2 spawn_pos = obtenir_punt_spawn(player_id); naus_[player_id].inicialitzar(&spawn_pos, true); // No visual message, just spawn (per user requirement) diff --git a/source/game/escenes/escena_joc.hpp b/source/game/escenes/escena_joc.hpp index 0894328..fcd1cda 100644 --- a/source/game/escenes/escena_joc.hpp +++ b/source/game/escenes/escena_joc.hpp @@ -64,7 +64,7 @@ class EscenaJoc { float continue_tick_timer_; // Timer for countdown tick (1.0s) int continues_usados_; // Continues used this game (0-3 max) float game_over_timer_; // Final GAME OVER timer before title screen - Punt punt_mort_; // Death position (for respawn) + Vec2 punt_mort_; // Death position (for respawn) std::array puntuacio_per_jugador_; // [0]=P1, [1]=P2 // Text vectorial @@ -85,7 +85,7 @@ class EscenaJoc { void dibuixar_marges() const; // Dibuixar vores de la zona de joc void dibuixar_marcador(); // Dibuixar marcador de puntuació void disparar_bala(uint8_t player_id); // Shoot bullet from player - [[nodiscard]] Punt obtenir_punt_spawn(uint8_t player_id) const; // Get spawn position for player + [[nodiscard]] Vec2 obtenir_punt_spawn(uint8_t player_id) const; // Get spawn position for player // [NEW] Continue & Join system void unir_jugador(uint8_t player_id); // Join inactive player mid-game @@ -100,7 +100,7 @@ class EscenaJoc { // [NEW] Funcions d'animació per INIT_HUD void dibuixar_marges_animat(float progress) const; // Rectangle amb creixement uniforme void dibuixar_marcador_animat(float progress); // Marcador que puja des de baix - [[nodiscard]] Punt calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const; // Posició animada de la nau + [[nodiscard]] Vec2 calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const; // Posició animada de la nau // [NEW] Función helper del sistema de animación INIT_HUD [[nodiscard]] float calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const; diff --git a/source/game/escenes/escena_logo.cpp b/source/game/escenes/escena_logo.cpp index 96453d2..494bad5 100644 --- a/source/game/escenes/escena_logo.cpp +++ b/source/game/escenes/escena_logo.cpp @@ -347,7 +347,7 @@ void EscenaLogo::dibuixar() { ? std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0F) : 1.0F; // POST: mantenir al 100% - const Punt ORIGEN_ZOOM = {.x = ORIGEN_ZOOM_X, .y = ORIGEN_ZOOM_Y}; + const Vec2 ORIGEN_ZOOM = {.x = ORIGEN_ZOOM_X, .y = ORIGEN_ZOOM_Y}; for (size_t i = 0; i < lletres_.size(); i++) { const auto& lletra = lletres_[i]; @@ -362,7 +362,7 @@ void EscenaLogo::dibuixar() { continue; } - Punt pos_actual; + Vec2 pos_actual; pos_actual.x = ORIGEN_ZOOM.x + ((lletra.posicio.x - ORIGEN_ZOOM.x) * letra_progress); pos_actual.y = diff --git a/source/game/escenes/escena_logo.hpp b/source/game/escenes/escena_logo.hpp index a1d2579..360bfc2 100644 --- a/source/game/escenes/escena_logo.hpp +++ b/source/game/escenes/escena_logo.hpp @@ -51,7 +51,7 @@ class EscenaLogo { // Estructura per a cada lletra del logo struct LetraLogo { std::shared_ptr forma; - Punt posicio; // Posició final en pantalla + Vec2 posicio; // Posició final en pantalla float ancho; // Ancho del bounding box float offset_centre; // Distància de min_x a shape_centre.x }; @@ -74,8 +74,8 @@ class EscenaLogo { // Constants d'animació seqüencial static constexpr float THRESHOLD_LETRA = 0.6F; // Umbral per activar següent lletra (0.0-1.0) - static constexpr float ORIGEN_ZOOM_X = Defaults::Game::WIDTH * 0.5F; // Punt inicial X del zoom - static constexpr float ORIGEN_ZOOM_Y = Defaults::Game::HEIGHT * 0.4F; // Punt inicial Y del zoom + 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 // Mètodes privats void inicialitzar_lletres(); diff --git a/source/game/escenes/escena_titol.cpp b/source/game/escenes/escena_titol.cpp index 0e1de2a..2d8ecec 100644 --- a/source/game/escenes/escena_titol.cpp +++ b/source/game/escenes/escena_titol.cpp @@ -51,7 +51,7 @@ EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context) } // Crear starfield de fons - Punt centre_pantalla{ + Vec2 centre_pantalla{ .x = Defaults::Game::WIDTH / 2.0F, .y = Defaults::Game::HEIGHT / 2.0F}; @@ -583,7 +583,7 @@ void EscenaTitol::dibuixar() { // Ombra "ORNI" for (size_t i = 0; i < lletres_orni_.size(); ++i) { - Punt pos_shadow; + Vec2 pos_shadow; pos_shadow.x = posicions_originals_orni_[i].x + static_cast(std::round(shadow_offset_x)); pos_shadow.y = posicions_originals_orni_[i].y + static_cast(std::round(shadow_offset_y)); @@ -600,7 +600,7 @@ void EscenaTitol::dibuixar() { // Ombra "ATTACK!" for (size_t i = 0; i < lletres_attack_.size(); ++i) { - Punt pos_shadow; + Vec2 pos_shadow; pos_shadow.x = posicions_originals_attack_[i].x + static_cast(std::round(shadow_offset_x)); pos_shadow.y = posicions_originals_attack_[i].y + static_cast(std::round(shadow_offset_y)); diff --git a/source/game/escenes/escena_titol.hpp b/source/game/escenes/escena_titol.hpp index 8f27887..1b0d216 100644 --- a/source/game/escenes/escena_titol.hpp +++ b/source/game/escenes/escena_titol.hpp @@ -44,7 +44,7 @@ class EscenaTitol { // Estructura per emmagatzemar informació de cada lletra del títol struct LetraLogo { std::shared_ptr forma; // Forma vectorial de la lletra - Punt posicio; // Posició en pantalla + Vec2 posicio; // Posició en pantalla float ancho; // Amplada escalada float altura; // Altura escalada float offset_centre; // Offset del centre per posicionament @@ -66,8 +66,8 @@ class EscenaTitol { // Estat d'animació del logo float temps_animacio_; // Temps acumulat per animació orbital - std::vector posicions_originals_orni_; // Posicions originals de "ORNI" - std::vector posicions_originals_attack_; // Posicions originals de "ATTACK!" + std::vector posicions_originals_orni_; // Posicions originals de "ORNI" + std::vector posicions_originals_attack_; // Posicions originals de "ATTACK!" // Estat d'arrencada de l'animació float temps_estat_main_; // Temps acumulat en estat MAIN diff --git a/source/game/stage_system/spawn_controller.cpp b/source/game/stage_system/spawn_controller.cpp index ddf93b6..70872c8 100644 --- a/source/game/stage_system/spawn_controller.cpp +++ b/source/game/stage_system/spawn_controller.cpp @@ -149,7 +149,7 @@ TipusEnemic SpawnController::seleccionar_tipus_aleatori() const { return TipusEnemic::MOLINILLO; } -void SpawnController::spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Punt* ship_pos) { +void SpawnController::spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Vec2* ship_pos) { // Initialize enemy (with safe spawn if ship_pos provided) enemic.inicialitzar(tipus, ship_pos); diff --git a/source/game/stage_system/spawn_controller.hpp b/source/game/stage_system/spawn_controller.hpp index f042c4f..adff60c 100644 --- a/source/game/stage_system/spawn_controller.hpp +++ b/source/game/stage_system/spawn_controller.hpp @@ -39,7 +39,7 @@ class SpawnController { [[nodiscard]] uint8_t get_enemics_spawnejats() const; // [NEW] Set ship position reference for safe spawn - void set_ship_position(const Punt* ship_pos) { ship_position_ = ship_pos; } + void set_ship_position(const Vec2* ship_pos) { ship_position_ = ship_pos; } private: const ConfigStage* config_; // Non-owning pointer to current stage config @@ -50,9 +50,9 @@ class SpawnController { // Spawn generation void generar_spawn_events(); [[nodiscard]] TipusEnemic seleccionar_tipus_aleatori() const; - void spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Punt* ship_pos = nullptr); + void spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Vec2* ship_pos = nullptr); void aplicar_multiplicadors(Enemic& enemic) const; - const Punt* ship_position_; // [NEW] Non-owning pointer to ship position + const Vec2* ship_position_; // [NEW] Non-owning pointer to ship position }; } // namespace StageSystem diff --git a/source/game/title/ship_animator.cpp b/source/game/title/ship_animator.cpp index bcc5c51..945136a 100644 --- a/source/game/title/ship_animator.cpp +++ b/source/game/title/ship_animator.cpp @@ -232,8 +232,8 @@ void ShipAnimator::actualitzar_exiting(NauTitol& nau, float delta_time) { // Aplicar easing (ease_in_quad per acceleració cap al punt de fuga) float eased_progress = Easing::ease_in_quad(progress); - // Punt de fuga (centre del starfield) - constexpr Punt punt_fuga{.x = VANISHING_POINT_X, .y = VANISHING_POINT_Y}; + // Vec2 de fuga (centre del starfield) + constexpr Vec2 punt_fuga{.x = VANISHING_POINT_X, .y = VANISHING_POINT_Y}; // Lerp posició cap al punt de fuga (preservar posició inicial actual) // Nota: posicio_inicial conté la posició on estava quan es va activar EXITING @@ -320,7 +320,7 @@ void ShipAnimator::configurar_nau_p2(NauTitol& nau) { nau.visible = true; } -Punt ShipAnimator::calcular_posicio_fora_pantalla(float angle_rellotge) const { +Vec2 ShipAnimator::calcular_posicio_fora_pantalla(float angle_rellotge) const { using namespace Defaults::Title::Ships; // Convertir angle del rellotge a radians (per exemple: 240° per clock 8) diff --git a/source/game/title/ship_animator.hpp b/source/game/title/ship_animator.hpp index 281496a..efdf577 100644 --- a/source/game/title/ship_animator.hpp +++ b/source/game/title/ship_animator.hpp @@ -30,9 +30,9 @@ struct NauTitol { float temps_estat; // Temps acumulat en l'estat actual // Posicions - Punt posicio_inicial; // Posició d'inici (fora de pantalla per ENTERING) - Punt posicio_objectiu; // Posició objectiu (rellotge 8 o 4) - Punt posicio_actual; // Posició interpolada actual + Vec2 posicio_inicial; // Posició d'inici (fora de pantalla per ENTERING) + Vec2 posicio_objectiu; // Posició objectiu (rellotge 8 o 4) + Vec2 posicio_actual; // Posició interpolada actual // Escales (simulació eix Z) float escala_inicial; // Escala d'inici (més gran = més a prop) @@ -91,7 +91,7 @@ class ShipAnimator { // Configuració void configurar_nau_p1(NauTitol& nau); void configurar_nau_p2(NauTitol& nau); - [[nodiscard]] Punt calcular_posicio_fora_pantalla(float angle_rellotge) const; + [[nodiscard]] Vec2 calcular_posicio_fora_pantalla(float angle_rellotge) const; }; } // namespace Title diff --git a/source/main.cpp b/source/main.cpp index 5e24d80..76ae868 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,4 +1,4 @@ -// main.cpp - Punt d'entrada del joc Asteroides +// main.cpp - Vec2 d'entrada del joc Asteroides // © 1999 Visente i Sergi (versió Pascal) // © 2025 Port a C++20 amb SDL3 From ae5cc1cfb4ee06ff66efa9049ea8c7a17c21407d Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 19 May 2026 11:37:18 +0200 Subject: [PATCH 03/27] Fase 1b: rename d'entitats i metodes virtuals a CamelCase/camelBack Tots els tipus d'entitat passen del catala a l'angles seguint el .clang-tidy del projecte (tipus en CamelCase, metodes en camelBack, membres en lower_case amb sufix _). Renames de tipus: - Entitat -> Entity (core/entities/entity.hpp) - Nau -> Ship (game/entities/ship.{hpp,cpp}) - Enemic -> Enemy (game/entities/enemy.{hpp,cpp}) - Bala -> Bullet (game/entities/bullet.{hpp,cpp}) - TipusEnemic -> EnemyType - AnimacioEnemic -> EnemyAnimation Metodes virtuals (s'aplica a tot el codi, no nomes a entitats): - actualitzar -> update - dibuixar -> draw - inicialitzar -> init - processar_input -> processInput - esta_actiu -> isActive - es_collidable -> isCollidable - get_collision_radius -> getCollisionRadius Getters comuns: - get_centre -> getCenter - get_angle -> getAngle - get_brightness -> getBrightness - get_forma -> getShape Metodes especifics: - esta_viva -> isAlive - esta_tocada -> isHit - es_invulnerable -> isInvulnerable - get_velocitat_vector -> getVelocityVector - set_centre -> setCenter - marcar_tocada -> markHit - aplicar_fisica -> applyPhysics - get_tipus -> getType Camps privats: - centre_ -> center_ - velocitat_ -> velocity_ - forma_ -> shape_ - esta_tocada_ -> is_hit_ - tipus_ -> type_ L'import d'audio/input d'AEEA quedara coherent (mateix estil). Diff net: 30 fitxers, +437/-437 (la majoria es renames simetrics). Co-Authored-By: Claude Opus 4.7 (1M context) --- source/core/entities/entitat.hpp | 49 ---- source/core/entities/entity.hpp | 49 ++++ source/core/graphics/shape.cpp | 8 +- source/core/graphics/shape.hpp | 4 +- source/core/graphics/starfield.cpp | 4 +- source/core/graphics/starfield.hpp | 4 +- source/core/physics/collision.hpp | 12 +- source/core/rendering/shape_renderer.cpp | 4 +- source/core/rendering/shape_renderer.hpp | 2 +- source/game/effects/debris_manager.cpp | 6 +- source/game/effects/debris_manager.hpp | 4 +- .../game/effects/gestor_puntuacio_flotant.cpp | 4 +- .../game/effects/gestor_puntuacio_flotant.hpp | 4 +- source/game/entities/{bala.cpp => bullet.cpp} | 50 ++-- source/game/entities/{bala.hpp => bullet.hpp} | 28 +-- .../game/entities/{enemic.cpp => enemy.cpp} | 150 ++++++------ .../game/entities/{enemic.hpp => enemy.hpp} | 50 ++-- source/game/entities/nau.hpp | 62 ----- source/game/entities/{nau.cpp => ship.cpp} | 92 ++++---- source/game/entities/ship.hpp | 62 +++++ source/game/escenes/escena_joc.cpp | 218 +++++++++--------- source/game/escenes/escena_joc.hpp | 18 +- source/game/escenes/escena_logo.cpp | 20 +- source/game/escenes/escena_logo.hpp | 4 +- source/game/escenes/escena_titol.cpp | 26 +-- source/game/escenes/escena_titol.hpp | 4 +- source/game/stage_system/spawn_controller.cpp | 32 +-- source/game/stage_system/spawn_controller.hpp | 16 +- source/game/stage_system/stage_manager.cpp | 8 +- source/game/stage_system/stage_manager.hpp | 4 +- source/game/title/ship_animator.cpp | 6 +- source/game/title/ship_animator.hpp | 6 +- 32 files changed, 505 insertions(+), 505 deletions(-) delete mode 100644 source/core/entities/entitat.hpp create mode 100644 source/core/entities/entity.hpp rename source/game/entities/{bala.cpp => bullet.cpp} (73%) rename source/game/entities/{bala.hpp => bullet.hpp} (59%) rename source/game/entities/{enemic.cpp => enemy.cpp} (83%) rename source/game/entities/{enemic.hpp => enemy.hpp} (72%) delete mode 100644 source/game/entities/nau.hpp rename source/game/entities/{nau.cpp => ship.cpp} (69%) create mode 100644 source/game/entities/ship.hpp diff --git a/source/core/entities/entitat.hpp b/source/core/entities/entitat.hpp deleted file mode 100644 index a9882bb..0000000 --- a/source/core/entities/entitat.hpp +++ /dev/null @@ -1,49 +0,0 @@ -// entitat.hpp - Classe base abstracta per a totes les entitats del joc -// © 2025 Orni Attack - Arquitectura d'entitats - -#pragma once - -#include - -#include - -#include "core/graphics/shape.hpp" -#include "core/types.hpp" - -namespace Entities { - -class Entitat { - public: - virtual ~Entitat() = default; - - // Interfície principal (virtual pur) - virtual void inicialitzar() = 0; - virtual void actualitzar(float delta_time) = 0; - virtual void dibuixar() const = 0; - [[nodiscard]] virtual bool esta_actiu() const = 0; - - // Interfície de col·lisió (override opcional) - [[nodiscard]] virtual float get_collision_radius() const { return 0.0F; } - [[nodiscard]] virtual bool es_collidable() const { return false; } - - // Getters comuns (inline, sense overhead) - [[nodiscard]] const Vec2& get_centre() const { return centre_; } - [[nodiscard]] float get_angle() const { return angle_; } - [[nodiscard]] float get_brightness() const { return brightness_; } - [[nodiscard]] const std::shared_ptr& get_forma() const { return forma_; } - - protected: - // Estat comú (accés directe, sense overhead) - SDL_Renderer* renderer_; - std::shared_ptr forma_; - Vec2 centre_; - float angle_{0.0F}; - float brightness_{1.0F}; - - // Constructor protegit (classe abstracta) - Entitat(SDL_Renderer* renderer = nullptr) - : renderer_(renderer), - centre_({.x = 0.0F, .y = 0.0F}) {} -}; - -} // namespace Entities diff --git a/source/core/entities/entity.hpp b/source/core/entities/entity.hpp new file mode 100644 index 0000000..52b085e --- /dev/null +++ b/source/core/entities/entity.hpp @@ -0,0 +1,49 @@ +// entitat.hpp - Classe base abstracta per a totes les entitats del joc +// © 2025 Orni Attack - Arquitectura d'entitats + +#pragma once + +#include + +#include + +#include "core/graphics/shape.hpp" +#include "core/types.hpp" + +namespace Entities { + +class Entity { + public: + virtual ~Entity() = default; + + // Interfície principal (virtual pur) + virtual void init() = 0; + virtual void update(float delta_time) = 0; + virtual void draw() const = 0; + [[nodiscard]] virtual bool isActive() const = 0; + + // Interfície de col·lisió (override opcional) + [[nodiscard]] virtual float getCollisionRadius() const { return 0.0F; } + [[nodiscard]] virtual bool isCollidable() const { return false; } + + // Getters comuns (inline, sense overhead) + [[nodiscard]] const Vec2& getCenter() const { return center_; } + [[nodiscard]] float getAngle() const { return angle_; } + [[nodiscard]] float getBrightness() const { return brightness_; } + [[nodiscard]] const std::shared_ptr& getShape() const { return shape_; } + + protected: + // Estat comú (accés directe, sense overhead) + SDL_Renderer* renderer_; + std::shared_ptr shape_; + Vec2 center_; + float angle_{0.0F}; + float brightness_{1.0F}; + + // Constructor protegit (classe abstracta) + Entity(SDL_Renderer* renderer = nullptr) + : renderer_(renderer), + center_({.x = 0.0F, .y = 0.0F}) {} +}; + +} // namespace Entities diff --git a/source/core/graphics/shape.cpp b/source/core/graphics/shape.cpp index c69ac70..b7f0af9 100644 --- a/source/core/graphics/shape.cpp +++ b/source/core/graphics/shape.cpp @@ -11,7 +11,7 @@ namespace Graphics { Shape::Shape(const std::string& filepath) - : centre_({.x = 0.0F, .y = 0.0F}), + : center_({.x = 0.0F, .y = 0.0F}), escala_defecte_(1.0F), nom_("unnamed") { carregar(filepath); @@ -124,11 +124,11 @@ void Shape::parse_center(const std::string& value) { size_t comma = val.find(','); if (comma != std::string::npos) { try { - centre_.x = std::stof(trim(val.substr(0, comma))); - centre_.y = std::stof(trim(val.substr(comma + 1))); + center_.x = std::stof(trim(val.substr(0, comma))); + center_.y = std::stof(trim(val.substr(comma + 1))); } catch (...) { std::cerr << "[Shape] Warning: centre invàlid, usant (0,0)" << '\n'; - centre_ = {.x = 0.0F, .y = 0.0F}; + center_ = {.x = 0.0F, .y = 0.0F}; } } } diff --git a/source/core/graphics/shape.hpp b/source/core/graphics/shape.hpp index c206813..f20ffdd 100644 --- a/source/core/graphics/shape.hpp +++ b/source/core/graphics/shape.hpp @@ -39,7 +39,7 @@ class Shape { [[nodiscard]] const std::vector& get_primitives() const { return primitives_; } - [[nodiscard]] const Vec2& get_centre() const { return centre_; } + [[nodiscard]] const Vec2& getCenter() const { return center_; } [[nodiscard]] float get_escala_defecte() const { return escala_defecte_; } [[nodiscard]] bool es_valida() const { return !primitives_.empty(); } @@ -49,7 +49,7 @@ class Shape { private: std::vector primitives_; - Vec2 centre_; // Centre/origen de la forma + Vec2 center_; // Centre/origen de la forma float escala_defecte_; // Escala per defecte (normalment 1.0) std::string nom_; // Nom de la forma (per depuració) diff --git a/source/core/graphics/starfield.cpp b/source/core/graphics/starfield.cpp index 6f5fa79..4f4044a 100644 --- a/source/core/graphics/starfield.cpp +++ b/source/core/graphics/starfield.cpp @@ -113,7 +113,7 @@ float Starfield::calcular_brightness(const Estrella& estrella) const { } // Actualitzar posicions de les estrelles -void Starfield::actualitzar(float delta_time) { +void Starfield::update(float delta_time) { for (auto& estrella : estrelles_) { // Obtenir configuració de la capa const CapaConfig& capa = capes_[estrella.capa]; @@ -145,7 +145,7 @@ void Starfield::set_brightness(float multiplier) { } // Dibuixar totes les estrelles -void Starfield::dibuixar() { +void Starfield::draw() { if (!shape_estrella_->es_valida()) { return; } diff --git a/source/core/graphics/starfield.hpp b/source/core/graphics/starfield.hpp index 34e71cf..6304154 100644 --- a/source/core/graphics/starfield.hpp +++ b/source/core/graphics/starfield.hpp @@ -35,10 +35,10 @@ class Starfield { int densitat = 150); // Actualitzar posicions de les estrelles - void actualitzar(float delta_time); + void update(float delta_time); // Dibuixar totes les estrelles - void dibuixar(); + void draw(); // Setters per ajustar paràmetres en temps real void set_punt_fuga(const Vec2& punt) { punt_fuga_ = punt; } diff --git a/source/core/physics/collision.hpp b/source/core/physics/collision.hpp index 2a67483..0891fd4 100644 --- a/source/core/physics/collision.hpp +++ b/source/core/physics/collision.hpp @@ -3,25 +3,25 @@ #pragma once -#include "core/entities/entitat.hpp" +#include "core/entities/entity.hpp" #include "core/types.hpp" namespace Physics { // Comprovació genèrica de col·lisió entre dues entitats -inline bool check_collision(const Entities::Entitat& a, const Entities::Entitat& b, float amplifier = 1.0F) { +inline bool check_collision(const Entities::Entity& a, const Entities::Entity& b, float amplifier = 1.0F) { // Comprovar si ambdós són col·lisionables - if (!a.es_collidable() || !b.es_collidable()) { + if (!a.isCollidable() || !b.isCollidable()) { return false; } // Calcular radi combinat (amb amplificador per hitbox generós) - float suma_radis = (a.get_collision_radius() + b.get_collision_radius()) * amplifier; + float suma_radis = (a.getCollisionRadius() + b.getCollisionRadius()) * amplifier; float suma_radis_sq = suma_radis * suma_radis; // Comprovació distància al quadrat (sense sqrt) - const Vec2& pos_a = a.get_centre(); - const Vec2& pos_b = b.get_centre(); + const Vec2& pos_a = a.getCenter(); + const Vec2& pos_b = b.getCenter(); float dx = pos_a.x - pos_b.x; float dy = pos_a.y - pos_b.y; float dist_sq = (dx * dx) + (dy * dy); diff --git a/source/core/rendering/shape_renderer.cpp b/source/core/rendering/shape_renderer.cpp index a35a809..5873bfb 100644 --- a/source/core/rendering/shape_renderer.cpp +++ b/source/core/rendering/shape_renderer.cpp @@ -85,13 +85,13 @@ void render_shape(SDL_Renderer* renderer, return; } - // Si progress < 1.0, no dibuixar (tot o res) + // Si progress < 1.0, no draw (tot o res) if (progress < 1.0F) { return; } // Obtenir el centre de la forma per a transformacions - const Vec2& shape_centre = shape->get_centre(); + const Vec2& shape_centre = shape->getCenter(); // Iterar sobre totes les primitives for (const auto& primitive : shape->get_primitives()) { diff --git a/source/core/rendering/shape_renderer.hpp b/source/core/rendering/shape_renderer.hpp index 72f8242..64e838b 100644 --- a/source/core/rendering/shape_renderer.hpp +++ b/source/core/rendering/shape_renderer.hpp @@ -34,7 +34,7 @@ struct Rotation3D { // Renderitzar forma amb transformacions // - renderer: SDL renderer -// - shape: forma vectorial a dibuixar +// - shape: forma vectorial a draw // - posicio: posició del centre en coordenades mundials // - angle: rotació en radians (0 = amunt, sentit horari) // - escala: factor d'escala (1.0 = mida original) diff --git a/source/game/effects/debris_manager.cpp b/source/game/effects/debris_manager.cpp index 10865c1..da3977f 100644 --- a/source/game/effects/debris_manager.cpp +++ b/source/game/effects/debris_manager.cpp @@ -62,7 +62,7 @@ void DebrisManager::explotar(const std::shared_ptr& shape, Audio::get()->playSound(sound, Audio::Group::GAME); // Obtenir centre de la forma per a transformacions - const Vec2& shape_centre = shape->get_centre(); + const Vec2& shape_centre = shape->getCenter(); // Iterar sobre totes les primitives de la forma for (const auto& primitive : shape->get_primitives()) { @@ -204,7 +204,7 @@ void DebrisManager::explotar(const std::shared_ptr& shape, } } -void DebrisManager::actualitzar(float delta_time) { +void DebrisManager::update(float delta_time) { for (auto& debris : debris_pool_) { if (!debris.actiu) { continue; @@ -302,7 +302,7 @@ void DebrisManager::actualitzar(float delta_time) { } } -void DebrisManager::dibuixar() const { +void DebrisManager::draw() const { for (const auto& debris : debris_pool_) { if (!debris.actiu) { continue; diff --git a/source/game/effects/debris_manager.hpp b/source/game/effects/debris_manager.hpp index 4020ab5..93fe099 100644 --- a/source/game/effects/debris_manager.hpp +++ b/source/game/effects/debris_manager.hpp @@ -42,10 +42,10 @@ class DebrisManager { const std::string& sound = Defaults::Sound::EXPLOSION); // Actualitzar tots els fragments actius - void actualitzar(float delta_time); + void update(float delta_time); // Dibuixar tots els fragments actius - void dibuixar() const; + void draw() const; // Reiniciar tots els fragments (neteja) void reiniciar(); diff --git a/source/game/effects/gestor_puntuacio_flotant.cpp b/source/game/effects/gestor_puntuacio_flotant.cpp index 4376f7a..2f0156e 100644 --- a/source/game/effects/gestor_puntuacio_flotant.cpp +++ b/source/game/effects/gestor_puntuacio_flotant.cpp @@ -33,7 +33,7 @@ void GestorPuntuacioFlotant::crear(int punts, const Vec2& posicio) { pf->actiu = true; } -void GestorPuntuacioFlotant::actualitzar(float delta_time) { +void GestorPuntuacioFlotant::update(float delta_time) { for (auto& pf : pool_) { if (!pf.actiu) { continue; @@ -57,7 +57,7 @@ void GestorPuntuacioFlotant::actualitzar(float delta_time) { } } -void GestorPuntuacioFlotant::dibuixar() { +void GestorPuntuacioFlotant::draw() { for (const auto& pf : pool_) { if (!pf.actiu) { continue; diff --git a/source/game/effects/gestor_puntuacio_flotant.hpp b/source/game/effects/gestor_puntuacio_flotant.hpp index 0b4b1b8..f276bb4 100644 --- a/source/game/effects/gestor_puntuacio_flotant.hpp +++ b/source/game/effects/gestor_puntuacio_flotant.hpp @@ -26,10 +26,10 @@ class GestorPuntuacioFlotant { void crear(int punts, const Vec2& posicio); // Actualitzar tots els números actius - void actualitzar(float delta_time); + void update(float delta_time); // Dibuixar tots els números actius - void dibuixar(); + void draw(); // Reiniciar tots (neteja) void reiniciar(); diff --git a/source/game/entities/bala.cpp b/source/game/entities/bullet.cpp similarity index 73% rename from source/game/entities/bala.cpp rename to source/game/entities/bullet.cpp index b3d2bc7..c195b93 100644 --- a/source/game/entities/bala.cpp +++ b/source/game/entities/bullet.cpp @@ -2,7 +2,7 @@ // © 1999 Visente i Sergi (versió Pascal) // © 2025 Port a C++20 amb SDL3 -#include "game/entities/bala.hpp" +#include "game/entities/bullet.hpp" #include #include @@ -11,15 +11,15 @@ #include "core/audio/audio.hpp" #include "core/defaults.hpp" -#include "core/entities/entitat.hpp" +#include "core/entities/entity.hpp" #include "core/graphics/shape_loader.hpp" #include "core/rendering/shape_renderer.hpp" #include "core/types.hpp" #include "game/constants.hpp" -Bala::Bala(SDL_Renderer* renderer) - : Entitat(renderer), - velocitat_(0.0F), +Bullet::Bullet(SDL_Renderer* renderer) + : Entity(renderer), + velocity_(0.0F), esta_(false), owner_id_(0), grace_timer_(0.0F) { @@ -27,23 +27,23 @@ Bala::Bala(SDL_Renderer* renderer) brightness_ = Defaults::Brightness::BALA; // [NUEVO] Carregar forma compartida des de fitxer - forma_ = Graphics::ShapeLoader::load("bullet.shp"); + shape_ = Graphics::ShapeLoader::load("bullet.shp"); - if (!forma_ || !forma_->es_valida()) { - std::cerr << "[Bala] Error: no s'ha pogut carregar bullet.shp" << '\n'; + if (!shape_ || !shape_->es_valida()) { + std::cerr << "[Bullet] Error: no s'ha pogut carregar bullet.shp" << '\n'; } } -void Bala::inicialitzar() { +void Bullet::init() { // Inicialment inactiva esta_ = false; - centre_ = {.x = 0.0F, .y = 0.0F}; + center_ = {.x = 0.0F, .y = 0.0F}; angle_ = 0.0F; - velocitat_ = 0.0F; + velocity_ = 0.0F; grace_timer_ = 0.0F; } -void Bala::disparar(const Vec2& posicio, float angle, uint8_t owner_id) { +void Bullet::disparar(const Vec2& posicio, float angle, uint8_t owner_id) { // Activar bala i posicionar-la a la nau // Basat en joc_asteroides.cpp línies 188-200 @@ -51,8 +51,8 @@ void Bala::disparar(const Vec2& posicio, float angle, uint8_t owner_id) { esta_ = true; // Posició inicial = centre de la nau - centre_.x = posicio.x; - centre_.y = posicio.y; + center_.x = posicio.x; + center_.y = posicio.y; // Angle = angle de la nau (dispara en la direcció que apunta) angle_ = angle; @@ -62,7 +62,7 @@ void Bala::disparar(const Vec2& posicio, float angle, uint8_t owner_id) { // Velocitat alta (el joc Pascal original usava 7 px/frame) // 7 px/frame × 20 FPS = 140 px/s - velocitat_ = 140.0F; + velocity_ = 140.0F; // Activar grace period (prevents instant self-collision) grace_timer_ = Defaults::Game::BULLET_GRACE_PERIOD; @@ -71,7 +71,7 @@ void Bala::disparar(const Vec2& posicio, float angle, uint8_t owner_id) { Audio::get()->playSound(Defaults::Sound::LASER, Audio::Group::GAME); } -void Bala::actualitzar(float delta_time) { +void Bullet::update(float delta_time) { if (esta_) { // Decrementar grace timer if (grace_timer_ > 0.0F) { @@ -83,30 +83,30 @@ void Bala::actualitzar(float delta_time) { } } -void Bala::dibuixar() const { - if (esta_ && forma_) { +void Bullet::draw() const { + if (esta_ && shape_) { // [NUEVO] Usar render_shape en lloc de rota_pol // Les bales roten segons l'angle de trajectòria - Rendering::render_shape(renderer_, forma_, centre_, angle_, 1.0F, 1.0F, brightness_); + Rendering::render_shape(renderer_, shape_, center_, angle_, 1.0F, 1.0F, brightness_); } } -void Bala::mou(float delta_time) { +void Bullet::mou(float delta_time) { // Moviment rectilini de la bala // Basat en el codi Pascal original: procedure mou_bales // Copiat EXACTAMENT de joc_asteroides.cpp línies 396-419 // Calcular nova posició (moviment polar time-based) // velocitat ja està en px/s (140 px/s), només cal multiplicar per delta_time - float velocitat_efectiva = velocitat_ * delta_time; + float velocitat_efectiva = velocity_ * delta_time; // Calcular desplaçament (angle-PI/2 perquè angle=0 apunta amunt) float dy = velocitat_efectiva * std::sin(angle_ - (Constants::PI / 2.0F)); float dx = velocitat_efectiva * std::cos(angle_ - (Constants::PI / 2.0F)); // Acumulació directa amb precisió subpíxel - centre_.y += dy; - centre_.x += dx; + center_.y += dy; + center_.x += dx; // Desactivar si surt de la zona de joc (no rebota com els ORNIs) // CORRECCIÓ: Usar límits segurs amb radi de la bala @@ -120,8 +120,8 @@ void Bala::mou(float delta_time) { min_y, max_y); - if (centre_.x < min_x || centre_.x > max_x || - centre_.y < min_y || centre_.y > max_y) { + if (center_.x < min_x || center_.x > max_x || + center_.y < min_y || center_.y > max_y) { esta_ = false; } } diff --git a/source/game/entities/bala.hpp b/source/game/entities/bullet.hpp similarity index 59% rename from source/game/entities/bala.hpp rename to source/game/entities/bullet.hpp index e83660d..0448a16 100644 --- a/source/game/entities/bala.hpp +++ b/source/game/entities/bullet.hpp @@ -8,28 +8,28 @@ #include #include "core/defaults.hpp" -#include "core/entities/entitat.hpp" +#include "core/entities/entity.hpp" #include "core/types.hpp" -class Bala : public Entities::Entitat { +class Bullet : public Entities::Entity { public: - Bala() - : Entitat(nullptr) {} - Bala(SDL_Renderer* renderer); + Bullet() + : Entity(nullptr) {} + Bullet(SDL_Renderer* renderer); - void inicialitzar() override; + void init() override; void disparar(const Vec2& posicio, float angle, uint8_t owner_id); - void actualitzar(float delta_time) override; - void dibuixar() const override; + void update(float delta_time) override; + void draw() const override; - // Override: Interfície d'Entitat - [[nodiscard]] bool esta_actiu() const override { return esta_; } + // Override: Interfície d'Entity + [[nodiscard]] bool isActive() const override { return esta_; } // Override: Interfície de col·lisió - [[nodiscard]] float get_collision_radius() const override { + [[nodiscard]] float getCollisionRadius() const override { return Defaults::Entities::BULLET_RADIUS; } - [[nodiscard]] bool es_collidable() const override { + [[nodiscard]] bool isCollidable() const override { return esta_ && grace_timer_ <= 0.0F; } @@ -40,8 +40,8 @@ class Bala : public Entities::Entitat { void desactivar() { esta_ = false; } private: - // Membres específics de Bala (heretats: renderer_, forma_, centre_, angle_, brightness_) - float velocitat_; + // Membres específics de Bullet (heretats: renderer_, shape_, center_, angle_, brightness_) + float velocity_; bool esta_; uint8_t owner_id_; // 0=P1, 1=P2 float grace_timer_; // Grace period timer (0.0 = vulnerable) diff --git a/source/game/entities/enemic.cpp b/source/game/entities/enemy.cpp similarity index 83% rename from source/game/entities/enemic.cpp rename to source/game/entities/enemy.cpp index b21489c..e77eb70 100644 --- a/source/game/entities/enemic.cpp +++ b/source/game/entities/enemy.cpp @@ -2,7 +2,7 @@ // © 1999 Visente i Sergi (versió Pascal) // © 2025 Port a C++20 amb SDL3 -#include "game/entities/enemic.hpp" +#include "game/entities/enemy.hpp" #include #include @@ -10,19 +10,19 @@ #include #include "core/defaults.hpp" -#include "core/entities/entitat.hpp" +#include "core/entities/entity.hpp" #include "core/graphics/shape_loader.hpp" #include "core/rendering/shape_renderer.hpp" #include "core/types.hpp" #include "game/constants.hpp" -Enemic::Enemic(SDL_Renderer* renderer) - : Entitat(renderer), - velocitat_(0.0F), +Enemy::Enemy(SDL_Renderer* renderer) + : Entity(renderer), + velocity_(0.0F), drotacio_(0.0F), rotacio_(0.0F), esta_(false), - tipus_(TipusEnemic::PENTAGON), + type_(EnemyType::PENTAGON), tracking_timer_(0.0F), ship_position_(nullptr), tracking_strength_(0.5F), // Default tracking strength @@ -30,57 +30,57 @@ Enemic::Enemic(SDL_Renderer* renderer) // [NUEVO] Brightness específic per enemics brightness_ = Defaults::Brightness::ENEMIC; - // [NUEVO] Forma es carrega a inicialitzar() segons el tipus + // [NUEVO] Forma es carrega a init() segons el tipus // Constructor no carrega forma per permetre tipus diferents } -void Enemic::inicialitzar(TipusEnemic tipus, const Vec2* ship_pos) { +void Enemy::init(EnemyType tipus, const Vec2* ship_pos) { // Guardar tipus - tipus_ = tipus; + type_ = tipus; // Carregar forma segons el tipus const char* shape_file; float drotacio_min; float drotacio_max; - switch (tipus_) { - case TipusEnemic::PENTAGON: + switch (type_) { + case EnemyType::PENTAGON: shape_file = Defaults::Enemies::Pentagon::SHAPE_FILE; - velocitat_ = Defaults::Enemies::Pentagon::VELOCITAT; + velocity_ = Defaults::Enemies::Pentagon::VELOCITAT; drotacio_min = Defaults::Enemies::Pentagon::DROTACIO_MIN; drotacio_max = Defaults::Enemies::Pentagon::DROTACIO_MAX; break; - case TipusEnemic::QUADRAT: + case EnemyType::QUADRAT: shape_file = Defaults::Enemies::Quadrat::SHAPE_FILE; - velocitat_ = Defaults::Enemies::Quadrat::VELOCITAT; + velocity_ = Defaults::Enemies::Quadrat::VELOCITAT; drotacio_min = Defaults::Enemies::Quadrat::DROTACIO_MIN; drotacio_max = Defaults::Enemies::Quadrat::DROTACIO_MAX; tracking_timer_ = 0.0F; break; - case TipusEnemic::MOLINILLO: + case EnemyType::MOLINILLO: shape_file = Defaults::Enemies::Molinillo::SHAPE_FILE; - velocitat_ = Defaults::Enemies::Molinillo::VELOCITAT; + velocity_ = Defaults::Enemies::Molinillo::VELOCITAT; drotacio_min = Defaults::Enemies::Molinillo::DROTACIO_MIN; drotacio_max = Defaults::Enemies::Molinillo::DROTACIO_MAX; break; default: // Fallback segur: usar valors de PENTAGON - std::cerr << "[Enemic] Error: tipus desconegut (" - << static_cast(tipus_) << "), utilitzant PENTAGON\n"; + std::cerr << "[Enemy] Error: tipus desconegut (" + << static_cast(type_) << "), utilitzant PENTAGON\n"; shape_file = Defaults::Enemies::Pentagon::SHAPE_FILE; - velocitat_ = Defaults::Enemies::Pentagon::VELOCITAT; + velocity_ = Defaults::Enemies::Pentagon::VELOCITAT; drotacio_min = Defaults::Enemies::Pentagon::DROTACIO_MIN; drotacio_max = Defaults::Enemies::Pentagon::DROTACIO_MAX; break; } // Carregar forma - forma_ = Graphics::ShapeLoader::load(shape_file); - if (!forma_ || !forma_->es_valida()) { - std::cerr << "[Enemic] Error: no s'ha pogut carregar " << shape_file << '\n'; + shape_ = Graphics::ShapeLoader::load(shape_file); + if (!shape_ || !shape_->es_valida()) { + std::cerr << "[Enemy] Error: no s'ha pogut carregar " << shape_file << '\n'; } // [MODIFIED] Posició aleatòria amb comprovació de seguretat @@ -103,8 +103,8 @@ void Enemic::inicialitzar(TipusEnemic tipus, const Vec2* ship_pos) { float candidate_y; if (intent_spawn_safe(*ship_pos, candidate_x, candidate_y)) { - centre_.x = candidate_x; - centre_.y = candidate_y; + center_.x = candidate_x; + center_.y = candidate_y; found_safe_position = true; break; } @@ -114,18 +114,18 @@ void Enemic::inicialitzar(TipusEnemic tipus, const Vec2* ship_pos) { // Fallback: spawn anywhere (user's preference) int range_x = static_cast(max_x - min_x); int range_y = static_cast(max_y - min_y); - centre_.x = static_cast((std::rand() % range_x) + static_cast(min_x)); - centre_.y = static_cast((std::rand() % range_y) + static_cast(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 << "[Enemic] Advertència: spawn sense zona segura després de " + std::cout << "[Enemy] Advertència: spawn sense zona segura després de " << Defaults::Enemies::Spawn::MAX_SPAWN_ATTEMPTS << " intents" << '\n'; } } else { // [EXISTING] No ship position: spawn anywhere (backward compatibility) int range_x = static_cast(max_x - min_x); int range_y = static_cast(max_y - min_y); - centre_.x = static_cast((std::rand() % range_x) + static_cast(min_x)); - centre_.y = static_cast((std::rand() % range_y) + static_cast(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)); } // Angle aleatori de moviment @@ -137,7 +137,7 @@ void Enemic::inicialitzar(TipusEnemic tipus, const Vec2* ship_pos) { rotacio_ = 0.0F; // Inicialitzar estat d'animació - animacio_ = AnimacioEnemic(); // Reset to defaults + animacio_ = EnemyAnimation(); // Reset to defaults animacio_.drotacio_base = drotacio_; animacio_.drotacio_objetivo = drotacio_; animacio_.drotacio_t = 1.0F; // Start without interpolating @@ -150,7 +150,7 @@ void Enemic::inicialitzar(TipusEnemic tipus, const Vec2* ship_pos) { esta_ = true; } -void Enemic::actualitzar(float delta_time) { +void Enemy::update(float delta_time) { if (esta_) { // [NEW] Update invulnerability timer and brightness if (timer_invulnerabilitat_ > 0.0F) { @@ -179,26 +179,26 @@ void Enemic::actualitzar(float delta_time) { } } -void Enemic::dibuixar() const { - if (esta_ && forma_) { +void Enemy::draw() const { + if (esta_ && shape_) { // Calculate animated scale (includes invulnerability LERP) float escala = calcular_escala_actual(); - // brightness_ is already updated in actualitzar() - Rendering::render_shape(renderer_, forma_, centre_, rotacio_, escala, 1.0F, brightness_); + // brightness_ is already updated in update() + Rendering::render_shape(renderer_, shape_, center_, rotacio_, escala, 1.0F, brightness_); } } -void Enemic::mou(float delta_time) { +void Enemy::mou(float delta_time) { // Dispatcher: crida el comportament específic segons el tipus - switch (tipus_) { - case TipusEnemic::PENTAGON: + switch (type_) { + case EnemyType::PENTAGON: comportament_pentagon(delta_time); break; - case TipusEnemic::QUADRAT: + case EnemyType::QUADRAT: comportament_quadrat(delta_time); break; - case TipusEnemic::MOLINILLO: + case EnemyType::MOLINILLO: comportament_molinillo(delta_time); break; default: @@ -208,18 +208,18 @@ void Enemic::mou(float delta_time) { } } -void Enemic::comportament_pentagon(float delta_time) { +void Enemy::comportament_pentagon(float delta_time) { // Pentagon: zigzag esquivador (frequent direction changes) // Similar a comportament original però amb probabilitat més alta - float velocitat_efectiva = velocitat_ * delta_time; + float velocitat_efectiva = velocity_ * delta_time; // Calcular desplaçament (angle-PI/2 perquè angle=0 apunta amunt) float dy = velocitat_efectiva * std::sin(angle_ - (Constants::PI / 2.0F)); float dx = velocitat_efectiva * std::cos(angle_ - (Constants::PI / 2.0F)); - float new_y = centre_.y + dy; - float new_x = centre_.x + dx; + float new_y = center_.y + dy; + float new_x = center_.x + dx; // Obtenir límits segurs float min_x; @@ -234,7 +234,7 @@ void Enemic::comportament_pentagon(float delta_time) { // Zigzag: canvi d'angle més freqüent en tocar límits if (new_y >= min_y && new_y <= max_y) { - centre_.y = new_y; + center_.y = new_y; } else { // Probabilitat més alta de canvi d'angle if (static_cast(std::rand()) / RAND_MAX < Defaults::Enemies::Pentagon::CANVI_ANGLE_PROB) { @@ -245,7 +245,7 @@ void Enemic::comportament_pentagon(float delta_time) { } if (new_x >= min_x && new_x <= max_x) { - centre_.x = new_x; + center_.x = new_x; } else { if (static_cast(std::rand()) / RAND_MAX < Defaults::Enemies::Pentagon::CANVI_ANGLE_PROB) { float rand_angle = (static_cast(std::rand()) / RAND_MAX) * @@ -255,7 +255,7 @@ void Enemic::comportament_pentagon(float delta_time) { } } -void Enemic::comportament_quadrat(float delta_time) { +void Enemy::comportament_quadrat(float delta_time) { // Quadrat: perseguidor (tracks player position) // Update tracking timer @@ -267,8 +267,8 @@ void Enemic::comportament_quadrat(float delta_time) { if (ship_position_ != nullptr) { // Calculate angle to ship - float dx = ship_position_->x - centre_.x; - float dy = ship_position_->y - centre_.y; + float dx = ship_position_->x - center_.x; + float dy = ship_position_->y - center_.y; float target_angle = std::atan2(dy, dx) + (Constants::PI / 2.0F); // Interpolate toward target angle @@ -288,12 +288,12 @@ void Enemic::comportament_quadrat(float delta_time) { } // Move in current direction - float velocitat_efectiva = velocitat_ * delta_time; + float velocitat_efectiva = velocity_ * delta_time; float dy = velocitat_efectiva * std::sin(angle_ - (Constants::PI / 2.0F)); float dx = velocitat_efectiva * std::cos(angle_ - (Constants::PI / 2.0F)); - float new_y = centre_.y + dy; - float new_x = centre_.x + dx; + float new_y = center_.y + dy; + float new_x = center_.x + dx; // Obtenir límits segurs float min_x; @@ -308,25 +308,25 @@ void Enemic::comportament_quadrat(float delta_time) { // Bounce on walls (simple reflection) if (new_y >= min_y && new_y <= max_y) { - centre_.y = new_y; + center_.y = new_y; } else { angle_ = -angle_; // Vertical reflection } if (new_x >= min_x && new_x <= max_x) { - centre_.x = new_x; + center_.x = new_x; } else { angle_ = Constants::PI - angle_; // Horizontal reflection } } -void Enemic::comportament_molinillo(float delta_time) { +void Enemy::comportament_molinillo(float delta_time) { // Molinillo: agressiu (fast, straight lines, proximity spin-up) // Check proximity to ship for spin-up effect if (ship_position_ != nullptr) { - float dx = ship_position_->x - centre_.x; - float dy = ship_position_->y - centre_.y; + float dx = ship_position_->x - center_.x; + float dy = ship_position_->y - center_.y; float distance = std::sqrt((dx * dx) + (dy * dy)); if (distance < Defaults::Enemies::Molinillo::PROXIMITY_DISTANCE) { @@ -340,12 +340,12 @@ void Enemic::comportament_molinillo(float delta_time) { } // Fast straight-line movement - float velocitat_efectiva = velocitat_ * delta_time; + float velocitat_efectiva = velocity_ * delta_time; float dy = velocitat_efectiva * std::sin(angle_ - (Constants::PI / 2.0F)); float dx = velocitat_efectiva * std::cos(angle_ - (Constants::PI / 2.0F)); - float new_y = centre_.y + dy; - float new_x = centre_.x + dx; + float new_y = center_.y + dy; + float new_x = center_.x + dx; // Obtenir límits segurs float min_x; @@ -360,7 +360,7 @@ void Enemic::comportament_molinillo(float delta_time) { // Rare angle changes on wall hits if (new_y >= min_y && new_y <= max_y) { - centre_.y = new_y; + center_.y = new_y; } else { if (static_cast(std::rand()) / RAND_MAX < Defaults::Enemies::Molinillo::CANVI_ANGLE_PROB) { float rand_angle = (static_cast(std::rand()) / RAND_MAX) * @@ -370,7 +370,7 @@ void Enemic::comportament_molinillo(float delta_time) { } if (new_x >= min_x && new_x <= max_x) { - centre_.x = new_x; + center_.x = new_x; } else { if (static_cast(std::rand()) / RAND_MAX < Defaults::Enemies::Molinillo::CANVI_ANGLE_PROB) { float rand_angle = (static_cast(std::rand()) / RAND_MAX) * @@ -380,12 +380,12 @@ void Enemic::comportament_molinillo(float delta_time) { } } -void Enemic::actualitzar_animacio(float delta_time) { +void Enemy::actualitzar_animacio(float delta_time) { actualitzar_palpitacio(delta_time); actualitzar_rotacio_accelerada(delta_time); } -void Enemic::actualitzar_palpitacio(float delta_time) { +void Enemy::actualitzar_palpitacio(float delta_time) { if (animacio_.palpitacio_activa) { // Advance phase (2π * frequency * dt) animacio_.palpitacio_fase += 2.0F * Constants::PI * animacio_.palpitacio_frequencia * delta_time; @@ -426,7 +426,7 @@ void Enemic::actualitzar_palpitacio(float delta_time) { } } -void Enemic::actualitzar_rotacio_accelerada(float delta_time) { +void Enemy::actualitzar_rotacio_accelerada(float delta_time) { if (animacio_.drotacio_t < 1.0F) { // Transitioning to new target animacio_.drotacio_t += delta_time / animacio_.drotacio_duracio; @@ -471,7 +471,7 @@ void Enemic::actualitzar_rotacio_accelerada(float delta_time) { } } -float Enemic::calcular_escala_actual() const { +float Enemy::calcular_escala_actual() const { float escala = 1.0F; // [NEW] Invulnerability LERP prioritza sobre palpitació @@ -497,33 +497,33 @@ float Enemic::calcular_escala_actual() const { // [NEW] Stage system API implementations -float Enemic::get_base_velocity() const { - switch (tipus_) { - case TipusEnemic::PENTAGON: +float Enemy::get_base_velocity() const { + switch (type_) { + case EnemyType::PENTAGON: return Defaults::Enemies::Pentagon::VELOCITAT; - case TipusEnemic::QUADRAT: + case EnemyType::QUADRAT: return Defaults::Enemies::Quadrat::VELOCITAT; - case TipusEnemic::MOLINILLO: + case EnemyType::MOLINILLO: return Defaults::Enemies::Molinillo::VELOCITAT; default: return Defaults::Enemies::Pentagon::VELOCITAT; // Fallback segur } } -float Enemic::get_base_rotation() const { +float Enemy::get_base_rotation() const { // Return the base rotation speed (drotacio_base if available, otherwise current drotacio_) return animacio_.drotacio_base != 0.0F ? animacio_.drotacio_base : drotacio_; } -void Enemic::set_tracking_strength(float strength) { +void Enemy::set_tracking_strength(float strength) { // Only applies to QUADRAT type - if (tipus_ == TipusEnemic::QUADRAT) { + if (type_ == EnemyType::QUADRAT) { tracking_strength_ = strength; } } // [NEW] Safe spawn helper - checks if position is away from ship -bool Enemic::intent_spawn_safe(const Vec2& ship_pos, float& out_x, float& out_y) { +bool Enemy::intent_spawn_safe(const Vec2& ship_pos, float& out_x, float& out_y) { // Generate random position within safe bounds float min_x; float max_x; diff --git a/source/game/entities/enemic.hpp b/source/game/entities/enemy.hpp similarity index 72% rename from source/game/entities/enemic.hpp rename to source/game/entities/enemy.hpp index 18c25b3..9669e3d 100644 --- a/source/game/entities/enemic.hpp +++ b/source/game/entities/enemy.hpp @@ -9,19 +9,19 @@ #include #include "core/defaults.hpp" -#include "core/entities/entitat.hpp" +#include "core/entities/entity.hpp" #include "core/types.hpp" #include "game/constants.hpp" // Tipus d'enemic -enum class TipusEnemic : uint8_t { +enum class EnemyType : uint8_t { PENTAGON = 0, // Pentàgon esquivador (zigzag) QUADRAT = 1, // Quadrat perseguidor (tracks ship) MOLINILLO = 2 // Molinillo agressiu (fast, spinning) }; // Estat d'animació (palpitació i rotació accelerada) -struct AnimacioEnemic { +struct EnemyAnimation { // Palpitation (breathing effect) bool palpitacio_activa = false; float palpitacio_fase = 0.0F; // Phase in cycle (0.0-2π) @@ -36,35 +36,35 @@ struct AnimacioEnemic { float drotacio_duracio = 0.0F; // Duration of transition (seconds) }; -class Enemic : public Entities::Entitat { +class Enemy : public Entities::Entity { public: - Enemic() - : Entitat(nullptr) {} - Enemic(SDL_Renderer* renderer); + Enemy() + : Entity(nullptr) {} + Enemy(SDL_Renderer* renderer); - void inicialitzar() override { inicialitzar(TipusEnemic::PENTAGON, nullptr); } - void inicialitzar(TipusEnemic tipus, const Vec2* ship_pos = nullptr); - void actualitzar(float delta_time) override; - void dibuixar() const override; + void init() override { init(EnemyType::PENTAGON, nullptr); } + void init(EnemyType tipus, const Vec2* ship_pos = nullptr); + void update(float delta_time) override; + void draw() const override; - // Override: Interfície d'Entitat - [[nodiscard]] bool esta_actiu() const override { return esta_; } + // Override: Interfície d'Entity + [[nodiscard]] bool isActive() const override { return esta_; } // Override: Interfície de col·lisió - [[nodiscard]] float get_collision_radius() const override { + [[nodiscard]] float getCollisionRadius() const override { return Defaults::Entities::ENEMY_RADIUS; } - [[nodiscard]] bool es_collidable() const override { + [[nodiscard]] bool isCollidable() const override { return esta_ && timer_invulnerabilitat_ <= 0.0F; } // Getters (API pública sense canvis) void destruir() { esta_ = false; } [[nodiscard]] float get_drotacio() const { return drotacio_; } - [[nodiscard]] Vec2 get_velocitat_vector() const { + [[nodiscard]] Vec2 getVelocityVector() const { return { - .x = velocitat_ * std::cos(angle_ - (Constants::PI / 2.0F)), - .y = velocitat_ * std::sin(angle_ - (Constants::PI / 2.0F))}; + .x = velocity_ * std::cos(angle_ - (Constants::PI / 2.0F)), + .y = velocity_ * std::sin(angle_ - (Constants::PI / 2.0F))}; } // Set ship position reference for tracking behavior @@ -73,10 +73,10 @@ class Enemic : public Entities::Entitat { // [NEW] Getters for stage system (base stats) [[nodiscard]] float get_base_velocity() const; [[nodiscard]] float get_base_rotation() const; - [[nodiscard]] TipusEnemic get_tipus() const { return tipus_; } + [[nodiscard]] EnemyType getType() const { return type_; } // [NEW] Setters for difficulty multipliers (stage system) - void set_velocity(float vel) { velocitat_ = vel; } + void set_velocity(float vel) { velocity_ = vel; } void set_rotation(float rot) { drotacio_ = rot; animacio_.drotacio_base = rot; @@ -84,21 +84,21 @@ class Enemic : public Entities::Entitat { void set_tracking_strength(float strength); // [NEW] Invulnerability queries - [[nodiscard]] bool es_invulnerable() const { return timer_invulnerabilitat_ > 0.0F; } + [[nodiscard]] bool isInvulnerable() const { return timer_invulnerabilitat_ > 0.0F; } [[nodiscard]] float get_temps_invulnerabilitat() const { return timer_invulnerabilitat_; } private: - // Membres específics d'Enemic (heretats: renderer_, forma_, centre_, angle_, brightness_) - float velocitat_; + // Membres específics d'Enemy (heretats: renderer_, shape_, center_, angle_, brightness_) + float velocity_; float drotacio_; // Delta rotació visual (rad/s) float rotacio_; // Rotació visual acumulada bool esta_; // [NEW] Enemy type and configuration - TipusEnemic tipus_; + EnemyType type_; // [NEW] Animation state - AnimacioEnemic animacio_; + EnemyAnimation animacio_; // [NEW] Behavior state (type-specific) float tracking_timer_; // For Quadrat: time since last angle update diff --git a/source/game/entities/nau.hpp b/source/game/entities/nau.hpp deleted file mode 100644 index ca4dc91..0000000 --- a/source/game/entities/nau.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// nau.hpp - Classe per a la nave del jugador -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 - -#pragma once -#include - -#include -#include - -#include "core/defaults.hpp" -#include "core/entities/entitat.hpp" -#include "core/types.hpp" -#include "game/constants.hpp" - -class Nau : public Entities::Entitat { - public: - Nau() - : Entitat(nullptr) {} - Nau(SDL_Renderer* renderer, const char* shape_file = "ship.shp"); - - void inicialitzar() override { inicialitzar(nullptr, false); } - void inicialitzar(const Vec2* spawn_point, bool activar_invulnerabilitat = false); - void processar_input(float delta_time, uint8_t player_id); - void actualitzar(float delta_time) override; - void dibuixar() const override; - - // Override: Interfície d'Entitat - [[nodiscard]] bool esta_actiu() const override { return !esta_tocada_; } - - // Override: Interfície de col·lisió - [[nodiscard]] float get_collision_radius() const override { - return Defaults::Entities::SHIP_RADIUS; - } - [[nodiscard]] bool es_collidable() const override { - return !esta_tocada_ && invulnerable_timer_ <= 0.0F; - } - - // Getters (API pública sense canvis) - [[nodiscard]] bool esta_viva() const { return !esta_tocada_; } - [[nodiscard]] bool esta_tocada() const { return esta_tocada_; } - [[nodiscard]] bool es_invulnerable() const { return invulnerable_timer_ > 0.0F; } - [[nodiscard]] Vec2 get_velocitat_vector() const { - return { - .x = velocitat_ * std::cos(angle_ - (Constants::PI / 2.0F)), - .y = velocitat_ * std::sin(angle_ - (Constants::PI / 2.0F))}; - } - - // Setters - void set_centre(const Vec2& nou_centre) { centre_ = nou_centre; } - - // Col·lisions (Fase 10) - void marcar_tocada() { esta_tocada_ = true; } - - private: - // Membres específics de Nau (heretats: renderer_, forma_, centre_, angle_, brightness_) - float velocitat_; // Velocitat (px/s) - bool esta_tocada_; - float invulnerable_timer_; // 0.0f = vulnerable, >0.0f = invulnerable - - void aplicar_fisica(float delta_time); -}; diff --git a/source/game/entities/nau.cpp b/source/game/entities/ship.cpp similarity index 69% rename from source/game/entities/nau.cpp rename to source/game/entities/ship.cpp index de86098..28eb4ca 100644 --- a/source/game/entities/nau.cpp +++ b/source/game/entities/ship.cpp @@ -2,7 +2,7 @@ // © 1999 Visente i Sergi (versió Pascal) // © 2025 Port a C++20 amb SDL3 -#include "game/entities/nau.hpp" +#include "game/entities/ship.hpp" #include @@ -12,7 +12,7 @@ #include #include "core/defaults.hpp" -#include "core/entities/entitat.hpp" +#include "core/entities/entity.hpp" #include "core/graphics/shape_loader.hpp" #include "core/input/input.hpp" #include "core/input/input_types.hpp" @@ -20,23 +20,23 @@ #include "core/types.hpp" #include "game/constants.hpp" -Nau::Nau(SDL_Renderer* renderer, const char* shape_file) - : Entitat(renderer), - velocitat_(0.0F), - esta_tocada_(false), +Ship::Ship(SDL_Renderer* renderer, const char* shape_file) + : Entity(renderer), + velocity_(0.0F), + is_hit_(false), invulnerable_timer_(0.0F) { // [NUEVO] Brightness específic per naus brightness_ = Defaults::Brightness::NAU; // [NUEVO] Carregar forma compartida des de fitxer - forma_ = Graphics::ShapeLoader::load(shape_file); + shape_ = Graphics::ShapeLoader::load(shape_file); - if (!forma_ || !forma_->es_valida()) { - std::cerr << "[Nau] Error: no s'ha pogut carregar " << shape_file << '\n'; + if (!shape_ || !shape_->es_valida()) { + std::cerr << "[Ship] Error: no s'ha pogut carregar " << shape_file << '\n'; } } -void Nau::inicialitzar(const Vec2* spawn_point, bool activar_invulnerabilitat) { +void Ship::init(const Vec2* spawn_point, bool activar_invulnerabilitat) { // Inicialització de la nau (triangle) // Basat en el codi Pascal original: lines 380-384 // Copiat de joc_asteroides.cpp línies 30-44 @@ -46,20 +46,20 @@ void Nau::inicialitzar(const Vec2* spawn_point, bool activar_invulnerabilitat) { // Use custom spawn point if provided, otherwise use center if (spawn_point != nullptr) { - centre_.x = spawn_point->x; - centre_.y = spawn_point->y; + center_.x = spawn_point->x; + center_.y = spawn_point->y; } else { // Default: center of play area float centre_x; float centre_y; Constants::obtenir_centre_zona(centre_x, centre_y); - centre_.x = static_cast(centre_x); - centre_.y = static_cast(centre_y); + center_.x = static_cast(centre_x); + center_.y = static_cast(centre_y); } // Estat inicial angle_ = 0.0F; - velocitat_ = 0.0F; + velocity_ = 0.0F; // Activar invulnerabilidad solo si es respawn if (activar_invulnerabilitat) { @@ -68,14 +68,14 @@ void Nau::inicialitzar(const Vec2* spawn_point, bool activar_invulnerabilitat) { invulnerable_timer_ = 0.0F; } - esta_tocada_ = false; + is_hit_ = false; } -void Nau::processar_input(float delta_time, uint8_t player_id) { +void Ship::processInput(float delta_time, uint8_t player_id) { // Processar input continu (com teclapuls() del Pascal original) // Basat en joc_asteroides.cpp línies 66-85 // Només processa input si la nau està viva - if (esta_tocada_) { + if (is_hit_) { return; } @@ -93,9 +93,9 @@ void Nau::processar_input(float delta_time, uint8_t player_id) { } if (input->checkActionPlayer1(InputAction::THRUST, Input::ALLOW_REPEAT)) { - if (velocitat_ < Defaults::Physics::MAX_VELOCITY) { - velocitat_ += Defaults::Physics::ACCELERATION * delta_time; - velocitat_ = std::min(velocitat_, Defaults::Physics::MAX_VELOCITY); + if (velocity_ < Defaults::Physics::MAX_VELOCITY) { + velocity_ += Defaults::Physics::ACCELERATION * delta_time; + velocity_ = std::min(velocity_, Defaults::Physics::MAX_VELOCITY); } } } else { @@ -109,17 +109,17 @@ void Nau::processar_input(float delta_time, uint8_t player_id) { } if (input->checkActionPlayer2(InputAction::THRUST, Input::ALLOW_REPEAT)) { - if (velocitat_ < Defaults::Physics::MAX_VELOCITY) { - velocitat_ += Defaults::Physics::ACCELERATION * delta_time; - velocitat_ = std::min(velocitat_, Defaults::Physics::MAX_VELOCITY); + if (velocity_ < Defaults::Physics::MAX_VELOCITY) { + velocity_ += Defaults::Physics::ACCELERATION * delta_time; + velocity_ = std::min(velocity_, Defaults::Physics::MAX_VELOCITY); } } } } -void Nau::actualitzar(float delta_time) { - // Només actualitzar si la nau està viva - if (esta_tocada_) { +void Ship::update(float delta_time) { + // Només update si la nau està viva + if (is_hit_) { return; } @@ -130,17 +130,17 @@ void Nau::actualitzar(float delta_time) { } // Aplicar física (moviment + fricció) - aplicar_fisica(delta_time); + applyPhysics(delta_time); } -void Nau::dibuixar() const { - // Només dibuixar si la nau està viva - if (esta_tocada_) { +void Ship::draw() const { + // Només draw si la nau està viva + if (is_hit_) { return; } // Si invulnerable, parpadear (toggle on/off) - if (es_invulnerable()) { + if (isInvulnerable()) { // Calcular ciclo de parpadeo float blink_cycle = Defaults::Ship::BLINK_VISIBLE_TIME + Defaults::Ship::BLINK_INVISIBLE_TIME; @@ -152,7 +152,7 @@ void Nau::dibuixar() const { } } - if (!forma_) { + if (!shape_) { return; } @@ -164,25 +164,25 @@ void Nau::dibuixar() const { // [NUEVO] Convertir suma de velocitat_visual a escala multiplicativa // Radio base del ship = 12 px // velocitat_visual = 0-6 → r = 12-18 → escala = 1.0-1.5 - float velocitat_visual = velocitat_ / 33.33F; + float velocitat_visual = velocity_ / 33.33F; float escala = 1.0F + (velocitat_visual / 12.0F); - Rendering::render_shape(renderer_, forma_, centre_, angle_, escala, 1.0F, brightness_); + Rendering::render_shape(renderer_, shape_, center_, angle_, escala, 1.0F, brightness_); } -void Nau::aplicar_fisica(float delta_time) { +void Ship::applyPhysics(float delta_time) { // Aplicar física de moviment // Basat en joc_asteroides.cpp línies 87-113 // Calcular nova posició basada en velocitat i angle // S'usa (angle - PI/2) perquè angle=0 apunta cap amunt, no cap a la dreta - // velocitat_ està en px/s, així que multipliquem per delta_time + // velocity_ està en px/s, així que multipliquem per delta_time float dy = - ((velocitat_ * delta_time) * std::sin(angle_ - (Constants::PI / 2.0F))) + - centre_.y; + ((velocity_ * delta_time) * std::sin(angle_ - (Constants::PI / 2.0F))) + + center_.y; float dx = - ((velocitat_ * delta_time) * std::cos(angle_ - (Constants::PI / 2.0F))) + - centre_.x; + ((velocity_ * delta_time) * std::cos(angle_ - (Constants::PI / 2.0F))) + + center_.x; // Boundary checking amb radi de la nau // CORRECCIÓ: Usar límits segurs i inequalitats inclusives @@ -198,16 +198,16 @@ void Nau::aplicar_fisica(float delta_time) { // Inequalitats inclusives (>= i <=) if (dy >= min_y && dy <= max_y) { - centre_.y = dy; + center_.y = dy; } if (dx >= min_x && dx <= max_x) { - centre_.x = dx; + center_.x = dx; } // Fricció - desacceleració gradual (time-based) - if (velocitat_ > 0.1F) { - velocitat_ -= Defaults::Physics::FRICTION * delta_time; - velocitat_ = std::max(velocitat_, 0.0F); + if (velocity_ > 0.1F) { + velocity_ -= Defaults::Physics::FRICTION * delta_time; + velocity_ = std::max(velocity_, 0.0F); } } diff --git a/source/game/entities/ship.hpp b/source/game/entities/ship.hpp new file mode 100644 index 0000000..a94caaa --- /dev/null +++ b/source/game/entities/ship.hpp @@ -0,0 +1,62 @@ +// nau.hpp - Classe per a la nave del jugador +// © 1999 Visente i Sergi (versió Pascal) +// © 2025 Port a C++20 amb SDL3 + +#pragma once +#include + +#include +#include + +#include "core/defaults.hpp" +#include "core/entities/entity.hpp" +#include "core/types.hpp" +#include "game/constants.hpp" + +class Ship : public Entities::Entity { + public: + Ship() + : Entity(nullptr) {} + Ship(SDL_Renderer* renderer, const char* shape_file = "ship.shp"); + + void init() override { init(nullptr, false); } + void init(const Vec2* spawn_point, bool activar_invulnerabilitat = false); + void processInput(float delta_time, uint8_t player_id); + void update(float delta_time) override; + void draw() const override; + + // Override: Interfície d'Entity + [[nodiscard]] bool isActive() const override { return !is_hit_; } + + // Override: Interfície de col·lisió + [[nodiscard]] float getCollisionRadius() const override { + return Defaults::Entities::SHIP_RADIUS; + } + [[nodiscard]] bool isCollidable() const override { + return !is_hit_ && invulnerable_timer_ <= 0.0F; + } + + // Getters (API pública sense canvis) + [[nodiscard]] bool isAlive() const { return !is_hit_; } + [[nodiscard]] bool isHit() const { return is_hit_; } + [[nodiscard]] bool isInvulnerable() const { return invulnerable_timer_ > 0.0F; } + [[nodiscard]] Vec2 getVelocityVector() const { + return { + .x = velocity_ * std::cos(angle_ - (Constants::PI / 2.0F)), + .y = velocity_ * std::sin(angle_ - (Constants::PI / 2.0F))}; + } + + // Setters + void setCenter(const Vec2& nou_centre) { center_ = nou_centre; } + + // Col·lisions (Fase 10) + void markHit() { is_hit_ = true; } + + private: + // Membres específics de Ship (heretats: renderer_, shape_, center_, angle_, brightness_) + float velocity_; // Velocitat (px/s) + bool is_hit_; + float invulnerable_timer_; // 0.0f = vulnerable, >0.0f = invulnerable + + void applyPhysics(float delta_time); +}; diff --git a/source/game/escenes/escena_joc.cpp b/source/game/escenes/escena_joc.cpp index 7f2dbda..4c76348 100644 --- a/source/game/escenes/escena_joc.cpp +++ b/source/game/escenes/escena_joc.cpp @@ -12,7 +12,7 @@ #include #include "core/audio/audio.hpp" -#include "core/entities/entitat.hpp" +#include "core/entities/entity.hpp" #include "core/input/input.hpp" #include "core/input/mouse.hpp" #include "core/math/easing.hpp" @@ -49,17 +49,17 @@ EscenaJoc::EscenaJoc(SDLManager& sdl, ContextEscenes& context) (void)opcio; // Suprimir warning de variable no usada // Inicialitzar naus amb renderer (P1=ship.shp, P2=ship2.shp) - naus_[0] = Nau(sdl.obte_renderer(), "ship.shp"); // Jugador 1: nave estàndar - naus_[1] = Nau(sdl.obte_renderer(), "ship2.shp"); // Jugador 2: interceptor amb ales + naus_[0] = Ship(sdl.obte_renderer(), "ship.shp"); // Jugador 1: nave estàndar + naus_[1] = Ship(sdl.obte_renderer(), "ship2.shp"); // Jugador 2: interceptor amb ales // Inicialitzar bales amb renderer for (auto& bala : bales_) { - bala = Bala(sdl.obte_renderer()); + bala = Bullet(sdl.obte_renderer()); } // Inicialitzar enemics amb renderer for (auto& enemy : orni_) { - enemy = Enemic(sdl.obte_renderer()); + enemy = Enemy(sdl.obte_renderer()); } } @@ -67,7 +67,7 @@ void EscenaJoc::executar() { std::cout << "Escena Joc: Inicialitzant...\n"; // Inicialitzar estat del joc - inicialitzar(); + init(); SDL_Event event; Uint64 last_time = SDL_GetTicks(); @@ -102,7 +102,7 @@ void EscenaJoc::executar() { } // Actualitzar física del joc amb delta_time real - actualitzar(delta_time); + update(delta_time); // Actualitzar sistema d'audio Audio::update(); @@ -117,7 +117,7 @@ void EscenaJoc::executar() { sdl_.updateRenderingContext(); // Dibuixar joc - dibuixar(); + draw(); // Presentar renderer (swap buffers) sdl_.presenta(); @@ -126,7 +126,7 @@ void EscenaJoc::executar() { std::cout << "Escena Joc: Finalitzant...\n"; } -void EscenaJoc::inicialitzar() { +void EscenaJoc::init() { // Inicialitzar generador de números aleatoris // Basat en el codi Pascal original: line 376 std::srand(static_cast(std::time(nullptr))); @@ -142,10 +142,10 @@ void EscenaJoc::inicialitzar() { // [NEW] Initialize stage manager stage_manager_ = std::make_unique(stage_config_.get()); - stage_manager_->inicialitzar(); + stage_manager_->init(); // [NEW] Set ship position reference for safe spawn (P1 for now, TODO: dual tracking) - stage_manager_->get_spawn_controller().set_ship_position(&naus_[0].get_centre()); + stage_manager_->get_spawn_controller().set_ship_position(&naus_[0].getCenter()); // Inicialitzar timers de muerte per jugador itocado_per_jugador_[0] = 0.0F; @@ -175,13 +175,13 @@ void EscenaJoc::inicialitzar() { bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; if (jugador_actiu) { - // Jugador actiu: inicialitzar normalment + // Jugador actiu: init normalment Vec2 spawn_pos = obtenir_punt_spawn(i); - naus_[i].inicialitzar(&spawn_pos, false); // No invulnerability at start + naus_[i].init(&spawn_pos, false); // No invulnerability at start std::cout << "[EscenaJoc] Jugador " << (i + 1) << " inicialitzat\n"; } else { // Jugador inactiu: marcar com a mort permanent - naus_[i].marcar_tocada(); + naus_[i].markHit(); itocado_per_jugador_[i] = 999.0F; // Valor sentinella (permanent inactiu) vides_per_jugador_[i] = 0; // Sense vides std::cout << "[EscenaJoc] Jugador " << (i + 1) << " inactiu\n"; @@ -190,14 +190,14 @@ void EscenaJoc::inicialitzar() { // [MODIFIED] Initialize enemies as inactive (stage system will spawn them) for (auto& enemy : orni_) { - enemy = Enemic(sdl_.obte_renderer()); - enemy.set_ship_position(&naus_[0].get_centre()); // Set ship reference (P1 for now) - // DON'T call enemy.inicialitzar() here - stage system handles spawning + enemy = Enemy(sdl_.obte_renderer()); + enemy.set_ship_position(&naus_[0].getCenter()); // Set ship reference (P1 for now) + // DON'T call enemy.init() here - stage system handles spawning } // Inicialitzar bales (now 6 instead of 3) for (auto& bala : bales_) { - bala.inicialitzar(); + bala.init(); } // [ELIMINAT] Iniciar música de joc (ara es gestiona en stage_manager) @@ -208,7 +208,7 @@ void EscenaJoc::inicialitzar() { init_hud_rect_sound_played_ = false; } -void EscenaJoc::actualitzar(float delta_time) { +void EscenaJoc::update(float delta_time) { // Processar disparos (state-based, no event-based) if (estat_game_over_ == EstatGameOver::NONE) { auto* input = Input::get(); @@ -271,13 +271,13 @@ void EscenaJoc::actualitzar(float delta_time) { // Still update enemies, bullets, and effects during continue screen for (auto& enemy : orni_) { - enemy.actualitzar(delta_time); + enemy.update(delta_time); } for (auto& bala : bales_) { - bala.actualitzar(delta_time); + bala.update(delta_time); } - debris_manager_.actualitzar(delta_time); - gestor_puntuacio_.actualitzar(delta_time); + debris_manager_.update(delta_time); + gestor_puntuacio_.update(delta_time); return; } @@ -297,15 +297,15 @@ void EscenaJoc::actualitzar(float delta_time) { // Enemies and bullets continue moving during game over for (auto& enemy : orni_) { - enemy.actualitzar(delta_time); + enemy.update(delta_time); } for (auto& bala : bales_) { - bala.actualitzar(delta_time); + bala.update(delta_time); } - debris_manager_.actualitzar(delta_time); - gestor_puntuacio_.actualitzar(delta_time); + debris_manager_.update(delta_time); + gestor_puntuacio_.update(delta_time); return; } @@ -327,7 +327,7 @@ void EscenaJoc::actualitzar(float delta_time) { if (vides_per_jugador_[i] > 0) { // Respawn ship en spawn position con invulnerabilidad Vec2 spawn_pos = obtenir_punt_spawn(i); - naus_[i].inicialitzar(&spawn_pos, true); + naus_[i].init(&spawn_pos, true); itocado_per_jugador_[i] = 0.0F; } else { // Player is permanently dead (out of lives) @@ -352,15 +352,15 @@ void EscenaJoc::actualitzar(float delta_time) { if (algun_jugador_mort) { // Enemies and bullets continue moving during death sequence for (auto& enemy : orni_) { - enemy.actualitzar(delta_time); + enemy.update(delta_time); } for (auto& bala : bales_) { - bala.actualitzar(delta_time); + bala.update(delta_time); } - debris_manager_.actualitzar(delta_time); - gestor_puntuacio_.actualitzar(delta_time); + debris_manager_.update(delta_time); + gestor_puntuacio_.update(delta_time); // Don't return - allow alive players to continue playing } @@ -372,9 +372,9 @@ void EscenaJoc::actualitzar(float delta_time) { switch (estat) { case StageSystem::EstatStage::INIT_HUD: { // Update stage manager timer (pot canviar l'estat!) - stage_manager_->actualitzar(delta_time); + stage_manager_->update(delta_time); - // [FIX] Si l'estat ha canviat durant actualitzar(), sortir immediatament + // [FIX] Si l'estat ha canviat durant update(), sortir immediatament // per evitar recalcular la posició de la nau amb el nou timer if (stage_manager_->get_estat() != StageSystem::EstatStage::INIT_HUD) { break; @@ -398,12 +398,12 @@ void EscenaJoc::actualitzar(float delta_time) { // [MODIFICAT] Animar AMBAS naus con sus progress respectivos if (config_partida_.jugador1_actiu && ship1_progress < 1.0F) { Vec2 pos_p1 = calcular_posicio_nau_init_hud(ship1_progress, 0); - naus_[0].set_centre(pos_p1); + naus_[0].setCenter(pos_p1); } if (config_partida_.jugador2_actiu && ship2_progress < 1.0F) { Vec2 pos_p2 = calcular_posicio_nau_init_hud(ship2_progress, 1); - naus_[1].set_centre(pos_p2); + naus_[1].setCenter(pos_p2); } // Una vegada l'animació acaba, permetre control normal @@ -416,36 +416,36 @@ void EscenaJoc::actualitzar(float delta_time) { // [DEBUG] Log entrada a LEVEL_START static bool first_entry = true; if (first_entry) { - std::cout << "[LEVEL_START] ENTERED with P1 pos.y=" << naus_[0].get_centre().y << '\n'; + std::cout << "[LEVEL_START] ENTERED with P1 pos.y=" << naus_[0].getCenter().y << '\n'; first_entry = false; } // Update countdown timer - stage_manager_->actualitzar(delta_time); + stage_manager_->update(delta_time); // [NEW] Allow both ships movement and shooting during intro for (uint8_t i = 0; i < 2; i++) { bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players - naus_[i].processar_input(delta_time, i); - naus_[i].actualitzar(delta_time); + naus_[i].processInput(delta_time, i); + naus_[i].update(delta_time); } } // [NEW] Update bullets for (auto& bala : bales_) { - bala.actualitzar(delta_time); + bala.update(delta_time); } // [NEW] Update debris - debris_manager_.actualitzar(delta_time); + debris_manager_.update(delta_time); break; } case StageSystem::EstatStage::PLAYING: { // [NEW] Update stage manager (spawns enemies, pause if BOTH dead) bool pausar_spawn = (itocado_per_jugador_[0] > 0.0F && itocado_per_jugador_[1] > 0.0F); - stage_manager_->get_spawn_controller().actualitzar(delta_time, orni_, pausar_spawn); + stage_manager_->get_spawn_controller().update(delta_time, orni_, pausar_spawn); // [NEW] Check stage completion (only when at least one player alive) bool algun_jugador_viu = (itocado_per_jugador_[0] == 0.0F || itocado_per_jugador_[1] == 0.0F); @@ -462,68 +462,68 @@ void EscenaJoc::actualitzar(float delta_time) { for (uint8_t i = 0; i < 2; i++) { bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players - naus_[i].processar_input(delta_time, i); - naus_[i].actualitzar(delta_time); + naus_[i].processInput(delta_time, i); + naus_[i].update(delta_time); } } for (auto& enemy : orni_) { - enemy.actualitzar(delta_time); + enemy.update(delta_time); } for (auto& bala : bales_) { - bala.actualitzar(delta_time); + bala.update(delta_time); } detectar_col·lisions_bales_enemics(); detectar_col·lisio_naus_enemics(); detectar_col·lisions_bales_jugadors(); - debris_manager_.actualitzar(delta_time); - gestor_puntuacio_.actualitzar(delta_time); + debris_manager_.update(delta_time); + gestor_puntuacio_.update(delta_time); break; } case StageSystem::EstatStage::LEVEL_COMPLETED: // Update countdown timer - stage_manager_->actualitzar(delta_time); + stage_manager_->update(delta_time); // [NEW] Allow both ships movement and shooting during outro for (uint8_t i = 0; i < 2; i++) { bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players - naus_[i].processar_input(delta_time, i); - naus_[i].actualitzar(delta_time); + naus_[i].processInput(delta_time, i); + naus_[i].update(delta_time); } } // [NEW] Update bullets (allow last shots to continue) for (auto& bala : bales_) { - bala.actualitzar(delta_time); + bala.update(delta_time); } // [NEW] Update debris (from last destroyed enemies) - debris_manager_.actualitzar(delta_time); - gestor_puntuacio_.actualitzar(delta_time); + debris_manager_.update(delta_time); + gestor_puntuacio_.update(delta_time); break; } } -void EscenaJoc::dibuixar() { +void EscenaJoc::draw() { // Handle CONTINUE screen if (estat_game_over_ == EstatGameOver::CONTINUE) { // Draw game background elements first dibuixar_marges(); for (const auto& enemy : orni_) { - enemy.dibuixar(); + enemy.draw(); } for (const auto& bala : bales_) { - bala.dibuixar(); + bala.draw(); } - debris_manager_.dibuixar(); - gestor_puntuacio_.dibuixar(); + debris_manager_.draw(); + gestor_puntuacio_.draw(); dibuixar_marcador(); // Draw CONTINUE screen overlay @@ -537,15 +537,15 @@ void EscenaJoc::dibuixar() { dibuixar_marges(); for (const auto& enemy : orni_) { - enemy.dibuixar(); + enemy.draw(); } for (const auto& bala : bales_) { - bala.dibuixar(); + bala.draw(); } - debris_manager_.dibuixar(); - gestor_puntuacio_.dibuixar(); + debris_manager_.draw(); + gestor_puntuacio_.draw(); // Draw centered "GAME OVER" text const std::string game_over_text = "GAME OVER"; @@ -610,12 +610,12 @@ void EscenaJoc::dibuixar() { } // [MODIFICAT] Dibuixar naus amb progress independent - if (ship1_progress > 0.0F && config_partida_.jugador1_actiu && !naus_[0].esta_tocada()) { - naus_[0].dibuixar(); + if (ship1_progress > 0.0F && config_partida_.jugador1_actiu && !naus_[0].isHit()) { + naus_[0].draw(); } - if (ship2_progress > 0.0F && config_partida_.jugador2_actiu && !naus_[1].esta_tocada()) { - naus_[1].dibuixar(); + if (ship2_progress > 0.0F && config_partida_.jugador2_actiu && !naus_[1].isHit()) { + naus_[1].draw(); } break; @@ -627,18 +627,18 @@ void EscenaJoc::dibuixar() { for (uint8_t i = 0; i < 2; i++) { bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { - naus_[i].dibuixar(); + naus_[i].draw(); } } // [NEW] Draw bullets for (const auto& bala : bales_) { - bala.dibuixar(); + bala.draw(); } // [NEW] Draw debris - debris_manager_.dibuixar(); - gestor_puntuacio_.dibuixar(); + debris_manager_.draw(); + gestor_puntuacio_.draw(); // [EXISTING] Draw intro message and score dibuixar_missatge_stage(stage_manager_->get_missatge_level_start()); @@ -652,20 +652,20 @@ void EscenaJoc::dibuixar() { for (uint8_t i = 0; i < 2; i++) { bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { - naus_[i].dibuixar(); + naus_[i].draw(); } } for (const auto& enemy : orni_) { - enemy.dibuixar(); + enemy.draw(); } for (const auto& bala : bales_) { - bala.dibuixar(); + bala.draw(); } - debris_manager_.dibuixar(); - gestor_puntuacio_.dibuixar(); + debris_manager_.draw(); + gestor_puntuacio_.draw(); dibuixar_marcador(); break; @@ -675,18 +675,18 @@ void EscenaJoc::dibuixar() { for (uint8_t i = 0; i < 2; i++) { bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { - naus_[i].dibuixar(); + naus_[i].draw(); } } // [NEW] Draw bullets (allow last shots to be visible) for (const auto& bala : bales_) { - bala.dibuixar(); + bala.draw(); } // [NEW] Draw debris (from last destroyed enemies) - debris_manager_.dibuixar(); - gestor_puntuacio_.dibuixar(); + debris_manager_.draw(); + gestor_puntuacio_.draw(); // [EXISTING] Draw completion message and score dibuixar_missatge_stage(StageSystem::Constants::MISSATGE_LEVEL_COMPLETED); @@ -699,28 +699,28 @@ void EscenaJoc::tocado(uint8_t player_id) { // Death sequence: 3 phases // Phase 1: First call (itocado_per_jugador_[player_id] == 0) - trigger explosion // Phase 2: Animation (0 < itocado_ < 3.0s) - debris animation - // Phase 3: Respawn or game over (itocado_ >= 3.0s) - handled in actualitzar() + // Phase 3: Respawn or game over (itocado_ >= 3.0s) - handled in update() if (itocado_per_jugador_[player_id] == 0.0F) { // *** PHASE 1: TRIGGER DEATH *** // Mark ship as dead (stops rendering and input) - naus_[player_id].marcar_tocada(); + naus_[player_id].markHit(); // Create ship explosion - const Vec2& ship_pos = naus_[player_id].get_centre(); - float ship_angle = naus_[player_id].get_angle(); - Vec2 vel_nau = naus_[player_id].get_velocitat_vector(); + const Vec2& ship_pos = naus_[player_id].getCenter(); + float ship_angle = naus_[player_id].getAngle(); + Vec2 vel_nau = naus_[player_id].getVelocityVector(); // Reduir a 80% la velocitat heretada per la nau (més realista) Vec2 vel_nau_80 = {.x = vel_nau.x * 0.8F, .y = vel_nau.y * 0.8F}; debris_manager_.explotar( - naus_[player_id].get_forma(), // Ship shape (3 lines) + naus_[player_id].getShape(), // Ship shape (3 lines) ship_pos, // Center position ship_angle, // Ship orientation 1.0F, // Normal scale Defaults::Physics::Debris::VELOCITAT_BASE, // 80 px/s - naus_[player_id].get_brightness(), // Heredar brightness + naus_[player_id].getBrightness(), // Heredar brightness vel_nau_80, // Heredar 80% velocitat 0.0F, // Nave: trayectorias rectas (sin drotacio) 0.0F, // Sin herencia visual (rotación aleatoria) @@ -730,8 +730,8 @@ void EscenaJoc::tocado(uint8_t player_id) { // Start death timer (non-zero to avoid re-triggering) itocado_per_jugador_[player_id] = 0.001F; } - // Phase 2 is automatic (debris updates in actualitzar()) - // Phase 3 is handled in actualitzar() when itocado_per_jugador_ >= DEATH_DURATION + // Phase 2 is automatic (debris updates in update()) + // Phase 3 is handled in update() when itocado_per_jugador_ >= DEATH_DURATION } void EscenaJoc::dibuixar_marges() const { @@ -957,18 +957,18 @@ void EscenaJoc::detectar_col·lisions_bales_enemics() { if (Physics::check_collision(bala, enemic, AMPLIFIER)) { // *** COL·LISIÓ DETECTADA *** - const Vec2& pos_enemic = enemic.get_centre(); + const Vec2& pos_enemic = enemic.getCenter(); // 1. Calculate score for enemy type int punts = 0; - switch (enemic.get_tipus()) { - case TipusEnemic::PENTAGON: + switch (enemic.getType()) { + case EnemyType::PENTAGON: punts = Defaults::Enemies::Scoring::PENTAGON_SCORE; break; - case TipusEnemic::QUADRAT: + case EnemyType::QUADRAT: punts = Defaults::Enemies::Scoring::QUADRAT_SCORE; break; - case TipusEnemic::MOLINILLO: + case EnemyType::MOLINILLO: punts = Defaults::Enemies::Scoring::MOLINILLO_SCORE; break; } @@ -984,14 +984,14 @@ void EscenaJoc::detectar_col·lisions_bales_enemics() { enemic.destruir(); // 2. Crear explosió de fragments - Vec2 vel_enemic = enemic.get_velocitat_vector(); + Vec2 vel_enemic = enemic.getVelocityVector(); debris_manager_.explotar( - enemic.get_forma(), // Forma vectorial del pentàgon + enemic.getShape(), // Forma vectorial del pentàgon pos_enemic, // Posició central 0.0F, // Angle (enemic té rotació interna) 1.0F, // Escala normal VELOCITAT_EXPLOSIO, // 50 px/s (explosió suau) - enemic.get_brightness(), // Heredar brightness + enemic.getBrightness(), // Heredar brightness vel_enemic, // Heredar velocitat enemic.get_drotacio(), // Heredar velocitat angular (trayectorias curvas) 0.0F // Sin herencia visual (rotación aleatoria) @@ -1017,17 +1017,17 @@ void EscenaJoc::detectar_col·lisio_naus_enemics() { if (itocado_per_jugador_[i] > 0.0F) { continue; } - if (!naus_[i].esta_viva()) { + if (!naus_[i].isAlive()) { continue; } - if (naus_[i].es_invulnerable()) { + if (naus_[i].isInvulnerable()) { continue; } // Check collision with all active enemies for (const auto& enemic : orni_) { // Skip collision if enemy is invulnerable - if (enemic.es_invulnerable()) { + if (enemic.isInvulnerable()) { continue; } @@ -1068,10 +1068,10 @@ void EscenaJoc::detectar_col·lisions_bales_jugadors() { if (itocado_per_jugador_[player_id] > 0.0F) { continue; } - if (!naus_[player_id].esta_viva()) { + if (!naus_[player_id].isAlive()) { continue; } - if (naus_[player_id].es_invulnerable()) { + if (naus_[player_id].isInvulnerable()) { continue; } @@ -1206,13 +1206,13 @@ void EscenaJoc::disparar_bala(uint8_t player_id) { if (itocado_per_jugador_[player_id] > 0.0F) { return; } - if (!naus_[player_id].esta_viva()) { + if (!naus_[player_id].isAlive()) { return; } // Calcular posición en la punta de la nave - const Vec2& ship_centre = naus_[player_id].get_centre(); - float ship_angle = naus_[player_id].get_angle(); + const Vec2& ship_centre = naus_[player_id].getCenter(); + float ship_angle = naus_[player_id].getAngle(); constexpr float LOCAL_TIP_X = 0.0F; constexpr float LOCAL_TIP_Y = -12.0F; @@ -1296,7 +1296,7 @@ void EscenaJoc::processar_input_continue() { // Spawn with invulnerability Vec2 spawn_pos = obtenir_punt_spawn(player_to_revive); - naus_[player_to_revive].inicialitzar(&spawn_pos, true); + naus_[player_to_revive].init(&spawn_pos, true); // Check if other player wants to continue too if (p1_start && p2_start) { @@ -1306,7 +1306,7 @@ void EscenaJoc::processar_input_continue() { itocado_per_jugador_[other_player] = 0.0F; config_partida_.jugador2_actiu = true; Vec2 spawn_pos2 = obtenir_punt_spawn(other_player); - naus_[other_player].inicialitzar(&spawn_pos2, true); + naus_[other_player].init(&spawn_pos2, true); } // Resume game @@ -1392,7 +1392,7 @@ void EscenaJoc::unir_jugador(uint8_t player_id) { // Spawn with invulnerability Vec2 spawn_pos = obtenir_punt_spawn(player_id); - naus_[player_id].inicialitzar(&spawn_pos, true); + naus_[player_id].init(&spawn_pos, true); // No visual message, just spawn (per user requirement) diff --git a/source/game/escenes/escena_joc.hpp b/source/game/escenes/escena_joc.hpp index fcd1cda..25dad6d 100644 --- a/source/game/escenes/escena_joc.hpp +++ b/source/game/escenes/escena_joc.hpp @@ -18,9 +18,9 @@ #include "game/constants.hpp" #include "game/effects/debris_manager.hpp" #include "game/effects/gestor_puntuacio_flotant.hpp" -#include "game/entities/bala.hpp" -#include "game/entities/enemic.hpp" -#include "game/entities/nau.hpp" +#include "game/entities/bullet.hpp" +#include "game/entities/enemy.hpp" +#include "game/entities/ship.hpp" #include "game/stage_system/stage_config.hpp" #include "game/stage_system/stage_manager.hpp" @@ -38,9 +38,9 @@ class EscenaJoc { ~EscenaJoc() = default; void executar(); // Bucle principal de l'escena - void inicialitzar(); - void actualitzar(float delta_time); - void dibuixar(); + void init(); + void update(float delta_time); + void draw(); private: SDLManager& sdl_; @@ -52,9 +52,9 @@ class EscenaJoc { Effects::GestorPuntuacioFlotant gestor_puntuacio_; // Estat del joc - std::array naus_; // [0]=P1, [1]=P2 - std::array orni_; - std::array bales_; // 6 balas: P1=[0,1,2], P2=[3,4,5] + std::array naus_; // [0]=P1, [1]=P2 + std::array orni_; + std::array bales_; // 6 balas: P1=[0,1,2], P2=[3,4,5] std::array itocado_per_jugador_; // Death timers per player (seconds) // Lives and game over system diff --git a/source/game/escenes/escena_logo.cpp b/source/game/escenes/escena_logo.cpp index 494bad5..2d99c91 100644 --- a/source/game/escenes/escena_logo.cpp +++ b/source/game/escenes/escena_logo.cpp @@ -108,7 +108,7 @@ void EscenaLogo::executar() { } // Actualitzar lògica - actualitzar(delta_time); + update(delta_time); // Actualitzar colors oscil·lats (efecte verd global) sdl_.updateColors(delta_time); @@ -117,7 +117,7 @@ void EscenaLogo::executar() { sdl_.updateRenderingContext(); // Dibuixar - dibuixar(); + draw(); } std::cout << "Escena Logo: Finalitzant...\n"; @@ -164,7 +164,7 @@ void EscenaLogo::inicialitzar_lletres() { // IMPORTANT: Escalar ancho i offset amb ESCALA_FINAL // per que les posicions finals coincideixin amb la mida real de les lletres float ancho = ancho_sin_escalar * ESCALA_FINAL; - float offset_centre = (forma->get_centre().x - min_x) * ESCALA_FINAL; + float offset_centre = (forma->getCenter().x - min_x) * ESCALA_FINAL; lletres_.push_back({forma, {.x = 0.0F, .y = 0.0F}, // Posició es calcularà després @@ -264,7 +264,7 @@ void EscenaLogo::actualitzar_explosions(float delta_time) { } } -void EscenaLogo::actualitzar(float delta_time) { +void EscenaLogo::update(float delta_time) { temps_estat_actual_ += delta_time; switch (estat_actual_) { @@ -326,10 +326,10 @@ void EscenaLogo::actualitzar(float delta_time) { } // Actualitzar animacions de debris - debris_manager_->actualitzar(delta_time); + debris_manager_->update(delta_time); } -void EscenaLogo::dibuixar() { +void EscenaLogo::draw() { // Fons negre sdl_.neteja(0, 0, 0); @@ -407,10 +407,10 @@ void EscenaLogo::dibuixar() { } } - // POST_EXPLOSION: No dibuixar lletres, només debris (a baix) + // POST_EXPLOSION: No draw lletres, només debris (a baix) - // Sempre dibuixar debris (si n'hi ha d'actius) - debris_manager_->dibuixar(); + // Sempre draw debris (si n'hi ha d'actius) + debris_manager_->draw(); sdl_.presenta(); } @@ -420,5 +420,5 @@ auto EscenaLogo::checkSkipButtonPressed() -> bool { } void EscenaLogo::processar_events(const SDL_Event& event) { - // No procesar eventos genéricos aquí - la lógica se movió a actualitzar() + // No procesar eventos genéricos aquí - la lógica se movió a update() } diff --git a/source/game/escenes/escena_logo.hpp b/source/game/escenes/escena_logo.hpp index 360bfc2..9b685b7 100644 --- a/source/game/escenes/escena_logo.hpp +++ b/source/game/escenes/escena_logo.hpp @@ -79,9 +79,9 @@ class EscenaLogo { // Mètodes privats void inicialitzar_lletres(); - void actualitzar(float delta_time); + void update(float delta_time); void actualitzar_explosions(float delta_time); - void dibuixar(); + void draw(); void processar_events(const SDL_Event& event); auto checkSkipButtonPressed() -> bool; diff --git a/source/game/escenes/escena_titol.cpp b/source/game/escenes/escena_titol.cpp index 2d8ecec..e260b39 100644 --- a/source/game/escenes/escena_titol.cpp +++ b/source/game/escenes/escena_titol.cpp @@ -79,7 +79,7 @@ EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context) // Inicialitzar animador de naus 3D ship_animator_ = std::make_unique(sdl_.obte_renderer()); - ship_animator_->inicialitzar(); + ship_animator_->init(); if (estat_actual_ == EstatTitol::MAIN) { // Jump to MAIN: empezar entrada inmediatamente @@ -145,7 +145,7 @@ void EscenaTitol::inicialitzar_titol() { // Escalar ancho, altura i offset amb LOGO_SCALE float ancho = ancho_sin_escalar * Defaults::Title::Layout::LOGO_SCALE; float altura = altura_sin_escalar * Defaults::Title::Layout::LOGO_SCALE; - float offset_centre = (forma->get_centre().x - min_x) * Defaults::Title::Layout::LOGO_SCALE; + float offset_centre = (forma->getCenter().x - min_x) * Defaults::Title::Layout::LOGO_SCALE; lletres_orni_.push_back({forma, {.x = 0.0F, .y = 0.0F}, ancho, altura, offset_centre}); @@ -219,7 +219,7 @@ void EscenaTitol::inicialitzar_titol() { // Escalar ancho, altura i offset amb LOGO_SCALE float ancho = ancho_sin_escalar * Defaults::Title::Layout::LOGO_SCALE; float altura = altura_sin_escalar * Defaults::Title::Layout::LOGO_SCALE; - float offset_centre = (forma->get_centre().x - min_x) * Defaults::Title::Layout::LOGO_SCALE; + float offset_centre = (forma->getCenter().x - min_x) * Defaults::Title::Layout::LOGO_SCALE; lletres_attack_.push_back({forma, {.x = 0.0F, .y = 0.0F}, ancho, altura, offset_centre}); @@ -295,7 +295,7 @@ void EscenaTitol::executar() { } // Actualitzar lògica - actualitzar(delta_time); + update(delta_time); // Actualitzar sistema d'audio Audio::update(); @@ -310,7 +310,7 @@ void EscenaTitol::executar() { sdl_.updateRenderingContext(); // Dibuixar - dibuixar(); + draw(); // Presentar renderer (swap buffers) sdl_.presenta(); @@ -319,10 +319,10 @@ void EscenaTitol::executar() { std::cout << "Escena Titol: Finalitzant...\n"; } -void EscenaTitol::actualitzar(float delta_time) { +void EscenaTitol::update(float delta_time) { // Actualitzar starfield (sempre actiu) if (starfield_) { - starfield_->actualitzar(delta_time); + starfield_->update(delta_time); } // Actualitzar naus (quan visibles) @@ -331,7 +331,7 @@ void EscenaTitol::actualitzar(float delta_time) { estat_actual_ == EstatTitol::STARFIELD || estat_actual_ == EstatTitol::MAIN || estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE)) { - ship_animator_->actualitzar(delta_time); + ship_animator_->update(delta_time); } switch (estat_actual_) { @@ -541,10 +541,10 @@ void EscenaTitol::actualitzar_animacio_logo(float delta_time) { } } -void EscenaTitol::dibuixar() { +void EscenaTitol::draw() { // Dibuixar starfield de fons (en tots els estats excepte BLACK_SCREEN) if (starfield_ && estat_actual_ != EstatTitol::BLACK_SCREEN) { - starfield_->dibuixar(); + starfield_->draw(); } // Dibuixar naus (després starfield, abans logo) @@ -553,7 +553,7 @@ void EscenaTitol::dibuixar() { estat_actual_ == EstatTitol::STARFIELD || estat_actual_ == EstatTitol::MAIN || estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE)) { - ship_animator_->dibuixar(); + ship_animator_->draw(); } // En els estats STARFIELD_FADE_IN i STARFIELD, només mostrar starfield (sense text) @@ -562,7 +562,7 @@ void EscenaTitol::dibuixar() { } // Estat MAIN i PLAYER_JOIN_PHASE: Dibuixar títol i text (sobre el starfield) - // BLACK_SCREEN: no dibuixar res (fons negre ja està netejat) + // BLACK_SCREEN: no draw res (fons negre ja està netejat) if (estat_actual_ == EstatTitol::MAIN || estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE) { // === Calcular i renderitzar ombra (només si animació activa) === if (animacio_activa_) { @@ -726,5 +726,5 @@ auto EscenaTitol::checkStartGameButtonPressed() -> bool { } void EscenaTitol::processar_events(const SDL_Event& event) { - // No procesar eventos genéricos aquí - la lógica se movió a actualitzar() + // No procesar eventos genéricos aquí - la lógica se movió a update() } diff --git a/source/game/escenes/escena_titol.hpp b/source/game/escenes/escena_titol.hpp index 1b0d216..7f6ee0c 100644 --- a/source/game/escenes/escena_titol.hpp +++ b/source/game/escenes/escena_titol.hpp @@ -102,9 +102,9 @@ class EscenaTitol { static constexpr float DURACIO_LERP = 2.0F; // 2s per arribar a amplitud completa // Mètodes privats - void actualitzar(float delta_time); + void update(float delta_time); void actualitzar_animacio_logo(float delta_time); // Actualitza l'animació orbital del logo - void dibuixar(); + void draw(); void processar_events(const SDL_Event& event); auto checkSkipButtonPressed() -> bool; auto checkStartGameButtonPressed() -> bool; diff --git a/source/game/stage_system/spawn_controller.cpp b/source/game/stage_system/spawn_controller.cpp index 70872c8..844f053 100644 --- a/source/game/stage_system/spawn_controller.cpp +++ b/source/game/stage_system/spawn_controller.cpp @@ -10,7 +10,7 @@ #include #include "core/types.hpp" -#include "game/entities/enemic.hpp" +#include "game/entities/enemy.hpp" #include "stage_config.hpp" namespace StageSystem { @@ -44,7 +44,7 @@ void SpawnController::reset() { index_spawn_actual_ = 0; } -void SpawnController::actualitzar(float delta_time, std::array& orni_array, bool pausar) { +void SpawnController::update(float delta_time, std::array& orni_array, bool pausar) { if ((config_ == nullptr) || spawn_queue_.empty()) { return; } @@ -66,7 +66,7 @@ void SpawnController::actualitzar(float delta_time, std::array& orni if (temps_transcorregut_ >= event.temps_spawn) { // Find first inactive enemy for (auto& enemic : orni_array) { - if (!enemic.esta_actiu()) { + if (!enemic.isActive()) { spawn_enemic(enemic, event.tipus, ship_position_); event.spawnejat = true; index_spawn_actual_++; @@ -89,13 +89,13 @@ bool SpawnController::tots_enemics_spawnejats() const { return index_spawn_actual_ >= spawn_queue_.size(); } -bool SpawnController::tots_enemics_destruits(const std::array& orni_array) const { +bool SpawnController::tots_enemics_destruits(const std::array& orni_array) const { if (!tots_enemics_spawnejats()) { return false; } for (const auto& enemic : orni_array) { - if (enemic.esta_actiu()) { + if (enemic.isActive()) { return false; } } @@ -103,10 +103,10 @@ bool SpawnController::tots_enemics_destruits(const std::array& orni_ return true; } -uint8_t SpawnController::get_enemics_vius(const std::array& orni_array) const { +uint8_t SpawnController::get_enemics_vius(const std::array& orni_array) const { uint8_t count = 0; for (const auto& enemic : orni_array) { - if (enemic.esta_actiu()) { + if (enemic.isActive()) { count++; } } @@ -126,38 +126,38 @@ void SpawnController::generar_spawn_events() { float spawn_time = config_->config_spawn.delay_inicial + (i * config_->config_spawn.interval_spawn); - TipusEnemic tipus = seleccionar_tipus_aleatori(); + EnemyType tipus = seleccionar_tipus_aleatori(); spawn_queue_.push_back({spawn_time, tipus, false}); } } -TipusEnemic SpawnController::seleccionar_tipus_aleatori() const { +EnemyType SpawnController::seleccionar_tipus_aleatori() const { if (config_ == nullptr) { - return TipusEnemic::PENTAGON; + return EnemyType::PENTAGON; } // Weighted random selection based on distribution int rand_val = std::rand() % 100; if (std::cmp_less(rand_val, config_->distribucio.pentagon)) { - return TipusEnemic::PENTAGON; + return EnemyType::PENTAGON; } if (rand_val < config_->distribucio.pentagon + config_->distribucio.quadrat) { - return TipusEnemic::QUADRAT; + return EnemyType::QUADRAT; } - return TipusEnemic::MOLINILLO; + return EnemyType::MOLINILLO; } -void SpawnController::spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Vec2* ship_pos) { +void SpawnController::spawn_enemic(Enemy& enemic, EnemyType tipus, const Vec2* ship_pos) { // Initialize enemy (with safe spawn if ship_pos provided) - enemic.inicialitzar(tipus, ship_pos); + enemic.init(tipus, ship_pos); // Apply difficulty multipliers aplicar_multiplicadors(enemic); } -void SpawnController::aplicar_multiplicadors(Enemic& enemic) const { +void SpawnController::aplicar_multiplicadors(Enemy& enemic) const { if (config_ == nullptr) { return; } diff --git a/source/game/stage_system/spawn_controller.hpp b/source/game/stage_system/spawn_controller.hpp index adff60c..f5cf23b 100644 --- a/source/game/stage_system/spawn_controller.hpp +++ b/source/game/stage_system/spawn_controller.hpp @@ -8,7 +8,7 @@ #include #include "core/types.hpp" -#include "game/entities/enemic.hpp" +#include "game/entities/enemy.hpp" #include "stage_config.hpp" namespace StageSystem { @@ -16,7 +16,7 @@ namespace StageSystem { // Informació de spawn planificat struct SpawnEvent { float temps_spawn; // Temps absolut (segons) per spawnejar - TipusEnemic tipus; // Tipus d'enemic + EnemyType tipus; // Tipus d'enemic bool spawnejat; // Ja s'ha processat? }; @@ -30,12 +30,12 @@ class SpawnController { void reset(); // Clear all pending spawns // Update - void actualitzar(float delta_time, std::array& orni_array, bool pausar = false); + void update(float delta_time, std::array& orni_array, bool pausar = false); // Status queries [[nodiscard]] bool tots_enemics_spawnejats() const; - [[nodiscard]] bool tots_enemics_destruits(const std::array& orni_array) const; - [[nodiscard]] uint8_t get_enemics_vius(const std::array& orni_array) const; + [[nodiscard]] bool tots_enemics_destruits(const std::array& orni_array) const; + [[nodiscard]] uint8_t get_enemics_vius(const std::array& orni_array) const; [[nodiscard]] uint8_t get_enemics_spawnejats() const; // [NEW] Set ship position reference for safe spawn @@ -49,9 +49,9 @@ class SpawnController { // Spawn generation void generar_spawn_events(); - [[nodiscard]] TipusEnemic seleccionar_tipus_aleatori() const; - void spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Vec2* ship_pos = nullptr); - void aplicar_multiplicadors(Enemic& enemic) const; + [[nodiscard]] EnemyType seleccionar_tipus_aleatori() const; + void spawn_enemic(Enemy& enemic, EnemyType tipus, const Vec2* ship_pos = nullptr); + void aplicar_multiplicadors(Enemy& enemic) const; const Vec2* ship_position_; // [NEW] Non-owning pointer to ship position }; diff --git a/source/game/stage_system/stage_manager.cpp b/source/game/stage_system/stage_manager.cpp index 6fb3d2f..00fb32b 100644 --- a/source/game/stage_system/stage_manager.cpp +++ b/source/game/stage_system/stage_manager.cpp @@ -24,7 +24,7 @@ StageManager::StageManager(const ConfigSistemaStages* config) } } -void StageManager::inicialitzar() { +void StageManager::init() { stage_actual_ = 1; carregar_stage(stage_actual_); canviar_estat(EstatStage::INIT_HUD); @@ -33,7 +33,7 @@ void StageManager::inicialitzar() { << '\n'; } -void StageManager::actualitzar(float delta_time, bool pausar_spawn) { +void StageManager::update(float delta_time, bool pausar_spawn) { switch (estat_) { case EstatStage::INIT_HUD: processar_init_hud(delta_time); @@ -129,10 +129,10 @@ void StageManager::processar_level_start(float delta_time) { void StageManager::processar_playing(float delta_time, bool pausar_spawn) { // Update spawn controller (pauses when pausar_spawn = true) - // Note: The actual enemy array update happens in EscenaJoc::actualitzar() + // Note: The actual enemy array update happens in EscenaJoc::update() // This is just for internal timekeeping (void)delta_time; // Spawn controller is updated externally - (void)pausar_spawn; // Passed to spawn_controller_.actualitzar() by EscenaJoc + (void)pausar_spawn; // Passed to spawn_controller_.update() by EscenaJoc } void StageManager::processar_level_completed(float delta_time) { diff --git a/source/game/stage_system/stage_manager.hpp b/source/game/stage_system/stage_manager.hpp index 96371de..bcf7ee9 100644 --- a/source/game/stage_system/stage_manager.hpp +++ b/source/game/stage_system/stage_manager.hpp @@ -24,8 +24,8 @@ class StageManager { explicit StageManager(const ConfigSistemaStages* config); // Lifecycle - void inicialitzar(); // Reset to stage 1 - void actualitzar(float delta_time, bool pausar_spawn = false); + void init(); // Reset to stage 1 + void update(float delta_time, bool pausar_spawn = false); // Stage progression void stage_completat(); // Call when all enemies destroyed diff --git a/source/game/title/ship_animator.cpp b/source/game/title/ship_animator.cpp index 945136a..dff2f83 100644 --- a/source/game/title/ship_animator.cpp +++ b/source/game/title/ship_animator.cpp @@ -17,7 +17,7 @@ ShipAnimator::ShipAnimator(SDL_Renderer* renderer) : renderer_(renderer) { } -void ShipAnimator::inicialitzar() { +void ShipAnimator::init() { // Carregar formes de naus amb perspectiva pre-calculada auto forma_p1 = Graphics::ShapeLoader::load("ship_perspective.shp"); // Perspectiva esquerra auto forma_p2 = Graphics::ShapeLoader::load("ship2_perspective.shp"); // Perspectiva dreta @@ -33,7 +33,7 @@ void ShipAnimator::inicialitzar() { configurar_nau_p2(naus_[1]); } -void ShipAnimator::actualitzar(float delta_time) { +void ShipAnimator::update(float delta_time) { // Dispatcher segons estat de cada nau for (auto& nau : naus_) { if (!nau.visible) { @@ -54,7 +54,7 @@ void ShipAnimator::actualitzar(float delta_time) { } } -void ShipAnimator::dibuixar() const { +void ShipAnimator::draw() const { for (const auto& nau : naus_) { if (!nau.visible) { continue; diff --git a/source/game/title/ship_animator.hpp b/source/game/title/ship_animator.hpp index efdf577..4245ace 100644 --- a/source/game/title/ship_animator.hpp +++ b/source/game/title/ship_animator.hpp @@ -64,9 +64,9 @@ class ShipAnimator { explicit ShipAnimator(SDL_Renderer* renderer); // Cicle de vida - void inicialitzar(); - void actualitzar(float delta_time); - void dibuixar() const; + void init(); + void update(float delta_time); + void draw() const; // Control d'estat (cridat per EscenaTitol) void start_entry_animation(); From 5871d29d48342ca0794c53b0a39f9595ab0cd61f Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 19 May 2026 11:41:11 +0200 Subject: [PATCH 04/27] Fase 1c: rename d'escenes i sistema d'escenes Tots els tipus, fitxers, namespace, enums i metodes relacionats amb les escenes passen del catala a l'angles seguint el .clang-tidy: Fitxers (renames git): - source/game/escenes/escena_joc.{hpp,cpp} -> game/scenes/game_scene.{hpp,cpp} - source/game/escenes/escena_titol.{hpp,cpp} -> game/scenes/title_scene.{hpp,cpp} - source/game/escenes/escena_logo.{hpp,cpp} -> game/scenes/logo_scene.{hpp,cpp} - source/core/system/context_escenes.hpp -> core/system/scene_context.hpp - Carpeta game/escenes/ -> game/scenes/ Tipus (CamelCase): - EscenaJoc -> GameScene - EscenaTitol -> TitleScene - EscenaLogo -> LogoScene - ContextEscenes -> SceneContext - Escena (enum class) -> SceneType - Opcio -> Option - EstatGameOver -> GameOverState - EstatTitol -> TitleState - EstatAnimacio -> AnimationState - ConfigPartida -> MatchConfig Namespace: - GestorEscenes -> SceneManager Valors d'enum SceneType: - TITOL -> TITLE - JOC -> GAME - EIXIR -> EXIT (LOGO mantingut) Metodes (camelBack): - executar -> run - canviar_escena -> setNextScene - escena_desti -> nextScene - opcio (getter) -> option - consumir_opcio -> consumeOption - reset_opcio -> resetOption - set_config_partida -> setMatchConfig - get_config_partida -> getMatchConfig Camps privats (lower_case_): - escena_desti_ -> next_scene_ - opcio_ -> option_ - config_partida_ -> match_config_ Co-Authored-By: Claude Opus 4.7 (1M context) --- source/core/system/context_escenes.hpp | 81 -------- source/core/system/director.cpp | 50 ++--- source/core/system/game_config.hpp | 2 +- source/core/system/global_events.cpp | 16 +- source/core/system/global_events.hpp | 6 +- source/core/system/scene_context.hpp | 81 ++++++++ .../escena_joc.cpp => scenes/game_scene.cpp} | 170 ++++++++--------- .../escena_joc.hpp => scenes/game_scene.hpp} | 18 +- .../escena_logo.cpp => scenes/logo_scene.cpp} | 94 +++++----- .../escena_logo.hpp => scenes/logo_scene.hpp} | 18 +- .../title_scene.cpp} | 176 +++++++++--------- .../title_scene.hpp} | 18 +- source/game/stage_system/stage_manager.cpp | 4 +- source/game/title/ship_animator.hpp | 2 +- 14 files changed, 368 insertions(+), 368 deletions(-) delete mode 100644 source/core/system/context_escenes.hpp create mode 100644 source/core/system/scene_context.hpp rename source/game/{escenes/escena_joc.cpp => scenes/game_scene.cpp} (90%) rename source/game/{escenes/escena_joc.hpp => scenes/game_scene.hpp} (91%) rename source/game/{escenes/escena_logo.cpp => scenes/logo_scene.cpp} (82%) rename source/game/{escenes/escena_logo.hpp => scenes/logo_scene.hpp} (88%) rename source/game/{escenes/escena_titol.cpp => scenes/title_scene.cpp} (81%) rename source/game/{escenes/escena_titol.hpp => scenes/title_scene.hpp} (91%) diff --git a/source/core/system/context_escenes.hpp b/source/core/system/context_escenes.hpp deleted file mode 100644 index 7ce2f90..0000000 --- a/source/core/system/context_escenes.hpp +++ /dev/null @@ -1,81 +0,0 @@ -// context_escenes.hpp - Sistema de gestió d'escenes i context de transicions -// © 2025 Port a C++20 - -#pragma once - -#include "core/system/game_config.hpp" - -namespace GestorEscenes { - -// Context de transició entre escenes -// Conté l'escena destinació i opcions específiques per aquella escena -class ContextEscenes { - public: - // Tipus d'escena del joc - enum class Escena { - LOGO, // Pantalla d'inici (logo JAILGAMES) - TITOL, // Pantalla de títol amb menú - JOC, // Joc principal (Asteroids) - EIXIR // Sortir del programa - }; - - // Opcions específiques per a cada escena - enum class Opcio { - NONE, // Sense opcions especials (comportament per defecte) - JUMP_TO_TITLE_MAIN, // TITOL: Saltar directament a MAIN (starfield instantani) - // MODE_DEMO, // JOC: Mode demostració amb IA (futur) - }; - - // Constructor inicial amb escena LOGO i sense opcions - ContextEscenes() = default; - - // Canviar escena amb opció específica - void canviar_escena(Escena nova_escena, Opcio opcio = Opcio::NONE) { - escena_desti_ = nova_escena; - opcio_ = opcio; - } - - // Consultar escena destinació - [[nodiscard]] auto escena_desti() const -> Escena { - return escena_desti_; - } - - // Consultar opció actual - [[nodiscard]] auto opcio() const -> Opcio { - return opcio_; - } - - // Consumir opció (retorna valor i reseteja a NONE) - // Utilitzar quan l'escena processa l'opció - [[nodiscard]] auto consumir_opcio() -> Opcio { - Opcio valor = opcio_; - opcio_ = Opcio::NONE; - return valor; - } - - // Reset opció a NONE (sense retornar valor) - void reset_opcio() { - opcio_ = Opcio::NONE; - } - - // Configurar partida abans de transicionar a JOC - void set_config_partida(const GameConfig::ConfigPartida& config) { - config_partida_ = config; - } - - // Obtenir configuració de partida (consumit per EscenaJoc) - [[nodiscard]] const GameConfig::ConfigPartida& get_config_partida() const { - return config_partida_; - } - - private: - Escena escena_desti_{Escena::LOGO}; // Escena a la qual transicionar - Opcio opcio_{Opcio::NONE}; // Opció específica per l'escena - GameConfig::ConfigPartida config_partida_; // Configuració de partida (jugadors actius, mode) -}; - -// Variable global inline per gestionar l'escena actual (backward compatibility) -// Sincronitzada amb context.escena_desti() pel Director -inline ContextEscenes::Escena actual = ContextEscenes::Escena::LOGO; - -} // namespace GestorEscenes diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 5f3eda0..e1603be 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -7,7 +7,7 @@ #include #include -#include "context_escenes.hpp" +#include "scene_context.hpp" #include "core/audio/audio.hpp" #include "core/audio/audio_cache.hpp" #include "core/defaults.hpp" @@ -17,9 +17,9 @@ #include "core/resources/resource_helper.hpp" #include "core/resources/resource_loader.hpp" #include "core/utils/path_utils.hpp" -#include "game/escenes/escena_joc.hpp" -#include "game/escenes/escena_logo.hpp" -#include "game/escenes/escena_titol.hpp" +#include "game/scenes/game_scene.hpp" +#include "game/scenes/logo_scene.hpp" +#include "game/scenes/title_scene.hpp" #include "game/options.hpp" #include "project.h" @@ -29,8 +29,8 @@ #endif // Using declarations per simplificar el codi -using GestorEscenes::ContextEscenes; -using Escena = ContextEscenes::Escena; +using SceneManager::SceneContext; +using SceneType = SceneContext::SceneType; // Constructor Director::Director(std::vector const& args) { @@ -238,35 +238,35 @@ auto Director::run() -> int { } // Crear context d'escenes - ContextEscenes context; + SceneContext context; #ifdef _DEBUG - context.canviar_escena(Escena::TITOL); + context.setNextScene(SceneType::TITLE); #else - context.canviar_escena(Escena::LOGO); + context.setNextScene(SceneType::LOGO); #endif // Bucle principal de gestió d'escenes - while (context.escena_desti() != Escena::EIXIR) { - // Sincronitzar GestorEscenes::actual amb context - // (altres sistemes encara poden llegir GestorEscenes::actual) - GestorEscenes::actual = context.escena_desti(); + while (context.nextScene() != SceneType::EXIT) { + // Sincronitzar SceneManager::actual amb context + // (altres sistemes encara poden llegir SceneManager::actual) + SceneManager::actual = context.nextScene(); - switch (context.escena_desti()) { - case Escena::LOGO: { - EscenaLogo logo(sdl, context); - logo.executar(); + switch (context.nextScene()) { + case SceneType::LOGO: { + LogoScene logo(sdl, context); + logo.run(); break; } - case Escena::TITOL: { - EscenaTitol titol(sdl, context); - titol.executar(); + case SceneType::TITLE: { + TitleScene titol(sdl, context); + titol.run(); break; } - case Escena::JOC: { - EscenaJoc joc(sdl, context); - joc.executar(); + case SceneType::GAME: { + GameScene joc(sdl, context); + joc.run(); break; } @@ -275,8 +275,8 @@ auto Director::run() -> int { } } - // Sincronitzar final amb GestorEscenes::actual - GestorEscenes::actual = Escena::EIXIR; + // Sincronitzar final amb SceneManager::actual + SceneManager::actual = SceneType::EXIT; return 0; } diff --git a/source/core/system/game_config.hpp b/source/core/system/game_config.hpp index ef0e907..e0707f1 100644 --- a/source/core/system/game_config.hpp +++ b/source/core/system/game_config.hpp @@ -11,7 +11,7 @@ enum class Mode { }; // Configuració d'una partida -struct ConfigPartida { +struct MatchConfig { bool jugador1_actiu{false}; // És actiu el jugador 1? bool jugador2_actiu{false}; // És actiu el jugador 2? Mode mode{Mode::NORMAL}; // Mode de joc diff --git a/source/core/system/global_events.cpp b/source/core/system/global_events.cpp index 0024ec2..2893bdf 100644 --- a/source/core/system/global_events.cpp +++ b/source/core/system/global_events.cpp @@ -5,18 +5,18 @@ #include -#include "context_escenes.hpp" +#include "scene_context.hpp" #include "core/input/input.hpp" #include "core/input/mouse.hpp" #include "core/rendering/sdl_manager.hpp" // Using declarations per simplificar el codi -using GestorEscenes::ContextEscenes; -using Escena = ContextEscenes::Escena; +using SceneManager::SceneContext; +using SceneType = SceneContext::SceneType; namespace GlobalEvents { -bool handle(const SDL_Event& event, SDLManager& sdl, ContextEscenes& context) { +bool handle(const SDL_Event& event, SDLManager& sdl, SceneContext& context) { // 1. Permitir que Input procese el evento (para hotplug de gamepads) auto event_msg = Input::get()->handleEvent(event); if (!event_msg.empty()) { @@ -25,8 +25,8 @@ bool handle(const SDL_Event& event, SDLManager& sdl, ContextEscenes& context) { // 2. Procesar SDL_EVENT_QUIT directamente (no es input de juego) if (event.type == SDL_EVENT_QUIT) { - context.canviar_escena(Escena::EIXIR); - GestorEscenes::actual = Escena::EIXIR; + context.setNextScene(SceneType::EXIT); + SceneManager::actual = SceneType::EXIT; return true; } @@ -54,8 +54,8 @@ bool handle(const SDL_Event& event, SDLManager& sdl, ContextEscenes& context) { return true; case SDL_SCANCODE_ESCAPE: - context.canviar_escena(Escena::EIXIR); - GestorEscenes::actual = Escena::EIXIR; + context.setNextScene(SceneType::EXIT); + SceneManager::actual = SceneType::EXIT; return true; default: diff --git a/source/core/system/global_events.hpp b/source/core/system/global_events.hpp index a11241d..b1edd60 100644 --- a/source/core/system/global_events.hpp +++ b/source/core/system/global_events.hpp @@ -8,12 +8,12 @@ // Forward declarations class SDLManager; -namespace GestorEscenes { -class ContextEscenes; +namespace SceneManager { +class SceneContext; } namespace GlobalEvents { // Processa events globals (F1/F2/F3/ESC/QUIT) // Retorna true si l'event ha estat processat i no cal seguir processant-lo -bool handle(const SDL_Event& event, SDLManager& sdl, GestorEscenes::ContextEscenes& context); +bool handle(const SDL_Event& event, SDLManager& sdl, SceneManager::SceneContext& context); } // namespace GlobalEvents diff --git a/source/core/system/scene_context.hpp b/source/core/system/scene_context.hpp new file mode 100644 index 0000000..83de5fe --- /dev/null +++ b/source/core/system/scene_context.hpp @@ -0,0 +1,81 @@ +// context_escenes.hpp - Sistema de gestió d'escenes i context de transicions +// © 2025 Port a C++20 + +#pragma once + +#include "core/system/game_config.hpp" + +namespace SceneManager { + +// Context de transició entre escenes +// Conté l'escena destinació i opcions específiques per aquella escena +class SceneContext { + public: + // Tipus d'escena del joc + enum class SceneType { + LOGO, // Pantalla d'inici (logo JAILGAMES) + TITLE, // Pantalla de títol amb menú + GAME, // Joc principal (Asteroids) + EXIT // Sortir del programa + }; + + // Opcions específiques per a cada escena + enum class Option { + NONE, // Sense opcions especials (comportament per defecte) + JUMP_TO_TITLE_MAIN, // TITLE: Saltar directament a MAIN (starfield instantani) + // MODE_DEMO, // GAME: Mode demostració amb IA (futur) + }; + + // Constructor inicial amb escena LOGO i sense opcions + SceneContext() = default; + + // Canviar escena amb opció específica + void setNextScene(SceneType next_scene, Option option = Option::NONE) { + next_scene_ = next_scene; + option_ = option; + } + + // Consultar escena destinació + [[nodiscard]] auto nextScene() const -> SceneType { + return next_scene_; + } + + // Consultar opció actual + [[nodiscard]] auto option() const -> Option { + return option_; + } + + // Consumir opció (retorna valor i reseteja a NONE) + // Utilitzar quan l'escena processa l'opció + [[nodiscard]] auto consumeOption() -> Option { + Option valor = option_; + option_ = Option::NONE; + return valor; + } + + // Reset opció a NONE (sense retornar valor) + void resetOption() { + option_ = Option::NONE; + } + + // Configurar partida abans de transicionar a GAME + void setMatchConfig(const GameConfig::MatchConfig& config) { + match_config_ = config; + } + + // Obtenir configuració de partida (consumit per GameScene) + [[nodiscard]] const GameConfig::MatchConfig& getMatchConfig() const { + return match_config_; + } + + private: + SceneType next_scene_{SceneType::LOGO}; // SceneType a la qual transicionar + Option option_{Option::NONE}; // Opció específica per l'escena + GameConfig::MatchConfig match_config_; // Configuració de partida (jugadors actius, mode) +}; + +// Variable global inline per gestionar l'escena actual (backward compatibility) +// Sincronitzada amb context.nextScene() pel Director +inline SceneContext::SceneType actual = SceneContext::SceneType::LOGO; + +} // namespace SceneManager diff --git a/source/game/escenes/escena_joc.cpp b/source/game/scenes/game_scene.cpp similarity index 90% rename from source/game/escenes/escena_joc.cpp rename to source/game/scenes/game_scene.cpp index 4c76348..2f54778 100644 --- a/source/game/escenes/escena_joc.cpp +++ b/source/game/scenes/game_scene.cpp @@ -2,7 +2,7 @@ // © 1999 Visente i Sergi (versió Pascal) // © 2025 Port a C++20 amb SDL3 -#include "escena_joc.hpp" +#include "game_scene.hpp" #include #include @@ -18,16 +18,16 @@ #include "core/math/easing.hpp" #include "core/physics/collision.hpp" #include "core/rendering/line_renderer.hpp" -#include "core/system/context_escenes.hpp" +#include "core/system/scene_context.hpp" #include "core/system/global_events.hpp" #include "game/stage_system/stage_loader.hpp" // Using declarations per simplificar el codi -using GestorEscenes::ContextEscenes; -using Escena = ContextEscenes::Escena; -using Opcio = ContextEscenes::Opcio; +using SceneManager::SceneContext; +using SceneType = SceneContext::SceneType; +using Option = SceneContext::Option; -EscenaJoc::EscenaJoc(SDLManager& sdl, ContextEscenes& context) +GameScene::GameScene(SDLManager& sdl, SceneContext& context) : sdl_(sdl), context_(context), debris_manager_(sdl.obte_renderer()), @@ -35,18 +35,18 @@ EscenaJoc::EscenaJoc(SDLManager& sdl, ContextEscenes& context) text_(sdl.obte_renderer()), init_hud_rect_sound_played_(false) { // Recuperar configuració de partida des del context - config_partida_ = context_.get_config_partida(); + match_config_ = context_.getMatchConfig(); // Debug output de la configuració - std::cout << "[EscenaJoc] Configuració de partida - P1: " - << (config_partida_.jugador1_actiu ? "ACTIU" : "INACTIU") + std::cout << "[GameScene] Configuració de partida - P1: " + << (match_config_.jugador1_actiu ? "ACTIU" : "INACTIU") << ", P2: " - << (config_partida_.jugador2_actiu ? "ACTIU" : "INACTIU") + << (match_config_.jugador2_actiu ? "ACTIU" : "INACTIU") << '\n'; // Consumir opcions (preparació per MODE_DEMO futur) - auto opcio = context_.consumir_opcio(); - (void)opcio; // Suprimir warning de variable no usada + auto option = context_.consumeOption(); + (void)option; // Suprimir warning de variable no usada // Inicialitzar naus amb renderer (P1=ship.shp, P2=ship2.shp) naus_[0] = Ship(sdl.obte_renderer(), "ship.shp"); // Jugador 1: nave estàndar @@ -63,8 +63,8 @@ EscenaJoc::EscenaJoc(SDLManager& sdl, ContextEscenes& context) } } -void EscenaJoc::executar() { - std::cout << "Escena Joc: Inicialitzant...\n"; +void GameScene::run() { + std::cout << "SceneType Joc: Inicialitzant...\n"; // Inicialitzar estat del joc init(); @@ -72,7 +72,7 @@ void EscenaJoc::executar() { SDL_Event event; Uint64 last_time = SDL_GetTicks(); - while (GestorEscenes::actual == Escena::JOC) { + while (SceneManager::actual == SceneType::GAME) { // Calcular delta_time real Uint64 current_time = SDL_GetTicks(); float delta_time = (current_time - last_time) / 1000.0F; @@ -123,10 +123,10 @@ void EscenaJoc::executar() { sdl_.presenta(); } - std::cout << "Escena Joc: Finalitzant...\n"; + std::cout << "SceneType Joc: Finalitzant...\n"; } -void EscenaJoc::init() { +void GameScene::init() { // Inicialitzar generador de números aleatoris // Basat en el codi Pascal original: line 376 std::srand(static_cast(std::time(nullptr))); @@ -135,7 +135,7 @@ void EscenaJoc::init() { if (!stage_config_) { stage_config_ = StageSystem::StageLoader::carregar("data/stages/stages.yaml"); if (!stage_config_) { - std::cerr << "[EscenaJoc] Error: no s'ha pogut carregar stages.yaml" << '\n'; + std::cerr << "[GameScene] Error: no s'ha pogut carregar stages.yaml" << '\n'; // Continue without stage system (will crash, but helps debugging) } } @@ -154,7 +154,7 @@ void EscenaJoc::init() { // Initialize lives and game over state (independent lives per player) vides_per_jugador_[0] = Defaults::Game::STARTING_LIVES; vides_per_jugador_[1] = Defaults::Game::STARTING_LIVES; - estat_game_over_ = EstatGameOver::NONE; + estat_game_over_ = GameOverState::NONE; continue_counter_ = 0; continue_tick_timer_ = 0.0F; continues_usados_ = 0; @@ -172,19 +172,19 @@ void EscenaJoc::init() { // Inicialitzar naus segons configuració (només jugadors actius) for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; + bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; if (jugador_actiu) { // Jugador actiu: init normalment Vec2 spawn_pos = obtenir_punt_spawn(i); naus_[i].init(&spawn_pos, false); // No invulnerability at start - std::cout << "[EscenaJoc] Jugador " << (i + 1) << " inicialitzat\n"; + std::cout << "[GameScene] Jugador " << (i + 1) << " inicialitzat\n"; } else { // Jugador inactiu: marcar com a mort permanent naus_[i].markHit(); itocado_per_jugador_[i] = 999.0F; // Valor sentinella (permanent inactiu) vides_per_jugador_[i] = 0; // Sense vides - std::cout << "[EscenaJoc] Jugador " << (i + 1) << " inactiu\n"; + std::cout << "[GameScene] Jugador " << (i + 1) << " inactiu\n"; } } @@ -208,20 +208,20 @@ void EscenaJoc::init() { init_hud_rect_sound_played_ = false; } -void EscenaJoc::update(float delta_time) { +void GameScene::update(float delta_time) { // Processar disparos (state-based, no event-based) - if (estat_game_over_ == EstatGameOver::NONE) { + if (estat_game_over_ == GameOverState::NONE) { auto* input = Input::get(); // Jugador 1 dispara (només si està actiu) - if (config_partida_.jugador1_actiu) { + if (match_config_.jugador1_actiu) { if (input->checkActionPlayer1(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) { disparar_bala(0); } } // Jugador 2 dispara (només si està actiu) - if (config_partida_.jugador2_actiu) { + if (match_config_.jugador2_actiu) { if (input->checkActionPlayer2(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) { disparar_bala(1); } @@ -232,17 +232,17 @@ void EscenaJoc::update(float delta_time) { if (stage_manager_->get_estat() == StageSystem::EstatStage::PLAYING) { // Check if at least one player is alive and playing (game in progress) bool algun_jugador_viu = false; - if (config_partida_.jugador1_actiu && itocado_per_jugador_[0] != 999.0F) { + if (match_config_.jugador1_actiu && itocado_per_jugador_[0] != 999.0F) { algun_jugador_viu = true; } - if (config_partida_.jugador2_actiu && itocado_per_jugador_[1] != 999.0F) { + if (match_config_.jugador2_actiu && itocado_per_jugador_[1] != 999.0F) { algun_jugador_viu = true; } // Only allow join if there's an active game if (algun_jugador_viu) { // P2 can join if not currently playing (never joined OR dead without lives) - bool p2_no_juga = !config_partida_.jugador2_actiu || // Never joined + bool p2_no_juga = !match_config_.jugador2_actiu || // Never joined itocado_per_jugador_[1] == 999.0F; // Dead without lives if (p2_no_juga) { @@ -252,7 +252,7 @@ void EscenaJoc::update(float delta_time) { } // P1 can join if not currently playing (never joined OR dead without lives) - bool p1_no_juga = !config_partida_.jugador1_actiu || // Never joined + bool p1_no_juga = !match_config_.jugador1_actiu || // Never joined itocado_per_jugador_[0] == 999.0F; // Dead without lives if (p1_no_juga) { @@ -265,7 +265,7 @@ void EscenaJoc::update(float delta_time) { } // Handle CONTINUE screen - if (estat_game_over_ == EstatGameOver::CONTINUE) { + if (estat_game_over_ == GameOverState::CONTINUE) { actualitzar_continue(delta_time); processar_input_continue(); @@ -282,7 +282,7 @@ void EscenaJoc::update(float delta_time) { } // Handle final GAME OVER state - if (estat_game_over_ == EstatGameOver::GAME_OVER) { + if (estat_game_over_ == GameOverState::GAME_OVER) { // Game over: only update timer, enemies, bullets, and debris game_over_timer_ -= delta_time; @@ -290,8 +290,8 @@ void EscenaJoc::update(float delta_time) { // Aturar música de joc abans de tornar al títol Audio::get()->stopMusic(); // Transició a pantalla de títol - context_.canviar_escena(Escena::TITOL); - GestorEscenes::actual = Escena::TITOL; + context_.setNextScene(SceneType::TITLE); + SceneManager::actual = SceneType::TITLE; return; } @@ -335,11 +335,11 @@ void EscenaJoc::update(float delta_time) { itocado_per_jugador_[i] = 999.0F; // Check if ALL ACTIVE players are dead (trigger continue screen) - bool p1_dead = !config_partida_.jugador1_actiu || vides_per_jugador_[0] <= 0; - bool p2_dead = !config_partida_.jugador2_actiu || vides_per_jugador_[1] <= 0; + bool p1_dead = !match_config_.jugador1_actiu || vides_per_jugador_[0] <= 0; + bool p2_dead = !match_config_.jugador2_actiu || vides_per_jugador_[1] <= 0; if (p1_dead && p2_dead) { - estat_game_over_ = EstatGameOver::CONTINUE; + estat_game_over_ = GameOverState::CONTINUE; continue_counter_ = Defaults::Game::CONTINUE_COUNT_START; continue_tick_timer_ = Defaults::Game::CONTINUE_TICK_DURATION; } @@ -396,12 +396,12 @@ void EscenaJoc::update(float delta_time) { Defaults::Game::INIT_HUD_SHIP2_RATIO_END); // [MODIFICAT] Animar AMBAS naus con sus progress respectivos - if (config_partida_.jugador1_actiu && ship1_progress < 1.0F) { + if (match_config_.jugador1_actiu && ship1_progress < 1.0F) { Vec2 pos_p1 = calcular_posicio_nau_init_hud(ship1_progress, 0); naus_[0].setCenter(pos_p1); } - if (config_partida_.jugador2_actiu && ship2_progress < 1.0F) { + if (match_config_.jugador2_actiu && ship2_progress < 1.0F) { Vec2 pos_p2 = calcular_posicio_nau_init_hud(ship2_progress, 1); naus_[1].setCenter(pos_p2); } @@ -425,7 +425,7 @@ void EscenaJoc::update(float delta_time) { // [NEW] Allow both ships movement and shooting during intro for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; + bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players naus_[i].processInput(delta_time, i); naus_[i].update(delta_time); @@ -460,7 +460,7 @@ void EscenaJoc::update(float delta_time) { // [EXISTING] Normal gameplay - update active players for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; + bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players naus_[i].processInput(delta_time, i); naus_[i].update(delta_time); @@ -489,7 +489,7 @@ void EscenaJoc::update(float delta_time) { // [NEW] Allow both ships movement and shooting during outro for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; + bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players naus_[i].processInput(delta_time, i); naus_[i].update(delta_time); @@ -508,9 +508,9 @@ void EscenaJoc::update(float delta_time) { } } -void EscenaJoc::draw() { +void GameScene::draw() { // Handle CONTINUE screen - if (estat_game_over_ == EstatGameOver::CONTINUE) { + if (estat_game_over_ == GameOverState::CONTINUE) { // Draw game background elements first dibuixar_marges(); @@ -532,7 +532,7 @@ void EscenaJoc::draw() { } // Handle final GAME OVER state - if (estat_game_over_ == EstatGameOver::GAME_OVER) { + if (estat_game_over_ == GameOverState::GAME_OVER) { // Game over: draw enemies, bullets, debris, and "GAME OVER" text dibuixar_marges(); @@ -610,11 +610,11 @@ void EscenaJoc::draw() { } // [MODIFICAT] Dibuixar naus amb progress independent - if (ship1_progress > 0.0F && config_partida_.jugador1_actiu && !naus_[0].isHit()) { + if (ship1_progress > 0.0F && match_config_.jugador1_actiu && !naus_[0].isHit()) { naus_[0].draw(); } - if (ship2_progress > 0.0F && config_partida_.jugador2_actiu && !naus_[1].isHit()) { + if (ship2_progress > 0.0F && match_config_.jugador2_actiu && !naus_[1].isHit()) { naus_[1].draw(); } @@ -625,7 +625,7 @@ void EscenaJoc::draw() { dibuixar_marges(); // [NEW] Draw both ships if active and alive for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; + bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { naus_[i].draw(); } @@ -650,7 +650,7 @@ void EscenaJoc::draw() { // [EXISTING] Normal rendering - active ships for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; + bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { naus_[i].draw(); } @@ -673,7 +673,7 @@ void EscenaJoc::draw() { dibuixar_marges(); // [NEW] Draw both ships if active and alive for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; + bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { naus_[i].draw(); } @@ -695,7 +695,7 @@ void EscenaJoc::draw() { } } -void EscenaJoc::tocado(uint8_t player_id) { +void GameScene::tocado(uint8_t player_id) { // Death sequence: 3 phases // Phase 1: First call (itocado_per_jugador_[player_id] == 0) - trigger explosion // Phase 2: Animation (0 < itocado_ < 3.0s) - debris animation @@ -734,7 +734,7 @@ void EscenaJoc::tocado(uint8_t player_id) { // Phase 3 is handled in update() when itocado_per_jugador_ >= DEATH_DURATION } -void EscenaJoc::dibuixar_marges() const { +void GameScene::dibuixar_marges() const { // Dibuixar rectangle de la zona de joc const SDL_FRect& zona = Defaults::Zones::PLAYAREA; @@ -751,7 +751,7 @@ void EscenaJoc::dibuixar_marges() const { Rendering::linea(sdl_.obte_renderer(), x2, y1, x2, y2); // Right } -void EscenaJoc::dibuixar_marcador() { +void GameScene::dibuixar_marcador() { // Construir text del marcador std::string text = construir_marcador(); @@ -768,7 +768,7 @@ void EscenaJoc::dibuixar_marcador() { text_.render_centered(text, {.x = centre_x, .y = centre_y}, escala, spacing); } -void EscenaJoc::dibuixar_marges_animat(float progress) const { +void GameScene::dibuixar_marges_animat(float progress) const { // Animació seqüencial del rectangle amb efecte de "pinzell" // Dos pinzells comencen al centre superior i baixen pels laterals @@ -827,7 +827,7 @@ void EscenaJoc::dibuixar_marges_animat(float progress) const { } } -void EscenaJoc::dibuixar_marcador_animat(float progress) { +void GameScene::dibuixar_marcador_animat(float progress) { // Animació del marcador pujant des de baix amb easing // Calcular progrés amb easing @@ -855,7 +855,7 @@ void EscenaJoc::dibuixar_marcador_animat(float progress) { text_.render_centered(text, {.x = centre_x, .y = centre_y_animada}, escala, spacing); } -Vec2 EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const { +Vec2 GameScene::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const { // Animació de la nau pujant des de baix amb easing // [MODIFICAT] Ambas naves usan ease_out_quad (desfase temporal via INIT/END) @@ -879,7 +879,7 @@ Vec2 EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) return {.x = x_final, .y = y_animada}; } -float EscenaJoc::calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const { +float GameScene::calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const { // Convierte global_progress (0.0→1.0) a element_progress usando ventana [INIT, END] // // Casos: @@ -904,11 +904,11 @@ float EscenaJoc::calcular_progress_rango(float global_progress, float ratio_init return (global_progress - ratio_init) / (ratio_end - ratio_init); } -std::string EscenaJoc::construir_marcador() const { +std::string GameScene::construir_marcador() const { // Puntuació P1 (6 dígits) - mostrar zeros si inactiu std::string score_p1; std::string vides_p1; - if (config_partida_.jugador1_actiu) { + if (match_config_.jugador1_actiu) { score_p1 = std::to_string(puntuacio_per_jugador_[0]); score_p1 = std::string(6 - std::min(6, static_cast(score_p1.length())), '0') + score_p1; vides_p1 = (vides_per_jugador_[0] < 10) @@ -927,7 +927,7 @@ std::string EscenaJoc::construir_marcador() const { // Puntuació P2 (6 dígits) - mostrar zeros si inactiu std::string score_p2; std::string vides_p2; - if (config_partida_.jugador2_actiu) { + if (match_config_.jugador2_actiu) { score_p2 = std::to_string(puntuacio_per_jugador_[1]); score_p2 = std::string(6 - std::min(6, static_cast(score_p2.length())), '0') + score_p2; vides_p2 = (vides_per_jugador_[1] < 10) @@ -943,7 +943,7 @@ std::string EscenaJoc::construir_marcador() const { return score_p1 + " " + vides_p1 + " LEVEL " + stage_str + " " + score_p2 + " " + vides_p2; } -void EscenaJoc::detectar_col·lisions_bales_enemics() { +void GameScene::detectar_col·lisions_bales_enemics() { // Amplificador per hitbox més generós (115%) constexpr float AMPLIFIER = Defaults::Game::COLLISION_BULLET_ENEMY_AMPLIFIER; @@ -1007,7 +1007,7 @@ void EscenaJoc::detectar_col·lisions_bales_enemics() { } } -void EscenaJoc::detectar_col·lisio_naus_enemics() { +void GameScene::detectar_col·lisio_naus_enemics() { // Amplificador per hitbox generós (80%) constexpr float AMPLIFIER = Defaults::Game::COLLISION_SHIP_ENEMY_AMPLIFIER; @@ -1040,7 +1040,7 @@ void EscenaJoc::detectar_col·lisio_naus_enemics() { } } -void EscenaJoc::detectar_col·lisions_bales_jugadors() { +void GameScene::detectar_col·lisions_bales_jugadors() { // Skip if friendly fire disabled if (!Defaults::Game::FRIENDLY_FIRE_ENABLED) { return; @@ -1076,8 +1076,8 @@ void EscenaJoc::detectar_col·lisions_bales_jugadors() { } // Skip inactive players - bool jugador_actiu = (player_id == 0) ? config_partida_.jugador1_actiu - : config_partida_.jugador2_actiu; + bool jugador_actiu = (player_id == 0) ? match_config_.jugador1_actiu + : match_config_.jugador2_actiu; if (!jugador_actiu) { continue; } @@ -1113,7 +1113,7 @@ void EscenaJoc::detectar_col·lisions_bales_jugadors() { // [NEW] Stage system helper methods -void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) { +void GameScene::dibuixar_missatge_stage(const std::string& missatge) { constexpr float escala_base = 1.0F; constexpr float spacing = 2.0F; @@ -1182,11 +1182,11 @@ void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) { // Helper methods for 2-player support // ======================================== -Vec2 EscenaJoc::obtenir_punt_spawn(uint8_t player_id) const { +Vec2 GameScene::obtenir_punt_spawn(uint8_t player_id) const { const SDL_FRect& zona = Defaults::Zones::PLAYAREA; float x_ratio; - if (config_partida_.es_un_jugador()) { + if (match_config_.es_un_jugador()) { // Un sol jugador: spawn al centre (50%) x_ratio = 0.5F; } else { @@ -1201,7 +1201,7 @@ Vec2 EscenaJoc::obtenir_punt_spawn(uint8_t player_id) const { .y = zona.y + (zona.h * Defaults::Game::SPAWN_Y_RATIO)}; } -void EscenaJoc::disparar_bala(uint8_t player_id) { +void GameScene::disparar_bala(uint8_t player_id) { // Verificar que el jugador está vivo if (itocado_per_jugador_[player_id] > 0.0F) { return; @@ -1234,14 +1234,14 @@ void EscenaJoc::disparar_bala(uint8_t player_id) { // ==================== CONTINUE & JOIN SYSTEM ==================== -void EscenaJoc::check_and_apply_continue_timeout() { +void GameScene::check_and_apply_continue_timeout() { if (continue_counter_ < 0) { - estat_game_over_ = EstatGameOver::GAME_OVER; + estat_game_over_ = GameOverState::GAME_OVER; game_over_timer_ = Defaults::Game::GAME_OVER_DURATION; } } -void EscenaJoc::actualitzar_continue(float delta_time) { +void GameScene::actualitzar_continue(float delta_time) { continue_tick_timer_ -= delta_time; if (continue_tick_timer_ <= 0.0F) { @@ -1252,13 +1252,13 @@ void EscenaJoc::actualitzar_continue(float delta_time) { check_and_apply_continue_timeout(); // Play sound only if still in CONTINUE state (not transitioned to GAME_OVER) - if (estat_game_over_ == EstatGameOver::CONTINUE) { + if (estat_game_over_ == GameOverState::CONTINUE) { Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME); } } } -void EscenaJoc::processar_input_continue() { +void GameScene::processar_input_continue() { auto* input = Input::get(); // Check START for both players @@ -1269,7 +1269,7 @@ void EscenaJoc::processar_input_continue() { // Check continue limit (skip if infinite continues) if (!Defaults::Game::INFINITE_CONTINUES && continues_usados_ >= Defaults::Game::MAX_CONTINUES) { // Max continues reached → final game over - estat_game_over_ = EstatGameOver::GAME_OVER; + estat_game_over_ = GameOverState::GAME_OVER; game_over_timer_ = Defaults::Game::GAME_OVER_DURATION; return; } @@ -1289,9 +1289,9 @@ void EscenaJoc::processar_input_continue() { // Activate player if not already if (player_to_revive == 0) { - config_partida_.jugador1_actiu = true; + match_config_.jugador1_actiu = true; } else { - config_partida_.jugador2_actiu = true; + match_config_.jugador2_actiu = true; } // Spawn with invulnerability @@ -1304,13 +1304,13 @@ void EscenaJoc::processar_input_continue() { puntuacio_per_jugador_[other_player] = 0; vides_per_jugador_[other_player] = Defaults::Game::STARTING_LIVES; itocado_per_jugador_[other_player] = 0.0F; - config_partida_.jugador2_actiu = true; + match_config_.jugador2_actiu = true; Vec2 spawn_pos2 = obtenir_punt_spawn(other_player); naus_[other_player].init(&spawn_pos2, true); } // Resume game - estat_game_over_ = EstatGameOver::NONE; + estat_game_over_ = GameOverState::NONE; continue_counter_ = 0; continue_tick_timer_ = 0.0F; @@ -1333,7 +1333,7 @@ void EscenaJoc::processar_input_continue() { check_and_apply_continue_timeout(); // Play sound only if still in CONTINUE state - if (estat_game_over_ == EstatGameOver::CONTINUE) { + if (estat_game_over_ == GameOverState::CONTINUE) { Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME); } @@ -1342,7 +1342,7 @@ void EscenaJoc::processar_input_continue() { } } -void EscenaJoc::dibuixar_continue() { +void GameScene::dibuixar_continue() { const SDL_FRect& play_area = Defaults::Zones::PLAYAREA; constexpr float spacing = 4.0F; @@ -1377,12 +1377,12 @@ void EscenaJoc::dibuixar_continue() { } } -void EscenaJoc::unir_jugador(uint8_t player_id) { +void GameScene::unir_jugador(uint8_t player_id) { // Activate player if (player_id == 0) { - config_partida_.jugador1_actiu = true; + match_config_.jugador1_actiu = true; } else { - config_partida_.jugador2_actiu = true; + match_config_.jugador2_actiu = true; } // Reset stats @@ -1396,5 +1396,5 @@ void EscenaJoc::unir_jugador(uint8_t player_id) { // No visual message, just spawn (per user requirement) - std::cout << "[EscenaJoc] Jugador " << (int)(player_id + 1) << " s'ha unit a la partida!" << '\n'; + std::cout << "[GameScene] Jugador " << (int)(player_id + 1) << " s'ha unit a la partida!" << '\n'; } diff --git a/source/game/escenes/escena_joc.hpp b/source/game/scenes/game_scene.hpp similarity index 91% rename from source/game/escenes/escena_joc.hpp rename to source/game/scenes/game_scene.hpp index 25dad6d..b50e3f4 100644 --- a/source/game/escenes/escena_joc.hpp +++ b/source/game/scenes/game_scene.hpp @@ -12,7 +12,7 @@ #include "core/graphics/vector_text.hpp" #include "core/rendering/sdl_manager.hpp" -#include "core/system/context_escenes.hpp" +#include "core/system/scene_context.hpp" #include "core/system/game_config.hpp" #include "core/types.hpp" #include "game/constants.hpp" @@ -25,27 +25,27 @@ #include "game/stage_system/stage_manager.hpp" // Game over state machine -enum class EstatGameOver { +enum class GameOverState { NONE, // Normal gameplay CONTINUE, // Continue countdown screen (9→0) GAME_OVER // Final game over (returning to title) }; // Classe principal del joc (escena) -class EscenaJoc { +class GameScene { public: - explicit EscenaJoc(SDLManager& sdl, GestorEscenes::ContextEscenes& context); - ~EscenaJoc() = default; + explicit GameScene(SDLManager& sdl, SceneManager::SceneContext& context); + ~GameScene() = default; - void executar(); // Bucle principal de l'escena + void run(); // Bucle principal de l'escena void init(); void update(float delta_time); void draw(); private: SDLManager& sdl_; - GestorEscenes::ContextEscenes& context_; - GameConfig::ConfigPartida config_partida_; // Configuració de jugadors actius + SceneManager::SceneContext& context_; + GameConfig::MatchConfig match_config_; // Configuració de jugadors actius // Efectes visuals Effects::DebrisManager debris_manager_; @@ -59,7 +59,7 @@ class EscenaJoc { // Lives and game over system std::array vides_per_jugador_; // [0]=P1, [1]=P2 - EstatGameOver estat_game_over_; // Game over state machine (NONE, CONTINUE, GAME_OVER) + GameOverState estat_game_over_; // Game over state machine (NONE, CONTINUE, GAME_OVER) int continue_counter_; // Continue countdown (9→0) float continue_tick_timer_; // Timer for countdown tick (1.0s) int continues_usados_; // Continues used this game (0-3 max) diff --git a/source/game/escenes/escena_logo.cpp b/source/game/scenes/logo_scene.cpp similarity index 82% rename from source/game/escenes/escena_logo.cpp rename to source/game/scenes/logo_scene.cpp index 2d99c91..9b97979 100644 --- a/source/game/escenes/escena_logo.cpp +++ b/source/game/scenes/logo_scene.cpp @@ -1,7 +1,7 @@ // escena_logo.cpp - Implementació de l'escena logo // © 2025 Port a C++20 -#include "escena_logo.hpp" +#include "logo_scene.hpp" #include #include @@ -14,13 +14,13 @@ #include "core/input/input.hpp" #include "core/input/mouse.hpp" #include "core/rendering/shape_renderer.hpp" -#include "core/system/context_escenes.hpp" +#include "core/system/scene_context.hpp" #include "core/system/global_events.hpp" // Using declarations per simplificar el codi -using GestorEscenes::ContextEscenes; -using Escena = ContextEscenes::Escena; -using Opcio = ContextEscenes::Opcio; +using SceneManager::SceneContext; +using SceneType = SceneContext::SceneType; +using Option = SceneContext::Option; // Helper: calcular el progrés individual d'una lletra // en funció del progrés global (efecte seqüencial) @@ -45,35 +45,35 @@ static float calcular_progress_letra(size_t letra_index, size_t num_letras, floa return (global_progress - start) / (end - start); } -EscenaLogo::EscenaLogo(SDLManager& sdl, ContextEscenes& context) +LogoScene::LogoScene(SDLManager& sdl, SceneContext& context) : sdl_(sdl), context_(context), - estat_actual_(EstatAnimacio::PRE_ANIMATION), + estat_actual_(AnimationState::PRE_ANIMATION), temps_estat_actual_(0.0F), debris_manager_(std::make_unique(sdl.obte_renderer())), lletra_explosio_index_(0), temps_des_ultima_explosio_(0.0F) { - std::cout << "Escena Logo: Inicialitzant...\n"; + std::cout << "SceneType Logo: Inicialitzant...\n"; // Consumir opcions (LOGO no processa opcions actualment) - auto opcio = context_.consumir_opcio(); - (void)opcio; // Suprimir warning + auto option = context_.consumeOption(); + (void)option; // Suprimir warning so_reproduit_.fill(false); // Inicialitzar seguiment de sons inicialitzar_lletres(); } -EscenaLogo::~EscenaLogo() { +LogoScene::~LogoScene() { // Aturar tots els sons i la música Audio::get()->stopAllSounds(); - std::cout << "Escena Logo: Sons aturats\n"; + std::cout << "SceneType Logo: Sons aturats\n"; } -void EscenaLogo::executar() { +void LogoScene::run() { SDL_Event event; Uint64 last_time = SDL_GetTicks(); - while (GestorEscenes::actual == Escena::LOGO) { + while (SceneManager::actual == SceneType::LOGO) { // Calcular delta_time real Uint64 current_time = SDL_GetTicks(); float delta_time = (current_time - last_time) / 1000.0F; @@ -120,10 +120,10 @@ void EscenaLogo::executar() { draw(); } - std::cout << "Escena Logo: Finalitzant...\n"; + std::cout << "SceneType Logo: Finalitzant...\n"; } -void EscenaLogo::inicialitzar_lletres() { +void LogoScene::inicialitzar_lletres() { using namespace Graphics; // Llista de fitxers .shp (A repetida per a les dues A's) @@ -144,7 +144,7 @@ void EscenaLogo::inicialitzar_lletres() { for (const auto& fitxer : fitxers) { auto forma = ShapeLoader::load(fitxer); if (!forma || !forma->es_valida()) { - std::cerr << "[EscenaLogo] Error carregant " << fitxer << '\n'; + std::cerr << "[LogoScene] Error carregant " << fitxer << '\n'; continue; } @@ -198,16 +198,16 @@ void EscenaLogo::inicialitzar_lletres() { x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES; } - std::cout << "[EscenaLogo] " << lletres_.size() + std::cout << "[LogoScene] " << lletres_.size() << " lletres carregades, ancho total: " << ancho_total << " px\n"; } -void EscenaLogo::canviar_estat(EstatAnimacio nou_estat) { +void LogoScene::canviar_estat(AnimationState nou_estat) { estat_actual_ = nou_estat; temps_estat_actual_ = 0.0F; // Reset temps // Inicialitzar estat d'explosió - if (nou_estat == EstatAnimacio::EXPLOSION) { + if (nou_estat == AnimationState::EXPLOSION) { lletra_explosio_index_ = 0; temps_des_ultima_explosio_ = 0.0F; @@ -219,20 +219,20 @@ void EscenaLogo::canviar_estat(EstatAnimacio nou_estat) { std::random_device rd; std::mt19937 g(rd()); std::shuffle(ordre_explosio_.begin(), ordre_explosio_.end(), g); - } else if (nou_estat == EstatAnimacio::POST_EXPLOSION) { + } else if (nou_estat == AnimationState::POST_EXPLOSION) { Audio::get()->playMusic("title.ogg"); } - std::cout << "[EscenaLogo] Canvi a estat: " << static_cast(nou_estat) + std::cout << "[LogoScene] Canvi a estat: " << static_cast(nou_estat) << "\n"; } -bool EscenaLogo::totes_lletres_completes() const { +bool LogoScene::totes_lletres_completes() const { // Quan global_progress = 1.0, totes les lletres tenen letra_progress = 1.0 return temps_estat_actual_ >= DURACIO_ZOOM; } -void EscenaLogo::actualitzar_explosions(float delta_time) { +void LogoScene::actualitzar_explosions(float delta_time) { temps_des_ultima_explosio_ += delta_time; // Comprovar si és el moment d'explotar la següent lletra @@ -252,29 +252,29 @@ void EscenaLogo::actualitzar_explosions(float delta_time) { {.x = 0.0F, .y = 0.0F} // Sense velocitat (per defecte) ); - std::cout << "[EscenaLogo] Explota lletra " << lletra_explosio_index_ << "\n"; + std::cout << "[LogoScene] Explota lletra " << lletra_explosio_index_ << "\n"; // Passar a la següent lletra lletra_explosio_index_++; temps_des_ultima_explosio_ = 0.0F; } else { // Totes les lletres han explotat, transició a POST_EXPLOSION - canviar_estat(EstatAnimacio::POST_EXPLOSION); + canviar_estat(AnimationState::POST_EXPLOSION); } } } -void EscenaLogo::update(float delta_time) { +void LogoScene::update(float delta_time) { temps_estat_actual_ += delta_time; switch (estat_actual_) { - case EstatAnimacio::PRE_ANIMATION: + case AnimationState::PRE_ANIMATION: if (temps_estat_actual_ >= DURACIO_PRE) { - canviar_estat(EstatAnimacio::ANIMATION); + canviar_estat(AnimationState::ANIMATION); } break; - case EstatAnimacio::ANIMATION: { + case AnimationState::ANIMATION: { // Reproduir so per cada lletra quan comença a aparèixer float global_progress = std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0F); @@ -295,55 +295,55 @@ void EscenaLogo::update(float delta_time) { } if (totes_lletres_completes()) { - canviar_estat(EstatAnimacio::POST_ANIMATION); + canviar_estat(AnimationState::POST_ANIMATION); } break; } - case EstatAnimacio::POST_ANIMATION: + case AnimationState::POST_ANIMATION: if (temps_estat_actual_ >= DURACIO_POST_ANIMATION) { - canviar_estat(EstatAnimacio::EXPLOSION); + canviar_estat(AnimationState::EXPLOSION); } break; - case EstatAnimacio::EXPLOSION: + case AnimationState::EXPLOSION: actualitzar_explosions(delta_time); break; - case EstatAnimacio::POST_EXPLOSION: + case AnimationState::POST_EXPLOSION: if (temps_estat_actual_ >= DURACIO_POST_EXPLOSION) { // Transició a pantalla de títol - context_.canviar_escena(Escena::TITOL); - GestorEscenes::actual = Escena::TITOL; + context_.setNextScene(SceneType::TITLE); + SceneManager::actual = SceneType::TITLE; } break; } // Verificar botones de skip (SHOOT P1/P2) if (checkSkipButtonPressed()) { - context_.canviar_escena(Escena::TITOL, Opcio::JUMP_TO_TITLE_MAIN); - GestorEscenes::actual = Escena::TITOL; + context_.setNextScene(SceneType::TITLE, Option::JUMP_TO_TITLE_MAIN); + SceneManager::actual = SceneType::TITLE; } // Actualitzar animacions de debris debris_manager_->update(delta_time); } -void EscenaLogo::draw() { +void LogoScene::draw() { // Fons negre sdl_.neteja(0, 0, 0); // PRE_ANIMATION: Només pantalla negra - if (estat_actual_ == EstatAnimacio::PRE_ANIMATION) { + if (estat_actual_ == AnimationState::PRE_ANIMATION) { sdl_.presenta(); return; // No renderitzar lletres } // ANIMATION o POST_ANIMATION: Dibuixar lletres amb animació - if (estat_actual_ == EstatAnimacio::ANIMATION || - estat_actual_ == EstatAnimacio::POST_ANIMATION) { + if (estat_actual_ == AnimationState::ANIMATION || + estat_actual_ == AnimationState::POST_ANIMATION) { float global_progress = - (estat_actual_ == EstatAnimacio::ANIMATION) + (estat_actual_ == AnimationState::ANIMATION) ? std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0F) : 1.0F; // POST: mantenir al 100% @@ -384,7 +384,7 @@ void EscenaLogo::draw() { } // EXPLOSION: Dibuixar només lletres que encara no han explotat - if (estat_actual_ == EstatAnimacio::EXPLOSION) { + if (estat_actual_ == AnimationState::EXPLOSION) { // Crear conjunt de lletres ja explotades std::set explotades; for (size_t i = 0; i < lletra_explosio_index_; i++) { @@ -415,10 +415,10 @@ void EscenaLogo::draw() { sdl_.presenta(); } -auto EscenaLogo::checkSkipButtonPressed() -> bool { +auto LogoScene::checkSkipButtonPressed() -> bool { return Input::get()->checkAnyPlayerAction(ARCADE_BUTTONS); } -void EscenaLogo::processar_events(const SDL_Event& event) { +void LogoScene::processar_events(const SDL_Event& event) { // No procesar eventos genéricos aquí - la lógica se movió a update() } diff --git a/source/game/escenes/escena_logo.hpp b/source/game/scenes/logo_scene.hpp similarity index 88% rename from source/game/escenes/escena_logo.hpp rename to source/game/scenes/logo_scene.hpp index 9b685b7..9195753 100644 --- a/source/game/escenes/escena_logo.hpp +++ b/source/game/scenes/logo_scene.hpp @@ -14,19 +14,19 @@ #include "core/graphics/shape.hpp" #include "core/input/input_types.hpp" #include "core/rendering/sdl_manager.hpp" -#include "core/system/context_escenes.hpp" +#include "core/system/scene_context.hpp" #include "core/types.hpp" #include "game/effects/debris_manager.hpp" -class EscenaLogo { +class LogoScene { public: - explicit EscenaLogo(SDLManager& sdl, GestorEscenes::ContextEscenes& context); - ~EscenaLogo(); // Destructor per aturar sons - void executar(); // Bucle principal de l'escena + explicit LogoScene(SDLManager& sdl, SceneManager::SceneContext& context); + ~LogoScene(); // Destructor per aturar sons + void run(); // Bucle principal de l'escena private: // Màquina d'estats per l'animació - enum class EstatAnimacio { + enum class AnimationState { PRE_ANIMATION, // Pantalla negra inicial ANIMATION, // Animació de zoom de lletres POST_ANIMATION, // Logo complet visible @@ -35,8 +35,8 @@ class EscenaLogo { }; SDLManager& sdl_; - GestorEscenes::ContextEscenes& context_; - EstatAnimacio estat_actual_; // Estat actual de la màquina + SceneManager::SceneContext& context_; + AnimationState estat_actual_; // Estat actual de la màquina float temps_estat_actual_; // Temps en l'estat actual (reset en cada transició) @@ -86,6 +86,6 @@ class EscenaLogo { auto checkSkipButtonPressed() -> bool; // Mètodes de gestió d'estats - void canviar_estat(EstatAnimacio nou_estat); + void canviar_estat(AnimationState nou_estat); [[nodiscard]] bool totes_lletres_completes() const; }; diff --git a/source/game/escenes/escena_titol.cpp b/source/game/scenes/title_scene.cpp similarity index 81% rename from source/game/escenes/escena_titol.cpp rename to source/game/scenes/title_scene.cpp index e260b39..77b315f 100644 --- a/source/game/escenes/escena_titol.cpp +++ b/source/game/scenes/title_scene.cpp @@ -1,7 +1,7 @@ // escena_titol.cpp - Implementació de l'escena de títol // © 2025 Port a C++20 -#include "escena_titol.hpp" +#include "title_scene.hpp" #include #include @@ -15,38 +15,38 @@ #include "core/input/input.hpp" #include "core/input/mouse.hpp" #include "core/rendering/shape_renderer.hpp" -#include "core/system/context_escenes.hpp" +#include "core/system/scene_context.hpp" #include "core/system/global_events.hpp" #include "project.h" // Using declarations per simplificar el codi -using GestorEscenes::ContextEscenes; -using Escena = ContextEscenes::Escena; -using Opcio = ContextEscenes::Opcio; +using SceneManager::SceneContext; +using SceneType = SceneContext::SceneType; +using Option = SceneContext::Option; -EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context) +TitleScene::TitleScene(SDLManager& sdl, SceneContext& context) : sdl_(sdl), context_(context), text_(sdl.obte_renderer()), - estat_actual_(EstatTitol::STARFIELD_FADE_IN), + estat_actual_(TitleState::STARFIELD_FADE_IN), temps_acumulat_(0.0F), temps_animacio_(0.0F), temps_estat_main_(0.0F), animacio_activa_(false), factor_lerp_(0.0F) { - std::cout << "Escena Titol: Inicialitzant...\n"; + std::cout << "SceneType Titol: Inicialitzant...\n"; // Inicialitzar configuració de partida (cap jugador actiu per defecte) - config_partida_.jugador1_actiu = false; - config_partida_.jugador2_actiu = false; - config_partida_.mode = GameConfig::Mode::NORMAL; + match_config_.jugador1_actiu = false; + match_config_.jugador2_actiu = false; + match_config_.mode = GameConfig::Mode::NORMAL; // Processar opció del context - auto opcio = context_.consumir_opcio(); + auto option = context_.consumeOption(); - if (opcio == Opcio::JUMP_TO_TITLE_MAIN) { - std::cout << "Escena Titol: Opció JUMP_TO_TITLE_MAIN activada\n"; - estat_actual_ = EstatTitol::MAIN; + if (option == Option::JUMP_TO_TITLE_MAIN) { + std::cout << "SceneType Titol: Opció JUMP_TO_TITLE_MAIN activada\n"; + estat_actual_ = TitleState::MAIN; temps_estat_main_ = 0.0F; } @@ -69,7 +69,7 @@ EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context) ); // Brightness depèn de l'opció - if (estat_actual_ == EstatTitol::MAIN) { + if (estat_actual_ == TitleState::MAIN) { // Si saltem a MAIN, starfield instantàniament brillant starfield_->set_brightness(BRIGHTNESS_STARFIELD); } else { @@ -81,7 +81,7 @@ EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context) ship_animator_ = std::make_unique(sdl_.obte_renderer()); ship_animator_->init(); - if (estat_actual_ == EstatTitol::MAIN) { + if (estat_actual_ == TitleState::MAIN) { // Jump to MAIN: empezar entrada inmediatamente ship_animator_->set_visible(true); ship_animator_->start_entry_animation(); @@ -99,12 +99,12 @@ EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context) } } -EscenaTitol::~EscenaTitol() { +TitleScene::~TitleScene() { // Aturar música de títol quan es destrueix l'escena Audio::get()->stopMusic(); } -void EscenaTitol::inicialitzar_titol() { +void TitleScene::inicialitzar_titol() { using namespace Graphics; // === LÍNIA 1: "ORNI" === @@ -120,7 +120,7 @@ void EscenaTitol::inicialitzar_titol() { for (const auto& fitxer : fitxers_orni) { auto forma = ShapeLoader::load(fitxer); if (!forma || !forma->es_valida()) { - std::cerr << "[EscenaTitol] Error carregant " << fitxer << '\n'; + std::cerr << "[TitleScene] Error carregant " << fitxer << '\n'; continue; } @@ -165,7 +165,7 @@ void EscenaTitol::inicialitzar_titol() { x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES; } - std::cout << "[EscenaTitol] Línia 1 (ORNI): " << lletres_orni_.size() + std::cout << "[TitleScene] Línia 1 (ORNI): " << lletres_orni_.size() << " lletres, ancho total: " << ancho_total_orni << " px\n"; // === Calcular posició Y dinàmica per "ATTACK!" === @@ -175,7 +175,7 @@ void EscenaTitol::inicialitzar_titol() { float separacion_lineas = Defaults::Game::HEIGHT * Defaults::Title::Layout::LOGO_LINE_SPACING; y_attack_dinamica_ = y_orni + altura_orni + separacion_lineas; - std::cout << "[EscenaTitol] Altura ORNI: " << altura_orni + std::cout << "[TitleScene] Altura ORNI: " << altura_orni << " px, Y_ATTACK dinàmica: " << y_attack_dinamica_ << " px\n"; // === LÍNIA 2: "ATTACK!" === @@ -194,7 +194,7 @@ void EscenaTitol::inicialitzar_titol() { for (const auto& fitxer : fitxers_attack) { auto forma = ShapeLoader::load(fitxer); if (!forma || !forma->es_valida()) { - std::cerr << "[EscenaTitol] Error carregant " << fitxer << '\n'; + std::cerr << "[TitleScene] Error carregant " << fitxer << '\n'; continue; } @@ -239,7 +239,7 @@ void EscenaTitol::inicialitzar_titol() { x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES; } - std::cout << "[EscenaTitol] Línia 2 (ATTACK!): " << lletres_attack_.size() + std::cout << "[TitleScene] Línia 2 (ATTACK!): " << lletres_attack_.size() << " lletres, ancho total: " << ancho_total_attack << " px\n"; // Guardar posicions originals per l'animació orbital @@ -253,14 +253,14 @@ void EscenaTitol::inicialitzar_titol() { posicions_originals_attack_.push_back(lletra.posicio); } - std::cout << "[EscenaTitol] Animació: Posicions originals guardades\n"; + std::cout << "[TitleScene] Animació: Posicions originals guardades\n"; } -void EscenaTitol::executar() { +void TitleScene::run() { SDL_Event event; Uint64 last_time = SDL_GetTicks(); - while (GestorEscenes::actual == Escena::TITOL) { + while (SceneManager::actual == SceneType::TITLE) { // Calcular delta_time real Uint64 current_time = SDL_GetTicks(); float delta_time = (current_time - last_time) / 1000.0F; @@ -316,10 +316,10 @@ void EscenaTitol::executar() { sdl_.presenta(); } - std::cout << "Escena Titol: Finalitzant...\n"; + std::cout << "SceneType Titol: Finalitzant...\n"; } -void EscenaTitol::update(float delta_time) { +void TitleScene::update(float delta_time) { // Actualitzar starfield (sempre actiu) if (starfield_) { starfield_->update(delta_time); @@ -327,15 +327,15 @@ void EscenaTitol::update(float delta_time) { // Actualitzar naus (quan visibles) if (ship_animator_ && - (estat_actual_ == EstatTitol::STARFIELD_FADE_IN || - estat_actual_ == EstatTitol::STARFIELD || - estat_actual_ == EstatTitol::MAIN || - estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE)) { + (estat_actual_ == TitleState::STARFIELD_FADE_IN || + estat_actual_ == TitleState::STARFIELD || + estat_actual_ == TitleState::MAIN || + estat_actual_ == TitleState::PLAYER_JOIN_PHASE)) { ship_animator_->update(delta_time); } switch (estat_actual_) { - case EstatTitol::STARFIELD_FADE_IN: { + case TitleState::STARFIELD_FADE_IN: { temps_acumulat_ += delta_time; // Calcular progrés del fade (0.0 → 1.0) @@ -347,17 +347,17 @@ void EscenaTitol::update(float delta_time) { // Transició a STARFIELD quan el fade es completa if (temps_acumulat_ >= DURACIO_FADE_IN) { - estat_actual_ = EstatTitol::STARFIELD; + estat_actual_ = TitleState::STARFIELD; temps_acumulat_ = 0.0F; // Reset timer per al següent estat starfield_->set_brightness(BRIGHTNESS_STARFIELD); // Assegurar valor final } break; } - case EstatTitol::STARFIELD: + case TitleState::STARFIELD: temps_acumulat_ += delta_time; if (temps_acumulat_ >= DURACIO_INIT) { - estat_actual_ = EstatTitol::MAIN; + estat_actual_ = TitleState::MAIN; temps_estat_main_ = 0.0F; // Reset timer al entrar a MAIN animacio_activa_ = false; // Comença estàtic factor_lerp_ = 0.0F; // Sense animació encara @@ -366,7 +366,7 @@ void EscenaTitol::update(float delta_time) { } break; - case EstatTitol::MAIN: { + case TitleState::MAIN: { temps_estat_main_ += delta_time; // Iniciar animació d'entrada de naus després del delay @@ -399,7 +399,7 @@ void EscenaTitol::update(float delta_time) { break; } - case EstatTitol::PLAYER_JOIN_PHASE: + case TitleState::PLAYER_JOIN_PHASE: temps_acumulat_ += delta_time; // Continuar animació orbital durant la transició @@ -407,22 +407,22 @@ void EscenaTitol::update(float delta_time) { // [NOU] Continuar comprovant si l'altre jugador vol unir-se durant la transició ("late join") { - bool p1_actiu_abans = config_partida_.jugador1_actiu; - bool p2_actiu_abans = config_partida_.jugador2_actiu; + bool p1_actiu_abans = match_config_.jugador1_actiu; + bool p2_actiu_abans = match_config_.jugador2_actiu; if (checkStartGameButtonPressed()) { - // Updates config_partida_ if pressed, logs are in the method - context_.set_config_partida(config_partida_); + // Updates match_config_ if pressed, logs are in the method + context_.setMatchConfig(match_config_); // Trigger animació de sortida per la nau que acaba d'unir-se if (ship_animator_) { - if (config_partida_.jugador1_actiu && !p1_actiu_abans) { + if (match_config_.jugador1_actiu && !p1_actiu_abans) { ship_animator_->trigger_exit_animation_for_player(1); - std::cout << "[EscenaTitol] P1 late join - ship exiting\n"; + std::cout << "[TitleScene] P1 late join - ship exiting\n"; } - if (config_partida_.jugador2_actiu && !p2_actiu_abans) { + if (match_config_.jugador2_actiu && !p2_actiu_abans) { ship_animator_->trigger_exit_animation_for_player(2); - std::cout << "[EscenaTitol] P2 late join - ship exiting\n"; + std::cout << "[TitleScene] P2 late join - ship exiting\n"; } } @@ -432,35 +432,35 @@ void EscenaTitol::update(float delta_time) { // Reiniciar el timer per allargar el temps de transició temps_acumulat_ = 0.0F; - std::cout << "[EscenaTitol] Segon jugador s'ha unit - so i timer reiniciats\n"; + std::cout << "[TitleScene] Segon jugador s'ha unit - so i timer reiniciats\n"; } } if (temps_acumulat_ >= DURACIO_TRANSITION) { // Transició a pantalla negra - estat_actual_ = EstatTitol::BLACK_SCREEN; + estat_actual_ = TitleState::BLACK_SCREEN; temps_acumulat_ = 0.0F; - std::cout << "[EscenaTitol] Passant a BLACK_SCREEN\n"; + std::cout << "[TitleScene] Passant a BLACK_SCREEN\n"; } break; - case EstatTitol::BLACK_SCREEN: + case TitleState::BLACK_SCREEN: temps_acumulat_ += delta_time; // No animation, no input checking - just wait if (temps_acumulat_ >= DURACIO_BLACK_SCREEN) { - // Transició a escena JOC - GestorEscenes::actual = Escena::JOC; - std::cout << "[EscenaTitol] Canviant a escena JOC\n"; + // Transició a escena GAME + SceneManager::actual = SceneType::GAME; + std::cout << "[TitleScene] Canviant a escena GAME\n"; } break; } // Verificar botones de skip (FIRE/THRUST/START) para saltar escenas ANTES de MAIN - if (estat_actual_ == EstatTitol::STARFIELD_FADE_IN || estat_actual_ == EstatTitol::STARFIELD) { + if (estat_actual_ == TitleState::STARFIELD_FADE_IN || estat_actual_ == TitleState::STARFIELD) { if (checkSkipButtonPressed()) { // Saltar a MAIN - estat_actual_ = EstatTitol::MAIN; + estat_actual_ = TitleState::MAIN; starfield_->set_brightness(BRIGHTNESS_STARFIELD); temps_estat_main_ = 0.0F; @@ -469,10 +469,10 @@ void EscenaTitol::update(float delta_time) { } // Verificar boton START para iniciar partida desde MAIN - if (estat_actual_ == EstatTitol::MAIN) { + if (estat_actual_ == TitleState::MAIN) { // Guardar estat anterior per detectar qui ha premut START AQUEST frame - bool p1_actiu_abans = config_partida_.jugador1_actiu; - bool p2_actiu_abans = config_partida_.jugador2_actiu; + bool p1_actiu_abans = match_config_.jugador1_actiu; + bool p2_actiu_abans = match_config_.jugador2_actiu; if (checkStartGameButtonPressed()) { // Si START es prem durant el delay (naus encara invisibles), saltar-les a FLOATING @@ -482,26 +482,26 @@ void EscenaTitol::update(float delta_time) { } // Configurar partida abans de canviar d'escena - context_.set_config_partida(config_partida_); - std::cout << "[EscenaTitol] Configuració de partida - P1: " - << (config_partida_.jugador1_actiu ? "ACTIU" : "INACTIU") + context_.setMatchConfig(match_config_); + std::cout << "[TitleScene] Configuració de partida - P1: " + << (match_config_.jugador1_actiu ? "ACTIU" : "INACTIU") << ", P2: " - << (config_partida_.jugador2_actiu ? "ACTIU" : "INACTIU") + << (match_config_.jugador2_actiu ? "ACTIU" : "INACTIU") << '\n'; - context_.canviar_escena(Escena::JOC); - estat_actual_ = EstatTitol::PLAYER_JOIN_PHASE; + context_.setNextScene(SceneType::GAME); + estat_actual_ = TitleState::PLAYER_JOIN_PHASE; temps_acumulat_ = 0.0F; // Trigger animació de sortida NOMÉS per les naus que han premut START if (ship_animator_) { - if (config_partida_.jugador1_actiu && !p1_actiu_abans) { + if (match_config_.jugador1_actiu && !p1_actiu_abans) { ship_animator_->trigger_exit_animation_for_player(1); - std::cout << "[EscenaTitol] P1 ship exiting\n"; + std::cout << "[TitleScene] P1 ship exiting\n"; } - if (config_partida_.jugador2_actiu && !p2_actiu_abans) { + if (match_config_.jugador2_actiu && !p2_actiu_abans) { ship_animator_->trigger_exit_animation_for_player(2); - std::cout << "[EscenaTitol] P2 ship exiting\n"; + std::cout << "[TitleScene] P2 ship exiting\n"; } } @@ -511,7 +511,7 @@ void EscenaTitol::update(float delta_time) { } } -void EscenaTitol::actualitzar_animacio_logo(float delta_time) { +void TitleScene::actualitzar_animacio_logo(float delta_time) { // Només calcular i aplicar offsets si l'animació està activa if (animacio_activa_) { // Acumular temps escalat @@ -541,29 +541,29 @@ void EscenaTitol::actualitzar_animacio_logo(float delta_time) { } } -void EscenaTitol::draw() { +void TitleScene::draw() { // Dibuixar starfield de fons (en tots els estats excepte BLACK_SCREEN) - if (starfield_ && estat_actual_ != EstatTitol::BLACK_SCREEN) { + if (starfield_ && estat_actual_ != TitleState::BLACK_SCREEN) { starfield_->draw(); } // Dibuixar naus (després starfield, abans logo) if (ship_animator_ && - (estat_actual_ == EstatTitol::STARFIELD_FADE_IN || - estat_actual_ == EstatTitol::STARFIELD || - estat_actual_ == EstatTitol::MAIN || - estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE)) { + (estat_actual_ == TitleState::STARFIELD_FADE_IN || + estat_actual_ == TitleState::STARFIELD || + estat_actual_ == TitleState::MAIN || + estat_actual_ == TitleState::PLAYER_JOIN_PHASE)) { ship_animator_->draw(); } // En els estats STARFIELD_FADE_IN i STARFIELD, només mostrar starfield (sense text) - if (estat_actual_ == EstatTitol::STARFIELD_FADE_IN || estat_actual_ == EstatTitol::STARFIELD) { + if (estat_actual_ == TitleState::STARFIELD_FADE_IN || estat_actual_ == TitleState::STARFIELD) { return; } // Estat MAIN i PLAYER_JOIN_PHASE: Dibuixar títol i text (sobre el starfield) // BLACK_SCREEN: no draw res (fons negre ja està netejat) - if (estat_actual_ == EstatTitol::MAIN || estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE) { + if (estat_actual_ == TitleState::MAIN || estat_actual_ == TitleState::PLAYER_JOIN_PHASE) { // === Calcular i renderitzar ombra (només si animació activa) === if (animacio_activa_) { float temps_shadow = temps_animacio_ - SHADOW_DELAY; @@ -648,7 +648,7 @@ void EscenaTitol::draw() { const float spacing = Defaults::Title::Layout::TEXT_SPACING; bool mostrar_text = true; - if (estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE) { + if (estat_actual_ == TitleState::PLAYER_JOIN_PHASE) { // Parpelleig: sin oscil·la entre -1 i 1, volem ON quan > 0 float fase = temps_acumulat_ * BLINK_FREQUENCY * 2.0F * std::numbers::pi_v; // 2π × freq × temps mostrar_text = (std::sin(fase) > 0.0F); @@ -697,27 +697,27 @@ void EscenaTitol::draw() { } } -auto EscenaTitol::checkSkipButtonPressed() -> bool { +auto TitleScene::checkSkipButtonPressed() -> bool { return Input::get()->checkAnyPlayerAction(ARCADE_BUTTONS); } -auto EscenaTitol::checkStartGameButtonPressed() -> bool { +auto TitleScene::checkStartGameButtonPressed() -> bool { auto* input = Input::get(); bool any_pressed = false; for (auto action : START_GAME_BUTTONS) { if (input->checkActionPlayer1(action, Input::DO_NOT_ALLOW_REPEAT)) { - if (!config_partida_.jugador1_actiu) { - config_partida_.jugador1_actiu = true; + if (!match_config_.jugador1_actiu) { + match_config_.jugador1_actiu = true; any_pressed = true; - std::cout << "[EscenaTitol] P1 pressed START\n"; + std::cout << "[TitleScene] P1 pressed START\n"; } } if (input->checkActionPlayer2(action, Input::DO_NOT_ALLOW_REPEAT)) { - if (!config_partida_.jugador2_actiu) { - config_partida_.jugador2_actiu = true; + if (!match_config_.jugador2_actiu) { + match_config_.jugador2_actiu = true; any_pressed = true; - std::cout << "[EscenaTitol] P2 pressed START\n"; + std::cout << "[TitleScene] P2 pressed START\n"; } } } @@ -725,6 +725,6 @@ auto EscenaTitol::checkStartGameButtonPressed() -> bool { return any_pressed; } -void EscenaTitol::processar_events(const SDL_Event& event) { +void TitleScene::processar_events(const SDL_Event& event) { // No procesar eventos genéricos aquí - la lógica se movió a update() } diff --git a/source/game/escenes/escena_titol.hpp b/source/game/scenes/title_scene.hpp similarity index 91% rename from source/game/escenes/escena_titol.hpp rename to source/game/scenes/title_scene.hpp index 7f6ee0c..82c1271 100644 --- a/source/game/escenes/escena_titol.hpp +++ b/source/game/scenes/title_scene.hpp @@ -16,7 +16,7 @@ #include "core/graphics/vector_text.hpp" #include "core/input/input_types.hpp" #include "core/rendering/sdl_manager.hpp" -#include "core/system/context_escenes.hpp" +#include "core/system/scene_context.hpp" #include "core/system/game_config.hpp" #include "core/types.hpp" #include "game/title/ship_animator.hpp" @@ -25,15 +25,15 @@ static constexpr std::array START_GAME_BUTTONS = { InputAction::START}; -class EscenaTitol { +class TitleScene { public: - explicit EscenaTitol(SDLManager& sdl, GestorEscenes::ContextEscenes& context); - ~EscenaTitol(); // Destructor per aturar música - void executar(); // Bucle principal de l'escena + explicit TitleScene(SDLManager& sdl, SceneManager::SceneContext& context); + ~TitleScene(); // Destructor per aturar música + void run(); // Bucle principal de l'escena private: // Màquina d'estats per la pantalla de títol - enum class EstatTitol { + enum class TitleState { STARFIELD_FADE_IN, // Fade-in del starfield (3.0s) STARFIELD, // Pantalla amb camp d'estrelles (4.0s) MAIN, // Pantalla de títol amb text (indefinit, fins START) @@ -51,12 +51,12 @@ class EscenaTitol { }; SDLManager& sdl_; - GestorEscenes::ContextEscenes& context_; - GameConfig::ConfigPartida config_partida_; // Configuració de jugadors actius + SceneManager::SceneContext& context_; + GameConfig::MatchConfig match_config_; // Configuració de jugadors actius Graphics::VectorText text_; // Sistema de text vectorial std::unique_ptr starfield_; // Camp d'estrelles de fons std::unique_ptr ship_animator_; // Naus 3D flotants - EstatTitol estat_actual_; // Estat actual de la màquina + TitleState estat_actual_; // Estat actual de la màquina float temps_acumulat_; // Temps acumulat per l'estat INIT // Lletres del títol "ORNI ATTACK!" diff --git a/source/game/stage_system/stage_manager.cpp b/source/game/stage_system/stage_manager.cpp index 00fb32b..7b1bc31 100644 --- a/source/game/stage_system/stage_manager.cpp +++ b/source/game/stage_system/stage_manager.cpp @@ -129,10 +129,10 @@ void StageManager::processar_level_start(float delta_time) { void StageManager::processar_playing(float delta_time, bool pausar_spawn) { // Update spawn controller (pauses when pausar_spawn = true) - // Note: The actual enemy array update happens in EscenaJoc::update() + // Note: The actual enemy array update happens in GameScene::update() // This is just for internal timekeeping (void)delta_time; // Spawn controller is updated externally - (void)pausar_spawn; // Passed to spawn_controller_.update() by EscenaJoc + (void)pausar_spawn; // Passed to spawn_controller_.update() by GameScene } void StageManager::processar_level_completed(float delta_time) { diff --git a/source/game/title/ship_animator.hpp b/source/game/title/ship_animator.hpp index 4245ace..20f7641 100644 --- a/source/game/title/ship_animator.hpp +++ b/source/game/title/ship_animator.hpp @@ -68,7 +68,7 @@ class ShipAnimator { void update(float delta_time); void draw() const; - // Control d'estat (cridat per EscenaTitol) + // Control d'estat (cridat per TitleScene) void start_entry_animation(); void trigger_exit_animation(); // Anima totes les naus void trigger_exit_animation_for_player(int jugador_id); // Anima només una nau (P1=1, P2=2) From 7ee359b910930b5fc2e7897b8b6fa72cf9fcabeb Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 19 May 2026 11:44:45 +0200 Subject: [PATCH 05/27] Fase 1d: rename del codi restant (effects, stage_system, locals) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sweep final del naming a CamelCase/camelBack/lower_case: Fitxers renombrats: - effects/gestor_puntuacio_flotant.{hpp,cpp} -> floating_score_manager.{hpp,cpp} - effects/puntuacio_flotant.hpp -> floating_score.hpp Tipus (CamelCase): - GestorPuntuacioFlotant -> FloatingScoreManager - PuntuacioFlotant -> FloatingScore - ConfigStage -> StageConfig - ConfigSistemaStages -> StageSystemConfig - NauTitol -> TitleShip - EstatNau -> ShipState Metodes publics (camelBack): - obte_renderer -> getRenderer - get_num_actius -> getActiveCount - calcular_direccio_explosio -> computeExplosionDirection - trobar_slot_lliure -> findFreeSlot - explotar -> explode - reiniciar -> reset - es_valida -> isValid - parsejar_fitxer -> parseFile - carregar -> load - crear_explosio -> createExplosion - registrar_puntuacio -> registerScore - construir_marcador -> buildScoreboard - render_centered -> renderCentered Camps struct publics (snake_case): - actiu/actius -> active - rotacio -> rotation, rotacio_visual -> visual_rotation - acceleracio -> acceleration - velocitat -> velocity - escala/escala_inicial/objectiu/actual -> scale/initial_scale/... - posicio/posicio_inicial/objectiu/actual -> position/initial_position/... - fase_oscilacio -> oscillation_phase - temps_estat -> state_time - jugador_id -> player_id - estat -> state - brillantor -> brightness - tipus -> type Camps privats (sufix _): - naus_ -> ships_, orni_ -> enemies_, bales_ -> bullets_ - gestor_puntuacio_ -> floating_score_manager_ - punt_mort_ -> death_position_, punt_spawn_ -> spawn_position_ - itocado_per_jugador_ -> hit_timer_per_player_ - vides_per_jugador_ -> lives_per_player_ - puntuacio_per_jugador_ -> score_per_player_ - estat_game_over_ -> game_over_state_ - continues_usados_ -> continues_used_ Constants: - MARGE_ESQ/DRET/DALT/BAIX -> MARGIN_LEFT/RIGHT/TOP/BOTTOM Variables locals i parametres comuns (snake_case): - nau -> ship, enemic -> enemy, bala -> bullet - forma -> shape, punt(s) -> point(s) - jugador -> player, partida -> match - temps -> time, missatge -> message Diff: 59 fitxers, +1000/-1000 (simetric). Compila i enllaça. Pendents per a futures fases (no bloquejants): - Comentaris de capçalera en catala -> castella - Variables locals/parametres minoritaris en catala - Include guards (queden alguns #ifndef en lloc de #pragma once) Co-Authored-By: Claude Opus 4.7 (1M context) --- source/core/audio/audio_cache.cpp | 4 +- source/core/defaults.hpp | 36 +- source/core/graphics/shape.cpp | 16 +- source/core/graphics/shape.hpp | 24 +- source/core/graphics/shape_loader.cpp | 8 +- source/core/graphics/shape_loader.hpp | 2 +- source/core/graphics/starfield.cpp | 52 +- source/core/graphics/starfield.hpp | 12 +- source/core/graphics/vector_text.cpp | 56 +- source/core/graphics/vector_text.hpp | 22 +- source/core/input/input.cpp | 16 +- source/core/input/input.hpp | 10 +- source/core/input/input_types.hpp | 2 +- source/core/input/mouse.cpp | 6 +- source/core/input/mouse.hpp | 2 +- .../core/rendering/coordinate_transform.cpp | 2 +- .../core/rendering/coordinate_transform.hpp | 4 +- source/core/rendering/line_renderer.hpp | 4 +- source/core/rendering/sdl_manager.cpp | 4 +- source/core/rendering/sdl_manager.hpp | 4 +- source/core/rendering/shape_renderer.cpp | 42 +- source/core/rendering/shape_renderer.hpp | 14 +- source/core/resources/resource_loader.cpp | 6 +- source/core/resources/resource_pack.hpp | 2 +- source/core/system/director.cpp | 2 +- source/core/system/game_config.hpp | 16 +- source/core/system/global_events.hpp | 2 +- source/core/system/scene_context.hpp | 6 +- source/core/utils/path_utils.cpp | 2 +- source/game/constants.hpp | 14 +- source/game/effects/debris.hpp | 14 +- source/game/effects/debris_manager.cpp | 126 ++--- source/game/effects/debris_manager.hpp | 34 +- ...ntuacio_flotant.hpp => floating_score.hpp} | 12 +- ...flotant.cpp => floating_score_manager.cpp} | 52 +- ...flotant.hpp => floating_score_manager.hpp} | 28 +- source/game/entities/bullet.cpp | 28 +- source/game/entities/bullet.hpp | 4 +- source/game/entities/enemy.cpp | 40 +- source/game/entities/enemy.hpp | 6 +- source/game/entities/ship.cpp | 40 +- source/game/entities/ship.hpp | 2 +- source/game/options.cpp | 10 +- source/game/options.hpp | 2 +- source/game/scenes/game_scene.cpp | 516 +++++++++--------- source/game/scenes/game_scene.hpp | 34 +- source/game/scenes/logo_scene.cpp | 68 +-- source/game/scenes/logo_scene.hpp | 8 +- source/game/scenes/title_scene.cpp | 134 ++--- source/game/scenes/title_scene.hpp | 16 +- source/game/stage_system/spawn_controller.cpp | 38 +- source/game/stage_system/spawn_controller.hpp | 10 +- source/game/stage_system/stage_config.hpp | 14 +- source/game/stage_system/stage_loader.cpp | 20 +- source/game/stage_system/stage_loader.hpp | 6 +- source/game/stage_system/stage_manager.cpp | 10 +- source/game/stage_system/stage_manager.hpp | 8 +- source/game/title/ship_animator.cpp | 272 ++++----- source/game/title/ship_animator.hpp | 52 +- 59 files changed, 998 insertions(+), 998 deletions(-) rename source/game/effects/{puntuacio_flotant.hpp => floating_score.hpp} (69%) rename source/game/effects/{gestor_puntuacio_flotant.cpp => floating_score_manager.cpp} (55%) rename source/game/effects/{gestor_puntuacio_flotant.hpp => floating_score_manager.hpp} (55%) diff --git a/source/core/audio/audio_cache.cpp b/source/core/audio/audio_cache.cpp index f3b671e..85d4fa4 100644 --- a/source/core/audio/audio_cache.cpp +++ b/source/core/audio/audio_cache.cpp @@ -30,7 +30,7 @@ JA_Sound_t* AudioCache::getSound(const std::string& name) { // Load from resource system std::vector data = Resource::Helper::loadFile(normalized); if (data.empty()) { - std::cerr << "[AudioCache] Error: no s'ha pogut carregar " << normalized << std::endl; + std::cerr << "[AudioCache] Error: no s'ha pogut load " << normalized << std::endl; return nullptr; } @@ -64,7 +64,7 @@ JA_Music_t* AudioCache::getMusic(const std::string& name) { // Load from resource system std::vector data = Resource::Helper::loadFile(normalized); if (data.empty()) { - std::cerr << "[AudioCache] Error: no s'ha pogut carregar " << normalized << std::endl; + std::cerr << "[AudioCache] Error: no s'ha pogut load " << normalized << std::endl; return nullptr; } diff --git a/source/core/defaults.hpp b/source/core/defaults.hpp index 6c39e05..c8d091b 100644 --- a/source/core/defaults.hpp +++ b/source/core/defaults.hpp @@ -107,7 +107,7 @@ constexpr float ENEMY_RADIUS = 20.0F; constexpr float BULLET_RADIUS = 3.0F; } // namespace Entities -// Ship (nave del jugador) +// Ship (nave del player) namespace Ship { // Invulnerabilidad post-respawn constexpr float INVULNERABILITY_DURATION = 3.0F; // Segundos de invulnerabilidad @@ -151,11 +151,11 @@ constexpr float INIT_HUD_RECT_RATIO_END = 0.85F; constexpr float INIT_HUD_SCORE_RATIO_INIT = 0.60F; constexpr float INIT_HUD_SCORE_RATIO_END = 0.90F; -// SHIP1 (nave jugador 1) +// SHIP1 (nave player 1) constexpr float INIT_HUD_SHIP1_RATIO_INIT = 0.0F; constexpr float INIT_HUD_SHIP1_RATIO_END = 1.0F; -// SHIP2 (nave jugador 2) +// SHIP2 (nave player 2) constexpr float INIT_HUD_SHIP2_RATIO_INIT = 0.20F; constexpr float INIT_HUD_SHIP2_RATIO_END = 1.0F; @@ -220,7 +220,7 @@ constexpr float TEMPS_VIDA = 2.0F; // Duració màxima (segons) - enem constexpr float TEMPS_VIDA_NAU = 3.0F; // Ship debris lifetime (matches DEATH_DURATION) constexpr float SHRINK_RATE = 0.5F; // Reducció de mida (factor/s) -// Herència de velocitat angular (trayectorias curvas) +// Herència de velocity angular (trayectorias curvas) constexpr float FACTOR_HERENCIA_MIN = 0.7F; // Mínimo 70% del drotacio heredat constexpr float FACTOR_HERENCIA_MAX = 1.0F; // Màxim 100% del drotacio heredat constexpr float FRICCIO_ANGULAR = 0.5F; // Desacceleració angular (rad/s²) @@ -261,10 +261,10 @@ constexpr uint8_t BACKGROUND_MAX_G = 15; constexpr uint8_t BACKGROUND_MAX_B = 0; } // namespace Color -// Brillantor (control de intensitat per cada tipus d'entitat) +// Brillantor (control de intensitat per cada type d'entitat) namespace Brightness { // Brillantor estàtica per entitats de joc (0.0-1.0) -constexpr float NAU = 1.0F; // Màxima visibilitat (jugador) +constexpr float NAU = 1.0F; // Màxima visibilitat (player) constexpr float ENEMIC = 0.7F; // 30% més tènue (destaca menys) constexpr float BALA = 1.0F; // Brillo a tope (màxima visibilitat) @@ -306,7 +306,7 @@ constexpr const char* FRIENDLY_FIRE_HIT = "effects/friendly_fire.wav"; // constexpr const char* INIT_HUD = "effects/init_hud.wav"; // Para la animación del HUD constexpr const char* LASER = "effects/laser_shoot.wav"; // Disparo constexpr const char* LOGO = "effects/logo.wav"; // Logo -constexpr const char* START = "effects/start.wav"; // El jugador pulsa START +constexpr const char* START = "effects/start.wav"; // El player pulsa START constexpr const char* GOOD_JOB_COMMANDER = "voices/good_job_commander.wav"; // Voz: "Good job, commander" } // namespace Sound @@ -327,7 +327,7 @@ constexpr SDL_Keycode SHOOT = SDLK_LSHIFT; } // namespace P2 } // namespace Controls -// Enemy type configuration (tipus d'enemics) +// Enemy type configuration (type d'enemics) namespace Enemies { // Pentagon (esquivador - zigzag evasion) namespace Pentagon { @@ -395,7 +395,7 @@ constexpr float INVULNERABILITY_SCALE_START = 0.0F; // Invisible constexpr float INVULNERABILITY_SCALE_END = 1.0F; // Full size } // namespace Spawn -// Scoring system (puntuació per tipus d'enemic) +// Scoring system (puntuació per type d'enemy) namespace Scoring { constexpr int PENTAGON_SCORE = 100; // Pentàgon (esquivador, 35 px/s) constexpr int QUADRAT_SCORE = 150; // Quadrat (perseguidor, 40 px/s) @@ -426,7 +426,7 @@ constexpr float CLOCK_RADIUS = 150.0F; // Distància des del centre constexpr float CLOCK_8_ANGLE = 150.0F * Math::PI / 180.0F; // 8 o'clock (bottom-left) constexpr float CLOCK_4_ANGLE = 30.0F * Math::PI / 180.0F; // 4 o'clock (bottom-right) -// 5. Radio máximo de la forma de la nave (para calcular offset automáticamente) +// 5. Radio máximo de la shape de la nave (para calcular offset automáticamente) constexpr float SHIP_MAX_RADIUS = 30.0F; // Radi del cercle circumscrit a ship_starfield.shp // 6. Margen de seguridad para offset de entrada @@ -436,7 +436,7 @@ constexpr float ENTRY_OFFSET_MARGIN = 227.5F; // Para offset total de ~340px (a // VALORS DERIVATS (calculats automàticament - NO modificar) // ============================================================ -// Centre de la pantalla (punt de referència) +// Centre de la pantalla (point de referència) constexpr float CENTER_X = Game::WIDTH / 2.0F; // 320.0f constexpr float CENTER_Y = Game::HEIGHT / 2.0F; // 240.0f @@ -458,10 +458,10 @@ inline float P2_TARGET_Y() { // Escales d'animació (relatives a SHIP_BASE_SCALE) constexpr float ENTRY_SCALE_START = 1.5F * SHIP_BASE_SCALE; // Entrada: 50% més gran -constexpr float FLOATING_SCALE = 1.0F * SHIP_BASE_SCALE; // Flotant: escala base +constexpr float FLOATING_SCALE = 1.0F * SHIP_BASE_SCALE; // Flotant: scale base -// Offset d'entrada (ajustat automàticament a l'escala) -// Fórmula: (radi màxim de la nau * escala d'entrada) + marge +// Offset d'entrada (ajustat automàticament a l'scale) +// Fórmula: (radi màxim de la ship * scale d'entrada) + marge constexpr float ENTRY_OFFSET = (SHIP_MAX_RADIUS * ENTRY_SCALE_START) + ENTRY_OFFSET_MARGIN; // Vec2 de fuga (centre per a l'animació de sortida) @@ -476,7 +476,7 @@ constexpr float VANISHING_POINT_Y = CENTER_Y; // 240.0f constexpr float ENTRY_DURATION = 2.0F; // Entrada (segons) constexpr float EXIT_DURATION = 1.0F; // Sortida (segons) -// Flotació (oscil·lació reduïda i diferenciada per nau) +// Flotació (oscil·lació reduïda i diferenciada per ship) constexpr float FLOAT_AMPLITUDE_X = 4.0F; // Amplitud X (píxels) constexpr float FLOAT_AMPLITUDE_Y = 2.5F; // Amplitud Y (píxels) @@ -489,10 +489,10 @@ constexpr float FLOAT_PHASE_OFFSET = 1.57F; // π/2 (90°) constexpr float P1_ENTRY_DELAY = 0.0F; // P1 entra immediatament constexpr float P2_ENTRY_DELAY = 0.5F; // P2 entra 0.5s després -// Delay global abans d'iniciar l'animació d'entrada al estat MAIN +// Delay global abans d'iniciar l'animació d'entrada al state MAIN constexpr float ENTRANCE_DELAY = 5.0F; // Temps d'espera abans que les naus entrin -// Multiplicadors de freqüència per a cada nau (variació sutil ±12%) +// Multiplicadors de freqüència per a cada ship (variació sutil ±12%) constexpr float P1_FREQUENCY_MULTIPLIER = 0.88F; // 12% més lenta constexpr float P2_FREQUENCY_MULTIPLIER = 1.12F; // 12% més ràpida @@ -508,7 +508,7 @@ constexpr float COPYRIGHT1_POS = 0.90F; // Primera línia copyright constexpr float LOGO_LINE_SPACING = 0.02F; // Entre "ORNI" i "ATTACK!" (10px) constexpr float COPYRIGHT_LINE_SPACING = 0.0F; // Entre línies copyright (5px) -// Factors d'escala +// Factors d'scale constexpr float LOGO_SCALE = 0.6F; // Escala "ORNI ATTACK!" constexpr float PRESS_START_SCALE = 1.0F; // Escala "PRESS START TO PLAY" constexpr float COPYRIGHT_SCALE = 0.5F; // Escala copyright diff --git a/source/core/graphics/shape.cpp b/source/core/graphics/shape.cpp index b7f0af9..c165a34 100644 --- a/source/core/graphics/shape.cpp +++ b/source/core/graphics/shape.cpp @@ -14,10 +14,10 @@ Shape::Shape(const std::string& filepath) : center_({.x = 0.0F, .y = 0.0F}), escala_defecte_(1.0F), nom_("unnamed") { - carregar(filepath); + load(filepath); } -bool Shape::carregar(const std::string& filepath) { +bool Shape::load(const std::string& filepath) { // Llegir fitxer std::ifstream file(filepath); if (!file.is_open()) { @@ -32,10 +32,10 @@ bool Shape::carregar(const std::string& filepath) { file.close(); // Parsejar - return parsejar_fitxer(contingut); + return parseFile(contingut); } -bool Shape::parsejar_fitxer(const std::string& contingut) { +bool Shape::parseFile(const std::string& contingut) { std::istringstream iss(contingut); std::string line; @@ -55,7 +55,7 @@ bool Shape::parsejar_fitxer(const std::string& contingut) { try { escala_defecte_ = std::stof(extract_value(line)); } catch (...) { - std::cerr << "[Shape] Warning: escala invàlida, usant 1.0" << '\n'; + std::cerr << "[Shape] Warning: scale invàlida, usant 1.0" << '\n'; escala_defecte_ = 1.0F; } } else if (starts_with(line, "center:")) { @@ -65,7 +65,7 @@ bool Shape::parsejar_fitxer(const std::string& contingut) { if (points.size() >= 2) { primitives_.push_back({PrimitiveType::POLYLINE, points}); } else { - std::cerr << "[Shape] Warning: polyline amb menys de 2 punts ignorada" + std::cerr << "[Shape] Warning: polyline amb menys de 2 points ignorada" << '\n'; } } else if (starts_with(line, "line:")) { @@ -73,7 +73,7 @@ bool Shape::parsejar_fitxer(const std::string& contingut) { if (points.size() == 2) { primitives_.push_back({PrimitiveType::LINE, points}); } else { - std::cerr << "[Shape] Warning: line ha de tenir exactament 2 punts" + std::cerr << "[Shape] Warning: line ha de tenir exactament 2 points" << '\n'; } } @@ -147,7 +147,7 @@ std::vector Shape::parse_points(const std::string& str) const { float y = std::stof(pair.substr(comma + 1)); points.push_back({x, y}); } catch (...) { - std::cerr << "[Shape] Warning: punt invàlid ignorat: " << pair + std::cerr << "[Shape] Warning: point invàlid ignorat: " << pair << '\n'; } } diff --git a/source/core/graphics/shape.hpp b/source/core/graphics/shape.hpp index f20ffdd..c848b19 100644 --- a/source/core/graphics/shape.hpp +++ b/source/core/graphics/shape.hpp @@ -10,30 +10,30 @@ namespace Graphics { -// Tipus de primitiva dins d'una forma +// Tipus de primitiva dins d'una shape enum class PrimitiveType { - POLYLINE, // Seqüència de punts connectats - LINE // Línia individual (2 punts) + POLYLINE, // Seqüència de points connectats + LINE // Línia individual (2 points) }; // Primitiva individual (polyline o line) struct ShapePrimitive { PrimitiveType type; - std::vector points; // 2+ punts per polyline, exactament 2 per line + std::vector points; // 2+ points per polyline, exactament 2 per line }; -// Classe Shape - representa una forma vectorial carregada des de .shp +// Classe Shape - representa una shape vectorial carregada des de .shp class Shape { public: // Constructors Shape() = default; explicit Shape(const std::string& filepath); - // Carregar forma des de fitxer .shp - bool carregar(const std::string& filepath); + // Carregar shape des de fitxer .shp + bool load(const std::string& filepath); - // Parsejar forma des de buffer de memòria (per al sistema de recursos) - bool parsejar_fitxer(const std::string& contingut); + // Parsejar shape des de buffer de memòria (per al sistema de recursos) + bool parseFile(const std::string& contingut); // Getters [[nodiscard]] const std::vector& get_primitives() const { @@ -41,7 +41,7 @@ class Shape { } [[nodiscard]] const Vec2& getCenter() const { return center_; } [[nodiscard]] float get_escala_defecte() const { return escala_defecte_; } - [[nodiscard]] bool es_valida() const { return !primitives_.empty(); } + [[nodiscard]] bool isValid() const { return !primitives_.empty(); } // Info de depuració [[nodiscard]] std::string get_nom() const { return nom_; } @@ -49,9 +49,9 @@ class Shape { private: std::vector primitives_; - Vec2 center_; // Centre/origen de la forma + Vec2 center_; // Centre/origen de la shape float escala_defecte_; // Escala per defecte (normalment 1.0) - std::string nom_; // Nom de la forma (per depuració) + std::string nom_; // Nom de la shape (per depuració) // Helpers privats per parsejar [[nodiscard]] std::string trim(const std::string& str) const; diff --git a/source/core/graphics/shape_loader.cpp b/source/core/graphics/shape_loader.cpp index 99a7f5d..cd68f6a 100644 --- a/source/core/graphics/shape_loader.cpp +++ b/source/core/graphics/shape_loader.cpp @@ -32,7 +32,7 @@ std::shared_ptr ShapeLoader::load(const std::string& filename) { // Load from resource system std::vector data = Resource::Helper::loadFile(normalized); if (data.empty()) { - std::cerr << "[ShapeLoader] Error: no s'ha pogut carregar " << normalized + std::cerr << "[ShapeLoader] Error: no s'ha pogut load " << normalized << '\n'; return nullptr; } @@ -40,15 +40,15 @@ std::shared_ptr ShapeLoader::load(const std::string& filename) { // Convert bytes to string and parse std::string file_content(data.begin(), data.end()); auto shape = std::make_shared(); - if (!shape->parsejar_fitxer(file_content)) { + if (!shape->parseFile(file_content)) { std::cerr << "[ShapeLoader] Error: no s'ha pogut parsejar " << normalized << '\n'; return nullptr; } // Verify shape is valid - if (!shape->es_valida()) { - std::cerr << "[ShapeLoader] Error: forma invàlida " << normalized << '\n'; + if (!shape->isValid()) { + std::cerr << "[ShapeLoader] Error: shape invàlida " << normalized << '\n'; return nullptr; } diff --git a/source/core/graphics/shape_loader.hpp b/source/core/graphics/shape_loader.hpp index d606c0a..5f94d67 100644 --- a/source/core/graphics/shape_loader.hpp +++ b/source/core/graphics/shape_loader.hpp @@ -17,7 +17,7 @@ class ShapeLoader { // No instanciable (tot estàtic) ShapeLoader() = delete; - // Carregar forma des de fitxer (amb caché) + // Carregar shape des de fitxer (amb caché) // Retorna punter compartit (nullptr si error) // Exemple: load("ship.shp") → busca a "data/shapes/ship.shp" static std::shared_ptr load(const std::string& filename); diff --git a/source/core/graphics/starfield.cpp b/source/core/graphics/starfield.cpp index 4f4044a..02fec0e 100644 --- a/source/core/graphics/starfield.cpp +++ b/source/core/graphics/starfield.cpp @@ -22,11 +22,11 @@ Starfield::Starfield(SDL_Renderer* renderer, punt_fuga_(punt_fuga), area_(area), densitat_(densitat) { - // Carregar forma d'estrella amb ShapeLoader + // Carregar shape d'estrella amb ShapeLoader shape_estrella_ = ShapeLoader::load("star.shp"); - if (!shape_estrella_ || !shape_estrella_->es_valida()) { - std::cerr << "ERROR: No s'ha pogut carregar star.shp" << '\n'; + if (!shape_estrella_ || !shape_estrella_->isValid()) { + std::cerr << "ERROR: No s'ha pogut load star.shp" << '\n'; return; } @@ -60,8 +60,8 @@ Starfield::Starfield(SDL_Renderer* renderer, // Calcular posició des de la distància float radi = estrella.distancia_centre * radi_max_; - estrella.posicio.x = punt_fuga_.x + (radi * std::cos(estrella.angle)); - estrella.posicio.y = punt_fuga_.y + (radi * std::sin(estrella.angle)); + estrella.position.x = punt_fuga_.x + (radi * std::cos(estrella.angle)); + estrella.position.y = punt_fuga_.y + (radi * std::sin(estrella.angle)); estrelles_.push_back(estrella); } @@ -70,27 +70,27 @@ Starfield::Starfield(SDL_Renderer* renderer, // Inicialitzar una estrella (nova o regenerada) void Starfield::inicialitzar_estrella(Estrella& estrella) const { - // Angle aleatori des del punt de fuga cap a fora + // Angle aleatori des del point de fuga cap a fora estrella.angle = (static_cast(rand()) / RAND_MAX) * 2.0F * Defaults::Math::PI; // Distància inicial petita (5% del radi màxim) - neix prop del centre estrella.distancia_centre = 0.05F; - // Posició inicial: molt prop del punt de fuga + // Posició inicial: molt prop del point de fuga float radi = estrella.distancia_centre * radi_max_; - estrella.posicio.x = punt_fuga_.x + (radi * std::cos(estrella.angle)); - estrella.posicio.y = punt_fuga_.y + (radi * std::sin(estrella.angle)); + estrella.position.x = punt_fuga_.x + (radi * std::cos(estrella.angle)); + estrella.position.y = punt_fuga_.y + (radi * std::sin(estrella.angle)); } // Verificar si una estrella està fora de l'àrea bool Starfield::fora_area(const Estrella& estrella) const { - return (estrella.posicio.x < area_.x || - estrella.posicio.x > area_.x + area_.w || - estrella.posicio.y < area_.y || - estrella.posicio.y > area_.y + area_.h); + return (estrella.position.x < area_.x || + estrella.position.x > area_.x + area_.w || + estrella.position.y < area_.y || + estrella.position.y > area_.y + area_.h); } -// Calcular escala dinàmica segons distància del centre +// Calcular scale dinàmica segons distància del centre float Starfield::calcular_escala(const Estrella& estrella) const { const CapaConfig& capa = capes_[estrella.capa]; @@ -119,16 +119,16 @@ void Starfield::update(float delta_time) { const CapaConfig& capa = capes_[estrella.capa]; // Moure cap a fora des del centre - float velocitat = capa.velocitat_base; - float dx = velocitat * std::cos(estrella.angle) * delta_time; - float dy = velocitat * std::sin(estrella.angle) * delta_time; + float velocity = capa.velocitat_base; + float dx = velocity * std::cos(estrella.angle) * delta_time; + float dy = velocity * std::sin(estrella.angle) * delta_time; - estrella.posicio.x += dx; - estrella.posicio.y += dy; + estrella.position.x += dx; + estrella.position.y += dy; // Actualitzar distància del centre - float dx_centre = estrella.posicio.x - punt_fuga_.x; - float dy_centre = estrella.posicio.y - punt_fuga_.y; + float dx_centre = estrella.position.x - punt_fuga_.x; + float dy_centre = estrella.position.y - punt_fuga_.y; float dist_px = std::sqrt((dx_centre * dx_centre) + (dy_centre * dy_centre)); estrella.distancia_centre = dist_px / radi_max_; @@ -146,22 +146,22 @@ void Starfield::set_brightness(float multiplier) { // Dibuixar totes les estrelles void Starfield::draw() { - if (!shape_estrella_->es_valida()) { + if (!shape_estrella_->isValid()) { return; } for (const auto& estrella : estrelles_) { - // Calcular escala i brightness dinàmicament - float escala = calcular_escala(estrella); + // Calcular scale i brightness dinàmicament + float scale = calcular_escala(estrella); float brightness = calcular_brightness(estrella); // Renderitzar estrella sense rotació Rendering::render_shape( renderer_, shape_estrella_, - estrella.posicio, + estrella.position, 0.0F, // angle (les estrelles no giren) - escala, // escala dinàmica + scale, // scale dinàmica 1.0F, // progress (sempre visible) brightness // brightness dinàmica ); diff --git a/source/core/graphics/starfield.hpp b/source/core/graphics/starfield.hpp index 6304154..0c772fe 100644 --- a/source/core/graphics/starfield.hpp +++ b/source/core/graphics/starfield.hpp @@ -26,7 +26,7 @@ class Starfield { public: // Constructor // - renderer: SDL renderer - // - punt_fuga: punt d'origen/fuga des d'on surten les estrelles + // - punt_fuga: point d'origen/fuga des d'on surten les estrelles // - area: rectangle on actuen les estrelles (SDL_FRect) // - densitat: nombre total d'estrelles (es divideix entre capes) Starfield(SDL_Renderer* renderer, @@ -40,14 +40,14 @@ class Starfield { // Dibuixar totes les estrelles void draw(); - // Setters per ajustar paràmetres en temps real - void set_punt_fuga(const Vec2& punt) { punt_fuga_ = punt; } + // Setters per ajustar paràmetres en time real + void set_punt_fuga(const Vec2& point) { punt_fuga_ = point; } void set_brightness(float multiplier); private: // Estructura interna per cada estrella struct Estrella { - Vec2 posicio; // Posició actual + Vec2 position; // Posició actual float angle; // Angle de moviment (radians) float distancia_centre; // Distància normalitzada del centre (0.0-1.0) int capa; // Índex de capa (0=lluny, 1=mitjà, 2=prop) @@ -59,7 +59,7 @@ class Starfield { // Verificar si una estrella està fora de l'àrea [[nodiscard]] bool fora_area(const Estrella& estrella) const; - // Calcular escala dinàmica segons distància del centre + // Calcular scale dinàmica segons distància del centre [[nodiscard]] float calcular_escala(const Estrella& estrella) const; // Calcular brightness dinàmica segons distància del centre @@ -76,7 +76,7 @@ class Starfield { SDL_FRect area_; // Àrea activa float radi_max_; // Distància màxima del centre al límit de pantalla int densitat_; // Nombre total d'estrelles - float multiplicador_brightness_{1.0F}; // Multiplicador de brillantor (1.0 = default) + float multiplicador_brightness_{1.0F}; // Multiplicador de brightness (1.0 = default) }; } // namespace Graphics diff --git a/source/core/graphics/vector_text.cpp b/source/core/graphics/vector_text.cpp index ceae3fe..88e6452 100644 --- a/source/core/graphics/vector_text.cpp +++ b/source/core/graphics/vector_text.cpp @@ -26,10 +26,10 @@ void VectorText::load_charset() { std::string filename = get_shape_filename(c); auto shape = ShapeLoader::load(filename); - if (shape && shape->es_valida()) { + if (shape && shape->isValid()) { chars_[c] = shape; } else { - std::cerr << "[VectorText] Warning: no s'ha pogut carregar " << filename + std::cerr << "[VectorText] Warning: no s'ha pogut load " << filename << '\n'; } } @@ -39,10 +39,10 @@ void VectorText::load_charset() { std::string filename = get_shape_filename(c); auto shape = ShapeLoader::load(filename); - if (shape && shape->es_valida()) { + if (shape && shape->isValid()) { chars_[c] = shape; } else { - std::cerr << "[VectorText] Warning: no s'ha pogut carregar " << filename + std::cerr << "[VectorText] Warning: no s'ha pogut load " << filename << '\n'; } } @@ -54,10 +54,10 @@ void VectorText::load_charset() { std::string filename = get_shape_filename(c); auto shape = ShapeLoader::load(filename); - if (shape && shape->es_valida()) { + if (shape && shape->isValid()) { chars_[c] = shape; } else { - std::cerr << "[VectorText] Warning: no s'ha pogut carregar " << filename + std::cerr << "[VectorText] Warning: no s'ha pogut load " << filename << '\n'; } } @@ -69,10 +69,10 @@ void VectorText::load_charset() { std::string filename = "font/char_copyright.shp"; auto shape = ShapeLoader::load(filename); - if (shape && shape->es_valida()) { + if (shape && shape->isValid()) { chars_[c] = shape; } else { - std::cerr << "[VectorText] Warning: no s'ha pogut carregar " << filename + std::cerr << "[VectorText] Warning: no s'ha pogut load " << filename << '\n'; } } @@ -168,7 +168,7 @@ std::string VectorText::get_shape_filename(char c) const { case '?': return "font/char_question.shp"; case ' ': - return ""; // Espai es maneja sense carregar shape + return ""; // Espai es maneja sense load shape case '\xA9': // Copyright symbol (©) - UTF-8 U+00A9 return "font/char_copyright.shp"; @@ -182,23 +182,23 @@ bool VectorText::is_supported(char c) const { return chars_.contains(c); } -void VectorText::render(const std::string& text, const Vec2& posicio, float escala, float spacing, float brightness) const { +void VectorText::render(const std::string& text, const Vec2& position, float scale, float spacing, float brightness) const { if (renderer_ == nullptr) { return; } - // Ancho de un carácter base (20 px a escala 1.0) - const float char_width_scaled = char_width * escala; + // Ancho de un carácter base (20 px a scale 1.0) + const float char_width_scaled = char_width * scale; // Spacing escalado - const float spacing_scaled = spacing * escala; + const float spacing_scaled = spacing * scale; // Altura de un carácter escalado (necesario para ajustar Y) - const float char_height_scaled = char_height * escala; + const float char_height_scaled = char_height * scale; // Posición X del borde izquierdo del carácter actual // (se ajustará +char_width/2 para obtener el centro al renderizar) - float current_x = posicio.x; + float current_x = position.x; // Iterar sobre cada byte del string (con detecció UTF-8) for (size_t i = 0; i < text.length(); i++) { @@ -221,10 +221,10 @@ void VectorText::render(const std::string& text, const Vec2& posicio, float esca auto it = chars_.find(c); if (it != chars_.end()) { // Renderizar carácter - // Ajustar X e Y para que posicio represente esquina superior izquierda + // Ajustar X e Y para que position represente esquina superior izquierda // (render_shape espera el centro, así que sumamos la mitad de ancho y altura) - Vec2 char_pos = {.x = current_x + (char_width_scaled / 2.0F), .y = posicio.y + (char_height_scaled / 2.0F)}; - Rendering::render_shape(renderer_, it->second, char_pos, 0.0F, escala, 1.0F, brightness); + Vec2 char_pos = {.x = current_x + (char_width_scaled / 2.0F), .y = position.y + (char_height_scaled / 2.0F)}; + Rendering::render_shape(renderer_, it->second, char_pos, 0.0F, scale, 1.0F, brightness); // Avanzar posición current_x += char_width_scaled + spacing_scaled; @@ -237,28 +237,28 @@ void VectorText::render(const std::string& text, const Vec2& posicio, float esca } } -void VectorText::render_centered(const std::string& text, const Vec2& centre_punt, float escala, float spacing, float brightness) const { +void VectorText::renderCentered(const std::string& text, const Vec2& centre_punt, float scale, float spacing, float brightness) const { // Calcular dimensions del text - float text_width = get_text_width(text, escala, spacing); - float text_height = get_text_height(escala); + float text_width = get_text_width(text, scale, spacing); + float text_height = get_text_height(scale); // Calcular posició de l'esquina superior esquerra - // restant la meitat de les dimensions del punt central + // restant la meitat de les dimensions del point central Vec2 posicio_esquerra = { .x = centre_punt.x - (text_width / 2.0F), .y = centre_punt.y - (text_height / 2.0F)}; // Delegar al mètode render() existent - render(text, posicio_esquerra, escala, spacing, brightness); + render(text, posicio_esquerra, scale, spacing, brightness); } -float VectorText::get_text_width(const std::string& text, float escala, float spacing) const { +float VectorText::get_text_width(const std::string& text, float scale, float spacing) const { if (text.empty()) { return 0.0F; } - const float char_width_scaled = char_width * escala; - const float spacing_scaled = spacing * escala; + const float char_width_scaled = char_width * scale; + const float spacing_scaled = spacing * scale; // Contar caracteres visuals (no bytes) - manejar UTF-8 size_t visual_chars = 0; @@ -279,8 +279,8 @@ float VectorText::get_text_width(const std::string& text, float escala, float sp return (visual_chars * char_width_scaled) + ((visual_chars - 1) * spacing_scaled); } -float VectorText::get_text_height(float escala) const { - return char_height * escala; +float VectorText::get_text_height(float scale) const { + return char_height * scale; } } // namespace Graphics diff --git a/source/core/graphics/vector_text.hpp b/source/core/graphics/vector_text.hpp index a88d9c0..aeb30f0 100644 --- a/source/core/graphics/vector_text.hpp +++ b/source/core/graphics/vector_text.hpp @@ -21,25 +21,25 @@ class VectorText { // Renderizar string completo // - text: cadena a renderizar (soporta: A-Z, a-z, 0-9, '.', ',', '-', ':', // '!', '?', ' ') - // - posicio: posición inicial (esquina superior izquierda) - // - escala: factor de escala (1.0 = 20×40 px por carácter) - // - spacing: espacio entre caracteres en píxeles (a escala 1.0) - // - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor) - void render(const std::string& text, const Vec2& posicio, float escala = 1.0F, float spacing = 2.0F, float brightness = 1.0F) const; + // - position: posición inicial (esquina superior izquierda) + // - scale: factor de scale (1.0 = 20×40 px por carácter) + // - spacing: espacio entre caracteres en píxeles (a scale 1.0) + // - brightness: factor de brightness (0.0-1.0, default 1.0 = màxima brightness) + void render(const std::string& text, const Vec2& position, float scale = 1.0F, float spacing = 2.0F, float brightness = 1.0F) const; // Renderizar string centrado en un punto // - text: cadena a renderizar // - centre_punt: punto central del texto (no esquina superior izquierda) - // - escala: factor de escala (1.0 = 20×40 px por carácter) - // - spacing: espacio entre caracteres en píxeles (a escala 1.0) - // - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor) - void render_centered(const std::string& text, const Vec2& centre_punt, float escala = 1.0F, float spacing = 2.0F, float brightness = 1.0F) const; + // - scale: factor de scale (1.0 = 20×40 px por carácter) + // - spacing: espacio entre caracteres en píxeles (a scale 1.0) + // - brightness: factor de brightness (0.0-1.0, default 1.0 = màxima brightness) + void renderCentered(const std::string& text, const Vec2& centre_punt, float scale = 1.0F, float spacing = 2.0F, float brightness = 1.0F) const; // Calcular ancho total de un string (útil para centrado) - [[nodiscard]] float get_text_width(const std::string& text, float escala = 1.0F, float spacing = 2.0F) const; + [[nodiscard]] float get_text_width(const std::string& text, float scale = 1.0F, float spacing = 2.0F) const; // Calcular altura del texto (útil para centrado vertical) - [[nodiscard]] float get_text_height(float escala = 1.0F) const; + [[nodiscard]] float get_text_height(float scale = 1.0F) const; // Verificar si un carácter está soportado [[nodiscard]] bool is_supported(char c) const; diff --git a/source/core/input/input.cpp b/source/core/input/input.cpp index f89f3f7..7ed92f1 100644 --- a/source/core/input/input.cpp +++ b/source/core/input/input.cpp @@ -30,7 +30,7 @@ Input::Input(std::string game_controller_db_path) // Inicializar bindings del teclado (valores por defecto) // Estos serán sobrescritos por applyPlayer1BindingsFromOptions() keyboard_.bindings = { - // Movimiento del jugador + // Movimiento del player {Action::LEFT, KeyState{.scancode = SDL_SCANCODE_LEFT}}, {Action::RIGHT, KeyState{.scancode = SDL_SCANCODE_RIGHT}}, {Action::THRUST, KeyState{.scancode = SDL_SCANCODE_UP}}, @@ -188,7 +188,7 @@ auto Input::checkAnyButton(bool repeat) -> bool { return false; } -// Comprueba si algún jugador (P1 o P2) presionó alguna acción de una lista +// Comprueba si algún player (P1 o P2) presionó alguna acción de una lista auto Input::checkAnyPlayerAction(const std::span& actions, bool repeat) -> bool { for (const auto& action : actions) { if (checkActionPlayer1(action, repeat) || checkActionPlayer2(action, repeat)) { @@ -388,14 +388,14 @@ void Input::update() { binding.second.is_held = key_is_down_now; } - // Actualizar bindings de jugador 1 + // Actualizar bindings de player 1 for (auto& binding : player1_keyboard_bindings_) { bool key_is_down_now = key_states[binding.second.scancode]; binding.second.just_pressed = key_is_down_now && !binding.second.is_held; binding.second.is_held = key_is_down_now; } - // Actualizar bindings de jugador 2 + // Actualizar bindings de player 2 for (auto& binding : player2_keyboard_bindings_) { bool key_is_down_now = key_states[binding.second.scancode]; binding.second.just_pressed = key_is_down_now && !binding.second.is_held; @@ -493,7 +493,7 @@ auto Input::findAvailableGamepadByName(const std::string& gamepad_name) -> std:: // ========== MÉTODOS ESPECÍFICOS POR JUGADOR (ORNI) ========== -// Aplica configuración de controles del jugador 1 +// Aplica configuración de controles del player 1 void Input::applyPlayer1BindingsFromOptions() { // 1. Aplicar bindings de teclado (NO usar bindKey, llenar mapa específico) player1_keyboard_bindings_[Action::LEFT].scancode = Options::player1.keyboard.key_left; @@ -527,7 +527,7 @@ void Input::applyPlayer1BindingsFromOptions() { player1_gamepad_ = gamepad; } -// Aplica configuración de controles del jugador 2 +// Aplica configuración de controles del player 2 void Input::applyPlayer2BindingsFromOptions() { // 1. Aplicar bindings de teclado (mapa específico de P2, no sobrescribe P1) player2_keyboard_bindings_[Action::LEFT].scancode = Options::player2.keyboard.key_left; @@ -561,7 +561,7 @@ void Input::applyPlayer2BindingsFromOptions() { player2_gamepad_ = gamepad; } -// Consulta de input para jugador 1 +// Consulta de input para player 1 auto Input::checkActionPlayer1(Action action, bool repeat) -> bool { // Comprobar teclado con el mapa específico de P1 bool keyboard_active = false; @@ -583,7 +583,7 @@ auto Input::checkActionPlayer1(Action action, bool repeat) -> bool { return keyboard_active || gamepad_active; } -// Consulta de input para jugador 2 +// Consulta de input para player 2 auto Input::checkActionPlayer2(Action action, bool repeat) -> bool { // Comprobar teclado con el mapa específico de P2 bool keyboard_active = false; diff --git a/source/core/input/input.hpp b/source/core/input/input.hpp index 9e70746..d6b8384 100644 --- a/source/core/input/input.hpp +++ b/source/core/input/input.hpp @@ -58,7 +58,7 @@ class Input { name(std::string(SDL_GetGamepadName(gamepad))), path(std::string(SDL_GetGamepadPath(pad))), bindings{ - // Movimiento y acciones del jugador + // Movimiento y acciones del player {Action::LEFT, ButtonState{.button = static_cast(SDL_GAMEPAD_BUTTON_DPAD_LEFT)}}, {Action::RIGHT, ButtonState{.button = static_cast(SDL_GAMEPAD_BUTTON_DPAD_RIGHT)}}, {Action::THRUST, ButtonState{.button = static_cast(SDL_GAMEPAD_BUTTON_WEST)}}, @@ -92,7 +92,7 @@ class Input { void applyKeyboardBindingsFromOptions(); void applyGamepadBindingsFromOptions(); - // Configuración por jugador (Orni - dos jugadores) + // Configuración por player (Orni - dos jugadores) void applyPlayer1BindingsFromOptions(); void applyPlayer2BindingsFromOptions(); @@ -105,7 +105,7 @@ class Input { auto checkAnyButton(bool repeat = DO_NOT_ALLOW_REPEAT) -> bool; void resetInputStates(); - // Consulta por jugador (Orni - dos jugadores) + // Consulta por player (Orni - dos jugadores) auto checkActionPlayer1(Action action, bool repeat = true) -> bool; auto checkActionPlayer2(Action action, bool repeat = true) -> bool; @@ -152,11 +152,11 @@ class Input { Keyboard keyboard_{}; // Estado del teclado (solo acciones globales) std::string gamepad_mappings_file_; // Ruta al archivo de mappings - // Referencias cacheadas a gamepads por jugador (Orni) + // Referencias cacheadas a gamepads por player (Orni) std::shared_ptr player1_gamepad_; std::shared_ptr player2_gamepad_; - // Mapas de bindings separados por jugador (Orni - dos jugadores) + // Mapas de bindings separados por player (Orni - dos jugadores) std::unordered_map player1_keyboard_bindings_; std::unordered_map player2_keyboard_bindings_; }; \ No newline at end of file diff --git a/source/core/input/input_types.hpp b/source/core/input/input_types.hpp index 603de00..c032638 100644 --- a/source/core/input/input_types.hpp +++ b/source/core/input/input_types.hpp @@ -13,7 +13,7 @@ enum class InputAction : int { // Acciones de entrada posibles en el juego RIGHT, // Rotar derecha THRUST, // Acelerar SHOOT, // Disparar - START, // Empezar partida + START, // Empezar match // Inputs de sistema (globales) WINDOW_INC_ZOOM, // F2 diff --git a/source/core/input/mouse.cpp b/source/core/input/mouse.cpp index d47740c..2338f95 100644 --- a/source/core/input/mouse.cpp +++ b/source/core/input/mouse.cpp @@ -17,13 +17,13 @@ Uint32 initialization_time = 0; constexpr Uint32 IGNORE_MOTION_DURATION = 1000; // Ignorar primers 1000ms void forceHide() { - // Forçar ocultació sincronitzant estat SDL i estat intern - std::cout << "[Mouse::forceHide] Ocultant cursor i sincronitzant estat. cursor_visible=" << cursor_visible + // Forçar ocultació sincronitzant state SDL i state intern + std::cout << "[Mouse::forceHide] Ocultant cursor i sincronitzant state. cursor_visible=" << cursor_visible << " -> false" << '\n'; SDL_HideCursor(); cursor_visible = false; last_mouse_move_time = 0; - initialization_time = SDL_GetTicks(); // Marcar temps per ignorar esdeveniments inicials + initialization_time = SDL_GetTicks(); // Marcar time per ignorar esdeveniments inicials std::cout << "[Mouse::forceHide] Ignorant moviments durant " << IGNORE_MOTION_DURATION << "ms" << '\n'; } diff --git a/source/core/input/mouse.hpp b/source/core/input/mouse.hpp index d3bad75..7233c47 100644 --- a/source/core/input/mouse.hpp +++ b/source/core/input/mouse.hpp @@ -7,7 +7,7 @@ extern Uint32 cursor_hide_time; // Tiempo en milisegundos para ocultar el c extern Uint32 last_mouse_move_time; // Última vez que el ratón se movió extern bool cursor_visible; // Estado del cursor -void forceHide(); // Forçar ocultació del cursor (sincronitza estat intern) +void forceHide(); // Forçar ocultació del cursor (sincronitza state intern) void handleEvent(const SDL_Event& event); void updateCursorVisibility(); diff --git a/source/core/rendering/coordinate_transform.cpp b/source/core/rendering/coordinate_transform.cpp index 4ed2314..b3e04b0 100644 --- a/source/core/rendering/coordinate_transform.cpp +++ b/source/core/rendering/coordinate_transform.cpp @@ -5,7 +5,7 @@ namespace Rendering { -// Factor d'escala global (inicialitzat a 1.0 per defecte) +// Factor d'scale global (inicialitzat a 1.0 per defecte) float g_current_scale_factor = 1.0F; } // namespace Rendering diff --git a/source/core/rendering/coordinate_transform.hpp b/source/core/rendering/coordinate_transform.hpp index 7bd859f..0d06597 100644 --- a/source/core/rendering/coordinate_transform.hpp +++ b/source/core/rendering/coordinate_transform.hpp @@ -7,7 +7,7 @@ namespace Rendering { -// Factor d'escala global (actualitzat cada frame per SDLManager) +// Factor d'scale global (actualitzat cada frame per SDLManager) extern float g_current_scale_factor; // Transforma coordenada lògica a física amb arrodoniment @@ -19,7 +19,7 @@ inline int transform_y(int logical_y, float scale) { return static_cast(std::round(logical_y * scale)); } -// Variant que usa el factor d'escala global +// Variant que usa el factor d'scale global inline int transform_x(int logical_x) { return transform_x(logical_x, g_current_scale_factor); } diff --git a/source/core/rendering/line_renderer.hpp b/source/core/rendering/line_renderer.hpp index 5fba73c..904a1e2 100644 --- a/source/core/rendering/line_renderer.hpp +++ b/source/core/rendering/line_renderer.hpp @@ -7,8 +7,8 @@ namespace Rendering { -// Dibuixa una línia entre dos punts en coordenades lògiques (640x480). -// brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor). +// Dibuixa una línia entre dos points en coordenades lògiques (640x480). +// brightness: factor de brightness (0.0-1.0, default 1.0 = màxima brightness). void linea(SDL_Renderer* renderer, int x1, int y1, int x2, int y2, float brightness = 1.0F); // Estableix el color global de les línies (utilitzat per ColorOscillator). diff --git a/source/core/rendering/sdl_manager.cpp b/source/core/rendering/sdl_manager.cpp index 091405d..12614d5 100644 --- a/source/core/rendering/sdl_manager.cpp +++ b/source/core/rendering/sdl_manager.cpp @@ -283,7 +283,7 @@ void SDLManager::updateViewport() { } void SDLManager::updateRenderingContext() const { - // Actualitzar el factor d'escala global per a totes les funcions de renderitzat + // Actualitzar el factor d'scale global per a totes les funcions de renderitzat Rendering::g_current_scale_factor = zoom_factor_; } @@ -430,7 +430,7 @@ void SDLManager::updateColors(float delta_time) { // [NUEVO] Actualitzar comptador de FPS void SDLManager::updateFPS(float delta_time) { - // Acumular temps i frames + // Acumular time i frames fps_accumulator_ += delta_time; fps_frame_count_++; diff --git a/source/core/rendering/sdl_manager.hpp b/source/core/rendering/sdl_manager.hpp index de775fe..fffcd73 100644 --- a/source/core/rendering/sdl_manager.hpp +++ b/source/core/rendering/sdl_manager.hpp @@ -39,13 +39,13 @@ class SDLManager { void updateFPS(float delta_time); // Getters - SDL_Renderer* obte_renderer() { return renderer_; } + SDL_Renderer* getRenderer() { return renderer_; } [[nodiscard]] float getScaleFactor() const { return zoom_factor_; } // [NUEVO] Actualitzar títol de la finestra void setWindowTitle(const std::string& title); - // [NUEVO] Actualitzar context de renderitzat (factor d'escala global) + // [NUEVO] Actualitzar context de renderitzat (factor d'scale global) void updateRenderingContext() const; private: diff --git a/source/core/rendering/shape_renderer.cpp b/source/core/rendering/shape_renderer.cpp index 5873bfb..f83c208 100644 --- a/source/core/rendering/shape_renderer.cpp +++ b/source/core/rendering/shape_renderer.cpp @@ -10,9 +10,9 @@ namespace Rendering { -// Helper: aplicar rotació 3D a un punt 2D (assumeix Z=0) +// Helper: aplicar rotació 3D a un point 2D (assumeix Z=0) static Vec2 apply_3d_rotation(float x, float y, const Rotation3D& rot) { - float z = 0.0F; // Tots els punts 2D comencen a Z=0 + float z = 0.0F; // Tots els points 2D comencen a Z=0 // Pitch (rotació eix X): cabeceo arriba/baix float cos_pitch = std::cos(rot.pitch); @@ -33,7 +33,7 @@ static Vec2 apply_3d_rotation(float x, float y, const Rotation3D& rot) { float y3 = (x2 * sin_roll) + (y1 * cos_roll); // Proyecció perspectiva (Z-divide simple) - // Naus volen cap al punt de fuga (320, 240) a "infinit" (Z → +∞) + // Naus volen cap al point de fuga (320, 240) a "infinit" (Z → +∞) // Z més gran = més lluny = més petit a pantalla constexpr float perspective_factor = 500.0F; float scale_factor = perspective_factor / (perspective_factor + z2); @@ -41,9 +41,9 @@ static Vec2 apply_3d_rotation(float x, float y, const Rotation3D& rot) { return {.x = x3 * scale_factor, .y = y3 * scale_factor}; } -// Helper: transformar un punt amb rotació, escala i trasllació -static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const Vec2& posicio, float angle, float escala, const Rotation3D* rotation_3d) { - // 1. Centrar el punt respecte al centre de la forma +// Helper: transformar un point amb rotació, scale i trasllació +static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const Vec2& position, float angle, float scale, const Rotation3D* rotation_3d) { + // 1. Centrar el point respecte al centre de la shape float centered_x = point.x - shape_centre.x; float centered_y = point.y - shape_centre.y; @@ -54,9 +54,9 @@ static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const V centered_y = rotated_3d.y; } - // 3. Aplicar escala al punt (després de rotació 3D) - float scaled_x = centered_x * escala; - float scaled_y = centered_y * escala; + // 3. Aplicar scale al point (després de rotació 3D) + float scaled_x = centered_x * scale; + float scaled_y = centered_y * scale; // 4. Aplicar rotació 2D (Z-axis, tradicional) // IMPORTANT: En el sistema original, angle=0 apunta AMUNT (no dreta) @@ -69,19 +69,19 @@ static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const V float rotated_y = (scaled_x * sin_a) + (scaled_y * cos_a); // 5. Aplicar trasllació a posició mundial - return {.x = rotated_x + posicio.x, .y = rotated_y + posicio.y}; + return {.x = rotated_x + position.x, .y = rotated_y + position.y}; } void render_shape(SDL_Renderer* renderer, const std::shared_ptr& shape, - const Vec2& posicio, + const Vec2& position, float angle, - float escala, + float scale, float progress, float brightness, const Rotation3D* rotation_3d) { - // Verificar que la forma és vàlida - if (!shape || !shape->es_valida()) { + // Verificar que la shape és vàlida + if (!shape || !shape->isValid()) { return; } @@ -90,25 +90,25 @@ void render_shape(SDL_Renderer* renderer, return; } - // Obtenir el centre de la forma per a transformacions + // Obtenir el centre de la shape per a transformacions const Vec2& shape_centre = shape->getCenter(); // Iterar sobre totes les primitives for (const auto& primitive : shape->get_primitives()) { if (primitive.type == Graphics::PrimitiveType::POLYLINE) { - // POLYLINE: connectar punts consecutius + // POLYLINE: connectar points consecutius for (size_t i = 0; i < primitive.points.size() - 1; i++) { - Vec2 p1 = transform_point(primitive.points[i], shape_centre, posicio, angle, escala, rotation_3d); - Vec2 p2 = transform_point(primitive.points[i + 1], shape_centre, posicio, angle, escala, rotation_3d); + Vec2 p1 = transform_point(primitive.points[i], shape_centre, position, angle, scale, rotation_3d); + Vec2 p2 = transform_point(primitive.points[i + 1], shape_centre, position, angle, scale, rotation_3d); linea(renderer, static_cast(p1.x), static_cast(p1.y), static_cast(p2.x), static_cast(p2.y), brightness); } } else { // PrimitiveType::LINE - // LINE: exactament 2 punts + // LINE: exactament 2 points if (primitive.points.size() >= 2) { - Vec2 p1 = transform_point(primitive.points[0], shape_centre, posicio, angle, escala, rotation_3d); - Vec2 p2 = transform_point(primitive.points[1], shape_centre, posicio, angle, escala, rotation_3d); + Vec2 p1 = transform_point(primitive.points[0], shape_centre, position, angle, scale, rotation_3d); + Vec2 p2 = transform_point(primitive.points[1], shape_centre, position, angle, scale, rotation_3d); linea(renderer, static_cast(p1.x), static_cast(p1.y), static_cast(p2.x), static_cast(p2.y), brightness); diff --git a/source/core/rendering/shape_renderer.hpp b/source/core/rendering/shape_renderer.hpp index 64e838b..c15fe91 100644 --- a/source/core/rendering/shape_renderer.hpp +++ b/source/core/rendering/shape_renderer.hpp @@ -32,19 +32,19 @@ struct Rotation3D { } }; -// Renderitzar forma amb transformacions +// Renderitzar shape amb transformacions // - renderer: SDL renderer -// - shape: forma vectorial a draw -// - posicio: posició del centre en coordenades mundials +// - shape: shape vectorial a draw +// - position: posició del centre en coordenades mundials // - angle: rotació en radians (0 = amunt, sentit horari) -// - escala: factor d'escala (1.0 = mida original) +// - scale: factor d'scale (1.0 = mida original) // - progress: progrés de l'animació (0.0-1.0, default 1.0 = tot visible) -// - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor) +// - brightness: factor de brightness (0.0-1.0, default 1.0 = màxima brightness) void render_shape(SDL_Renderer* renderer, const std::shared_ptr& shape, - const Vec2& posicio, + const Vec2& position, float angle, - float escala = 1.0F, + float scale = 1.0F, float progress = 1.0F, float brightness = 1.0F, const Rotation3D* rotation_3d = nullptr); diff --git a/source/core/resources/resource_loader.cpp b/source/core/resources/resource_loader.cpp index 4426f55..ffcb8f1 100644 --- a/source/core/resources/resource_loader.cpp +++ b/source/core/resources/resource_loader.cpp @@ -19,12 +19,12 @@ Loader& Loader::get() { bool Loader::initialize(const std::string& pack_file, bool enable_fallback) { fallback_enabled_ = enable_fallback; - // Intentar carregar el paquet + // Intentar load el paquet pack_ = std::make_unique(); if (!pack_->loadPack(pack_file)) { if (!fallback_enabled_) { - std::cerr << "[ResourceLoader] ERROR FATAL: No es pot carregar " << pack_file + std::cerr << "[ResourceLoader] ERROR FATAL: No es pot load " << pack_file << " i el fallback està desactivat\n"; return false; } @@ -40,7 +40,7 @@ bool Loader::initialize(const std::string& pack_file, bool enable_fallback) { // Carregar un recurs std::vector Loader::loadResource(const std::string& filename) { - // Intentar carregar del paquet primer + // Intentar load del paquet primer if (pack_) { if (pack_->hasResource(filename)) { auto data = pack_->getResource(filename); diff --git a/source/core/resources/resource_pack.hpp b/source/core/resources/resource_pack.hpp index 4629305..63869e7 100644 --- a/source/core/resources/resource_pack.hpp +++ b/source/core/resources/resource_pack.hpp @@ -35,7 +35,7 @@ class Pack { bool addFile(const std::string& filepath, const std::string& pack_name); bool addDirectory(const std::string& dir_path, const std::string& base_path = ""); - // Guardar i carregar paquets + // Guardar i load paquets bool savePack(const std::string& pack_file); bool loadPack(const std::string& pack_file); diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index e1603be..b4879ad 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -53,7 +53,7 @@ Director::Director(std::vector const& args) { // Mode release: paquet obligatori, sense fallback std::string pack_path = resource_base + "/resources.pack"; if (!Resource::Helper::initializeResourceSystem(pack_path, false)) { - std::cerr << "ERROR FATAL: No es pot carregar " << pack_path << "\n"; + std::cerr << "ERROR FATAL: No es pot load " << pack_path << "\n"; std::cerr << "El joc no pot continuar sense els recursos.\n"; std::exit(1); } diff --git a/source/core/system/game_config.hpp b/source/core/system/game_config.hpp index e0707f1..59ccf8c 100644 --- a/source/core/system/game_config.hpp +++ b/source/core/system/game_config.hpp @@ -10,36 +10,36 @@ enum class Mode { DEMO // Mode demostració (futur) }; -// Configuració d'una partida +// Configuració d'una match struct MatchConfig { - bool jugador1_actiu{false}; // És actiu el jugador 1? - bool jugador2_actiu{false}; // És actiu el jugador 2? + bool jugador1_actiu{false}; // És active el player 1? + bool jugador2_actiu{false}; // És active el player 2? Mode mode{Mode::NORMAL}; // Mode de joc // Mètodes auxiliars - // Retorna true si només hi ha un jugador actiu + // Retorna true si només hi ha un player active [[nodiscard]] bool es_un_jugador() const { return (jugador1_actiu && !jugador2_actiu) || (!jugador1_actiu && jugador2_actiu); } - // Retorna true si hi ha dos jugadors actius + // Retorna true si hi ha dos jugadors active [[nodiscard]] bool son_dos_jugadors() const { return jugador1_actiu && jugador2_actiu; } - // Retorna true si no hi ha cap jugador actiu + // Retorna true si no hi ha cap player active [[nodiscard]] bool cap_jugador() const { return !jugador1_actiu && !jugador2_actiu; } - // Compte de jugadors actius (0, 1 o 2) + // Compte de jugadors active (0, 1 o 2) [[nodiscard]] uint8_t compte_jugadors() const { return (jugador1_actiu ? 1 : 0) + (jugador2_actiu ? 1 : 0); } - // Retorna l'ID de l'únic jugador actiu (0 o 1) + // Retorna l'ID de l'únic player active (0 o 1) // Només vàlid si es_un_jugador() retorna true [[nodiscard]] uint8_t id_unic_jugador() const { if (jugador1_actiu && !jugador2_actiu) { diff --git a/source/core/system/global_events.hpp b/source/core/system/global_events.hpp index b1edd60..c52b014 100644 --- a/source/core/system/global_events.hpp +++ b/source/core/system/global_events.hpp @@ -14,6 +14,6 @@ class SceneContext; namespace GlobalEvents { // Processa events globals (F1/F2/F3/ESC/QUIT) -// Retorna true si l'event ha estat processat i no cal seguir processant-lo +// Retorna true si l'event ha state processat i no cal seguir processant-lo bool handle(const SDL_Event& event, SDLManager& sdl, SceneManager::SceneContext& context); } // namespace GlobalEvents diff --git a/source/core/system/scene_context.hpp b/source/core/system/scene_context.hpp index 83de5fe..3163f65 100644 --- a/source/core/system/scene_context.hpp +++ b/source/core/system/scene_context.hpp @@ -58,12 +58,12 @@ class SceneContext { option_ = Option::NONE; } - // Configurar partida abans de transicionar a GAME + // Configurar match abans de transicionar a GAME void setMatchConfig(const GameConfig::MatchConfig& config) { match_config_ = config; } - // Obtenir configuració de partida (consumit per GameScene) + // Obtenir configuració de match (consumit per GameScene) [[nodiscard]] const GameConfig::MatchConfig& getMatchConfig() const { return match_config_; } @@ -71,7 +71,7 @@ class SceneContext { private: SceneType next_scene_{SceneType::LOGO}; // SceneType a la qual transicionar Option option_{Option::NONE}; // Opció específica per l'escena - GameConfig::MatchConfig match_config_; // Configuració de partida (jugadors actius, mode) + GameConfig::MatchConfig match_config_; // Configuració de match (jugadors active, mode) }; // Variable global inline per gestionar l'escena actual (backward compatibility) diff --git a/source/core/utils/path_utils.cpp b/source/core/utils/path_utils.cpp index e7d9214..b74a7b7 100644 --- a/source/core/utils/path_utils.cpp +++ b/source/core/utils/path_utils.cpp @@ -50,7 +50,7 @@ bool isMacOSBundle() { #ifdef MACOS_BUNDLE return true; #else - // Detecció en temps d'execució + // Detecció en time d'execució // Cercar ".app/Contents/MacOS" a la ruta de l'executable std::string exe_dir = getExecutableDirectory(); return exe_dir.find(".app/Contents/MacOS") != std::string::npos; diff --git a/source/game/constants.hpp b/source/game/constants.hpp index c0d8c65..5fd2b31 100644 --- a/source/game/constants.hpp +++ b/source/game/constants.hpp @@ -3,15 +3,15 @@ #include "core/defaults.hpp" // Aliases per a backward compatibility amb codi existent -// Permet usar Constants::MARGE_ESQ en lloc de Defaults::Game::MARGIN_LEFT +// Permet usar Constants::MARGIN_LEFT en lloc de Defaults::Game::MARGIN_LEFT namespace Constants { // Marges de l'àrea de joc (derivats de Defaults::Zones::GAME) -constexpr int MARGE_ESQ = static_cast(Defaults::Zones::PLAYAREA.x); -constexpr int MARGE_DRET = +constexpr int MARGIN_LEFT = static_cast(Defaults::Zones::PLAYAREA.x); +constexpr int MARGIN_RIGHT = static_cast(Defaults::Zones::PLAYAREA.x + Defaults::Zones::PLAYAREA.w); -constexpr int MARGE_DALT = static_cast(Defaults::Zones::PLAYAREA.y); -constexpr int MARGE_BAIX = +constexpr int MARGIN_TOP = static_cast(Defaults::Zones::PLAYAREA.y); +constexpr int MARGIN_BOTTOM = static_cast(Defaults::Zones::PLAYAREA.y + Defaults::Zones::PLAYAREA.h); // Límits d'objectes @@ -27,8 +27,8 @@ constexpr float PI = Defaults::Math::PI; // Helpers per comprovar límits de zona inline bool dins_zona_joc(float x, float y) { - const SDL_FPoint punt = {x, y}; - return SDL_PointInRectFloat(&punt, &Defaults::Zones::PLAYAREA); + const SDL_FPoint point = {x, y}; + return SDL_PointInRectFloat(&point, &Defaults::Zones::PLAYAREA); } inline void obtenir_limits_zona(float& min_x, float& max_x, float& min_y, float& max_y) { diff --git a/source/game/effects/debris.hpp b/source/game/effects/debris.hpp index f56fff5..fa70fcb 100644 --- a/source/game/effects/debris.hpp +++ b/source/game/effects/debris.hpp @@ -7,15 +7,15 @@ namespace Effects { // Debris: un segment de línia que vola perpendicular a sí mateix -// Representa un fragment d'una forma destruïda (nau, enemic, bala) +// Representa un fragment d'una shape destruïda (ship, enemy, bullet) struct Debris { - // Geometria del segment (2 punts en coordenades mundials) + // Geometria del segment (2 points en coordenades mundials) Vec2 p1; // Vec2 inicial del segment Vec2 p2; // Vec2 final del segment // Física - Vec2 velocitat; // Velocitat en px/s (components x, y) - float acceleracio; // Acceleració negativa (fricció) en px/s² + Vec2 velocity; // Velocitat en px/s (components x, y) + float acceleration; // Acceleració negativa (fricció) en px/s² // Rotació float angle_rotacio; // Angle de rotació acumulat (radians) @@ -25,13 +25,13 @@ struct Debris { // Estat de vida float temps_vida; // Temps transcorregut (segons) float temps_max; // Temps de vida màxim (segons) - bool actiu; // Està actiu? + bool active; // Està active? - // Shrinking (reducció de distància entre punts) + // Shrinking (reducció de distància entre points) float factor_shrink; // Factor de reducció per segon (0.0-1.0) // Rendering - float brightness; // Factor de brillantor (0.0-1.0, heretat de l'objecte original) + float brightness; // Factor de brightness (0.0-1.0, heretat de l'objecte original) }; } // namespace Effects diff --git a/source/game/effects/debris_manager.cpp b/source/game/effects/debris_manager.cpp index da3977f..4906a2e 100644 --- a/source/game/effects/debris_manager.cpp +++ b/source/game/effects/debris_manager.cpp @@ -14,16 +14,16 @@ namespace Effects { -// Helper: transformar punt amb rotació, escala i trasllació +// Helper: transformar point amb rotació, scale i trasllació // (Copiat de shape_renderer.cpp:12-34) -static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const Vec2& posicio, float angle, float escala) { - // 1. Centrar el punt respecte al centre de la forma +static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const Vec2& position, float angle, float scale) { + // 1. Centrar el point respecte al centre de la shape float centered_x = point.x - shape_centre.x; float centered_y = point.y - shape_centre.y; - // 2. Aplicar escala al punt centrat - float scaled_x = centered_x * escala; - float scaled_y = centered_y * escala; + // 2. Aplicar scale al point centrat + float scaled_x = centered_x * scale; + float scaled_y = centered_y * scale; // 3. Aplicar rotació float cos_a = std::cos(angle); @@ -33,38 +33,38 @@ static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const V float rotated_y = (scaled_x * sin_a) + (scaled_y * cos_a); // 4. Aplicar trasllació a posició mundial - return {.x = rotated_x + posicio.x, .y = rotated_y + posicio.y}; + return {.x = rotated_x + position.x, .y = rotated_y + position.y}; } DebrisManager::DebrisManager(SDL_Renderer* renderer) : renderer_(renderer) { // Inicialitzar tots els debris com inactius for (auto& debris : debris_pool_) { - debris.actiu = false; + debris.active = false; } } -void DebrisManager::explotar(const std::shared_ptr& shape, +void DebrisManager::explode(const std::shared_ptr& shape, const Vec2& centre, float angle, - float escala, + float scale, float velocitat_base, float brightness, const Vec2& velocitat_objecte, float velocitat_angular, float factor_herencia_visual, const std::string& sound) { - if (!shape || !shape->es_valida()) { + if (!shape || !shape->isValid()) { return; } // Reproducir sonido de explosión Audio::get()->playSound(sound, Audio::Group::GAME); - // Obtenir centre de la forma per a transformacions + // Obtenir centre de la shape per a transformacions const Vec2& shape_centre = shape->getCenter(); - // Iterar sobre totes les primitives de la forma + // Iterar sobre totes les primitives de la shape for (const auto& primitive : shape->get_primitives()) { // Processar cada segment de línia std::vector> segments; @@ -83,14 +83,14 @@ void DebrisManager::explotar(const std::shared_ptr& shape, // Crear debris per a cada segment for (const auto& [local_p1, local_p2] : segments) { - // 1. Transformar punts locals → coordenades mundials + // 1. Transformar points locals → coordenades mundials Vec2 world_p1 = - transform_point(local_p1, shape_centre, centre, angle, escala); + transform_point(local_p1, shape_centre, centre, angle, scale); Vec2 world_p2 = - transform_point(local_p2, shape_centre, centre, angle, escala); + transform_point(local_p2, shape_centre, centre, angle, scale); // 2. Trobar slot lliure - Debris* debris = trobar_slot_lliure(); + Debris* debris = findFreeSlot(); if (debris == nullptr) { std::cerr << "[DebrisManager] Warning: no debris slots disponibles\n"; return; // Pool ple @@ -101,20 +101,20 @@ void DebrisManager::explotar(const std::shared_ptr& shape, debris->p2 = world_p2; // 4. Calcular direcció d'explosió (radial, des del centre cap a fora) - Vec2 direccio = calcular_direccio_explosio(world_p1, world_p2, centre); + Vec2 direccio = computeExplosionDirection(world_p1, world_p2, centre); - // 5. Velocitat inicial (base ± variació aleatòria + velocitat heretada) + // 5. Velocitat inicial (base ± variació aleatòria + velocity heretada) float speed = velocitat_base + (((std::rand() / static_cast(RAND_MAX)) * 2.0F - 1.0F) * Defaults::Physics::Debris::VARIACIO_VELOCITAT); - // Heredar velocitat de l'objecte original (suma vectorial) - debris->velocitat.x = (direccio.x * speed) + velocitat_objecte.x; - debris->velocitat.y = (direccio.y * speed) + velocitat_objecte.y; - debris->acceleracio = Defaults::Physics::Debris::ACCELERACIO; + // Heredar velocity de l'objecte original (suma vectorial) + debris->velocity.x = (direccio.x * speed) + velocitat_objecte.x; + debris->velocity.y = (direccio.y * speed) + velocitat_objecte.y; + debris->acceleration = Defaults::Physics::Debris::ACCELERACIO; - // 6. Herència de velocitat angular amb cap + conversió d'excés + // 6. Herència de velocity angular amb cap + conversió d'excés // 6a. Rotació de TRAYECTORIA amb cap + conversió tangencial if (std::abs(velocitat_angular) > 0.01F) { @@ -137,10 +137,10 @@ void DebrisManager::explotar(const std::shared_ptr& shape, float sign_ang = (velocitat_ang_heretada >= 0.0F) ? 1.0F : -1.0F; if (abs_ang > CAP) { - // Excés: convertir a velocitat tangencial + // Excés: convertir a velocity tangencial float excess = abs_ang - CAP; - // Radi de la forma (enemics = 20 px) + // Radi de la shape (enemics = 20 px) float radius = 20.0F; // Velocitat tangencial = ω_excés × radi @@ -151,11 +151,11 @@ void DebrisManager::explotar(const std::shared_ptr& shape, float tangent_x = -direccio.y; float tangent_y = direccio.x; - // Afegir velocitat tangencial (suma vectorial) - debris->velocitat.x += tangent_x * v_tangential; - debris->velocitat.y += tangent_y * v_tangential; + // Afegir velocity tangencial (suma vectorial) + debris->velocity.x += tangent_x * v_tangential; + debris->velocity.y += tangent_y * v_tangential; - // Aplicar cap a velocitat angular (preservar signe) + // Aplicar cap a velocity angular (preservar signe) debris->velocitat_rot = sign_ang * CAP; } else { // Per sota del cap: comportament normal @@ -199,62 +199,62 @@ void DebrisManager::explotar(const std::shared_ptr& shape, debris->brightness = brightness; // 9. Activar - debris->actiu = true; + debris->active = true; } } } void DebrisManager::update(float delta_time) { for (auto& debris : debris_pool_) { - if (!debris.actiu) { + if (!debris.active) { continue; } - // 1. Actualitzar temps de vida + // 1. Actualitzar time de vida debris.temps_vida += delta_time; - // Desactivar si ha superat temps màxim + // Desactivar si ha superat time màxim if (debris.temps_vida >= debris.temps_max) { - debris.actiu = false; + debris.active = false; continue; } - // 2. Actualitzar velocitat (desacceleració) + // 2. Actualitzar velocity (desacceleració) // Aplicar fricció en la direcció del moviment - float speed = std::sqrt((debris.velocitat.x * debris.velocitat.x) + - (debris.velocitat.y * debris.velocitat.y)); + float speed = std::sqrt((debris.velocity.x * debris.velocity.x) + + (debris.velocity.y * debris.velocity.y)); if (speed > 1.0F) { // Calcular direcció normalitzada - float dir_x = debris.velocitat.x / speed; - float dir_y = debris.velocitat.y / speed; + float dir_x = debris.velocity.x / speed; + float dir_y = debris.velocity.y / speed; // Aplicar acceleració negativa (fricció) - float nova_speed = speed + (debris.acceleracio * delta_time); + float nova_speed = speed + (debris.acceleration * delta_time); nova_speed = std::max(nova_speed, 0.0F); - debris.velocitat.x = dir_x * nova_speed; - debris.velocitat.y = dir_y * nova_speed; + debris.velocity.x = dir_x * nova_speed; + debris.velocity.y = dir_y * nova_speed; } else { // Velocitat molt baixa, aturar - debris.velocitat.x = 0.0F; - debris.velocitat.y = 0.0F; + debris.velocity.x = 0.0F; + debris.velocity.y = 0.0F; } - // 2b. Rotar vector de velocitat (trayectoria curva) + // 2b. Rotar vector de velocity (trayectoria curva) if (std::abs(debris.velocitat_rot) > 0.01F) { // Calcular angle de rotació aquest frame float dangle = debris.velocitat_rot * delta_time; - // Rotar vector de velocitat usant matriu de rotació 2D - float vel_x_old = debris.velocitat.x; - float vel_y_old = debris.velocitat.y; + // Rotar vector de velocity usant matriu de rotació 2D + float vel_x_old = debris.velocity.x; + float vel_y_old = debris.velocity.y; float cos_a = std::cos(dangle); float sin_a = std::sin(dangle); - debris.velocitat.x = (vel_x_old * cos_a) - (vel_y_old * sin_a); - debris.velocitat.y = (vel_x_old * sin_a) + (vel_y_old * cos_a); + debris.velocity.x = (vel_x_old * cos_a) - (vel_y_old * sin_a); + debris.velocity.y = (vel_x_old * sin_a) + (vel_y_old * cos_a); } // 2c. Aplicar fricció angular (desacceleració gradual) @@ -275,18 +275,18 @@ void DebrisManager::update(float delta_time) { .y = (debris.p1.y + debris.p2.y) / 2.0F}; // 4. Actualitzar posició del centre - centre.x += debris.velocitat.x * delta_time; - centre.y += debris.velocitat.y * delta_time; + centre.x += debris.velocity.x * delta_time; + centre.y += debris.velocity.y * delta_time; // 5. Actualitzar rotació VISUAL debris.angle_rotacio += debris.velocitat_rot_visual * delta_time; - // 6. Aplicar shrinking (reducció de distància entre punts) + // 6. Aplicar shrinking (reducció de distància entre points) float shrink_factor = 1.0F - (debris.factor_shrink * debris.temps_vida / debris.temps_max); shrink_factor = std::max(0.0F, shrink_factor); // No negatiu - // Calcular distància original entre punts + // Calcular distància original entre points float dx = debris.p2.x - debris.p1.x; float dy = debris.p2.y - debris.p1.y; @@ -304,7 +304,7 @@ void DebrisManager::update(float delta_time) { void DebrisManager::draw() const { for (const auto& debris : debris_pool_) { - if (!debris.actiu) { + if (!debris.active) { continue; } @@ -318,16 +318,16 @@ void DebrisManager::draw() const { } } -Debris* DebrisManager::trobar_slot_lliure() { +Debris* DebrisManager::findFreeSlot() { for (auto& debris : debris_pool_) { - if (!debris.actiu) { + if (!debris.active) { return &debris; } } return nullptr; // Pool ple } -Vec2 DebrisManager::calcular_direccio_explosio(const Vec2& p1, +Vec2 DebrisManager::computeExplosionDirection(const Vec2& p1, const Vec2& p2, const Vec2& centre_objecte) const { // 1. Calcular centre del segment @@ -364,16 +364,16 @@ Vec2 DebrisManager::calcular_direccio_explosio(const Vec2& p1, return {.x = final_x, .y = final_y}; } -void DebrisManager::reiniciar() { +void DebrisManager::reset() { for (auto& debris : debris_pool_) { - debris.actiu = false; + debris.active = false; } } -int DebrisManager::get_num_actius() const { +int DebrisManager::getActiveCount() const { int count = 0; for (const auto& debris : debris_pool_) { - if (debris.actiu) { + if (debris.active) { count++; } } diff --git a/source/game/effects/debris_manager.hpp b/source/game/effects/debris_manager.hpp index 93fe099..4fde843 100644 --- a/source/game/effects/debris_manager.hpp +++ b/source/game/effects/debris_manager.hpp @@ -20,20 +20,20 @@ class DebrisManager { public: explicit DebrisManager(SDL_Renderer* renderer); - // Crear explosió a partir d'una forma - // - shape: forma vectorial a explotar + // Crear explosió a partir d'una shape + // - shape: shape vectorial a explode // - centre: posició del centre de l'objecte // - angle: orientació de l'objecte (radians) - // - escala: escala de l'objecte (1.0 = normal) - // - velocitat_base: velocitat inicial dels fragments (px/s) - // - brightness: factor de brillantor heretat (0.0-1.0, per defecte 1.0) - // - velocitat_objecte: velocitat de l'objecte que explota (px/s, per defecte 0) - // - velocitat_angular: velocitat angular heretada (rad/s, per defecte 0) + // - scale: scale de l'objecte (1.0 = normal) + // - velocitat_base: velocity inicial dels fragments (px/s) + // - brightness: factor de brightness heretat (0.0-1.0, per defecte 1.0) + // - velocitat_objecte: velocity de l'objecte que explota (px/s, per defecte 0) + // - velocitat_angular: velocity angular heretada (rad/s, per defecte 0) // - factor_herencia_visual: factor de herència rotació visual (0.0-1.0, per defecte 0.0) - void explotar(const std::shared_ptr& shape, + void explode(const std::shared_ptr& shape, const Vec2& centre, float angle, - float escala, + float scale, float velocitat_base, float brightness = 1.0F, const Vec2& velocitat_objecte = {.x = 0.0F, .y = 0.0F}, @@ -41,33 +41,33 @@ class DebrisManager { float factor_herencia_visual = 0.0F, const std::string& sound = Defaults::Sound::EXPLOSION); - // Actualitzar tots els fragments actius + // Actualitzar tots els fragments active void update(float delta_time); - // Dibuixar tots els fragments actius + // Dibuixar tots els fragments active void draw() const; // Reiniciar tots els fragments (neteja) - void reiniciar(); + void reset(); - // Obtenir número de fragments actius - [[nodiscard]] int get_num_actius() const; + // Obtenir número de fragments active + [[nodiscard]] int getActiveCount() const; private: SDL_Renderer* renderer_; // Pool de fragments (màxim concurrent) // Un pentàgon té 5 línies, 15 enemics = 75 línies - // + nau (3 línies) + bales (5 línies * 3) = 93 línies màxim + // + ship (3 línies) + bales (5 línies * 3) = 93 línies màxim // Arrodonit a 100 per seguretat static constexpr int MAX_DEBRIS = 150; std::array debris_pool_; // Trobar primer slot inactiu - Debris* trobar_slot_lliure(); + Debris* findFreeSlot(); // Calcular direcció d'explosió (radial, des del centre cap al segment) - [[nodiscard]] Vec2 calcular_direccio_explosio(const Vec2& p1, const Vec2& p2, const Vec2& centre_objecte) const; + [[nodiscard]] Vec2 computeExplosionDirection(const Vec2& p1, const Vec2& p2, const Vec2& centre_objecte) const; }; } // namespace Effects diff --git a/source/game/effects/puntuacio_flotant.hpp b/source/game/effects/floating_score.hpp similarity index 69% rename from source/game/effects/puntuacio_flotant.hpp rename to source/game/effects/floating_score.hpp index cd9daa0..61f7334 100644 --- a/source/game/effects/puntuacio_flotant.hpp +++ b/source/game/effects/floating_score.hpp @@ -9,17 +9,17 @@ namespace Effects { -// PuntuacioFlotant: text animat que mostra punts guanyats -// S'activa quan es destrueix un enemic i s'esvaeix després d'un temps -struct PuntuacioFlotant { +// FloatingScore: text animat que mostra points guanyats +// S'activa quan es destrueix un enemy i s'esvaeix després d'un time +struct FloatingScore { // Text a mostrar (e.g., "100", "150", "200") std::string text; // Posició actual (coordenades mundials) - Vec2 posicio; + Vec2 position; // Animació de moviment - Vec2 velocitat; // px/s (normalment cap amunt: {0.0f, -30.0f}) + Vec2 velocity; // px/s (normalment cap amunt: {0.0f, -30.0f}) // Animació de fade float temps_vida; // Temps transcorregut (segons) @@ -27,7 +27,7 @@ struct PuntuacioFlotant { float brightness; // Brillantor calculada (0.0-1.0) // Estat - bool actiu; + bool active; }; } // namespace Effects diff --git a/source/game/effects/gestor_puntuacio_flotant.cpp b/source/game/effects/floating_score_manager.cpp similarity index 55% rename from source/game/effects/gestor_puntuacio_flotant.cpp rename to source/game/effects/floating_score_manager.cpp index 2f0156e..d8a500c 100644 --- a/source/game/effects/gestor_puntuacio_flotant.cpp +++ b/source/game/effects/floating_score_manager.cpp @@ -1,95 +1,95 @@ // gestor_puntuacio_flotant.cpp - Implementació del gestor de números flotants // © 2025 Port a C++20 amb SDL3 -#include "gestor_puntuacio_flotant.hpp" +#include "floating_score_manager.hpp" #include namespace Effects { -GestorPuntuacioFlotant::GestorPuntuacioFlotant(SDL_Renderer* renderer) +FloatingScoreManager::FloatingScoreManager(SDL_Renderer* renderer) : text_(renderer) { // Inicialitzar tots els slots com inactius for (auto& pf : pool_) { - pf.actiu = false; + pf.active = false; } } -void GestorPuntuacioFlotant::crear(int punts, const Vec2& posicio) { +void FloatingScoreManager::crear(int points, const Vec2& position) { // 1. Trobar slot lliure - PuntuacioFlotant* pf = trobar_slot_lliure(); + FloatingScore* pf = findFreeSlot(); if (pf == nullptr) { return; // Pool ple (improbable) } // 2. Inicialitzar puntuació flotant - pf->text = std::to_string(punts); - pf->posicio = posicio; - pf->velocitat = {.x = Defaults::FloatingScore::VELOCITY_X, + pf->text = std::to_string(points); + pf->position = position; + pf->velocity = {.x = Defaults::FloatingScore::VELOCITY_X, .y = Defaults::FloatingScore::VELOCITY_Y}; pf->temps_vida = 0.0F; pf->temps_max = Defaults::FloatingScore::LIFETIME; pf->brightness = 1.0F; - pf->actiu = true; + pf->active = true; } -void GestorPuntuacioFlotant::update(float delta_time) { +void FloatingScoreManager::update(float delta_time) { for (auto& pf : pool_) { - if (!pf.actiu) { + if (!pf.active) { continue; } // 1. Actualitzar posició (deriva cap amunt) - pf.posicio.x += pf.velocitat.x * delta_time; - pf.posicio.y += pf.velocitat.y * delta_time; + pf.position.x += pf.velocity.x * delta_time; + pf.position.y += pf.velocity.y * delta_time; - // 2. Actualitzar temps de vida + // 2. Actualitzar time de vida pf.temps_vida += delta_time; // 3. Calcular brightness (fade lineal) float progress = pf.temps_vida / pf.temps_max; // 0.0 → 1.0 pf.brightness = 1.0F - progress; // 1.0 → 0.0 - // 4. Desactivar quan acaba el temps + // 4. Desactivar quan acaba el time if (pf.temps_vida >= pf.temps_max) { - pf.actiu = false; + pf.active = false; } } } -void GestorPuntuacioFlotant::draw() { +void FloatingScoreManager::draw() { for (const auto& pf : pool_) { - if (!pf.actiu) { + if (!pf.active) { continue; } // Renderitzar centrat amb brightness (fade) - constexpr float escala = Defaults::FloatingScore::SCALE; + constexpr float scale = Defaults::FloatingScore::SCALE; constexpr float spacing = Defaults::FloatingScore::SPACING; - text_.render_centered(pf.text, pf.posicio, escala, spacing, pf.brightness); + text_.renderCentered(pf.text, pf.position, scale, spacing, pf.brightness); } } -void GestorPuntuacioFlotant::reiniciar() { +void FloatingScoreManager::reset() { for (auto& pf : pool_) { - pf.actiu = false; + pf.active = false; } } -int GestorPuntuacioFlotant::get_num_actius() const { +int FloatingScoreManager::getActiveCount() const { int count = 0; for (const auto& pf : pool_) { - if (pf.actiu) { + if (pf.active) { count++; } } return count; } -PuntuacioFlotant* GestorPuntuacioFlotant::trobar_slot_lliure() { +FloatingScore* FloatingScoreManager::findFreeSlot() { for (auto& pf : pool_) { - if (!pf.actiu) { + if (!pf.active) { return &pf; } } diff --git a/source/game/effects/gestor_puntuacio_flotant.hpp b/source/game/effects/floating_score_manager.hpp similarity index 55% rename from source/game/effects/gestor_puntuacio_flotant.hpp rename to source/game/effects/floating_score_manager.hpp index f276bb4..b5cdfdc 100644 --- a/source/game/effects/gestor_puntuacio_flotant.hpp +++ b/source/game/effects/floating_score_manager.hpp @@ -10,32 +10,32 @@ #include "core/defaults.hpp" #include "core/graphics/vector_text.hpp" #include "core/types.hpp" -#include "puntuacio_flotant.hpp" +#include "floating_score.hpp" namespace Effects { // Gestor de números de puntuació flotants -// Manté un pool de PuntuacioFlotant i gestiona el seu cicle de vida -class GestorPuntuacioFlotant { +// Manté un pool de FloatingScore i gestiona el seu cicle de vida +class FloatingScoreManager { public: - explicit GestorPuntuacioFlotant(SDL_Renderer* renderer); + explicit FloatingScoreManager(SDL_Renderer* renderer); // Crear número flotant - // - punts: valor numèric (100, 150, 200) - // - posicio: on apareix (normalment centre d'enemic destruït) - void crear(int punts, const Vec2& posicio); + // - points: valor numèric (100, 150, 200) + // - position: on apareix (normalment centre d'enemy destruït) + void crear(int points, const Vec2& position); - // Actualitzar tots els números actius + // Actualitzar tots els números active void update(float delta_time); - // Dibuixar tots els números actius + // Dibuixar tots els números active void draw(); // Reiniciar tots (neteja) - void reiniciar(); + void reset(); - // Obtenir número actius (debug) - [[nodiscard]] int get_num_actius() const; + // Obtenir número active (debug) + [[nodiscard]] int getActiveCount() const; private: Graphics::VectorText text_; // Sistema de text vectorial @@ -44,10 +44,10 @@ class GestorPuntuacioFlotant { // Màxim 15 enemics simultanis = màxim 15 números static constexpr int MAX_PUNTUACIONS = Defaults::FloatingScore::MAX_CONCURRENT; - std::array pool_; + std::array pool_; // Trobar primer slot inactiu - PuntuacioFlotant* trobar_slot_lliure(); + FloatingScore* findFreeSlot(); }; } // namespace Effects diff --git a/source/game/entities/bullet.cpp b/source/game/entities/bullet.cpp index c195b93..09b9beb 100644 --- a/source/game/entities/bullet.cpp +++ b/source/game/entities/bullet.cpp @@ -1,4 +1,4 @@ -// bala.cpp - Implementació de projectils de la nau +// bullet.cpp - Implementació de projectils de la ship // © 1999 Visente i Sergi (versió Pascal) // © 2025 Port a C++20 amb SDL3 @@ -26,11 +26,11 @@ Bullet::Bullet(SDL_Renderer* renderer) // [NUEVO] Brightness específic per bales brightness_ = Defaults::Brightness::BALA; - // [NUEVO] Carregar forma compartida des de fitxer + // [NUEVO] Carregar shape compartida des de fitxer shape_ = Graphics::ShapeLoader::load("bullet.shp"); - if (!shape_ || !shape_->es_valida()) { - std::cerr << "[Bullet] Error: no s'ha pogut carregar bullet.shp" << '\n'; + if (!shape_ || !shape_->isValid()) { + std::cerr << "[Bullet] Error: no s'ha pogut load bullet.shp" << '\n'; } } @@ -43,18 +43,18 @@ void Bullet::init() { grace_timer_ = 0.0F; } -void Bullet::disparar(const Vec2& posicio, float angle, uint8_t owner_id) { - // Activar bala i posicionar-la a la nau +void Bullet::disparar(const Vec2& position, float angle, uint8_t owner_id) { + // Activar bullet i posicionar-la a la ship // Basat en joc_asteroides.cpp línies 188-200 - // Activar bala + // Activar bullet esta_ = true; - // Posició inicial = centre de la nau - center_.x = posicio.x; - center_.y = posicio.y; + // Posició inicial = centre de la ship + center_.x = position.x; + center_.y = position.y; - // Angle = angle de la nau (dispara en la direcció que apunta) + // Angle = angle de la ship (dispara en la direcció que apunta) angle_ = angle; // Almacenar propietario (0=P1, 1=P2) @@ -92,12 +92,12 @@ void Bullet::draw() const { } void Bullet::mou(float delta_time) { - // Moviment rectilini de la bala + // Moviment rectilini de la bullet // Basat en el codi Pascal original: procedure mou_bales // Copiat EXACTAMENT de joc_asteroides.cpp línies 396-419 // Calcular nova posició (moviment polar time-based) - // velocitat ja està en px/s (140 px/s), només cal multiplicar per delta_time + // velocity ja està en px/s (140 px/s), només cal multiplicar per delta_time float velocitat_efectiva = velocity_ * delta_time; // Calcular desplaçament (angle-PI/2 perquè angle=0 apunta amunt) @@ -109,7 +109,7 @@ void Bullet::mou(float delta_time) { center_.x += dx; // Desactivar si surt de la zona de joc (no rebota com els ORNIs) - // CORRECCIÓ: Usar límits segurs amb radi de la bala + // CORRECCIÓ: Usar límits segurs amb radi de la bullet float min_x; float max_x; float min_y; diff --git a/source/game/entities/bullet.hpp b/source/game/entities/bullet.hpp index 0448a16..a5160de 100644 --- a/source/game/entities/bullet.hpp +++ b/source/game/entities/bullet.hpp @@ -1,4 +1,4 @@ -// bala.hpp - Classe per a projectils de la nau +// bullet.hpp - Classe per a projectils de la ship // © 1999 Visente i Sergi (versió Pascal) // © 2025 Port a C++20 amb SDL3 @@ -18,7 +18,7 @@ class Bullet : public Entities::Entity { Bullet(SDL_Renderer* renderer); void init() override; - void disparar(const Vec2& posicio, float angle, uint8_t owner_id); + void disparar(const Vec2& position, float angle, uint8_t owner_id); void update(float delta_time) override; void draw() const override; diff --git a/source/game/entities/enemy.cpp b/source/game/entities/enemy.cpp index e77eb70..253ffe2 100644 --- a/source/game/entities/enemy.cpp +++ b/source/game/entities/enemy.cpp @@ -1,4 +1,4 @@ -// enemic.cpp - Implementació d'enemics (ORNIs) +// enemy.cpp - Implementació d'enemics (ORNIs) // © 1999 Visente i Sergi (versió Pascal) // © 2025 Port a C++20 amb SDL3 @@ -30,15 +30,15 @@ Enemy::Enemy(SDL_Renderer* renderer) // [NUEVO] Brightness específic per enemics brightness_ = Defaults::Brightness::ENEMIC; - // [NUEVO] Forma es carrega a init() segons el tipus - // Constructor no carrega forma per permetre tipus diferents + // [NUEVO] Forma es carrega a init() segons el type + // Constructor no carrega shape per permetre type diferents } -void Enemy::init(EnemyType tipus, const Vec2* ship_pos) { - // Guardar tipus - type_ = tipus; +void Enemy::init(EnemyType type, const Vec2* ship_pos) { + // Guardar type + type_ = type; - // Carregar forma segons el tipus + // Carregar shape segons el type const char* shape_file; float drotacio_min; float drotacio_max; @@ -68,7 +68,7 @@ void Enemy::init(EnemyType tipus, const Vec2* ship_pos) { default: // Fallback segur: usar valors de PENTAGON - std::cerr << "[Enemy] Error: tipus desconegut (" + std::cerr << "[Enemy] Error: type desconegut (" << static_cast(type_) << "), utilitzant PENTAGON\n"; shape_file = Defaults::Enemies::Pentagon::SHAPE_FILE; velocity_ = Defaults::Enemies::Pentagon::VELOCITAT; @@ -77,10 +77,10 @@ void Enemy::init(EnemyType tipus, const Vec2* ship_pos) { break; } - // Carregar forma + // Carregar shape shape_ = Graphics::ShapeLoader::load(shape_file); - if (!shape_ || !shape_->es_valida()) { - std::cerr << "[Enemy] Error: no s'ha pogut carregar " << shape_file << '\n'; + if (!shape_ || !shape_->isValid()) { + std::cerr << "[Enemy] Error: no s'ha pogut load " << shape_file << '\n'; } // [MODIFIED] Posició aleatòria amb comprovació de seguretat @@ -131,12 +131,12 @@ void Enemy::init(EnemyType tipus, const Vec2* ship_pos) { // Angle aleatori de moviment angle_ = (std::rand() % 360) * Constants::PI / 180.0F; - // Rotació visual aleatòria (rad/s) dins del rang del tipus + // Rotació visual aleatòria (rad/s) dins del rang del type float drotacio_range = drotacio_max - drotacio_min; drotacio_ = drotacio_min + ((static_cast(std::rand()) / RAND_MAX) * drotacio_range); rotacio_ = 0.0F; - // Inicialitzar estat d'animació + // Inicialitzar state d'animació animacio_ = EnemyAnimation(); // Reset to defaults animacio_.drotacio_base = drotacio_; animacio_.drotacio_objetivo = drotacio_; @@ -182,15 +182,15 @@ void Enemy::update(float delta_time) { void Enemy::draw() const { if (esta_ && shape_) { // Calculate animated scale (includes invulnerability LERP) - float escala = calcular_escala_actual(); + float scale = calcular_escala_actual(); // brightness_ is already updated in update() - Rendering::render_shape(renderer_, shape_, center_, rotacio_, escala, 1.0F, brightness_); + Rendering::render_shape(renderer_, shape_, center_, rotacio_, scale, 1.0F, brightness_); } } void Enemy::mou(float delta_time) { - // Dispatcher: crida el comportament específic segons el tipus + // Dispatcher: crida el comportament específic segons el type switch (type_) { case EnemyType::PENTAGON: comportament_pentagon(delta_time); @@ -472,7 +472,7 @@ void Enemy::actualitzar_rotacio_accelerada(float delta_time) { } float Enemy::calcular_escala_actual() const { - float escala = 1.0F; + float scale = 1.0F; // [NEW] Invulnerability LERP prioritza sobre palpitació if (timer_invulnerabilitat_ > 0.0F) { @@ -486,13 +486,13 @@ float Enemy::calcular_escala_actual() const { // LERP scale from 0.0 to 1.0 constexpr float START = Defaults::Enemies::Spawn::INVULNERABILITY_SCALE_START; constexpr float END = Defaults::Enemies::Spawn::INVULNERABILITY_SCALE_END; - escala = START + ((END - START) * smooth_t); + scale = START + ((END - START) * smooth_t); } else if (animacio_.palpitacio_activa) { // [EXISTING] Palpitació només quan no invulnerable - escala += animacio_.palpitacio_amplitud * std::sin(animacio_.palpitacio_fase); + scale += animacio_.palpitacio_amplitud * std::sin(animacio_.palpitacio_fase); } - return escala; + return scale; } // [NEW] Stage system API implementations diff --git a/source/game/entities/enemy.hpp b/source/game/entities/enemy.hpp index 9669e3d..ef126e7 100644 --- a/source/game/entities/enemy.hpp +++ b/source/game/entities/enemy.hpp @@ -1,4 +1,4 @@ -// enemic.hpp - Classe per a enemics (ORNIs pentàgons) +// enemy.hpp - Classe per a enemics (ORNIs pentàgons) // © 1999 Visente i Sergi (versió Pascal) // © 2025 Port a C++20 amb SDL3 @@ -13,7 +13,7 @@ #include "core/types.hpp" #include "game/constants.hpp" -// Tipus d'enemic +// Tipus d'enemy enum class EnemyType : uint8_t { PENTAGON = 0, // Pentàgon esquivador (zigzag) QUADRAT = 1, // Quadrat perseguidor (tracks ship) @@ -43,7 +43,7 @@ class Enemy : public Entities::Entity { Enemy(SDL_Renderer* renderer); void init() override { init(EnemyType::PENTAGON, nullptr); } - void init(EnemyType tipus, const Vec2* ship_pos = nullptr); + void init(EnemyType type, const Vec2* ship_pos = nullptr); void update(float delta_time) override; void draw() const override; diff --git a/source/game/entities/ship.cpp b/source/game/entities/ship.cpp index 28eb4ca..0a5a650 100644 --- a/source/game/entities/ship.cpp +++ b/source/game/entities/ship.cpp @@ -1,4 +1,4 @@ -// nau.cpp - Implementació de la nave del jugador +// ship.cpp - Implementació de la nave del player // © 1999 Visente i Sergi (versió Pascal) // © 2025 Port a C++20 amb SDL3 @@ -28,21 +28,21 @@ Ship::Ship(SDL_Renderer* renderer, const char* shape_file) // [NUEVO] Brightness específic per naus brightness_ = Defaults::Brightness::NAU; - // [NUEVO] Carregar forma compartida des de fitxer + // [NUEVO] Carregar shape compartida des de fitxer shape_ = Graphics::ShapeLoader::load(shape_file); - if (!shape_ || !shape_->es_valida()) { - std::cerr << "[Ship] Error: no s'ha pogut carregar " << shape_file << '\n'; + if (!shape_ || !shape_->isValid()) { + std::cerr << "[Ship] Error: no s'ha pogut load " << shape_file << '\n'; } } void Ship::init(const Vec2* spawn_point, bool activar_invulnerabilitat) { - // Inicialització de la nau (triangle) + // Inicialització de la ship (triangle) // Basat en el codi Pascal original: lines 380-384 // Copiat de joc_asteroides.cpp línies 30-44 - // [NUEVO] Ja no cal configurar punts polars - la geometria es carrega del - // fitxer Només inicialitzem l'estat de la instància + // [NUEVO] Ja no cal configurar points polars - la geometria es carrega del + // fitxer Només inicialitzem l'state de la instància // Use custom spawn point if provided, otherwise use center if (spawn_point != nullptr) { @@ -74,14 +74,14 @@ void Ship::init(const Vec2* spawn_point, bool activar_invulnerabilitat) { void Ship::processInput(float delta_time, uint8_t player_id) { // Processar input continu (com teclapuls() del Pascal original) // Basat en joc_asteroides.cpp línies 66-85 - // Només processa input si la nau està viva + // Només processa input si la ship està viva if (is_hit_) { return; } auto* input = Input::get(); - // Processar input segons el jugador + // Processar input segons el player if (player_id == 0) { // Jugador 1 if (input->checkActionPlayer1(InputAction::RIGHT, Input::ALLOW_REPEAT)) { @@ -118,7 +118,7 @@ void Ship::processInput(float delta_time, uint8_t player_id) { } void Ship::update(float delta_time) { - // Només update si la nau està viva + // Només update si la ship està viva if (is_hit_) { return; } @@ -134,7 +134,7 @@ void Ship::update(float delta_time) { } void Ship::draw() const { - // Només draw si la nau està viva + // Només draw si la ship està viva if (is_hit_) { return; } @@ -156,25 +156,25 @@ void Ship::draw() const { return; } - // Escalar velocitat per l'efecte visual (200 px/s → ~6 px d'efecte) - // El codi Pascal original sumava velocitat (0-6) al radi per donar - // sensació de "empenta". Ara velocitat està en px/s (0-200). + // Escalar velocity per l'efecte visual (200 px/s → ~6 px d'efecte) + // El codi Pascal original sumava velocity (0-6) al radi per donar + // sensació de "empenta". Ara velocity està en px/s (0-200). // Basat en joc_asteroides.cpp línies 127-134 // - // [NUEVO] Convertir suma de velocitat_visual a escala multiplicativa + // [NUEVO] Convertir suma de velocitat_visual a scale multiplicativa // Radio base del ship = 12 px - // velocitat_visual = 0-6 → r = 12-18 → escala = 1.0-1.5 + // velocitat_visual = 0-6 → r = 12-18 → scale = 1.0-1.5 float velocitat_visual = velocity_ / 33.33F; - float escala = 1.0F + (velocitat_visual / 12.0F); + float scale = 1.0F + (velocitat_visual / 12.0F); - Rendering::render_shape(renderer_, shape_, center_, angle_, escala, 1.0F, brightness_); + Rendering::render_shape(renderer_, shape_, center_, angle_, scale, 1.0F, brightness_); } void Ship::applyPhysics(float delta_time) { // Aplicar física de moviment // Basat en joc_asteroides.cpp línies 87-113 - // Calcular nova posició basada en velocitat i angle + // Calcular nova posició basada en velocity i angle // S'usa (angle - PI/2) perquè angle=0 apunta cap amunt, no cap a la dreta // velocity_ està en px/s, així que multipliquem per delta_time float dy = @@ -184,7 +184,7 @@ void Ship::applyPhysics(float delta_time) { ((velocity_ * delta_time) * std::cos(angle_ - (Constants::PI / 2.0F))) + center_.x; - // Boundary checking amb radi de la nau + // Boundary checking amb radi de la ship // CORRECCIÓ: Usar límits segurs i inequalitats inclusives float min_x; float max_x; diff --git a/source/game/entities/ship.hpp b/source/game/entities/ship.hpp index a94caaa..eb1574e 100644 --- a/source/game/entities/ship.hpp +++ b/source/game/entities/ship.hpp @@ -1,4 +1,4 @@ -// nau.hpp - Classe per a la nave del jugador +// ship.hpp - Classe per a la nave del player // © 1999 Visente i Sergi (versió Pascal) // © 2025 Port a C++20 amb SDL3 diff --git a/source/game/options.cpp b/source/game/options.cpp index 963835a..f3aaec6 100644 --- a/source/game/options.cpp +++ b/source/game/options.cpp @@ -222,7 +222,7 @@ void init() { // Establir la ruta del fitxer de configuració void setConfigFile(const std::string& path) { config_file_path = path; } -// Funcions auxiliars per carregar seccions del YAML +// Funcions auxiliars per load seccions del YAML static void loadWindowConfigFromYaml(const fkyaml::node& yaml) { if (yaml.contains("window")) { @@ -446,7 +446,7 @@ static void loadAudioConfigFromYaml(const fkyaml::node& yaml) { } } -// Carregar controls del jugador 1 des de YAML +// Carregar controls del player 1 des de YAML static void loadPlayer1ControlsFromYaml(const fkyaml::node& yaml) { if (!yaml.contains("player1")) { return; @@ -494,7 +494,7 @@ static void loadPlayer1ControlsFromYaml(const fkyaml::node& yaml) { } } -// Carregar controls del jugador 2 des de YAML +// Carregar controls del player 2 des de YAML static void loadPlayer2ControlsFromYaml(const fkyaml::node& yaml) { if (!yaml.contains("player2")) { return; @@ -611,7 +611,7 @@ auto loadFromFile() -> bool { } } -// Guardar controls del jugador 1 a YAML +// Guardar controls del player 1 a YAML static void savePlayer1ControlsToYaml(std::ofstream& file) { file << "# CONTROLS JUGADOR 1\n"; file << "player1:\n"; @@ -628,7 +628,7 @@ static void savePlayer1ControlsToYaml(std::ofstream& file) { file << " gamepad_name: \"" << player1.gamepad_name << "\" # Buit = primer disponible\n\n"; } -// Guardar controls del jugador 2 a YAML +// Guardar controls del player 2 a YAML static void savePlayer2ControlsToYaml(std::ofstream& file) { file << "# CONTROLS JUGADOR 2\n"; file << "player2:\n"; diff --git a/source/game/options.hpp b/source/game/options.hpp index 3d019d6..c226ee9 100644 --- a/source/game/options.hpp +++ b/source/game/options.hpp @@ -83,7 +83,7 @@ inline Gameplay gameplay{}; inline Rendering rendering{}; inline Audio audio{}; -// Controles per jugador +// Controles per player inline PlayerControls player1{ .keyboard = {.key_left = SDL_SCANCODE_LEFT, diff --git a/source/game/scenes/game_scene.cpp b/source/game/scenes/game_scene.cpp index 2f54778..439a6b3 100644 --- a/source/game/scenes/game_scene.cpp +++ b/source/game/scenes/game_scene.cpp @@ -30,15 +30,15 @@ using Option = SceneContext::Option; GameScene::GameScene(SDLManager& sdl, SceneContext& context) : sdl_(sdl), context_(context), - debris_manager_(sdl.obte_renderer()), - gestor_puntuacio_(sdl.obte_renderer()), - text_(sdl.obte_renderer()), + debris_manager_(sdl.getRenderer()), + floating_score_manager_(sdl.getRenderer()), + text_(sdl.getRenderer()), init_hud_rect_sound_played_(false) { - // Recuperar configuració de partida des del context + // Recuperar configuració de match des del context match_config_ = context_.getMatchConfig(); // Debug output de la configuració - std::cout << "[GameScene] Configuració de partida - P1: " + std::cout << "[GameScene] Configuració de match - P1: " << (match_config_.jugador1_actiu ? "ACTIU" : "INACTIU") << ", P2: " << (match_config_.jugador2_actiu ? "ACTIU" : "INACTIU") @@ -49,24 +49,24 @@ GameScene::GameScene(SDLManager& sdl, SceneContext& context) (void)option; // Suprimir warning de variable no usada // Inicialitzar naus amb renderer (P1=ship.shp, P2=ship2.shp) - naus_[0] = Ship(sdl.obte_renderer(), "ship.shp"); // Jugador 1: nave estàndar - naus_[1] = Ship(sdl.obte_renderer(), "ship2.shp"); // Jugador 2: interceptor amb ales + ships_[0] = Ship(sdl.getRenderer(), "ship.shp"); // Jugador 1: nave estàndar + ships_[1] = Ship(sdl.getRenderer(), "ship2.shp"); // Jugador 2: interceptor amb ales // Inicialitzar bales amb renderer - for (auto& bala : bales_) { - bala = Bullet(sdl.obte_renderer()); + for (auto& bullet : bullets_) { + bullet = Bullet(sdl.getRenderer()); } // Inicialitzar enemics amb renderer - for (auto& enemy : orni_) { - enemy = Enemy(sdl.obte_renderer()); + for (auto& enemy : enemies_) { + enemy = Enemy(sdl.getRenderer()); } } void GameScene::run() { std::cout << "SceneType Joc: Inicialitzant...\n"; - // Inicialitzar estat del joc + // Inicialitzar state del joc init(); SDL_Event event; @@ -113,7 +113,7 @@ void GameScene::run() { // Netejar pantalla (usa color oscil·lat) sdl_.neteja(0, 0, 0); - // Actualitzar context de renderitzat (factor d'escala global) + // Actualitzar context de renderitzat (factor d'scale global) sdl_.updateRenderingContext(); // Dibuixar joc @@ -133,9 +133,9 @@ void GameScene::init() { // [NEW] Load stage configuration (only once) if (!stage_config_) { - stage_config_ = StageSystem::StageLoader::carregar("data/stages/stages.yaml"); + stage_config_ = StageSystem::StageLoader::load("data/stages/stages.yaml"); if (!stage_config_) { - std::cerr << "[GameScene] Error: no s'ha pogut carregar stages.yaml" << '\n'; + std::cerr << "[GameScene] Error: no s'ha pogut load stages.yaml" << '\n'; // Continue without stage system (will crash, but helps debugging) } } @@ -145,59 +145,59 @@ void GameScene::init() { stage_manager_->init(); // [NEW] Set ship position reference for safe spawn (P1 for now, TODO: dual tracking) - stage_manager_->get_spawn_controller().set_ship_position(&naus_[0].getCenter()); + stage_manager_->get_spawn_controller().set_ship_position(&ships_[0].getCenter()); - // Inicialitzar timers de muerte per jugador - itocado_per_jugador_[0] = 0.0F; - itocado_per_jugador_[1] = 0.0F; + // Inicialitzar timers de muerte per player + hit_timer_per_player_[0] = 0.0F; + hit_timer_per_player_[1] = 0.0F; // Initialize lives and game over state (independent lives per player) - vides_per_jugador_[0] = Defaults::Game::STARTING_LIVES; - vides_per_jugador_[1] = Defaults::Game::STARTING_LIVES; - estat_game_over_ = GameOverState::NONE; + lives_per_player_[0] = Defaults::Game::STARTING_LIVES; + lives_per_player_[1] = Defaults::Game::STARTING_LIVES; + game_over_state_ = GameOverState::NONE; continue_counter_ = 0; continue_tick_timer_ = 0.0F; - continues_usados_ = 0; + continues_used_ = 0; game_over_timer_ = 0.0F; // Initialize scores (separate per player) - puntuacio_per_jugador_[0] = 0; - puntuacio_per_jugador_[1] = 0; - gestor_puntuacio_.reiniciar(); + score_per_player_[0] = 0; + score_per_player_[1] = 0; + floating_score_manager_.reset(); - // DEPRECATED: punt_spawn_ ja no s'usa, es calcula dinàmicament amb obtenir_punt_spawn(player_id) + // DEPRECATED: spawn_position_ ja no s'usa, es calcula dinàmicament amb obtenir_punt_spawn(player_id) // const SDL_FRect& zona = Defaults::Zones::PLAYAREA; - // punt_spawn_.x = zona.x + zona.w * 0.5f; - // punt_spawn_.y = zona.y + zona.h * Defaults::Game::INIT_HUD_SHIP_START_Y_RATIO; + // spawn_position_.x = zona.x + zona.w * 0.5f; + // spawn_position_.y = zona.y + zona.h * Defaults::Game::INIT_HUD_SHIP_START_Y_RATIO; - // Inicialitzar naus segons configuració (només jugadors actius) + // Inicialitzar naus segons configuració (només jugadors active) for (uint8_t i = 0; i < 2; i++) { bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; if (jugador_actiu) { - // Jugador actiu: init normalment + // Jugador active: init normalment Vec2 spawn_pos = obtenir_punt_spawn(i); - naus_[i].init(&spawn_pos, false); // No invulnerability at start + ships_[i].init(&spawn_pos, false); // No invulnerability at start std::cout << "[GameScene] Jugador " << (i + 1) << " inicialitzat\n"; } else { // Jugador inactiu: marcar com a mort permanent - naus_[i].markHit(); - itocado_per_jugador_[i] = 999.0F; // Valor sentinella (permanent inactiu) - vides_per_jugador_[i] = 0; // Sense vides + ships_[i].markHit(); + hit_timer_per_player_[i] = 999.0F; // Valor sentinella (permanent inactiu) + lives_per_player_[i] = 0; // Sense vides std::cout << "[GameScene] Jugador " << (i + 1) << " inactiu\n"; } } // [MODIFIED] Initialize enemies as inactive (stage system will spawn them) - for (auto& enemy : orni_) { - enemy = Enemy(sdl_.obte_renderer()); - enemy.set_ship_position(&naus_[0].getCenter()); // Set ship reference (P1 for now) + for (auto& enemy : enemies_) { + enemy = Enemy(sdl_.getRenderer()); + enemy.set_ship_position(&ships_[0].getCenter()); // Set ship reference (P1 for now) // DON'T call enemy.init() here - stage system handles spawning } // Inicialitzar bales (now 6 instead of 3) - for (auto& bala : bales_) { - bala.init(); + for (auto& bullet : bullets_) { + bullet.init(); } // [ELIMINAT] Iniciar música de joc (ara es gestiona en stage_manager) @@ -210,17 +210,17 @@ void GameScene::init() { void GameScene::update(float delta_time) { // Processar disparos (state-based, no event-based) - if (estat_game_over_ == GameOverState::NONE) { + if (game_over_state_ == GameOverState::NONE) { auto* input = Input::get(); - // Jugador 1 dispara (només si està actiu) + // Jugador 1 dispara (només si està active) if (match_config_.jugador1_actiu) { if (input->checkActionPlayer1(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) { disparar_bala(0); } } - // Jugador 2 dispara (només si està actiu) + // Jugador 2 dispara (només si està active) if (match_config_.jugador2_actiu) { if (input->checkActionPlayer2(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) { disparar_bala(1); @@ -232,10 +232,10 @@ void GameScene::update(float delta_time) { if (stage_manager_->get_estat() == StageSystem::EstatStage::PLAYING) { // Check if at least one player is alive and playing (game in progress) bool algun_jugador_viu = false; - if (match_config_.jugador1_actiu && itocado_per_jugador_[0] != 999.0F) { + if (match_config_.jugador1_actiu && hit_timer_per_player_[0] != 999.0F) { algun_jugador_viu = true; } - if (match_config_.jugador2_actiu && itocado_per_jugador_[1] != 999.0F) { + if (match_config_.jugador2_actiu && hit_timer_per_player_[1] != 999.0F) { algun_jugador_viu = true; } @@ -243,7 +243,7 @@ void GameScene::update(float delta_time) { if (algun_jugador_viu) { // P2 can join if not currently playing (never joined OR dead without lives) bool p2_no_juga = !match_config_.jugador2_actiu || // Never joined - itocado_per_jugador_[1] == 999.0F; // Dead without lives + hit_timer_per_player_[1] == 999.0F; // Dead without lives if (p2_no_juga) { if (input->checkActionPlayer2(InputAction::START, Input::DO_NOT_ALLOW_REPEAT)) { @@ -253,7 +253,7 @@ void GameScene::update(float delta_time) { // P1 can join if not currently playing (never joined OR dead without lives) bool p1_no_juga = !match_config_.jugador1_actiu || // Never joined - itocado_per_jugador_[0] == 999.0F; // Dead without lives + hit_timer_per_player_[0] == 999.0F; // Dead without lives if (p1_no_juga) { if (input->checkActionPlayer1(InputAction::START, Input::DO_NOT_ALLOW_REPEAT)) { @@ -265,24 +265,24 @@ void GameScene::update(float delta_time) { } // Handle CONTINUE screen - if (estat_game_over_ == GameOverState::CONTINUE) { + if (game_over_state_ == GameOverState::CONTINUE) { actualitzar_continue(delta_time); processar_input_continue(); // Still update enemies, bullets, and effects during continue screen - for (auto& enemy : orni_) { + for (auto& enemy : enemies_) { enemy.update(delta_time); } - for (auto& bala : bales_) { - bala.update(delta_time); + for (auto& bullet : bullets_) { + bullet.update(delta_time); } debris_manager_.update(delta_time); - gestor_puntuacio_.update(delta_time); + floating_score_manager_.update(delta_time); return; } // Handle final GAME OVER state - if (estat_game_over_ == GameOverState::GAME_OVER) { + if (game_over_state_ == GameOverState::GAME_OVER) { // Game over: only update timer, enemies, bullets, and debris game_over_timer_ -= delta_time; @@ -296,50 +296,50 @@ void GameScene::update(float delta_time) { } // Enemies and bullets continue moving during game over - for (auto& enemy : orni_) { + for (auto& enemy : enemies_) { enemy.update(delta_time); } - for (auto& bala : bales_) { - bala.update(delta_time); + for (auto& bullet : bullets_) { + bullet.update(delta_time); } debris_manager_.update(delta_time); - gestor_puntuacio_.update(delta_time); + floating_score_manager_.update(delta_time); return; } // Check death sequence state for BOTH players bool algun_jugador_mort = false; for (uint8_t i = 0; i < 2; i++) { - if (itocado_per_jugador_[i] > 0.0F && itocado_per_jugador_[i] < 999.0F) { + if (hit_timer_per_player_[i] > 0.0F && hit_timer_per_player_[i] < 999.0F) { algun_jugador_mort = true; // Death sequence active: update timer - itocado_per_jugador_[i] += delta_time; + hit_timer_per_player_[i] += delta_time; // Check if death duration completed (only trigger ONCE using sentinel value) - if (itocado_per_jugador_[i] >= Defaults::Game::DEATH_DURATION) { + if (hit_timer_per_player_[i] >= Defaults::Game::DEATH_DURATION) { // *** PHASE 3: RESPAWN OR GAME OVER *** // Decrement lives for this player (only once) - vides_per_jugador_[i]--; + lives_per_player_[i]--; - if (vides_per_jugador_[i] > 0) { + if (lives_per_player_[i] > 0) { // Respawn ship en spawn position con invulnerabilidad Vec2 spawn_pos = obtenir_punt_spawn(i); - naus_[i].init(&spawn_pos, true); - itocado_per_jugador_[i] = 0.0F; + ships_[i].init(&spawn_pos, true); + hit_timer_per_player_[i] = 0.0F; } else { // Player is permanently dead (out of lives) // Set sentinel value to prevent re-entering this block - itocado_per_jugador_[i] = 999.0F; + hit_timer_per_player_[i] = 999.0F; // Check if ALL ACTIVE players are dead (trigger continue screen) - bool p1_dead = !match_config_.jugador1_actiu || vides_per_jugador_[0] <= 0; - bool p2_dead = !match_config_.jugador2_actiu || vides_per_jugador_[1] <= 0; + bool p1_dead = !match_config_.jugador1_actiu || lives_per_player_[0] <= 0; + bool p2_dead = !match_config_.jugador2_actiu || lives_per_player_[1] <= 0; if (p1_dead && p2_dead) { - estat_game_over_ = GameOverState::CONTINUE; + game_over_state_ = GameOverState::CONTINUE; continue_counter_ = Defaults::Game::CONTINUE_COUNT_START; continue_tick_timer_ = Defaults::Game::CONTINUE_TICK_DURATION; } @@ -351,31 +351,31 @@ void GameScene::update(float delta_time) { // If any player is dead, still update enemies/bullets/effects if (algun_jugador_mort) { // Enemies and bullets continue moving during death sequence - for (auto& enemy : orni_) { + for (auto& enemy : enemies_) { enemy.update(delta_time); } - for (auto& bala : bales_) { - bala.update(delta_time); + for (auto& bullet : bullets_) { + bullet.update(delta_time); } debris_manager_.update(delta_time); - gestor_puntuacio_.update(delta_time); + floating_score_manager_.update(delta_time); // Don't return - allow alive players to continue playing } // *** STAGE SYSTEM STATE MACHINE *** - StageSystem::EstatStage estat = stage_manager_->get_estat(); + StageSystem::EstatStage state = stage_manager_->get_estat(); - switch (estat) { + switch (state) { case StageSystem::EstatStage::INIT_HUD: { - // Update stage manager timer (pot canviar l'estat!) + // Update stage manager timer (pot canviar l'state!) stage_manager_->update(delta_time); - // [FIX] Si l'estat ha canviat durant update(), sortir immediatament - // per evitar recalcular la posició de la nau amb el nou timer + // [FIX] Si l'state ha canviat durant update(), sortir immediatament + // per evitar recalcular la posició de la ship amb el nou timer if (stage_manager_->get_estat() != StageSystem::EstatStage::INIT_HUD) { break; } @@ -398,12 +398,12 @@ void GameScene::update(float delta_time) { // [MODIFICAT] Animar AMBAS naus con sus progress respectivos if (match_config_.jugador1_actiu && ship1_progress < 1.0F) { Vec2 pos_p1 = calcular_posicio_nau_init_hud(ship1_progress, 0); - naus_[0].setCenter(pos_p1); + ships_[0].setCenter(pos_p1); } if (match_config_.jugador2_actiu && ship2_progress < 1.0F) { Vec2 pos_p2 = calcular_posicio_nau_init_hud(ship2_progress, 1); - naus_[1].setCenter(pos_p2); + ships_[1].setCenter(pos_p2); } // Una vegada l'animació acaba, permetre control normal @@ -416,7 +416,7 @@ void GameScene::update(float delta_time) { // [DEBUG] Log entrada a LEVEL_START static bool first_entry = true; if (first_entry) { - std::cout << "[LEVEL_START] ENTERED with P1 pos.y=" << naus_[0].getCenter().y << '\n'; + std::cout << "[LEVEL_START] ENTERED with P1 pos.y=" << ships_[0].getCenter().y << '\n'; first_entry = false; } @@ -426,15 +426,15 @@ void GameScene::update(float delta_time) { // [NEW] Allow both ships movement and shooting during intro for (uint8_t i = 0; i < 2; i++) { bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; - if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players - naus_[i].processInput(delta_time, i); - naus_[i].update(delta_time); + if (jugador_actiu && hit_timer_per_player_[i] == 0.0F) { // Only active, alive players + ships_[i].processInput(delta_time, i); + ships_[i].update(delta_time); } } // [NEW] Update bullets - for (auto& bala : bales_) { - bala.update(delta_time); + for (auto& bullet : bullets_) { + bullet.update(delta_time); } // [NEW] Update debris @@ -444,14 +444,14 @@ void GameScene::update(float delta_time) { case StageSystem::EstatStage::PLAYING: { // [NEW] Update stage manager (spawns enemies, pause if BOTH dead) - bool pausar_spawn = (itocado_per_jugador_[0] > 0.0F && itocado_per_jugador_[1] > 0.0F); - stage_manager_->get_spawn_controller().update(delta_time, orni_, pausar_spawn); + bool pausar_spawn = (hit_timer_per_player_[0] > 0.0F && hit_timer_per_player_[1] > 0.0F); + stage_manager_->get_spawn_controller().update(delta_time, enemies_, pausar_spawn); // [NEW] Check stage completion (only when at least one player alive) - bool algun_jugador_viu = (itocado_per_jugador_[0] == 0.0F || itocado_per_jugador_[1] == 0.0F); + bool algun_jugador_viu = (hit_timer_per_player_[0] == 0.0F || hit_timer_per_player_[1] == 0.0F); if (algun_jugador_viu) { auto& spawn_ctrl = stage_manager_->get_spawn_controller(); - if (spawn_ctrl.tots_enemics_destruits(orni_)) { + if (spawn_ctrl.tots_enemics_destruits(enemies_)) { stage_manager_->stage_completat(); Audio::get()->playSound(Defaults::Sound::GOOD_JOB_COMMANDER, Audio::Group::GAME); break; @@ -461,25 +461,25 @@ void GameScene::update(float delta_time) { // [EXISTING] Normal gameplay - update active players for (uint8_t i = 0; i < 2; i++) { bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; - if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players - naus_[i].processInput(delta_time, i); - naus_[i].update(delta_time); + if (jugador_actiu && hit_timer_per_player_[i] == 0.0F) { // Only active, alive players + ships_[i].processInput(delta_time, i); + ships_[i].update(delta_time); } } - for (auto& enemy : orni_) { + for (auto& enemy : enemies_) { enemy.update(delta_time); } - for (auto& bala : bales_) { - bala.update(delta_time); + for (auto& bullet : bullets_) { + bullet.update(delta_time); } detectar_col·lisions_bales_enemics(); detectar_col·lisio_naus_enemics(); detectar_col·lisions_bales_jugadors(); debris_manager_.update(delta_time); - gestor_puntuacio_.update(delta_time); + floating_score_manager_.update(delta_time); break; } @@ -490,40 +490,40 @@ void GameScene::update(float delta_time) { // [NEW] Allow both ships movement and shooting during outro for (uint8_t i = 0; i < 2; i++) { bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; - if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players - naus_[i].processInput(delta_time, i); - naus_[i].update(delta_time); + if (jugador_actiu && hit_timer_per_player_[i] == 0.0F) { // Only active, alive players + ships_[i].processInput(delta_time, i); + ships_[i].update(delta_time); } } // [NEW] Update bullets (allow last shots to continue) - for (auto& bala : bales_) { - bala.update(delta_time); + for (auto& bullet : bullets_) { + bullet.update(delta_time); } // [NEW] Update debris (from last destroyed enemies) debris_manager_.update(delta_time); - gestor_puntuacio_.update(delta_time); + floating_score_manager_.update(delta_time); break; } } void GameScene::draw() { // Handle CONTINUE screen - if (estat_game_over_ == GameOverState::CONTINUE) { + if (game_over_state_ == GameOverState::CONTINUE) { // Draw game background elements first dibuixar_marges(); - for (const auto& enemy : orni_) { + for (const auto& enemy : enemies_) { enemy.draw(); } - for (const auto& bala : bales_) { - bala.draw(); + for (const auto& bullet : bullets_) { + bullet.draw(); } debris_manager_.draw(); - gestor_puntuacio_.draw(); + floating_score_manager_.draw(); dibuixar_marcador(); // Draw CONTINUE screen overlay @@ -532,24 +532,24 @@ void GameScene::draw() { } // Handle final GAME OVER state - if (estat_game_over_ == GameOverState::GAME_OVER) { + if (game_over_state_ == GameOverState::GAME_OVER) { // Game over: draw enemies, bullets, debris, and "GAME OVER" text dibuixar_marges(); - for (const auto& enemy : orni_) { + for (const auto& enemy : enemies_) { enemy.draw(); } - for (const auto& bala : bales_) { - bala.draw(); + for (const auto& bullet : bullets_) { + bullet.draw(); } debris_manager_.draw(); - gestor_puntuacio_.draw(); + floating_score_manager_.draw(); // Draw centered "GAME OVER" text const std::string game_over_text = "GAME OVER"; - constexpr float escala = Defaults::Game::GameOverScreen::TEXT_SCALE; + constexpr float scale = Defaults::Game::GameOverScreen::TEXT_SCALE; constexpr float spacing = Defaults::Game::GameOverScreen::TEXT_SPACING; // Calcular centre de l'àrea de joc usant constants @@ -557,16 +557,16 @@ void GameScene::draw() { float centre_x = play_area.x + (play_area.w / 2.0F); float centre_y = play_area.y + (play_area.h / 2.0F); - text_.render_centered(game_over_text, {.x = centre_x, .y = centre_y}, escala, spacing); + text_.renderCentered(game_over_text, {.x = centre_x, .y = centre_y}, scale, spacing); dibuixar_marcador(); return; } // [NEW] Stage state rendering - StageSystem::EstatStage estat = stage_manager_->get_estat(); + StageSystem::EstatStage state = stage_manager_->get_estat(); - switch (estat) { + switch (state) { case StageSystem::EstatStage::INIT_HUD: { // Calcular progrés de cada animació independent float timer = stage_manager_->get_timer_transicio(); @@ -610,12 +610,12 @@ void GameScene::draw() { } // [MODIFICAT] Dibuixar naus amb progress independent - if (ship1_progress > 0.0F && match_config_.jugador1_actiu && !naus_[0].isHit()) { - naus_[0].draw(); + if (ship1_progress > 0.0F && match_config_.jugador1_actiu && !ships_[0].isHit()) { + ships_[0].draw(); } - if (ship2_progress > 0.0F && match_config_.jugador2_actiu && !naus_[1].isHit()) { - naus_[1].draw(); + if (ship2_progress > 0.0F && match_config_.jugador2_actiu && !ships_[1].isHit()) { + ships_[1].draw(); } break; @@ -626,19 +626,19 @@ void GameScene::draw() { // [NEW] Draw both ships if active and alive for (uint8_t i = 0; i < 2; i++) { bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; - if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { - naus_[i].draw(); + if (jugador_actiu && hit_timer_per_player_[i] == 0.0F) { + ships_[i].draw(); } } // [NEW] Draw bullets - for (const auto& bala : bales_) { - bala.draw(); + for (const auto& bullet : bullets_) { + bullet.draw(); } // [NEW] Draw debris debris_manager_.draw(); - gestor_puntuacio_.draw(); + floating_score_manager_.draw(); // [EXISTING] Draw intro message and score dibuixar_missatge_stage(stage_manager_->get_missatge_level_start()); @@ -651,21 +651,21 @@ void GameScene::draw() { // [EXISTING] Normal rendering - active ships for (uint8_t i = 0; i < 2; i++) { bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; - if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { - naus_[i].draw(); + if (jugador_actiu && hit_timer_per_player_[i] == 0.0F) { + ships_[i].draw(); } } - for (const auto& enemy : orni_) { + for (const auto& enemy : enemies_) { enemy.draw(); } - for (const auto& bala : bales_) { - bala.draw(); + for (const auto& bullet : bullets_) { + bullet.draw(); } debris_manager_.draw(); - gestor_puntuacio_.draw(); + floating_score_manager_.draw(); dibuixar_marcador(); break; @@ -674,19 +674,19 @@ void GameScene::draw() { // [NEW] Draw both ships if active and alive for (uint8_t i = 0; i < 2; i++) { bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; - if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { - naus_[i].draw(); + if (jugador_actiu && hit_timer_per_player_[i] == 0.0F) { + ships_[i].draw(); } } // [NEW] Draw bullets (allow last shots to be visible) - for (const auto& bala : bales_) { - bala.draw(); + for (const auto& bullet : bullets_) { + bullet.draw(); } // [NEW] Draw debris (from last destroyed enemies) debris_manager_.draw(); - gestor_puntuacio_.draw(); + floating_score_manager_.draw(); // [EXISTING] Draw completion message and score dibuixar_missatge_stage(StageSystem::Constants::MISSATGE_LEVEL_COMPLETED); @@ -697,41 +697,41 @@ void GameScene::draw() { void GameScene::tocado(uint8_t player_id) { // Death sequence: 3 phases - // Phase 1: First call (itocado_per_jugador_[player_id] == 0) - trigger explosion + // Phase 1: First call (hit_timer_per_player_[player_id] == 0) - trigger explosion // Phase 2: Animation (0 < itocado_ < 3.0s) - debris animation // Phase 3: Respawn or game over (itocado_ >= 3.0s) - handled in update() - if (itocado_per_jugador_[player_id] == 0.0F) { + if (hit_timer_per_player_[player_id] == 0.0F) { // *** PHASE 1: TRIGGER DEATH *** // Mark ship as dead (stops rendering and input) - naus_[player_id].markHit(); + ships_[player_id].markHit(); // Create ship explosion - const Vec2& ship_pos = naus_[player_id].getCenter(); - float ship_angle = naus_[player_id].getAngle(); - Vec2 vel_nau = naus_[player_id].getVelocityVector(); - // Reduir a 80% la velocitat heretada per la nau (més realista) + 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}; - debris_manager_.explotar( - naus_[player_id].getShape(), // Ship shape (3 lines) + debris_manager_.explode( + ships_[player_id].getShape(), // Ship shape (3 lines) ship_pos, // Center position ship_angle, // Ship orientation 1.0F, // Normal scale Defaults::Physics::Debris::VELOCITAT_BASE, // 80 px/s - naus_[player_id].getBrightness(), // Heredar brightness - vel_nau_80, // Heredar 80% velocitat + ships_[player_id].getBrightness(), // Heredar brightness + vel_nau_80, // Heredar 80% velocity 0.0F, // Nave: trayectorias rectas (sin drotacio) 0.0F, // Sin herencia visual (rotación aleatoria) Defaults::Sound::EXPLOSION2 // Sonido alternativo para la explosión ); // Start death timer (non-zero to avoid re-triggering) - itocado_per_jugador_[player_id] = 0.001F; + hit_timer_per_player_[player_id] = 0.001F; } // Phase 2 is automatic (debris updates in update()) - // Phase 3 is handled in update() when itocado_per_jugador_ >= DEATH_DURATION + // Phase 3 is handled in update() when hit_timer_per_player_ >= DEATH_DURATION } void GameScene::dibuixar_marges() const { @@ -745,18 +745,18 @@ void GameScene::dibuixar_marges() const { int y2 = static_cast(zona.y + zona.h); // 4 línies per formar el rectangle - Rendering::linea(sdl_.obte_renderer(), x1, y1, x2, y1); // Top - Rendering::linea(sdl_.obte_renderer(), x1, y2, x2, y2); // Bottom - Rendering::linea(sdl_.obte_renderer(), x1, y1, x1, y2); // Left - Rendering::linea(sdl_.obte_renderer(), x2, y1, x2, y2); // Right + Rendering::linea(sdl_.getRenderer(), x1, y1, x2, y1); // Top + Rendering::linea(sdl_.getRenderer(), x1, y2, x2, y2); // Bottom + Rendering::linea(sdl_.getRenderer(), x1, y1, x1, y2); // Left + Rendering::linea(sdl_.getRenderer(), x2, y1, x2, y2); // Right } void GameScene::dibuixar_marcador() { // Construir text del marcador - std::string text = construir_marcador(); + std::string text = buildScoreboard(); // Paràmetres de renderització - const float escala = 0.85F; + const float scale = 0.85F; const float spacing = 0.0F; // Calcular centre de la zona del marcador @@ -765,7 +765,7 @@ void GameScene::dibuixar_marcador() { float centre_y = scoreboard.y + (scoreboard.h / 2.0F); // Renderitzar centrat - text_.render_centered(text, {.x = centre_x, .y = centre_y}, escala, spacing); + text_.renderCentered(text, {.x = centre_x, .y = centre_y}, scale, spacing); } void GameScene::dibuixar_marges_animat(float progress) const { @@ -794,11 +794,11 @@ void GameScene::dibuixar_marges_animat(float progress) const { // Línia esquerra: creix des del centre cap a l'esquerra int x1_phase1 = static_cast(cx - ((cx - x1) * phase1_progress)); - Rendering::linea(sdl_.obte_renderer(), cx, y1, x1_phase1, y1); + Rendering::linea(sdl_.getRenderer(), cx, y1, x1_phase1, y1); // Línia dreta: creix des del centre cap a la dreta int x2_phase1 = static_cast(cx + ((x2 - cx) * phase1_progress)); - Rendering::linea(sdl_.obte_renderer(), cx, y1, x2_phase1, y1); + Rendering::linea(sdl_.getRenderer(), cx, y1, x2_phase1, y1); } // --- FASE 2: Línies verticals laterals (33-66%) --- @@ -807,10 +807,10 @@ void GameScene::dibuixar_marges_animat(float progress) const { // Línia esquerra: creix des de dalt cap a baix int y2_phase2 = static_cast(y1 + ((y2 - y1) * phase2_progress)); - Rendering::linea(sdl_.obte_renderer(), x1, y1, x1, y2_phase2); + Rendering::linea(sdl_.getRenderer(), x1, y1, x1, y2_phase2); // Línia dreta: creix des de dalt cap a baix - Rendering::linea(sdl_.obte_renderer(), x2, y1, x2, y2_phase2); + Rendering::linea(sdl_.getRenderer(), x2, y1, x2, y2_phase2); } // --- FASE 3: Línies horitzontals inferiors (66-100%) --- @@ -819,11 +819,11 @@ void GameScene::dibuixar_marges_animat(float progress) const { // Línia esquerra: creix des de l'esquerra cap al centre int x_left_phase3 = static_cast(x1 + ((cx - x1) * phase3_progress)); - Rendering::linea(sdl_.obte_renderer(), x1, y2, x_left_phase3, y2); + Rendering::linea(sdl_.getRenderer(), x1, y2, x_left_phase3, y2); // Línia dreta: creix des de la dreta cap al centre int x_right_phase3 = static_cast(x2 - ((x2 - cx) * phase3_progress)); - Rendering::linea(sdl_.obte_renderer(), x2, y2, x_right_phase3, y2); + Rendering::linea(sdl_.getRenderer(), x2, y2, x_right_phase3, y2); } } @@ -834,10 +834,10 @@ void GameScene::dibuixar_marcador_animat(float progress) { float eased_progress = Easing::ease_out_quad(progress); // Construir text - std::string text = construir_marcador(); + std::string text = buildScoreboard(); // Paràmetres - const float escala = 0.85F; + const float scale = 0.85F; const float spacing = 0.0F; // Calcular centre de la zona del marcador @@ -852,11 +852,11 @@ void GameScene::dibuixar_marcador_animat(float progress) { float centre_y_animada = centre_y_inicial + ((centre_y_final - centre_y_inicial) * eased_progress); // Renderitzar centrat en posició animada - text_.render_centered(text, {.x = centre_x, .y = centre_y_animada}, escala, spacing); + text_.renderCentered(text, {.x = centre_x, .y = centre_y_animada}, scale, spacing); } Vec2 GameScene::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const { - // Animació de la nau pujant des de baix amb easing + // Animació de la ship pujant des de baix amb easing // [MODIFICAT] Ambas naves usan ease_out_quad (desfase temporal via INIT/END) // Aplicar easing (uniforme para ambas naves) @@ -864,7 +864,7 @@ Vec2 GameScene::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const SDL_FRect& zona = Defaults::Zones::PLAYAREA; - // Calcular posició final segons jugador (reutilitza obtenir_punt_spawn) + // Calcular posició final segons player (reutilitza obtenir_punt_spawn) Vec2 spawn_final = obtenir_punt_spawn(player_id); float x_final = spawn_final.x; float y_final = spawn_final.y; @@ -904,16 +904,16 @@ float GameScene::calcular_progress_rango(float global_progress, float ratio_init return (global_progress - ratio_init) / (ratio_end - ratio_init); } -std::string GameScene::construir_marcador() const { +std::string GameScene::buildScoreboard() const { // Puntuació P1 (6 dígits) - mostrar zeros si inactiu std::string score_p1; std::string vides_p1; if (match_config_.jugador1_actiu) { - score_p1 = std::to_string(puntuacio_per_jugador_[0]); + 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 = (vides_per_jugador_[0] < 10) - ? "0" + std::to_string(vides_per_jugador_[0]) - : std::to_string(vides_per_jugador_[0]); + vides_p1 = (lives_per_player_[0] < 10) + ? "0" + std::to_string(lives_per_player_[0]) + : std::to_string(lives_per_player_[0]); } else { score_p1 = "000000"; vides_p1 = "00"; @@ -928,11 +928,11 @@ std::string GameScene::construir_marcador() const { std::string score_p2; std::string vides_p2; if (match_config_.jugador2_actiu) { - score_p2 = std::to_string(puntuacio_per_jugador_[1]); + 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 = (vides_per_jugador_[1] < 10) - ? "0" + std::to_string(vides_per_jugador_[1]) - : std::to_string(vides_per_jugador_[1]); + vides_p2 = (lives_per_player_[1] < 10) + ? "0" + std::to_string(lives_per_player_[1]) + : std::to_string(lives_per_player_[1]); } else { score_p2 = "000000"; vides_p2 = "00"; @@ -951,56 +951,56 @@ void GameScene::detectar_col·lisions_bales_enemics() { constexpr float VELOCITAT_EXPLOSIO = 80.0F; // px/s (en lloc de 80.0f per defecte) // Iterar per totes les bales i enemics - for (auto& bala : bales_) { - for (auto& enemic : orni_) { + for (auto& bullet : bullets_) { + for (auto& enemy : enemies_) { // Comprovar col·lisió utilitzant la interfície genèrica - if (Physics::check_collision(bala, enemic, AMPLIFIER)) { + if (Physics::check_collision(bullet, enemy, AMPLIFIER)) { // *** COL·LISIÓ DETECTADA *** - const Vec2& pos_enemic = enemic.getCenter(); + const Vec2& pos_enemic = enemy.getCenter(); // 1. Calculate score for enemy type - int punts = 0; - switch (enemic.getType()) { + int points = 0; + switch (enemy.getType()) { case EnemyType::PENTAGON: - punts = Defaults::Enemies::Scoring::PENTAGON_SCORE; + points = Defaults::Enemies::Scoring::PENTAGON_SCORE; break; case EnemyType::QUADRAT: - punts = Defaults::Enemies::Scoring::QUADRAT_SCORE; + points = Defaults::Enemies::Scoring::QUADRAT_SCORE; break; case EnemyType::MOLINILLO: - punts = Defaults::Enemies::Scoring::MOLINILLO_SCORE; + points = Defaults::Enemies::Scoring::MOLINILLO_SCORE; break; } // 2. Add score to the player who shot it - uint8_t owner_id = bala.get_owner_id(); - puntuacio_per_jugador_[owner_id] += punts; + uint8_t owner_id = bullet.get_owner_id(); + score_per_player_[owner_id] += points; // 3. Create floating score number - gestor_puntuacio_.crear(punts, pos_enemic); + floating_score_manager_.crear(points, pos_enemic); - // 4. Destruir enemic (marca com inactiu) - enemic.destruir(); + // 4. Destruir enemy (marca com inactiu) + enemy.destruir(); // 2. Crear explosió de fragments - Vec2 vel_enemic = enemic.getVelocityVector(); - debris_manager_.explotar( - enemic.getShape(), // Forma vectorial del pentàgon + Vec2 vel_enemic = enemy.getVelocityVector(); + debris_manager_.explode( + enemy.getShape(), // Forma vectorial del pentàgon pos_enemic, // Posició central - 0.0F, // Angle (enemic té rotació interna) + 0.0F, // Angle (enemy té rotació interna) 1.0F, // Escala normal VELOCITAT_EXPLOSIO, // 50 px/s (explosió suau) - enemic.getBrightness(), // Heredar brightness - vel_enemic, // Heredar velocitat - enemic.get_drotacio(), // Heredar velocitat angular (trayectorias curvas) + enemy.getBrightness(), // Heredar brightness + vel_enemic, // Heredar velocity + enemy.get_drotacio(), // Heredar velocity angular (trayectorias curvas) 0.0F // Sin herencia visual (rotación aleatoria) ); - // 3. Desactivar bala - bala.desactivar(); + // 3. Desactivar bullet + bullet.desactivar(); - // 4. Eixir del bucle intern (bala només destrueix 1 enemic) + // 4. Eixir del bucle intern (bullet només destrueix 1 enemy) break; } } @@ -1014,25 +1014,25 @@ void GameScene::detectar_col·lisio_naus_enemics() { // Check collision for BOTH players for (uint8_t i = 0; i < 2; i++) { // Skip collisions if player is dead or invulnerable - if (itocado_per_jugador_[i] > 0.0F) { + if (hit_timer_per_player_[i] > 0.0F) { continue; } - if (!naus_[i].isAlive()) { + if (!ships_[i].isAlive()) { continue; } - if (naus_[i].isInvulnerable()) { + if (ships_[i].isInvulnerable()) { continue; } // Check collision with all active enemies - for (const auto& enemic : orni_) { + for (const auto& enemy : enemies_) { // Skip collision if enemy is invulnerable - if (enemic.isInvulnerable()) { + if (enemy.isInvulnerable()) { continue; } // Comprovar col·lisió utilitzant la interfície genèrica - if (Physics::check_collision(naus_[i], enemic, AMPLIFIER)) { + if (Physics::check_collision(ships_[i], enemy, AMPLIFIER)) { tocado(i); // Trigger death sequence for player i break; // Only one collision per player per frame } @@ -1050,28 +1050,28 @@ void GameScene::detectar_col·lisions_bales_jugadors() { constexpr float AMPLIFIER = Defaults::Game::COLLISION_BULLET_PLAYER_AMPLIFIER; // Check all active bullets - for (auto& bala : bales_) { - if (!bala.esta_activa()) { + for (auto& bullet : bullets_) { + if (!bullet.esta_activa()) { continue; } // Skip bullets in grace period (prevents instant self-collision) - if (bala.get_grace_timer() > 0.0F) { + if (bullet.get_grace_timer() > 0.0F) { continue; } - uint8_t bullet_owner = bala.get_owner_id(); + uint8_t bullet_owner = bullet.get_owner_id(); // Check collision with BOTH players for (uint8_t player_id = 0; player_id < 2; player_id++) { // Skip if player is dead, invulnerable, or inactive - if (itocado_per_jugador_[player_id] > 0.0F) { + if (hit_timer_per_player_[player_id] > 0.0F) { continue; } - if (!naus_[player_id].isAlive()) { + if (!ships_[player_id].isAlive()) { continue; } - if (naus_[player_id].isInvulnerable()) { + if (ships_[player_id].isInvulnerable()) { continue; } @@ -1083,7 +1083,7 @@ void GameScene::detectar_col·lisions_bales_jugadors() { } // Comprovar col·lisió utilitzant la interfície genèrica - if (Physics::check_collision(bala, naus_[player_id], AMPLIFIER)) { + if (Physics::check_collision(bullet, ships_[player_id], AMPLIFIER)) { // *** FRIENDLY FIRE HIT *** if (bullet_owner == player_id) { @@ -1096,14 +1096,14 @@ void GameScene::detectar_col·lisions_bales_jugadors() { tocado(player_id); // Attacker gains 1 life (no cap) - vides_per_jugador_[bullet_owner]++; + lives_per_player_[bullet_owner]++; } // Play distinct sound Audio::get()->playSound(Defaults::Sound::FRIENDLY_FIRE_HIT, Audio::Group::GAME); // Deactivate bullet - bala.desactivar(); + bullet.desactivar(); break; // Bullet only hits once per frame } @@ -1113,7 +1113,7 @@ void GameScene::detectar_col·lisions_bales_jugadors() { // [NEW] Stage system helper methods -void GameScene::dibuixar_missatge_stage(const std::string& missatge) { +void GameScene::dibuixar_missatge_stage(const std::string& message) { constexpr float escala_base = 1.0F; constexpr float spacing = 2.0F; @@ -1143,31 +1143,31 @@ void GameScene::dibuixar_missatge_stage(const std::string& missatge) { if (typing_ratio > 0.0F && progress < typing_ratio) { // Typewriter phase: show partial text float typing_progress = progress / typing_ratio; // Normalize to 0.0-1.0 - visible_chars = static_cast(missatge.length() * typing_progress); + visible_chars = static_cast(message.length() * typing_progress); if (visible_chars == 0 && progress > 0.0F) { visible_chars = 1; // Show at least 1 character after first frame } } else { // Display phase: show complete text // (Either after typing phase, or immediately if typing_ratio == 0.0) - visible_chars = missatge.length(); + visible_chars = message.length(); } // Create partial message (substring for typewriter) - std::string partial_message = missatge.substr(0, visible_chars); + std::string partial_message = message.substr(0, visible_chars); // =================================================== // Calculate text width at base scale (using FULL message for position calculation) - float text_width_at_base = text_.get_text_width(missatge, escala_base, spacing); + float text_width_at_base = text_.get_text_width(message, escala_base, spacing); // Auto-scale if text exceeds max width - float escala = (text_width_at_base <= max_width) + float scale = (text_width_at_base <= max_width) ? escala_base : max_width / text_width_at_base; // Recalculate dimensions with final scale (using FULL message for centering) - float full_text_width = text_.get_text_width(missatge, escala, spacing); - float text_height = text_.get_text_height(escala); + float full_text_width = text_.get_text_width(message, scale, spacing); + float text_height = text_.get_text_height(scale); // Calculate position as if FULL text was there (for fixed position typewriter) float x = play_area.x + ((play_area.w - full_text_width) / 2.0F); @@ -1175,7 +1175,7 @@ void GameScene::dibuixar_missatge_stage(const std::string& missatge) { // Render only the partial message (typewriter effect) Vec2 pos = {.x = x, .y = y}; - text_.render(partial_message, pos, escala, spacing); + text_.render(partial_message, pos, scale, spacing); } // ======================================== @@ -1187,7 +1187,7 @@ Vec2 GameScene::obtenir_punt_spawn(uint8_t player_id) const { float x_ratio; if (match_config_.es_un_jugador()) { - // Un sol jugador: spawn al centre (50%) + // Un sol player: spawn al centre (50%) x_ratio = 0.5F; } else { // Dos jugadors: spawn a posicions separades @@ -1202,17 +1202,17 @@ Vec2 GameScene::obtenir_punt_spawn(uint8_t player_id) const { } void GameScene::disparar_bala(uint8_t player_id) { - // Verificar que el jugador está vivo - if (itocado_per_jugador_[player_id] > 0.0F) { + // Verificar que el player está vivo + if (hit_timer_per_player_[player_id] > 0.0F) { return; } - if (!naus_[player_id].isAlive()) { + if (!ships_[player_id].isAlive()) { return; } // Calcular posición en la punta de la nave - const Vec2& ship_centre = naus_[player_id].getCenter(); - float ship_angle = naus_[player_id].getAngle(); + 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; @@ -1222,11 +1222,11 @@ void GameScene::disparar_bala(uint8_t player_id) { float tip_y = (LOCAL_TIP_X * sin_a) + (LOCAL_TIP_Y * cos_a) + ship_centre.y; Vec2 posicio_dispar = {.x = tip_x, .y = tip_y}; - // Buscar primera bala inactiva en el pool del jugador + // Buscar primera bullet inactiva en el pool del player int start_idx = player_id * 3; // P1=[0,1,2], P2=[3,4,5] for (int i = start_idx; i < start_idx + 3; i++) { - if (!bales_[i].esta_activa()) { - bales_[i].disparar(posicio_dispar, ship_angle, player_id); + if (!bullets_[i].esta_activa()) { + bullets_[i].disparar(posicio_dispar, ship_angle, player_id); break; } } @@ -1236,7 +1236,7 @@ void GameScene::disparar_bala(uint8_t player_id) { void GameScene::check_and_apply_continue_timeout() { if (continue_counter_ < 0) { - estat_game_over_ = GameOverState::GAME_OVER; + game_over_state_ = GameOverState::GAME_OVER; game_over_timer_ = Defaults::Game::GAME_OVER_DURATION; } } @@ -1252,7 +1252,7 @@ void GameScene::actualitzar_continue(float delta_time) { check_and_apply_continue_timeout(); // Play sound only if still in CONTINUE state (not transitioned to GAME_OVER) - if (estat_game_over_ == GameOverState::CONTINUE) { + if (game_over_state_ == GameOverState::CONTINUE) { Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME); } } @@ -1267,25 +1267,25 @@ void GameScene::processar_input_continue() { if (p1_start || p2_start) { // Check continue limit (skip if infinite continues) - if (!Defaults::Game::INFINITE_CONTINUES && continues_usados_ >= Defaults::Game::MAX_CONTINUES) { + if (!Defaults::Game::INFINITE_CONTINUES && continues_used_ >= Defaults::Game::MAX_CONTINUES) { // Max continues reached → final game over - estat_game_over_ = GameOverState::GAME_OVER; + game_over_state_ = GameOverState::GAME_OVER; game_over_timer_ = Defaults::Game::GAME_OVER_DURATION; return; } // Only increment if not infinite if (!Defaults::Game::INFINITE_CONTINUES) { - continues_usados_++; + continues_used_++; } // Determine which player(s) to revive uint8_t player_to_revive = p1_start ? 0 : 1; // Reset score and lives (KEEP level and enemies!) - puntuacio_per_jugador_[player_to_revive] = 0; - vides_per_jugador_[player_to_revive] = Defaults::Game::STARTING_LIVES; - itocado_per_jugador_[player_to_revive] = 0.0F; + score_per_player_[player_to_revive] = 0; + lives_per_player_[player_to_revive] = Defaults::Game::STARTING_LIVES; + hit_timer_per_player_[player_to_revive] = 0.0F; // Activate player if not already if (player_to_revive == 0) { @@ -1296,21 +1296,21 @@ void GameScene::processar_input_continue() { // Spawn with invulnerability Vec2 spawn_pos = obtenir_punt_spawn(player_to_revive); - naus_[player_to_revive].init(&spawn_pos, true); + ships_[player_to_revive].init(&spawn_pos, true); // Check if other player wants to continue too if (p1_start && p2_start) { uint8_t other_player = 1; - puntuacio_per_jugador_[other_player] = 0; - vides_per_jugador_[other_player] = Defaults::Game::STARTING_LIVES; - itocado_per_jugador_[other_player] = 0.0F; + score_per_player_[other_player] = 0; + lives_per_player_[other_player] = Defaults::Game::STARTING_LIVES; + hit_timer_per_player_[other_player] = 0.0F; match_config_.jugador2_actiu = true; Vec2 spawn_pos2 = obtenir_punt_spawn(other_player); - naus_[other_player].init(&spawn_pos2, true); + ships_[other_player].init(&spawn_pos2, true); } // Resume game - estat_game_over_ = GameOverState::NONE; + game_over_state_ = GameOverState::NONE; continue_counter_ = 0; continue_tick_timer_ = 0.0F; @@ -1333,7 +1333,7 @@ void GameScene::processar_input_continue() { check_and_apply_continue_timeout(); // Play sound only if still in CONTINUE state - if (estat_game_over_ == GameOverState::CONTINUE) { + if (game_over_state_ == GameOverState::CONTINUE) { Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME); } @@ -1354,7 +1354,7 @@ void GameScene::dibuixar_continue() { float centre_x = play_area.x + (play_area.w / 2.0F); float centre_y_continue = play_area.y + (play_area.h * y_ratio_continue); - text_.render_centered(continue_text, {.x = centre_x, .y = centre_y_continue}, escala_continue, spacing); + text_.renderCentered(continue_text, {.x = centre_x, .y = centre_y_continue}, escala_continue, spacing); // Countdown number (using constants) const std::string counter_str = std::to_string(continue_counter_); @@ -1363,17 +1363,17 @@ void GameScene::dibuixar_continue() { float centre_y_counter = play_area.y + (play_area.h * y_ratio_counter); - text_.render_centered(counter_str, {.x = centre_x, .y = centre_y_counter}, escala_counter, spacing); + text_.renderCentered(counter_str, {.x = centre_x, .y = centre_y_counter}, escala_counter, spacing); // "CONTINUES LEFT" (conditional + using constants) if (!Defaults::Game::INFINITE_CONTINUES) { - const std::string continues_text = "CONTINUES LEFT: " + std::to_string(Defaults::Game::MAX_CONTINUES - continues_usados_); + const std::string continues_text = "CONTINUES LEFT: " + std::to_string(Defaults::Game::MAX_CONTINUES - continues_used_); float escala_info = Defaults::Game::ContinueScreen::INFO_TEXT_SCALE; float y_ratio_info = Defaults::Game::ContinueScreen::INFO_TEXT_Y_RATIO; float centre_y_info = play_area.y + (play_area.h * y_ratio_info); - text_.render_centered(continues_text, {.x = centre_x, .y = centre_y_info}, escala_info, spacing); + text_.renderCentered(continues_text, {.x = centre_x, .y = centre_y_info}, escala_info, spacing); } } @@ -1386,15 +1386,15 @@ void GameScene::unir_jugador(uint8_t player_id) { } // Reset stats - vides_per_jugador_[player_id] = Defaults::Game::STARTING_LIVES; - puntuacio_per_jugador_[player_id] = 0; - itocado_per_jugador_[player_id] = 0.0F; + lives_per_player_[player_id] = Defaults::Game::STARTING_LIVES; + score_per_player_[player_id] = 0; + hit_timer_per_player_[player_id] = 0.0F; // Spawn with invulnerability Vec2 spawn_pos = obtenir_punt_spawn(player_id); - naus_[player_id].init(&spawn_pos, true); + ships_[player_id].init(&spawn_pos, true); // No visual message, just spawn (per user requirement) - std::cout << "[GameScene] Jugador " << (int)(player_id + 1) << " s'ha unit a la partida!" << '\n'; + std::cout << "[GameScene] Jugador " << (int)(player_id + 1) << " s'ha unit a la match!" << '\n'; } diff --git a/source/game/scenes/game_scene.hpp b/source/game/scenes/game_scene.hpp index b50e3f4..0c87642 100644 --- a/source/game/scenes/game_scene.hpp +++ b/source/game/scenes/game_scene.hpp @@ -17,7 +17,7 @@ #include "core/types.hpp" #include "game/constants.hpp" #include "game/effects/debris_manager.hpp" -#include "game/effects/gestor_puntuacio_flotant.hpp" +#include "game/effects/floating_score_manager.hpp" #include "game/entities/bullet.hpp" #include "game/entities/enemy.hpp" #include "game/entities/ship.hpp" @@ -45,33 +45,33 @@ class GameScene { private: SDLManager& sdl_; SceneManager::SceneContext& context_; - GameConfig::MatchConfig match_config_; // Configuració de jugadors actius + GameConfig::MatchConfig match_config_; // Configuració de jugadors active // Efectes visuals Effects::DebrisManager debris_manager_; - Effects::GestorPuntuacioFlotant gestor_puntuacio_; + Effects::FloatingScoreManager floating_score_manager_; // Estat del joc - std::array naus_; // [0]=P1, [1]=P2 - std::array orni_; - std::array bales_; // 6 balas: P1=[0,1,2], P2=[3,4,5] - std::array itocado_per_jugador_; // Death timers per player (seconds) + std::array ships_; // [0]=P1, [1]=P2 + std::array enemies_; + std::array bullets_; // 6 balas: P1=[0,1,2], P2=[3,4,5] + std::array hit_timer_per_player_; // Death timers per player (seconds) // Lives and game over system - std::array vides_per_jugador_; // [0]=P1, [1]=P2 - GameOverState estat_game_over_; // Game over state machine (NONE, CONTINUE, GAME_OVER) + std::array lives_per_player_; // [0]=P1, [1]=P2 + GameOverState game_over_state_; // Game over state machine (NONE, CONTINUE, GAME_OVER) int continue_counter_; // Continue countdown (9→0) float continue_tick_timer_; // Timer for countdown tick (1.0s) - int continues_usados_; // Continues used this game (0-3 max) + int continues_used_; // Continues used this game (0-3 max) float game_over_timer_; // Final GAME OVER timer before title screen - Vec2 punt_mort_; // Death position (for respawn) - std::array puntuacio_per_jugador_; // [0]=P1, [1]=P2 + Vec2 death_position_; // Death position (for respawn) + std::array score_per_player_; // [0]=P1, [1]=P2 // Text vectorial Graphics::VectorText text_; // [NEW] Stage system - std::unique_ptr stage_config_; + std::unique_ptr stage_config_; std::unique_ptr stage_manager_; // Control de sons d'animació INIT_HUD @@ -79,7 +79,7 @@ class GameScene { // Funcions privades void tocado(uint8_t player_id); - void detectar_col·lisions_bales_enemics(); // Col·lisions bala-enemic + void detectar_col·lisions_bales_enemics(); // Col·lisions bullet-enemy void detectar_col·lisio_naus_enemics(); // Ship-enemy collision detection (plural) void detectar_col·lisions_bales_jugadors(); // Bullet-player collision detection (friendly fire) void dibuixar_marges() const; // Dibuixar vores de la zona de joc @@ -95,18 +95,18 @@ class GameScene { void dibuixar_continue(); // Draw continue screen // [NEW] Stage system helpers - void dibuixar_missatge_stage(const std::string& missatge); + void dibuixar_missatge_stage(const std::string& message); // [NEW] Funcions d'animació per INIT_HUD void dibuixar_marges_animat(float progress) const; // Rectangle amb creixement uniforme void dibuixar_marcador_animat(float progress); // Marcador que puja des de baix - [[nodiscard]] Vec2 calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const; // Posició animada de la nau + [[nodiscard]] Vec2 calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const; // Posició animada de la ship // [NEW] Función helper del sistema de animación INIT_HUD [[nodiscard]] float calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const; // [NEW] Funció helper del marcador - [[nodiscard]] std::string construir_marcador() const; + [[nodiscard]] std::string buildScoreboard() const; }; #endif // ESCENA_JOC_HPP diff --git a/source/game/scenes/logo_scene.cpp b/source/game/scenes/logo_scene.cpp index 9b97979..a91098e 100644 --- a/source/game/scenes/logo_scene.cpp +++ b/source/game/scenes/logo_scene.cpp @@ -29,7 +29,7 @@ static float calcular_progress_letra(size_t letra_index, size_t num_letras, floa return 1.0F; } - // Calcular temps per lletra + // Calcular time per lletra float duration_per_letra = 1.0F / static_cast(num_letras); float step = threshold * duration_per_letra; float start = static_cast(letra_index) * step; @@ -50,7 +50,7 @@ LogoScene::LogoScene(SDLManager& sdl, SceneContext& context) context_(context), estat_actual_(AnimationState::PRE_ANIMATION), temps_estat_actual_(0.0F), - debris_manager_(std::make_unique(sdl.obte_renderer())), + debris_manager_(std::make_unique(sdl.getRenderer())), lletra_explosio_index_(0), temps_des_ultima_explosio_(0.0F) { std::cout << "SceneType Logo: Inicialitzant...\n"; @@ -113,7 +113,7 @@ void LogoScene::run() { // Actualitzar colors oscil·lats (efecte verd global) sdl_.updateColors(delta_time); - // Actualitzar context de renderitzat (factor d'escala global) + // Actualitzar context de renderitzat (factor d'scale global) sdl_.updateRenderingContext(); // Dibuixar @@ -142,20 +142,20 @@ void LogoScene::inicialitzar_lletres() { float ancho_total = 0.0F; for (const auto& fitxer : fitxers) { - auto forma = ShapeLoader::load(fitxer); - if (!forma || !forma->es_valida()) { + auto shape = ShapeLoader::load(fitxer); + if (!shape || !shape->isValid()) { std::cerr << "[LogoScene] Error carregant " << fitxer << '\n'; continue; } - // Calcular bounding box de la forma (trobar ancho) + // Calcular bounding box de la shape (trobar ancho) float min_x = FLT_MAX; float max_x = -FLT_MAX; - for (const auto& prim : forma->get_primitives()) { - for (const auto& punt : prim.points) { - min_x = std::min(min_x, punt.x); - max_x = std::max(max_x, punt.x); + for (const auto& prim : shape->get_primitives()) { + for (const auto& point : prim.points) { + min_x = std::min(min_x, point.x); + max_x = std::max(max_x, point.x); } } @@ -164,9 +164,9 @@ void LogoScene::inicialitzar_lletres() { // IMPORTANT: Escalar ancho i offset amb ESCALA_FINAL // per que les posicions finals coincideixin amb la mida real de les lletres float ancho = ancho_sin_escalar * ESCALA_FINAL; - float offset_centre = (forma->getCenter().x - min_x) * ESCALA_FINAL; + float offset_centre = (shape->getCenter().x - min_x) * ESCALA_FINAL; - lletres_.push_back({forma, + lletres_.push_back({shape, {.x = 0.0F, .y = 0.0F}, // Posició es calcularà després ancho, offset_centre}); @@ -188,11 +188,11 @@ void LogoScene::inicialitzar_lletres() { float x_actual = x_inicial; for (auto& lletra : lletres_) { - // Posicionar el centre de la forma (shape_centre) en pantalla + // Posicionar el centre de la shape (shape_centre) en pantalla // Usar offset_centre en lloc de ancho/2 perquè shape_centre // pot no estar exactament al mig del bounding box - lletra.posicio.x = x_actual + lletra.offset_centre; - lletra.posicio.y = y_centre; + lletra.position.x = x_actual + lletra.offset_centre; + lletra.position.y = y_centre; // Avançar per a següent lletra x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES; @@ -204,9 +204,9 @@ void LogoScene::inicialitzar_lletres() { void LogoScene::canviar_estat(AnimationState nou_estat) { estat_actual_ = nou_estat; - temps_estat_actual_ = 0.0F; // Reset temps + temps_estat_actual_ = 0.0F; // Reset time - // Inicialitzar estat d'explosió + // Inicialitzar state d'explosió if (nou_estat == AnimationState::EXPLOSION) { lletra_explosio_index_ = 0; temps_des_ultima_explosio_ = 0.0F; @@ -223,7 +223,7 @@ void LogoScene::canviar_estat(AnimationState nou_estat) { Audio::get()->playMusic("title.ogg"); } - std::cout << "[LogoScene] Canvi a estat: " << static_cast(nou_estat) + std::cout << "[LogoScene] Canvi a state: " << static_cast(nou_estat) << "\n"; } @@ -235,21 +235,21 @@ bool LogoScene::totes_lletres_completes() const { void LogoScene::actualitzar_explosions(float delta_time) { temps_des_ultima_explosio_ += delta_time; - // Comprovar si és el moment d'explotar la següent lletra + // Comprovar si és el moment d'explode la següent lletra if (temps_des_ultima_explosio_ >= DELAY_ENTRE_EXPLOSIONS) { if (lletra_explosio_index_ < lletres_.size()) { // Explotar lletra actual (en ordre aleatori) size_t index_actual = ordre_explosio_[lletra_explosio_index_]; const auto& lletra = lletres_[index_actual]; - debris_manager_->explotar( - lletra.forma, // Forma a explotar - lletra.posicio, // Posició + debris_manager_->explode( + lletra.shape, // Forma a explode + lletra.position, // Posició 0.0F, // Angle (sense rotació) - ESCALA_FINAL, // Escala (lletres a escala final) + ESCALA_FINAL, // Escala (lletres a scale final) VELOCITAT_EXPLOSIO, // Velocitat base 1.0F, // Brightness màxim (per defecte) - {.x = 0.0F, .y = 0.0F} // Sense velocitat (per defecte) + {.x = 0.0F, .y = 0.0F} // Sense velocity (per defecte) ); std::cout << "[LogoScene] Explota lletra " << lletra_explosio_index_ << "\n"; @@ -364,21 +364,21 @@ void LogoScene::draw() { Vec2 pos_actual; pos_actual.x = - ORIGEN_ZOOM.x + ((lletra.posicio.x - ORIGEN_ZOOM.x) * letra_progress); + ORIGEN_ZOOM.x + ((lletra.position.x - ORIGEN_ZOOM.x) * letra_progress); pos_actual.y = - ORIGEN_ZOOM.y + ((lletra.posicio.y - ORIGEN_ZOOM.y) * letra_progress); + ORIGEN_ZOOM.y + ((lletra.position.y - ORIGEN_ZOOM.y) * letra_progress); float t = letra_progress; float ease_factor = 1.0F - ((1.0F - t) * (1.0F - t)); - float escala_actual = + float current_scale = ESCALA_INICIAL + ((ESCALA_FINAL - ESCALA_INICIAL) * ease_factor); Rendering::render_shape( - sdl_.obte_renderer(), - lletra.forma, + sdl_.getRenderer(), + lletra.shape, pos_actual, 0.0F, - escala_actual, + current_scale, 1.0F); } } @@ -397,9 +397,9 @@ void LogoScene::draw() { const auto& lletra = lletres_[i]; Rendering::render_shape( - sdl_.obte_renderer(), - lletra.forma, - lletra.posicio, + sdl_.getRenderer(), + lletra.shape, + lletra.position, 0.0F, ESCALA_FINAL, 1.0F); @@ -409,7 +409,7 @@ void LogoScene::draw() { // POST_EXPLOSION: No draw lletres, només debris (a baix) - // Sempre draw debris (si n'hi ha d'actius) + // Sempre draw debris (si n'hi ha d'active) debris_manager_->draw(); sdl_.presenta(); diff --git a/source/game/scenes/logo_scene.hpp b/source/game/scenes/logo_scene.hpp index 9195753..addbf76 100644 --- a/source/game/scenes/logo_scene.hpp +++ b/source/game/scenes/logo_scene.hpp @@ -38,20 +38,20 @@ class LogoScene { SceneManager::SceneContext& context_; AnimationState estat_actual_; // Estat actual de la màquina float - temps_estat_actual_; // Temps en l'estat actual (reset en cada transició) + temps_estat_actual_; // Temps en l'state actual (reset en cada transició) // Gestor de fragments d'explosions std::unique_ptr debris_manager_; // Seguiment d'explosions seqüencials - size_t lletra_explosio_index_; // Índex de la següent lletra a explotar + size_t lletra_explosio_index_; // Índex de la següent lletra a explode float temps_des_ultima_explosio_; // Temps des de l'última explosió std::vector ordre_explosio_; // Ordre aleatori d'índexs de lletres // Estructura per a cada lletra del logo struct LetraLogo { - std::shared_ptr forma; - Vec2 posicio; // Posició final en pantalla + std::shared_ptr shape; + Vec2 position; // Posició final en pantalla float ancho; // Ancho del bounding box float offset_centre; // Distància de min_x a shape_centre.x }; diff --git a/source/game/scenes/title_scene.cpp b/source/game/scenes/title_scene.cpp index 77b315f..c1594eb 100644 --- a/source/game/scenes/title_scene.cpp +++ b/source/game/scenes/title_scene.cpp @@ -27,7 +27,7 @@ using Option = SceneContext::Option; TitleScene::TitleScene(SDLManager& sdl, SceneContext& context) : sdl_(sdl), context_(context), - text_(sdl.obte_renderer()), + text_(sdl.getRenderer()), estat_actual_(TitleState::STARFIELD_FADE_IN), temps_acumulat_(0.0F), temps_animacio_(0.0F), @@ -36,7 +36,7 @@ TitleScene::TitleScene(SDLManager& sdl, SceneContext& context) factor_lerp_(0.0F) { std::cout << "SceneType Titol: Inicialitzant...\n"; - // Inicialitzar configuració de partida (cap jugador actiu per defecte) + // Inicialitzar configuració de match (cap player active per defecte) match_config_.jugador1_actiu = false; match_config_.jugador2_actiu = false; match_config_.mode = GameConfig::Mode::NORMAL; @@ -62,7 +62,7 @@ TitleScene::TitleScene(SDLManager& sdl, SceneContext& context) static_cast(Defaults::Game::HEIGHT)}; starfield_ = std::make_unique( - sdl_.obte_renderer(), + sdl_.getRenderer(), centre_pantalla, area_completa, 150 // densitat: 150 estrelles (50 per capa) @@ -78,7 +78,7 @@ TitleScene::TitleScene(SDLManager& sdl, SceneContext& context) } // Inicialitzar animador de naus 3D - ship_animator_ = std::make_unique(sdl_.obte_renderer()); + ship_animator_ = std::make_unique(sdl_.getRenderer()); ship_animator_->init(); if (estat_actual_ == TitleState::MAIN) { @@ -118,24 +118,24 @@ void TitleScene::inicialitzar_titol() { float ancho_total_orni = 0.0F; for (const auto& fitxer : fitxers_orni) { - auto forma = ShapeLoader::load(fitxer); - if (!forma || !forma->es_valida()) { + auto shape = ShapeLoader::load(fitxer); + if (!shape || !shape->isValid()) { std::cerr << "[TitleScene] Error carregant " << fitxer << '\n'; continue; } - // Calcular bounding box de la forma (trobar ancho i altura) + // Calcular bounding box de la shape (trobar ancho i altura) float min_x = FLT_MAX; float max_x = -FLT_MAX; float min_y = FLT_MAX; float max_y = -FLT_MAX; - for (const auto& prim : forma->get_primitives()) { - for (const auto& punt : prim.points) { - min_x = std::min(min_x, punt.x); - max_x = std::max(max_x, punt.x); - min_y = std::min(min_y, punt.y); - max_y = std::max(max_y, punt.y); + for (const auto& prim : shape->get_primitives()) { + for (const auto& point : prim.points) { + min_x = std::min(min_x, point.x); + max_x = std::max(max_x, point.x); + min_y = std::min(min_y, point.y); + max_y = std::max(max_y, point.y); } } @@ -145,9 +145,9 @@ void TitleScene::inicialitzar_titol() { // Escalar ancho, altura i offset amb LOGO_SCALE float ancho = ancho_sin_escalar * Defaults::Title::Layout::LOGO_SCALE; float altura = altura_sin_escalar * Defaults::Title::Layout::LOGO_SCALE; - float offset_centre = (forma->getCenter().x - min_x) * Defaults::Title::Layout::LOGO_SCALE; + float offset_centre = (shape->getCenter().x - min_x) * Defaults::Title::Layout::LOGO_SCALE; - lletres_orni_.push_back({forma, {.x = 0.0F, .y = 0.0F}, ancho, altura, offset_centre}); + lletres_orni_.push_back({shape, {.x = 0.0F, .y = 0.0F}, ancho, altura, offset_centre}); ancho_total_orni += ancho; } @@ -160,8 +160,8 @@ void TitleScene::inicialitzar_titol() { float x_actual = x_inicial_orni; for (auto& lletra : lletres_orni_) { - lletra.posicio.x = x_actual + lletra.offset_centre; - lletra.posicio.y = Defaults::Game::HEIGHT * Defaults::Title::Layout::LOGO_POS; + lletra.position.x = x_actual + lletra.offset_centre; + lletra.position.y = Defaults::Game::HEIGHT * Defaults::Title::Layout::LOGO_POS; x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES; } @@ -192,24 +192,24 @@ void TitleScene::inicialitzar_titol() { float ancho_total_attack = 0.0F; for (const auto& fitxer : fitxers_attack) { - auto forma = ShapeLoader::load(fitxer); - if (!forma || !forma->es_valida()) { + auto shape = ShapeLoader::load(fitxer); + if (!shape || !shape->isValid()) { std::cerr << "[TitleScene] Error carregant " << fitxer << '\n'; continue; } - // Calcular bounding box de la forma (trobar ancho i altura) + // Calcular bounding box de la shape (trobar ancho i altura) float min_x = FLT_MAX; float max_x = -FLT_MAX; float min_y = FLT_MAX; float max_y = -FLT_MAX; - for (const auto& prim : forma->get_primitives()) { - for (const auto& punt : prim.points) { - min_x = std::min(min_x, punt.x); - max_x = std::max(max_x, punt.x); - min_y = std::min(min_y, punt.y); - max_y = std::max(max_y, punt.y); + for (const auto& prim : shape->get_primitives()) { + for (const auto& point : prim.points) { + min_x = std::min(min_x, point.x); + max_x = std::max(max_x, point.x); + min_y = std::min(min_y, point.y); + max_y = std::max(max_y, point.y); } } @@ -219,9 +219,9 @@ void TitleScene::inicialitzar_titol() { // Escalar ancho, altura i offset amb LOGO_SCALE float ancho = ancho_sin_escalar * Defaults::Title::Layout::LOGO_SCALE; float altura = altura_sin_escalar * Defaults::Title::Layout::LOGO_SCALE; - float offset_centre = (forma->getCenter().x - min_x) * Defaults::Title::Layout::LOGO_SCALE; + float offset_centre = (shape->getCenter().x - min_x) * Defaults::Title::Layout::LOGO_SCALE; - lletres_attack_.push_back({forma, {.x = 0.0F, .y = 0.0F}, ancho, altura, offset_centre}); + lletres_attack_.push_back({shape, {.x = 0.0F, .y = 0.0F}, ancho, altura, offset_centre}); ancho_total_attack += ancho; } @@ -234,8 +234,8 @@ void TitleScene::inicialitzar_titol() { x_actual = x_inicial_attack; for (auto& lletra : lletres_attack_) { - lletra.posicio.x = x_actual + lletra.offset_centre; - lletra.posicio.y = y_attack_dinamica_; // Usar posició dinàmica + lletra.position.x = x_actual + lletra.offset_centre; + lletra.position.y = y_attack_dinamica_; // Usar posició dinàmica x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES; } @@ -245,12 +245,12 @@ void TitleScene::inicialitzar_titol() { // Guardar posicions originals per l'animació orbital posicions_originals_orni_.clear(); for (const auto& lletra : lletres_orni_) { - posicions_originals_orni_.push_back(lletra.posicio); + posicions_originals_orni_.push_back(lletra.position); } posicions_originals_attack_.clear(); for (const auto& lletra : lletres_attack_) { - posicions_originals_attack_.push_back(lletra.posicio); + posicions_originals_attack_.push_back(lletra.position); } std::cout << "[TitleScene] Animació: Posicions originals guardades\n"; @@ -306,7 +306,7 @@ void TitleScene::run() { // Netejar pantalla sdl_.neteja(0, 0, 0); - // Actualitzar context de renderitzat (factor d'escala global) + // Actualitzar context de renderitzat (factor d'scale global) sdl_.updateRenderingContext(); // Dibuixar @@ -320,7 +320,7 @@ void TitleScene::run() { } void TitleScene::update(float delta_time) { - // Actualitzar starfield (sempre actiu) + // Actualitzar starfield (sempre active) if (starfield_) { starfield_->update(delta_time); } @@ -348,7 +348,7 @@ void TitleScene::update(float delta_time) { // Transició a STARFIELD quan el fade es completa if (temps_acumulat_ >= DURACIO_FADE_IN) { estat_actual_ = TitleState::STARFIELD; - temps_acumulat_ = 0.0F; // Reset timer per al següent estat + temps_acumulat_ = 0.0F; // Reset timer per al següent state starfield_->set_brightness(BRIGHTNESS_STARFIELD); // Assegurar valor final } break; @@ -405,7 +405,7 @@ void TitleScene::update(float delta_time) { // Continuar animació orbital durant la transició actualitzar_animacio_logo(delta_time); - // [NOU] Continuar comprovant si l'altre jugador vol unir-se durant la transició ("late join") + // [NOU] Continuar comprovant si l'altre player vol unir-se durant la transició ("late join") { bool p1_actiu_abans = match_config_.jugador1_actiu; bool p2_actiu_abans = match_config_.jugador2_actiu; @@ -414,7 +414,7 @@ void TitleScene::update(float delta_time) { // Updates match_config_ if pressed, logs are in the method context_.setMatchConfig(match_config_); - // Trigger animació de sortida per la nau que acaba d'unir-se + // Trigger animació de sortida per la ship que acaba d'unir-se if (ship_animator_) { if (match_config_.jugador1_actiu && !p1_actiu_abans) { ship_animator_->trigger_exit_animation_for_player(1); @@ -426,13 +426,13 @@ void TitleScene::update(float delta_time) { } } - // Reproducir so de START quan el segon jugador s'uneix + // Reproducir so de START quan el segon player s'uneix Audio::get()->playSound(Defaults::Sound::START, Audio::Group::GAME); - // Reiniciar el timer per allargar el temps de transició + // Reiniciar el timer per allargar el time de transició temps_acumulat_ = 0.0F; - std::cout << "[TitleScene] Segon jugador s'ha unit - so i timer reiniciats\n"; + std::cout << "[TitleScene] Segon player s'ha unit - so i timer reiniciats\n"; } } @@ -468,9 +468,9 @@ void TitleScene::update(float delta_time) { } } - // Verificar boton START para iniciar partida desde MAIN + // Verificar boton START para iniciar match desde MAIN if (estat_actual_ == TitleState::MAIN) { - // Guardar estat anterior per detectar qui ha premut START AQUEST frame + // Guardar state anterior per detectar qui ha premut START AQUEST frame bool p1_actiu_abans = match_config_.jugador1_actiu; bool p2_actiu_abans = match_config_.jugador2_actiu; @@ -481,9 +481,9 @@ void TitleScene::update(float delta_time) { ship_animator_->skip_to_floating_state(); } - // Configurar partida abans de canviar d'escena + // Configurar match abans de canviar d'escena context_.setMatchConfig(match_config_); - std::cout << "[TitleScene] Configuració de partida - P1: " + std::cout << "[TitleScene] Configuració de match - P1: " << (match_config_.jugador1_actiu ? "ACTIU" : "INACTIU") << ", P2: " << (match_config_.jugador2_actiu ? "ACTIU" : "INACTIU") @@ -514,7 +514,7 @@ void TitleScene::update(float delta_time) { void TitleScene::actualitzar_animacio_logo(float delta_time) { // Només calcular i aplicar offsets si l'animació està activa if (animacio_activa_) { - // Acumular temps escalat + // Acumular time escalat temps_animacio_ += delta_time * factor_lerp_; // Usar amplituds i freqüències completes @@ -529,14 +529,14 @@ void TitleScene::actualitzar_animacio_logo(float delta_time) { // Aplicar offset a totes les lletres de "ORNI" for (size_t i = 0; i < lletres_orni_.size(); ++i) { - lletres_orni_[i].posicio.x = posicions_originals_orni_[i].x + static_cast(std::round(offset_x)); - lletres_orni_[i].posicio.y = posicions_originals_orni_[i].y + static_cast(std::round(offset_y)); + lletres_orni_[i].position.x = posicions_originals_orni_[i].x + static_cast(std::round(offset_x)); + lletres_orni_[i].position.y = posicions_originals_orni_[i].y + static_cast(std::round(offset_y)); } // Aplicar offset a totes les lletres de "ATTACK!" for (size_t i = 0; i < lletres_attack_.size(); ++i) { - lletres_attack_[i].posicio.x = posicions_originals_attack_[i].x + static_cast(std::round(offset_x)); - lletres_attack_[i].posicio.y = posicions_originals_attack_[i].y + static_cast(std::round(offset_y)); + lletres_attack_[i].position.x = posicions_originals_attack_[i].x + static_cast(std::round(offset_x)); + lletres_attack_[i].position.y = posicions_originals_attack_[i].y + static_cast(std::round(offset_y)); } } } @@ -567,7 +567,7 @@ void TitleScene::draw() { // === Calcular i renderitzar ombra (només si animació activa) === if (animacio_activa_) { float temps_shadow = temps_animacio_ - SHADOW_DELAY; - temps_shadow = std::max(temps_shadow, 0.0F); // Evitar temps negatiu + temps_shadow = std::max(temps_shadow, 0.0F); // Evitar time negatiu // Usar amplituds i freqüències completes per l'ombra float amplitude_x_shadow = ORBIT_AMPLITUDE_X; @@ -588,13 +588,13 @@ void TitleScene::draw() { pos_shadow.y = posicions_originals_orni_[i].y + static_cast(std::round(shadow_offset_y)); Rendering::render_shape( - sdl_.obte_renderer(), - lletres_orni_[i].forma, + sdl_.getRenderer(), + lletres_orni_[i].shape, pos_shadow, 0.0F, Defaults::Title::Layout::LOGO_SCALE, 1.0F, // progress = 1.0 (totalment visible) - SHADOW_BRIGHTNESS // brightness = 0.4 (brillantor reduïda) + SHADOW_BRIGHTNESS // brightness = 0.4 (brightness reduïda) ); } @@ -605,8 +605,8 @@ void TitleScene::draw() { pos_shadow.y = posicions_originals_attack_[i].y + static_cast(std::round(shadow_offset_y)); Rendering::render_shape( - sdl_.obte_renderer(), - lletres_attack_[i].forma, + sdl_.getRenderer(), + lletres_attack_[i].shape, pos_shadow, 0.0F, Defaults::Title::Layout::LOGO_SCALE, @@ -620,9 +620,9 @@ void TitleScene::draw() { // Dibuixar "ORNI" (línia 1) for (const auto& lletra : lletres_orni_) { Rendering::render_shape( - sdl_.obte_renderer(), - lletra.forma, - lletra.posicio, + sdl_.getRenderer(), + lletra.shape, + lletra.position, 0.0F, Defaults::Title::Layout::LOGO_SCALE, 1.0F // Brillantor completa @@ -632,9 +632,9 @@ void TitleScene::draw() { // Dibuixar "ATTACK!" (línia 2) for (const auto& lletra : lletres_attack_) { Rendering::render_shape( - sdl_.obte_renderer(), - lletra.forma, - lletra.posicio, + sdl_.getRenderer(), + lletra.shape, + lletra.position, 0.0F, Defaults::Title::Layout::LOGO_SCALE, 1.0F // Brillantor completa @@ -642,15 +642,15 @@ void TitleScene::draw() { } // === Text "PRESS START TO PLAY" === - // En estat MAIN: sempre visible - // En estat TRANSITION: parpellejant (blink amb sinusoide) + // En state MAIN: sempre visible + // En state TRANSITION: parpellejant (blink amb sinusoide) const float spacing = Defaults::Title::Layout::TEXT_SPACING; bool mostrar_text = true; if (estat_actual_ == TitleState::PLAYER_JOIN_PHASE) { // Parpelleig: sin oscil·la entre -1 i 1, volem ON quan > 0 - float fase = temps_acumulat_ * BLINK_FREQUENCY * 2.0F * std::numbers::pi_v; // 2π × freq × temps + float fase = temps_acumulat_ * BLINK_FREQUENCY * 2.0F * std::numbers::pi_v; // 2π × freq × time mostrar_text = (std::sin(fase) > 0.0F); } @@ -661,7 +661,7 @@ void TitleScene::draw() { float centre_x = Defaults::Game::WIDTH / 2.0F; float centre_y = Defaults::Game::HEIGHT * Defaults::Title::Layout::PRESS_START_POS; - text_.render_centered(main_text, {.x = centre_x, .y = centre_y}, escala_main, spacing); + text_.renderCentered(main_text, {.x = centre_x, .y = centre_y}, escala_main, spacing); } // === Copyright a la part inferior (centrat horitzontalment, dues línies) === @@ -692,8 +692,8 @@ void TitleScene::draw() { // Renderitzar línees centrades float centre_x = Defaults::Game::WIDTH / 2.0F; - text_.render_centered(copyright_original, {.x = centre_x, .y = y_line1}, escala_copy, spacing); - text_.render_centered(copyright_port, {.x = centre_x, .y = y_line2}, escala_copy, spacing); + text_.renderCentered(copyright_original, {.x = centre_x, .y = y_line1}, escala_copy, spacing); + text_.renderCentered(copyright_port, {.x = centre_x, .y = y_line2}, escala_copy, spacing); } } diff --git a/source/game/scenes/title_scene.hpp b/source/game/scenes/title_scene.hpp index 82c1271..47194f3 100644 --- a/source/game/scenes/title_scene.hpp +++ b/source/game/scenes/title_scene.hpp @@ -1,5 +1,5 @@ // escena_titol.hpp - Pantalla de títol del joc -// Mostra missatge "PRESS BUTTON TO PLAY" i copyright +// Mostra message "PRESS BUTTON TO PLAY" i copyright // © 2025 Port a C++20 #pragma once @@ -43,8 +43,8 @@ class TitleScene { // Estructura per emmagatzemar informació de cada lletra del títol struct LetraLogo { - std::shared_ptr forma; // Forma vectorial de la lletra - Vec2 posicio; // Posició en pantalla + std::shared_ptr shape; // Forma vectorial de la lletra + Vec2 position; // Posició en pantalla float ancho; // Amplada escalada float altura; // Altura escalada float offset_centre; // Offset del centre per posicionament @@ -52,12 +52,12 @@ class TitleScene { SDLManager& sdl_; SceneManager::SceneContext& context_; - GameConfig::MatchConfig match_config_; // Configuració de jugadors actius + GameConfig::MatchConfig match_config_; // Configuració de jugadors active Graphics::VectorText text_; // Sistema de text vectorial std::unique_ptr starfield_; // Camp d'estrelles de fons std::unique_ptr ship_animator_; // Naus 3D flotants TitleState estat_actual_; // Estat actual de la màquina - float temps_acumulat_; // Temps acumulat per l'estat INIT + float temps_acumulat_; // Temps acumulat per l'state INIT // Lletres del títol "ORNI ATTACK!" std::vector lletres_orni_; // Lletres de "ORNI" (línia 1) @@ -70,14 +70,14 @@ class TitleScene { std::vector posicions_originals_attack_; // Posicions originals de "ATTACK!" // Estat d'arrencada de l'animació - float temps_estat_main_; // Temps acumulat en estat MAIN + float temps_estat_main_; // Temps acumulat en state MAIN bool animacio_activa_; // Flag: true quan animació està activa float factor_lerp_; // Factor de lerp actual (0.0 → 1.0) // Constants static constexpr float BRIGHTNESS_STARFIELD = 1.2F; // Brightness del starfield (>1.0 = més brillant) static constexpr float DURACIO_FADE_IN = 3.0F; // Duració del fade-in del starfield (1.5 segons) - static constexpr float DURACIO_INIT = 4.0F; // Duració de l'estat INIT (2 segons) + static constexpr float DURACIO_INIT = 4.0F; // Duració de l'state INIT (2 segons) static constexpr float DURACIO_TRANSITION = 2.5F; // Duració de la transició (1.5 segons) static constexpr float ESPAI_ENTRE_LLETRES = 10.0F; // Espai entre lletres static constexpr float BLINK_FREQUENCY = 3.0F; // Freqüència de parpelleig (3 Hz) @@ -93,7 +93,7 @@ class TitleScene { // Constants d'ombra del logo static constexpr float SHADOW_DELAY = 0.5F; // Retard temporal de l'ombra (segons) - static constexpr float SHADOW_BRIGHTNESS = 0.4F; // Multiplicador de brillantor de l'ombra (0.0-1.0) + static constexpr float SHADOW_BRIGHTNESS = 0.4F; // Multiplicador de brightness de l'ombra (0.0-1.0) static constexpr float SHADOW_OFFSET_X = 2.0F; // Offset espacial X fix (píxels) static constexpr float SHADOW_OFFSET_Y = 2.0F; // Offset espacial Y fix (píxels) diff --git a/source/game/stage_system/spawn_controller.cpp b/source/game/stage_system/spawn_controller.cpp index 844f053..ad654b1 100644 --- a/source/game/stage_system/spawn_controller.cpp +++ b/source/game/stage_system/spawn_controller.cpp @@ -21,7 +21,7 @@ SpawnController::SpawnController() index_spawn_actual_(0), ship_position_(nullptr) {} -void SpawnController::configurar(const ConfigStage* config) { +void SpawnController::configurar(const StageConfig* config) { config_ = config; } @@ -65,9 +65,9 @@ void SpawnController::update(float delta_time, std::array& orni_array if (temps_transcorregut_ >= event.temps_spawn) { // Find first inactive enemy - for (auto& enemic : orni_array) { - if (!enemic.isActive()) { - spawn_enemic(enemic, event.tipus, ship_position_); + for (auto& enemy : orni_array) { + if (!enemy.isActive()) { + spawn_enemic(enemy, event.type, ship_position_); event.spawnejat = true; index_spawn_actual_++; break; @@ -94,8 +94,8 @@ bool SpawnController::tots_enemics_destruits(const std::array& orni_a return false; } - for (const auto& enemic : orni_array) { - if (enemic.isActive()) { + for (const auto& enemy : orni_array) { + if (enemy.isActive()) { return false; } } @@ -105,8 +105,8 @@ bool SpawnController::tots_enemics_destruits(const std::array& orni_a uint8_t SpawnController::get_enemics_vius(const std::array& orni_array) const { uint8_t count = 0; - for (const auto& enemic : orni_array) { - if (enemic.isActive()) { + for (const auto& enemy : orni_array) { + if (enemy.isActive()) { count++; } } @@ -126,9 +126,9 @@ void SpawnController::generar_spawn_events() { float spawn_time = config_->config_spawn.delay_inicial + (i * config_->config_spawn.interval_spawn); - EnemyType tipus = seleccionar_tipus_aleatori(); + EnemyType type = seleccionar_tipus_aleatori(); - spawn_queue_.push_back({spawn_time, tipus, false}); + spawn_queue_.push_back({spawn_time, type, false}); } } @@ -149,29 +149,29 @@ EnemyType SpawnController::seleccionar_tipus_aleatori() const { return EnemyType::MOLINILLO; } -void SpawnController::spawn_enemic(Enemy& enemic, EnemyType tipus, const Vec2* ship_pos) { +void SpawnController::spawn_enemic(Enemy& enemy, EnemyType type, const Vec2* ship_pos) { // Initialize enemy (with safe spawn if ship_pos provided) - enemic.init(tipus, ship_pos); + enemy.init(type, ship_pos); // Apply difficulty multipliers - aplicar_multiplicadors(enemic); + aplicar_multiplicadors(enemy); } -void SpawnController::aplicar_multiplicadors(Enemy& enemic) const { +void SpawnController::aplicar_multiplicadors(Enemy& enemy) const { if (config_ == nullptr) { return; } // Apply velocity multiplier - float base_vel = enemic.get_base_velocity(); - enemic.set_velocity(base_vel * config_->multiplicadors.velocitat); + float base_vel = enemy.get_base_velocity(); + enemy.set_velocity(base_vel * config_->multiplicadors.velocity); // Apply rotation multiplier - float base_rot = enemic.get_base_rotation(); - enemic.set_rotation(base_rot * config_->multiplicadors.rotacio); + float base_rot = enemy.get_base_rotation(); + enemy.set_rotation(base_rot * config_->multiplicadors.rotation); // Apply tracking strength (only affects QUADRAT) - enemic.set_tracking_strength(config_->multiplicadors.tracking_strength); + enemy.set_tracking_strength(config_->multiplicadors.tracking_strength); } } // namespace StageSystem diff --git a/source/game/stage_system/spawn_controller.hpp b/source/game/stage_system/spawn_controller.hpp index f5cf23b..2f5923d 100644 --- a/source/game/stage_system/spawn_controller.hpp +++ b/source/game/stage_system/spawn_controller.hpp @@ -16,7 +16,7 @@ namespace StageSystem { // Informació de spawn planificat struct SpawnEvent { float temps_spawn; // Temps absolut (segons) per spawnejar - EnemyType tipus; // Tipus d'enemic + EnemyType type; // Tipus d'enemy bool spawnejat; // Ja s'ha processat? }; @@ -25,7 +25,7 @@ class SpawnController { SpawnController(); // Configuration - void configurar(const ConfigStage* config); // Set stage config + void configurar(const StageConfig* config); // Set stage config void iniciar(); // Generate spawn schedule void reset(); // Clear all pending spawns @@ -42,7 +42,7 @@ class SpawnController { void set_ship_position(const Vec2* ship_pos) { ship_position_ = ship_pos; } private: - const ConfigStage* config_; // Non-owning pointer to current stage config + const StageConfig* config_; // Non-owning pointer to current stage config std::vector spawn_queue_; float temps_transcorregut_; // Elapsed time since stage start uint8_t index_spawn_actual_; // Next spawn to process @@ -50,8 +50,8 @@ class SpawnController { // Spawn generation void generar_spawn_events(); [[nodiscard]] EnemyType seleccionar_tipus_aleatori() const; - void spawn_enemic(Enemy& enemic, EnemyType tipus, const Vec2* ship_pos = nullptr); - void aplicar_multiplicadors(Enemy& enemic) const; + void spawn_enemic(Enemy& enemy, EnemyType type, const Vec2* ship_pos = nullptr); + void aplicar_multiplicadors(Enemy& enemy) const; const Vec2* ship_position_; // [NEW] Non-owning pointer to ship position }; diff --git a/source/game/stage_system/stage_config.hpp b/source/game/stage_system/stage_config.hpp index ff41e34..9e347c6 100644 --- a/source/game/stage_system/stage_config.hpp +++ b/source/game/stage_system/stage_config.hpp @@ -24,7 +24,7 @@ struct ConfigSpawn { float interval_spawn; // Segons entre spawns consecutius }; -// Distribució de tipus d'enemics (percentatges) +// Distribució de type d'enemics (percentatges) struct DistribucioEnemics { uint8_t pentagon; // 0-100 uint8_t quadrat; // 0-100 @@ -34,8 +34,8 @@ struct DistribucioEnemics { // Multiplicadors de dificultat struct MultiplicadorsDificultat { - float velocitat; // 0.5-2.0 típic - float rotacio; // 0.5-2.0 típic + float velocity; // 0.5-2.0 típic + float rotation; // 0.5-2.0 típic float tracking_strength; // 0.0-1.5 (aplicat a Quadrat) }; @@ -47,7 +47,7 @@ struct MetadataStages { }; // Configuració completa d'un stage -struct ConfigStage { +struct StageConfig { uint8_t stage_id; // 1-10 uint8_t total_enemics; // 5-15 ConfigSpawn config_spawn; @@ -63,12 +63,12 @@ struct ConfigStage { }; // Configuració completa del sistema (carregada des de YAML) -struct ConfigSistemaStages { +struct StageSystemConfig { MetadataStages metadata; - std::vector stages; // Índex [0] = stage 1 + std::vector stages; // Índex [0] = stage 1 // Obtenir configuració d'un stage específic - [[nodiscard]] const ConfigStage* obte_stage(uint8_t stage_id) const { + [[nodiscard]] const StageConfig* obte_stage(uint8_t stage_id) const { if (stage_id < 1 || stage_id > stages.size()) { return nullptr; } diff --git a/source/game/stage_system/stage_loader.cpp b/source/game/stage_system/stage_loader.cpp index d1046f3..b233028 100644 --- a/source/game/stage_system/stage_loader.cpp +++ b/source/game/stage_system/stage_loader.cpp @@ -19,7 +19,7 @@ namespace StageSystem { -std::unique_ptr StageLoader::carregar(const std::string& path) { +std::unique_ptr StageLoader::load(const std::string& path) { try { // Normalize path: "data/stages/stages.yaml" → "stages/stages.yaml" std::string normalized = path; @@ -30,7 +30,7 @@ std::unique_ptr StageLoader::carregar(const std::string& pa // Load from resource system std::vector data = Resource::Helper::loadFile(normalized); if (data.empty()) { - std::cerr << "[StageLoader] Error: no es pot carregar " << normalized << '\n'; + std::cerr << "[StageLoader] Error: no es pot load " << normalized << '\n'; return nullptr; } @@ -40,7 +40,7 @@ std::unique_ptr StageLoader::carregar(const std::string& pa // Parse YAML fkyaml::node yaml = fkyaml::node::deserialize(stream); - auto config = std::make_unique(); + auto config = std::make_unique(); // Parse metadata if (!yaml.contains("metadata")) { @@ -63,7 +63,7 @@ std::unique_ptr StageLoader::carregar(const std::string& pa } for (const auto& stage_yaml : yaml["stages"]) { - ConfigStage stage; + StageConfig stage; if (!parse_stage(stage_yaml, stage)) { return nullptr; } @@ -105,7 +105,7 @@ bool StageLoader::parse_metadata(const fkyaml::node& yaml, MetadataStages& meta) } } -bool StageLoader::parse_stage(const fkyaml::node& yaml, ConfigStage& stage) { +bool StageLoader::parse_stage(const fkyaml::node& yaml, StageConfig& stage) { try { if (!yaml.contains("stage_id") || !yaml.contains("total_enemies") || !yaml.contains("spawn_config") || !yaml.contains("enemy_distribution") || @@ -194,15 +194,15 @@ bool StageLoader::parse_multipliers(const fkyaml::node& yaml, MultiplicadorsDifi return false; } - mult.velocitat = yaml["speed_multiplier"].get_value(); - mult.rotacio = yaml["rotation_multiplier"].get_value(); + mult.velocity = yaml["speed_multiplier"].get_value(); + mult.rotation = yaml["rotation_multiplier"].get_value(); mult.tracking_strength = yaml["tracking_strength"].get_value(); // Validar rangs raonables - if (mult.velocitat < 0.1F || mult.velocitat > 5.0F) { + if (mult.velocity < 0.1F || mult.velocity > 5.0F) { std::cerr << "[StageLoader] Warning: speed_multiplier fora de rang (0.1-5.0)" << '\n'; } - if (mult.rotacio < 0.1F || mult.rotacio > 5.0F) { + if (mult.rotation < 0.1F || mult.rotation > 5.0F) { std::cerr << "[StageLoader] Warning: rotation_multiplier fora de rang (0.1-5.0)" << '\n'; } if (mult.tracking_strength < 0.0F || mult.tracking_strength > 2.0F) { @@ -231,7 +231,7 @@ ModeSpawn StageLoader::parse_spawn_mode(const std::string& mode_str) { return ModeSpawn::PROGRESSIVE; } -bool StageLoader::validar_config(const ConfigSistemaStages& config) { +bool StageLoader::validar_config(const StageSystemConfig& config) { if (config.stages.empty()) { std::cerr << "[StageLoader] Error: cap stage carregat" << '\n'; return false; diff --git a/source/game/stage_system/stage_loader.hpp b/source/game/stage_system/stage_loader.hpp index 61238a3..f58a0cd 100644 --- a/source/game/stage_system/stage_loader.hpp +++ b/source/game/stage_system/stage_loader.hpp @@ -15,19 +15,19 @@ class StageLoader { public: // Carregar configuració des de fitxer YAML // Retorna nullptr si hi ha errors - static std::unique_ptr carregar(const std::string& path); + static std::unique_ptr load(const std::string& path); private: // Parsing helpers (implementats en .cpp) static bool parse_metadata(const fkyaml::node& yaml, MetadataStages& meta); - static bool parse_stage(const fkyaml::node& yaml, ConfigStage& stage); + static bool parse_stage(const fkyaml::node& yaml, StageConfig& stage); static bool parse_spawn_config(const fkyaml::node& yaml, ConfigSpawn& config); static bool parse_distribution(const fkyaml::node& yaml, DistribucioEnemics& dist); static bool parse_multipliers(const fkyaml::node& yaml, MultiplicadorsDificultat& mult); static ModeSpawn parse_spawn_mode(const std::string& mode_str); // Validació - static bool validar_config(const ConfigSistemaStages& config); + static bool validar_config(const StageSystemConfig& config); }; } // namespace StageSystem diff --git a/source/game/stage_system/stage_manager.cpp b/source/game/stage_system/stage_manager.cpp index 7b1bc31..2ab2bc6 100644 --- a/source/game/stage_system/stage_manager.cpp +++ b/source/game/stage_system/stage_manager.cpp @@ -14,7 +14,7 @@ namespace StageSystem { -StageManager::StageManager(const ConfigSistemaStages* config) +StageManager::StageManager(const StageSystemConfig* config) : config_(config), estat_(EstatStage::LEVEL_START), stage_actual_(1), @@ -65,7 +65,7 @@ bool StageManager::tot_completat() const { timer_transicio_ <= 0.0F; } -const ConfigStage* StageManager::get_config_actual() const { +const StageConfig* StageManager::get_config_actual() const { return config_->obte_stage(stage_actual_); } @@ -87,13 +87,13 @@ void StageManager::canviar_estat(EstatStage nou_estat) { missatge_level_start_actual_ = Constants::MISSATGES_LEVEL_START[index]; // [NOU] Iniciar música al entrar en LEVEL_START (després de INIT_HUD) - // Només si no està sonant ja (per evitar reiniciar en loops posteriors) + // Només si no està sonant ja (per evitar reset en loops posteriors) if (Audio::get()->getMusicState() != Audio::MusicState::PLAYING) { Audio::get()->playMusic("game.ogg"); } } - std::cout << "[StageManager] Canvi d'estat: "; + std::cout << "[StageManager] Canvi d'state: "; switch (nou_estat) { case EstatStage::INIT_HUD: std::cout << "INIT_HUD"; @@ -156,7 +156,7 @@ void StageManager::processar_level_completed(float delta_time) { } void StageManager::carregar_stage(uint8_t stage_id) { - const ConfigStage* stage_config = config_->obte_stage(stage_id); + const StageConfig* stage_config = config_->obte_stage(stage_id); if (stage_config == nullptr) { std::cerr << "[StageManager] Error: no es pot trobar stage " << static_cast(stage_id) << '\n'; diff --git a/source/game/stage_system/stage_manager.hpp b/source/game/stage_system/stage_manager.hpp index bcf7ee9..eb0f3f6 100644 --- a/source/game/stage_system/stage_manager.hpp +++ b/source/game/stage_system/stage_manager.hpp @@ -1,4 +1,4 @@ -// stage_manager.hpp - Gestor d'estat i progressió d'stages +// stage_manager.hpp - Gestor d'state i progressió d'stages // © 2025 Orni Attack #pragma once @@ -21,7 +21,7 @@ enum class EstatStage { class StageManager { public: - explicit StageManager(const ConfigSistemaStages* config); + explicit StageManager(const StageSystemConfig* config); // Lifecycle void init(); // Reset to stage 1 @@ -34,7 +34,7 @@ class StageManager { // Current state queries [[nodiscard]] EstatStage get_estat() const { return estat_; } [[nodiscard]] uint8_t get_stage_actual() const { return stage_actual_; } - [[nodiscard]] const ConfigStage* get_config_actual() const; + [[nodiscard]] const StageConfig* get_config_actual() const; [[nodiscard]] float get_timer_transicio() const { return timer_transicio_; } [[nodiscard]] const std::string& get_missatge_level_start() const { return missatge_level_start_actual_; } @@ -43,7 +43,7 @@ class StageManager { [[nodiscard]] const SpawnController& get_spawn_controller() const { return spawn_controller_; } private: - const ConfigSistemaStages* config_; // Non-owning pointer + const StageSystemConfig* config_; // Non-owning pointer SpawnController spawn_controller_; EstatStage estat_; diff --git a/source/game/title/ship_animator.cpp b/source/game/title/ship_animator.cpp index dff2f83..ed1909e 100644 --- a/source/game/title/ship_animator.cpp +++ b/source/game/title/ship_animator.cpp @@ -22,53 +22,53 @@ void ShipAnimator::init() { auto forma_p1 = Graphics::ShapeLoader::load("ship_perspective.shp"); // Perspectiva esquerra auto forma_p2 = Graphics::ShapeLoader::load("ship2_perspective.shp"); // Perspectiva dreta - // Configurar nau P1 - naus_[0].jugador_id = 1; - naus_[0].forma = forma_p1; - configurar_nau_p1(naus_[0]); + // Configurar ship P1 + ships_[0].player_id = 1; + ships_[0].shape = forma_p1; + configurar_nau_p1(ships_[0]); - // Configurar nau P2 - naus_[1].jugador_id = 2; - naus_[1].forma = forma_p2; - configurar_nau_p2(naus_[1]); + // Configurar ship P2 + ships_[1].player_id = 2; + ships_[1].shape = forma_p2; + configurar_nau_p2(ships_[1]); } void ShipAnimator::update(float delta_time) { - // Dispatcher segons estat de cada nau - for (auto& nau : naus_) { - if (!nau.visible) { + // Dispatcher segons state de cada ship + for (auto& ship : ships_) { + if (!ship.visible) { continue; } - switch (nau.estat) { - case EstatNau::ENTERING: - actualitzar_entering(nau, delta_time); + switch (ship.state) { + case ShipState::ENTERING: + actualitzar_entering(ship, delta_time); break; - case EstatNau::FLOATING: - actualitzar_floating(nau, delta_time); + case ShipState::FLOATING: + actualitzar_floating(ship, delta_time); break; - case EstatNau::EXITING: - actualitzar_exiting(nau, delta_time); + case ShipState::EXITING: + actualitzar_exiting(ship, delta_time); break; } } } void ShipAnimator::draw() const { - for (const auto& nau : naus_) { - if (!nau.visible) { + for (const auto& ship : ships_) { + if (!ship.visible) { continue; } - // Renderitzar nau (perspectiva ja incorporada a la forma) + // Renderitzar ship (perspectiva ja incorporada a la shape) Rendering::render_shape( renderer_, - nau.forma, - nau.posicio_actual, + ship.shape, + ship.current_position, 0.0F, // angle (rotació 2D no utilitzada) - nau.escala_actual, + ship.current_scale, 1.0F, // progress (sempre visible) - 1.0F // brightness (brillantor màxima) + 1.0F // brightness (brightness màxima) ); } } @@ -76,46 +76,46 @@ void ShipAnimator::draw() const { void ShipAnimator::start_entry_animation() { using namespace Defaults::Title::Ships; - // Configurar nau P1 per a l'animació d'entrada - naus_[0].estat = EstatNau::ENTERING; - naus_[0].temps_estat = 0.0F; - naus_[0].posicio_inicial = calcular_posicio_fora_pantalla(CLOCK_8_ANGLE); - naus_[0].posicio_actual = naus_[0].posicio_inicial; - naus_[0].escala_actual = naus_[0].escala_inicial; + // Configurar ship P1 per a l'animació d'entrada + ships_[0].state = ShipState::ENTERING; + ships_[0].state_time = 0.0F; + ships_[0].initial_position = calcular_posicio_fora_pantalla(CLOCK_8_ANGLE); + ships_[0].current_position = ships_[0].initial_position; + ships_[0].current_scale = ships_[0].initial_scale; - // Configurar nau P2 per a l'animació d'entrada - naus_[1].estat = EstatNau::ENTERING; - naus_[1].temps_estat = 0.0F; - naus_[1].posicio_inicial = calcular_posicio_fora_pantalla(CLOCK_4_ANGLE); - naus_[1].posicio_actual = naus_[1].posicio_inicial; - naus_[1].escala_actual = naus_[1].escala_inicial; + // Configurar ship P2 per a l'animació d'entrada + ships_[1].state = ShipState::ENTERING; + ships_[1].state_time = 0.0F; + ships_[1].initial_position = calcular_posicio_fora_pantalla(CLOCK_4_ANGLE); + ships_[1].current_position = ships_[1].initial_position; + ships_[1].current_scale = ships_[1].initial_scale; } void ShipAnimator::trigger_exit_animation() { // Configurar ambdues naus per a l'animació de sortida - for (auto& nau : naus_) { - // Canviar estat a EXITING - nau.estat = EstatNau::EXITING; - nau.temps_estat = 0.0F; + for (auto& ship : ships_) { + // Canviar state a EXITING + ship.state = ShipState::EXITING; + ship.state_time = 0.0F; // Preservar posició actual (pot estar a mig camí si START es prem durant ENTERING) - nau.posicio_inicial = nau.posicio_actual; + ship.initial_position = ship.current_position; - // La escala objectiu es preserva per a calcular la interpolació - // (escala_actual pot ser diferent si està en ENTERING) + // La scale objectiu es preserva per a calcular la interpolació + // (current_scale pot ser diferent si està en ENTERING) } } void ShipAnimator::skip_to_floating_state() { - // Posar ambdues naus directament en estat FLOATING - for (auto& nau : naus_) { - nau.estat = EstatNau::FLOATING; - nau.temps_estat = 0.0F; - nau.fase_oscilacio = 0.0F; + // Posar ambdues naus directament en state FLOATING + for (auto& ship : ships_) { + ship.state = ShipState::FLOATING; + ship.state_time = 0.0F; + ship.oscillation_phase = 0.0F; // Posar en posició objectiu (sense animació) - nau.posicio_actual = nau.posicio_objectiu; - nau.escala_actual = nau.escala_objectiu; + ship.current_position = ship.target_position; + ship.current_scale = ship.target_scale; // NO establir visibilitat aquí - ja ho fa el caller // (evita fer visibles ambdues naus quan només una ha premut START) @@ -123,201 +123,201 @@ void ShipAnimator::skip_to_floating_state() { } bool ShipAnimator::is_visible() const { - // Retorna true si almenys una nau és visible - for (const auto& nau : naus_) { - if (nau.visible) { + // Retorna true si almenys una ship és visible + for (const auto& ship : ships_) { + if (ship.visible) { return true; } } return false; } -void ShipAnimator::trigger_exit_animation_for_player(int jugador_id) { - // Trobar la nau del jugador especificat - for (auto& nau : naus_) { - if (nau.jugador_id == jugador_id) { - // Canviar estat a EXITING només per aquesta nau - nau.estat = EstatNau::EXITING; - nau.temps_estat = 0.0F; +void ShipAnimator::trigger_exit_animation_for_player(int player_id) { + // Trobar la ship del player especificat + for (auto& ship : ships_) { + if (ship.player_id == player_id) { + // Canviar state a EXITING només per aquesta ship + ship.state = ShipState::EXITING; + ship.state_time = 0.0F; // Preservar posició actual (pot estar a mig camí si START es prem durant ENTERING) - nau.posicio_inicial = nau.posicio_actual; + ship.initial_position = ship.current_position; - // La escala objectiu es preserva per a calcular la interpolació - // (escala_actual pot ser diferent si està en ENTERING) - break; // Només una nau per jugador + // La scale objectiu es preserva per a calcular la interpolació + // (current_scale pot ser diferent si està en ENTERING) + break; // Només una ship per player } } } void ShipAnimator::set_visible(bool visible) { - for (auto& nau : naus_) { - nau.visible = visible; + for (auto& ship : ships_) { + ship.visible = visible; } } bool ShipAnimator::is_animation_complete() const { // Comprovar si totes les naus són invisibles (han completat l'animació de sortida) - for (const auto& nau : naus_) { - if (nau.visible) { - return false; // Encara hi ha alguna nau visible + for (const auto& ship : ships_) { + if (ship.visible) { + return false; // Encara hi ha alguna ship visible } } return true; // Totes les naus són invisibles } // Mètodes d'animació (stubs) -void ShipAnimator::actualitzar_entering(NauTitol& nau, float delta_time) { +void ShipAnimator::actualitzar_entering(TitleShip& ship, float delta_time) { using namespace Defaults::Title::Ships; - nau.temps_estat += delta_time; + ship.state_time += delta_time; // Esperar al delay abans de començar l'animació - if (nau.temps_estat < nau.entry_delay) { - // Encara en delay: la nau es queda fora de pantalla (posició inicial) - nau.posicio_actual = nau.posicio_inicial; - nau.escala_actual = nau.escala_inicial; + if (ship.state_time < ship.entry_delay) { + // Encara en delay: la ship es queda fora de pantalla (posició inicial) + ship.current_position = ship.initial_position; + ship.current_scale = ship.initial_scale; return; } // Càlcul del progrés (restant el delay) - float elapsed = nau.temps_estat - nau.entry_delay; + float elapsed = ship.state_time - ship.entry_delay; float progress = std::min(1.0F, elapsed / ENTRY_DURATION); // Aplicar easing (ease_out_quad per arribada suau) float eased_progress = Easing::ease_out_quad(progress); // Lerp posició (inicial → objectiu) - nau.posicio_actual.x = Easing::lerp(nau.posicio_inicial.x, nau.posicio_objectiu.x, eased_progress); - nau.posicio_actual.y = Easing::lerp(nau.posicio_inicial.y, nau.posicio_objectiu.y, eased_progress); + ship.current_position.x = Easing::lerp(ship.initial_position.x, ship.target_position.x, eased_progress); + ship.current_position.y = Easing::lerp(ship.initial_position.y, ship.target_position.y, eased_progress); - // Lerp escala (gran → normal) - nau.escala_actual = Easing::lerp(nau.escala_inicial, nau.escala_objectiu, eased_progress); + // Lerp scale (gran → normal) + ship.current_scale = Easing::lerp(ship.initial_scale, ship.target_scale, eased_progress); // Transicionar a FLOATING quan completi if (elapsed >= ENTRY_DURATION) { - nau.estat = EstatNau::FLOATING; - nau.temps_estat = 0.0F; - nau.fase_oscilacio = 0.0F; // Reiniciar fase d'oscil·lació + ship.state = ShipState::FLOATING; + ship.state_time = 0.0F; + ship.oscillation_phase = 0.0F; // Reiniciar fase d'oscil·lació } } -void ShipAnimator::actualitzar_floating(NauTitol& nau, float delta_time) { +void ShipAnimator::actualitzar_floating(TitleShip& ship, float delta_time) { using namespace Defaults::Title::Ships; - // Actualitzar temps i fase d'oscil·lació - nau.temps_estat += delta_time; - nau.fase_oscilacio += delta_time; + // Actualitzar time i fase d'oscil·lació + ship.state_time += delta_time; + ship.oscillation_phase += delta_time; - // Oscil·lació sinusoïdal X/Y (paràmetres específics per nau) - float offset_x = nau.amplitude_x * std::sin(2.0F * Defaults::Math::PI * nau.frequency_x * nau.fase_oscilacio); - float offset_y = nau.amplitude_y * std::sin((2.0F * Defaults::Math::PI * nau.frequency_y * nau.fase_oscilacio) + FLOAT_PHASE_OFFSET); + // Oscil·lació sinusoïdal X/Y (paràmetres específics per ship) + float offset_x = ship.amplitude_x * std::sin(2.0F * Defaults::Math::PI * ship.frequency_x * ship.oscillation_phase); + float offset_y = ship.amplitude_y * std::sin((2.0F * Defaults::Math::PI * ship.frequency_y * ship.oscillation_phase) + FLOAT_PHASE_OFFSET); // Aplicar oscil·lació a la posició objectiu - nau.posicio_actual.x = nau.posicio_objectiu.x + offset_x; - nau.posicio_actual.y = nau.posicio_objectiu.y + offset_y; + ship.current_position.x = ship.target_position.x + offset_x; + ship.current_position.y = ship.target_position.y + offset_y; // Escala constant (sense "breathing" per ara) - nau.escala_actual = nau.escala_objectiu; + ship.current_scale = ship.target_scale; } -void ShipAnimator::actualitzar_exiting(NauTitol& nau, float delta_time) { +void ShipAnimator::actualitzar_exiting(TitleShip& ship, float delta_time) { using namespace Defaults::Title::Ships; - nau.temps_estat += delta_time; + ship.state_time += delta_time; // Calcular progrés (0.0 → 1.0) - float progress = std::min(1.0F, nau.temps_estat / EXIT_DURATION); + float progress = std::min(1.0F, ship.state_time / EXIT_DURATION); - // Aplicar easing (ease_in_quad per acceleració cap al punt de fuga) + // Aplicar easing (ease_in_quad per acceleració cap al point de fuga) float eased_progress = Easing::ease_in_quad(progress); // Vec2 de fuga (centre del starfield) constexpr Vec2 punt_fuga{.x = VANISHING_POINT_X, .y = VANISHING_POINT_Y}; - // Lerp posició cap al punt de fuga (preservar posició inicial actual) - // Nota: posicio_inicial conté la posició on estava quan es va activar EXITING - nau.posicio_actual.x = Easing::lerp(nau.posicio_inicial.x, punt_fuga.x, eased_progress); - nau.posicio_actual.y = Easing::lerp(nau.posicio_inicial.y, punt_fuga.y, eased_progress); + // Lerp posició cap al point de fuga (preservar posició inicial actual) + // Nota: initial_position conté la posició on estava quan es va activar EXITING + ship.current_position.x = Easing::lerp(ship.initial_position.x, punt_fuga.x, eased_progress); + ship.current_position.y = Easing::lerp(ship.initial_position.y, punt_fuga.y, eased_progress); // Escala redueix a 0 (simula Z → infinit) - nau.escala_actual = nau.escala_objectiu * (1.0F - eased_progress); + ship.current_scale = ship.target_scale * (1.0F - eased_progress); // Marcar invisible quan l'animació completi if (progress >= 1.0F) { - nau.visible = false; + ship.visible = false; } } // Configuració -void ShipAnimator::configurar_nau_p1(NauTitol& nau) { +void ShipAnimator::configurar_nau_p1(TitleShip& ship) { using namespace Defaults::Title::Ships; // Estat inicial: FLOATING (per test estàtic) - nau.estat = EstatNau::FLOATING; - nau.temps_estat = 0.0F; + ship.state = ShipState::FLOATING; + ship.state_time = 0.0F; // Posicions (clock 8, bottom-left) - nau.posicio_objectiu = {.x = P1_TARGET_X(), .y = P1_TARGET_Y()}; + ship.target_position = {.x = P1_TARGET_X(), .y = P1_TARGET_Y()}; // Calcular posició inicial (fora de pantalla) - nau.posicio_inicial = calcular_posicio_fora_pantalla(CLOCK_8_ANGLE); - nau.posicio_actual = nau.posicio_inicial; // Començar fora de pantalla + ship.initial_position = calcular_posicio_fora_pantalla(CLOCK_8_ANGLE); + ship.current_position = ship.initial_position; // Començar fora de pantalla // Escales - nau.escala_objectiu = FLOATING_SCALE; - nau.escala_actual = FLOATING_SCALE; - nau.escala_inicial = ENTRY_SCALE_START; + ship.target_scale = FLOATING_SCALE; + ship.current_scale = FLOATING_SCALE; + ship.initial_scale = ENTRY_SCALE_START; // Flotació - nau.fase_oscilacio = 0.0F; + ship.oscillation_phase = 0.0F; // Paràmetres d'entrada - nau.entry_delay = P1_ENTRY_DELAY; + ship.entry_delay = P1_ENTRY_DELAY; // Paràmetres d'oscil·lació específics P1 - nau.amplitude_x = FLOAT_AMPLITUDE_X; - nau.amplitude_y = FLOAT_AMPLITUDE_Y; - nau.frequency_x = FLOAT_FREQUENCY_X_BASE * P1_FREQUENCY_MULTIPLIER; - nau.frequency_y = FLOAT_FREQUENCY_Y_BASE * P1_FREQUENCY_MULTIPLIER; + ship.amplitude_x = FLOAT_AMPLITUDE_X; + ship.amplitude_y = FLOAT_AMPLITUDE_Y; + ship.frequency_x = FLOAT_FREQUENCY_X_BASE * P1_FREQUENCY_MULTIPLIER; + ship.frequency_y = FLOAT_FREQUENCY_Y_BASE * P1_FREQUENCY_MULTIPLIER; // Visibilitat - nau.visible = true; + ship.visible = true; } -void ShipAnimator::configurar_nau_p2(NauTitol& nau) { +void ShipAnimator::configurar_nau_p2(TitleShip& ship) { using namespace Defaults::Title::Ships; // Estat inicial: FLOATING (per test estàtic) - nau.estat = EstatNau::FLOATING; - nau.temps_estat = 0.0F; + ship.state = ShipState::FLOATING; + ship.state_time = 0.0F; // Posicions (clock 4, bottom-right) - nau.posicio_objectiu = {.x = P2_TARGET_X(), .y = P2_TARGET_Y()}; + ship.target_position = {.x = P2_TARGET_X(), .y = P2_TARGET_Y()}; // Calcular posició inicial (fora de pantalla) - nau.posicio_inicial = calcular_posicio_fora_pantalla(CLOCK_4_ANGLE); - nau.posicio_actual = nau.posicio_inicial; // Començar fora de pantalla + ship.initial_position = calcular_posicio_fora_pantalla(CLOCK_4_ANGLE); + ship.current_position = ship.initial_position; // Començar fora de pantalla // Escales - nau.escala_objectiu = FLOATING_SCALE; - nau.escala_actual = FLOATING_SCALE; - nau.escala_inicial = ENTRY_SCALE_START; + ship.target_scale = FLOATING_SCALE; + ship.current_scale = FLOATING_SCALE; + ship.initial_scale = ENTRY_SCALE_START; // Flotació - nau.fase_oscilacio = 0.0F; + ship.oscillation_phase = 0.0F; // Paràmetres d'entrada - nau.entry_delay = P2_ENTRY_DELAY; + ship.entry_delay = P2_ENTRY_DELAY; // Paràmetres d'oscil·lació específics P2 - nau.amplitude_x = FLOAT_AMPLITUDE_X; - nau.amplitude_y = FLOAT_AMPLITUDE_Y; - nau.frequency_x = FLOAT_FREQUENCY_X_BASE * P2_FREQUENCY_MULTIPLIER; - nau.frequency_y = FLOAT_FREQUENCY_Y_BASE * P2_FREQUENCY_MULTIPLIER; + ship.amplitude_x = FLOAT_AMPLITUDE_X; + ship.amplitude_y = FLOAT_AMPLITUDE_Y; + ship.frequency_x = FLOAT_FREQUENCY_X_BASE * P2_FREQUENCY_MULTIPLIER; + ship.frequency_y = FLOAT_FREQUENCY_Y_BASE * P2_FREQUENCY_MULTIPLIER; // Visibilitat - nau.visible = true; + ship.visible = true; } Vec2 ShipAnimator::calcular_posicio_fora_pantalla(float angle_rellotge) const { diff --git a/source/game/title/ship_animator.hpp b/source/game/title/ship_animator.hpp index 20f7641..d0c6b72 100644 --- a/source/game/title/ship_animator.hpp +++ b/source/game/title/ship_animator.hpp @@ -13,46 +13,46 @@ namespace Title { -// Estats de l'animació de la nau -enum class EstatNau { +// Estats de l'animació de la ship +enum class ShipState { ENTERING, // Entrant des de fora de pantalla FLOATING, // Flotant en posició estàtica - EXITING // Volant cap al punt de fuga + EXITING // Volant cap al point de fuga }; -// Dades d'una nau individual al títol -struct NauTitol { +// Dades d'una ship individual al títol +struct TitleShip { // Identificació - int jugador_id; // 1 o 2 + int player_id; // 1 o 2 // Estat - EstatNau estat; - float temps_estat; // Temps acumulat en l'estat actual + ShipState state; + float state_time; // Temps acumulat en l'state actual // Posicions - Vec2 posicio_inicial; // Posició d'inici (fora de pantalla per ENTERING) - Vec2 posicio_objectiu; // Posició objectiu (rellotge 8 o 4) - Vec2 posicio_actual; // Posició interpolada actual + Vec2 initial_position; // Posició d'inici (fora de pantalla per ENTERING) + Vec2 target_position; // Posició objectiu (rellotge 8 o 4) + Vec2 current_position; // Posició interpolada actual // Escales (simulació eix Z) - float escala_inicial; // Escala d'inici (més gran = més a prop) - float escala_objectiu; // Escala objectiu (mida flotació) - float escala_actual; // Escala interpolada actual + float initial_scale; // Escala d'inici (més gran = més a prop) + float target_scale; // Escala objectiu (mida flotació) + float current_scale; // Escala interpolada actual // Flotació - float fase_oscilacio; // Acumulador de fase per moviment sinusoïdal + float oscillation_phase; // Acumulador de fase per moviment sinusoïdal // Paràmetres d'entrada float entry_delay; // Delay abans d'entrar (0.0 per P1, 0.5 per P2) - // Paràmetres d'oscil·lació per nau + // Paràmetres d'oscil·lació per ship float amplitude_x; float amplitude_y; float frequency_x; float frequency_y; // Forma - std::shared_ptr forma; + std::shared_ptr shape; // Visibilitat bool visible; @@ -68,29 +68,29 @@ class ShipAnimator { void update(float delta_time); void draw() const; - // Control d'estat (cridat per TitleScene) + // Control d'state (cridat per TitleScene) void start_entry_animation(); void trigger_exit_animation(); // Anima totes les naus - void trigger_exit_animation_for_player(int jugador_id); // Anima només una nau (P1=1, P2=2) + void trigger_exit_animation_for_player(int player_id); // Anima només una ship (P1=1, P2=2) void skip_to_floating_state(); // Salta directament a FLOATING sense animació // Control de visibilitat void set_visible(bool visible); [[nodiscard]] bool is_animation_complete() const; - [[nodiscard]] bool is_visible() const; // Comprova si alguna nau és visible + [[nodiscard]] bool is_visible() const; // Comprova si alguna ship és visible private: SDL_Renderer* renderer_; - std::array naus_; // Naus P1 i P2 + std::array ships_; // Naus P1 i P2 // Mètodes d'animació - void actualitzar_entering(NauTitol& nau, float delta_time); - void actualitzar_floating(NauTitol& nau, float delta_time); - void actualitzar_exiting(NauTitol& nau, float delta_time); + void actualitzar_entering(TitleShip& ship, float delta_time); + void actualitzar_floating(TitleShip& ship, float delta_time); + void actualitzar_exiting(TitleShip& ship, float delta_time); // Configuració - void configurar_nau_p1(NauTitol& nau); - void configurar_nau_p2(NauTitol& nau); + void configurar_nau_p1(TitleShip& ship); + void configurar_nau_p2(TitleShip& ship); [[nodiscard]] Vec2 calcular_posicio_fora_pantalla(float angle_rellotge) const; }; From bf83f161b0c3bbef4eeb1c82fa04a00d48750864 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 19 May 2026 12:12:30 +0200 Subject: [PATCH 06/27] Fase 1e: cierre de naming sweep (#pragma once, locals, comentarios castellano) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tres tareas de pulido para cerrar la Fase 1 por completo: #pragma once uniforme: - sdl_manager.hpp y game_scene.hpp pasan de #ifndef/#define guards a #pragma once. Los archivos externos (stb_vorbis.h, fkyaml_node.hpp) se mantienen intactos (codigo de terceros). Variables locales y parametros restantes (catalan -> ingles): - fitxer -> file, moviment -> movement, inici -> start - comptador -> counter, escalada -> scaled - missatges -> messages, llista -> list - alçada -> height, amplada -> width, llargada -> length - origen -> origin, distancia -> distance, valor -> value, desti -> target - neteja -> clear, presenta -> present (SDLManager) - total_enemics -> total_enemies, configurar -> configure, iniciar -> start Comentarios catalan -> castellano: - Cabeceras de fichero actualizadas con nombres nuevos (escena_joc.hpp -> game_scene.hpp, etc.) - Palabras tecnicas: trasllacio->traslacion, col-lisio->colision, inicialitzacio->inicializacion, posicio->posicion, rotacio->rotacion, velocitat->velocidad, acceleracio->aceleracion, explosio->explosion, renderitzat->renderizado, calcul->calculo, transicio->transicion, comprovacio->comprobacion, substitucio->sustitucion, utilitzacio->utilizacion, opcio->opcion, configuracio->configuracion, funcio->funcion, distancia, animacio->animacion - Determinantes y conectores: aquest->este, aquesta->esta, amb->con, sense->sin, pero->pero, mai->nunca, nomes->solo, tambe->tambien, sempre->siempre, ja->ya, mateix->mismo, vegada->vez, dintre->dentro, fora->fuera, dreta->derecha, esquerra->izquierda, sortir->salir, sortida->salida, petit->pequeno, gran->grande, nou->nuevo, vell->viejo, molt->mucho, els->los, les->las, totes les->todas las, d'->de, com->como, quan->cuando, mentre->mientras, despres->despues, abans->antes, durant->durante, fins->hasta, encara->aun, llavors->entonces, aixi->asi, perque->porque - Sustantivos: classe->clase, metode->metodo, parametre->parametro, versio->version, entitat->entidad, joc->juego, nivell->nivel, enemic->enemigo, naus->naves, bales->balas, fitxer->archivo, pentagon->pentagono, pun- tuacio->puntuacion, flotant->flotante, titol->titulo, objectiu->objetivo, mostra->muestra, tipus->tipo Strings literales preservados en valenciano segun decision del usuario: el texto del HUD del juego (puntuaciones, mensajes en pantalla, archivo de config) se mantiene en valenciano original. 70 fitxers tocats, +1117 / -1123. Compila i enllaca. Co-Authored-By: Claude Opus 4.7 (1M context) --- source/core/audio/audio.cpp | 2 +- source/core/audio/audio_cache.cpp | 4 +- source/core/audio/audio_cache.hpp | 2 +- source/core/audio/jail_audio.hpp | 2 +- source/core/defaults.hpp | 116 ++++----- source/core/entities/entity.hpp | 12 +- source/core/graphics/shape.cpp | 12 +- source/core/graphics/shape.hpp | 14 +- source/core/graphics/shape_loader.cpp | 12 +- source/core/graphics/shape_loader.hpp | 8 +- source/core/graphics/starfield.cpp | 54 ++-- source/core/graphics/starfield.hpp | 48 ++-- source/core/graphics/vector_text.cpp | 18 +- source/core/graphics/vector_text.hpp | 2 +- source/core/input/mouse.cpp | 12 +- source/core/math/easing.hpp | 10 +- source/core/physics/collision.hpp | 8 +- source/core/rendering/color_oscillator.cpp | 6 +- source/core/rendering/color_oscillator.hpp | 4 +- .../core/rendering/coordinate_transform.cpp | 6 +- .../core/rendering/coordinate_transform.hpp | 8 +- source/core/rendering/line_renderer.cpp | 6 +- source/core/rendering/line_renderer.hpp | 8 +- source/core/rendering/sdl_manager.cpp | 62 ++--- source/core/rendering/sdl_manager.hpp | 27 +- source/core/rendering/shape_renderer.cpp | 40 +-- source/core/rendering/shape_renderer.hpp | 20 +- source/core/resources/resource_helper.cpp | 12 +- source/core/resources/resource_helper.hpp | 8 +- source/core/resources/resource_loader.cpp | 22 +- source/core/resources/resource_loader.hpp | 8 +- source/core/resources/resource_pack.cpp | 32 +-- source/core/resources/resource_pack.hpp | 20 +- source/core/system/director.cpp | 54 ++-- source/core/system/game_config.hpp | 22 +- source/core/system/global_events.hpp | 4 +- source/core/system/scene_context.hpp | 48 ++-- source/core/utils/path_utils.cpp | 14 +- source/core/utils/path_utils.hpp | 4 +- source/external/fkyaml_node.hpp | 232 +++++++++--------- source/game/constants.hpp | 10 +- source/game/effects/debris.hpp | 24 +- source/game/effects/debris_manager.cpp | 104 ++++---- source/game/effects/debris_manager.hpp | 28 +-- source/game/effects/floating_score.hpp | 16 +- .../game/effects/floating_score_manager.cpp | 14 +- .../game/effects/floating_score_manager.hpp | 22 +- source/game/entities/bullet.cpp | 24 +- source/game/entities/bullet.hpp | 10 +- source/game/entities/enemy.cpp | 48 ++-- source/game/entities/enemy.hpp | 26 +- source/game/entities/ship.cpp | 38 +-- source/game/entities/ship.hpp | 14 +- source/game/options.cpp | 42 ++-- source/game/options.hpp | 12 +- source/game/scenes/game_scene.cpp | 178 +++++++------- source/game/scenes/game_scene.hpp | 37 ++- source/game/scenes/logo_scene.cpp | 100 ++++---- source/game/scenes/logo_scene.hpp | 40 +-- source/game/scenes/title_scene.cpp | 140 +++++------ source/game/scenes/title_scene.hpp | 62 ++--- source/game/stage_system/spawn_controller.cpp | 10 +- source/game/stage_system/spawn_controller.hpp | 10 +- source/game/stage_system/stage_config.hpp | 38 +-- source/game/stage_system/stage_loader.cpp | 26 +- source/game/stage_system/stage_loader.hpp | 6 +- source/game/stage_system/stage_manager.cpp | 28 +-- source/game/stage_system/stage_manager.hpp | 12 +- source/game/title/ship_animator.cpp | 108 ++++---- source/game/title/ship_animator.hpp | 50 ++-- source/main.cpp | 10 +- 71 files changed, 1142 insertions(+), 1148 deletions(-) diff --git a/source/core/audio/audio.cpp b/source/core/audio/audio.cpp index be1eac7..6adf336 100644 --- a/source/core/audio/audio.cpp +++ b/source/core/audio/audio.cpp @@ -64,7 +64,7 @@ void Audio::playMusic(const std::string& name, const int loop) { // Llamada al motor para reproducir la nueva pista JA_PlayMusic(resource, loop); - // Actualizar estado y metadatos después de iniciar con éxito + // Actualizar estado y metadatos después de start con éxito music_.name = name; music_.loop = new_loop; music_.state = MusicState::PLAYING; diff --git a/source/core/audio/audio_cache.cpp b/source/core/audio/audio_cache.cpp index 85d4fa4..e7e6164 100644 --- a/source/core/audio/audio_cache.cpp +++ b/source/core/audio/audio_cache.cpp @@ -1,5 +1,5 @@ // audio_cache.cpp - Implementació del caché de sons i música -// © 2025 Port a C++20 amb SDL3 +// © 2025 Port a C++20 con SDL3 #include "core/audio/audio_cache.hpp" @@ -7,7 +7,7 @@ #include "core/resources/resource_helper.hpp" -// Inicialització de variables estàtiques +// Inicialización de variables estàtiques std::unordered_map AudioCache::sounds_; std::unordered_map AudioCache::musics_; std::string AudioCache::sounds_base_path_ = "data/sounds/"; diff --git a/source/core/audio/audio_cache.hpp b/source/core/audio/audio_cache.hpp index b209952..2381333 100644 --- a/source/core/audio/audio_cache.hpp +++ b/source/core/audio/audio_cache.hpp @@ -1,5 +1,5 @@ // audio_cache.hpp - Caché simplificado de sonidos y música -// © 2025 Port a C++20 amb SDL3 +// © 2025 Port a C++20 con SDL3 #pragma once diff --git a/source/core/audio/jail_audio.hpp b/source/core/audio/jail_audio.hpp index 582094a..5e09a86 100644 --- a/source/core/audio/jail_audio.hpp +++ b/source/core/audio/jail_audio.hpp @@ -158,7 +158,7 @@ inline JA_Music_t* JA_LoadMusic(const Uint8* buffer, Uint32 length) { } inline JA_Music_t* JA_LoadMusic(const char* filename) { - // [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid. + // [RZC 28/08/22] Carreguem primer el arxiu en memòria y después el descomprimim. Es algo més rapid. FILE* f = fopen(filename, "rb"); if (!f) return NULL; // Añadida comprobación de apertura fseek(f, 0, SEEK_END); diff --git a/source/core/defaults.hpp b/source/core/defaults.hpp index c8d091b..64973ba 100644 --- a/source/core/defaults.hpp +++ b/source/core/defaults.hpp @@ -19,27 +19,27 @@ constexpr float ZOOM_INCREMENT = 0.1F; // 10% steps (F1/F2) constexpr bool FULLSCREEN = true; // Pantalla completa activadapor defecto } // namespace Window -// Dimensions base del joc (coordenades lògiques) +// Dimensions base del juego (coordenades lògiques) namespace Game { constexpr int WIDTH = 640; constexpr int HEIGHT = 480; } // namespace Game -// Zones del joc (SDL_FRect amb càlculs automàtics basat en percentatges) +// Zones del juego (SDL_FRect con cálculos automàtics basat en percentatges) namespace Zones { // --- CONFIGURACIÓ DE PORCENTATGES --- -// Totes les zones definides com a percentatges de Game::WIDTH (640) i Game::HEIGHT (480) +// Todas las zones definides como a percentatges de Game::WIDTH (640) i Game::HEIGHT (480) -// Percentatges d'alçada (divisió vertical) +// Percentatges de height (divisió vertical) constexpr float SCOREBOARD_TOP_HEIGHT_PERCENT = 0.02F; // 10% superior constexpr float MAIN_PLAYAREA_HEIGHT_PERCENT = 0.88F; // 80% central constexpr float SCOREBOARD_BOTTOM_HEIGHT_PERCENT = 0.10F; // 10% inferior -// Padding horizontal per a PLAYAREA (dins de MAIN_PLAYAREA) +// Padding horizontal para PLAYAREA (dins de MAIN_PLAYAREA) constexpr float PLAYAREA_PADDING_HORIZONTAL_PERCENT = 0.015F; // 5% a cada costat // --- CÀLCULS AUTOMÀTICS DE PÍXELS --- -// Càlculs automàtics a partir dels percentatges +// Cálculos automàtics a partir dels percentatges // Alçades constexpr float SCOREBOARD_TOP_H = Game::HEIGHT * SCOREBOARD_TOP_HEIGHT_PERCENT; @@ -56,7 +56,7 @@ constexpr float PLAYAREA_PADDING_H = Game::WIDTH * PLAYAREA_PADDING_HORIZONTAL_P // --- ZONES FINALS (SDL_FRect) --- -// Marcador superior (reservat per a futur ús) +// Marcador superior (reservat para futur ús) // Ocupa: 10% superior (0-48px) constexpr SDL_FRect SCOREBOARD_TOP = { 0.0F, // x = 0.0 @@ -65,7 +65,7 @@ constexpr SDL_FRect SCOREBOARD_TOP = { SCOREBOARD_TOP_H // h = 48.0 }; -// Àrea de joc principal (contenidor del 80% central, sense padding) +// Àrea de juego principal (contenidor del 80% central, sin padding) // Ocupa: 10-90% (48-432px), ample complet constexpr SDL_FRect MAIN_PLAYAREA = { 0.0F, // x = 0.0 @@ -74,9 +74,9 @@ constexpr SDL_FRect MAIN_PLAYAREA = { MAIN_PLAYAREA_H // h = 384.0 }; -// Zona de joc real (amb padding horizontal del 5%) -// Ocupa: dins de MAIN_PLAYAREA, amb marges laterals -// S'utilitza per a límits del joc, col·lisions, spawn +// Zona de juego real (con padding horizontal del 5%) +// Ocupa: dins de MAIN_PLAYAREA, con marges laterals +// S'utilitza para límits del juego, colisiones, spawn constexpr SDL_FRect PLAYAREA = { PLAYAREA_PADDING_H, // x = 32.0 MAIN_PLAYAREA_Y, // y = 48.0 (igual que MAIN_PLAYAREA) @@ -93,7 +93,7 @@ constexpr SDL_FRect SCOREBOARD = { SCOREBOARD_BOTTOM_H // h = 48.0 }; -// Padding horizontal del marcador (per alinear zones esquerra/dreta amb PLAYAREA) +// Padding horizontal del marcador (per alinear zones izquierda/derecha con PLAYAREA) constexpr float SCOREBOARD_PADDING_H = 0.0F; // Game::WIDTH * 0.015f; } // namespace Zones @@ -211,11 +211,11 @@ constexpr float VELOCITY_SCALE = 20.0F; // factor conversión frame→tiempo // Explosions (debris physics) namespace Debris { -constexpr float VELOCITAT_BASE = 80.0F; // Velocitat inicial (px/s) +constexpr float VELOCITAT_BASE = 80.0F; // Velocidad inicial (px/s) constexpr float VARIACIO_VELOCITAT = 40.0F; // ±variació aleatòria (px/s) constexpr float ACCELERACIO = -60.0F; // Fricció/desacceleració (px/s²) -constexpr float ROTACIO_MIN = 0.1F; // Rotació mínima (rad/s ~5.7°/s) -constexpr float ROTACIO_MAX = 0.3F; // Rotació màxima (rad/s ~17.2°/s) +constexpr float ROTACIO_MIN = 0.1F; // Rotación mínima (rad/s ~5.7°/s) +constexpr float ROTACIO_MAX = 0.3F; // Rotación màxima (rad/s ~17.2°/s) constexpr float TEMPS_VIDA = 2.0F; // Duració màxima (segons) - enemy/bullet debris constexpr float TEMPS_VIDA_NAU = 3.0F; // Ship debris lifetime (matches DEATH_DURATION) constexpr float SHRINK_RATE = 0.5F; // Reducció de mida (factor/s) @@ -225,7 +225,7 @@ constexpr float FACTOR_HERENCIA_MIN = 0.7F; // Mínimo 70% del drotacio heredat constexpr float FACTOR_HERENCIA_MAX = 1.0F; // Màxim 100% del drotacio heredat constexpr float FRICCIO_ANGULAR = 0.5F; // Desacceleració angular (rad/s²) -// Angular velocity cap for trajectory inheritance +// Angular velocity sin for trajectory inheritance // Excess above this threshold is converted to tangential linear velocity // Prevents "vortex trap" problem with high-rotation enemies constexpr float VELOCITAT_ROT_MAX = 1.5F; // rad/s (~86°/s) @@ -261,21 +261,21 @@ constexpr uint8_t BACKGROUND_MAX_G = 15; constexpr uint8_t BACKGROUND_MAX_B = 0; } // namespace Color -// Brillantor (control de intensitat per cada type d'entitat) +// Brillantor (control de intensitat per cada type de entidad) namespace Brightness { -// Brillantor estàtica per entitats de joc (0.0-1.0) +// Brillantor estàtica per entidades de juego (0.0-1.0) constexpr float NAU = 1.0F; // Màxima visibilitat (player) constexpr float ENEMIC = 0.7F; // 30% més tènue (destaca menys) constexpr float BALA = 1.0F; // Brillo a tope (màxima visibilitat) -// Starfield: gradient segons distància al centre -// distancia_centre: 0.0 (centre) → 1.0 (vora pantalla) +// Starfield: gradient segons distancia al centro +// distancia_centre: 0.0 (centro) → 1.0 (vora pantalla) // brightness = MIN + (MAX - MIN) * distancia_centre -constexpr float STARFIELD_MIN = 0.3F; // Estrelles llunyanes (prop del centre) +constexpr float STARFIELD_MIN = 0.3F; // Estrelles llunyanes (prop del centro) constexpr float STARFIELD_MAX = 0.8F; // Estrelles properes (vora pantalla) } // namespace Brightness -// Renderització (V-Sync i altres opcions de render) +// Renderització (V-Sync i altres opciones de render) namespace Rendering { constexpr int VSYNC_DEFAULT = 1; // 0=disabled, 1=enabled } // namespace Rendering @@ -327,7 +327,7 @@ constexpr SDL_Keycode SHOOT = SDLK_LSHIFT; } // namespace P2 } // namespace Controls -// Enemy type configuration (type d'enemics) +// Enemy type configuration (type de enemigos) namespace Enemies { // Pentagon (esquivador - zigzag evasion) namespace Pentagon { @@ -339,15 +339,15 @@ constexpr float DROTACIO_MAX = 3.75F; // Max visual rotation (rad/s) [+50%] constexpr const char* SHAPE_FILE = "enemy_pentagon.shp"; } // namespace Pentagon -// Quadrat (perseguidor - tracks player) -namespace Quadrat { +// Cuadrado (perseguidor - tracks player) +namespace Cuadrado { constexpr float VELOCITAT = 40.0F; // px/s (medium speed) 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%] constexpr float DROTACIO_MAX = 1.5F; // [+50%] constexpr const char* SHAPE_FILE = "enemy_square.shp"; -} // namespace Quadrat +} // namespace Cuadrado // Molinillo (agressiu - fast straight lines, proximity spin-up) namespace Molinillo { @@ -395,34 +395,34 @@ constexpr float INVULNERABILITY_SCALE_START = 0.0F; // Invisible constexpr float INVULNERABILITY_SCALE_END = 1.0F; // Full size } // namespace Spawn -// Scoring system (puntuació per type d'enemy) +// Scoring system (puntuación per type de enemy) namespace Scoring { -constexpr int PENTAGON_SCORE = 100; // Pentàgon (esquivador, 35 px/s) -constexpr int QUADRAT_SCORE = 150; // Quadrat (perseguidor, 40 px/s) +constexpr int PENTAGON_SCORE = 100; // Pentágono (esquivador, 35 px/s) +constexpr int QUADRAT_SCORE = 150; // Cuadrado (perseguidor, 40 px/s) constexpr int MOLINILLO_SCORE = 200; // Molinillo (agressiu, 50 px/s) } // namespace Scoring } // namespace Enemies -// Title scene ship animations (naus 3D flotants a l'escena de títol) +// Title scene ship animations (naves 3D flotantes a l'escena de título) namespace Title { namespace Ships { // ============================================================ // PARÀMETRES BASE (ajustar aquí per experimentar) // ============================================================ -// 1. Escala global de les naus +// 1. Escala global de las naves constexpr float SHIP_BASE_SCALE = 2.5F; // Multiplicador (1.0 = mida original del .shp) // 2. Altura vertical (cercanía al centro) // Ratio Y desde el centro de la pantalla (0.0 = centro, 1.0 = bottom de pantalla) constexpr float TARGET_Y_RATIO = 0.15625F; -// 3. Radio orbital (distancia radial desde centro en coordenadas polares) -constexpr float CLOCK_RADIUS = 150.0F; // Distància des del centre +// 3. Radio orbital (distance radial desde centro en coordenadas polares) +constexpr float CLOCK_RADIUS = 150.0F; // Distancia des del centro // 4. Ángulos de posición (clock positions en coordenadas polares) -// En coordenades de pantalla: 0° = dreta, 90° = baix, 180° = esquerra, 270° = dalt +// En coordenades de pantalla: 0° = derecha, 90° = baix, 180° = izquierda, 270° = dalt constexpr float CLOCK_8_ANGLE = 150.0F * Math::PI / 180.0F; // 8 o'clock (bottom-left) constexpr float CLOCK_4_ANGLE = 30.0F * Math::PI / 180.0F; // 4 o'clock (bottom-right) @@ -436,13 +436,13 @@ constexpr float ENTRY_OFFSET_MARGIN = 227.5F; // Para offset total de ~340px (a // VALORS DERIVATS (calculats automàticament - NO modificar) // ============================================================ -// Centre de la pantalla (point de referència) +// Centro de la pantalla (point de referència) constexpr float CENTER_X = Game::WIDTH / 2.0F; // 320.0f constexpr float CENTER_Y = Game::HEIGHT / 2.0F; // 240.0f -// Posicions target (calculades dinàmicament des dels paràmetres base) -// Nota: std::cos/sin no són constexpr en C++20, però funcionen en runtime -// Les funcions inline són optimitzades pel compilador (zero overhead) +// Posicions target (calculades dinàmicament des dels parámetros base) +// Nota: std::cos/sin no són constexpr en C++20, pero funcionen en runtime +// Les funciones inline són optimitzades por el compilador (zero overhead) inline float P1_TARGET_X() { return CENTER_X + (CLOCK_RADIUS * std::cos(CLOCK_8_ANGLE)); } @@ -456,15 +456,15 @@ inline float P2_TARGET_Y() { return CENTER_Y + ((Game::HEIGHT / 2.0F) * TARGET_Y_RATIO); } -// Escales d'animació (relatives a SHIP_BASE_SCALE) -constexpr float ENTRY_SCALE_START = 1.5F * SHIP_BASE_SCALE; // Entrada: 50% més gran -constexpr float FLOATING_SCALE = 1.0F * SHIP_BASE_SCALE; // Flotant: scale base +// Escales de animación (relatives a SHIP_BASE_SCALE) +constexpr float ENTRY_SCALE_START = 1.5F * SHIP_BASE_SCALE; // Entrada: 50% més grande +constexpr float FLOATING_SCALE = 1.0F * SHIP_BASE_SCALE; // Flotante: scale base -// Offset d'entrada (ajustat automàticament a l'scale) -// Fórmula: (radi màxim de la ship * scale d'entrada) + marge +// Offset de entrada (ajustat automàticament a l'scale) +// Fórmula: (radi màxim de la ship * scale de entrada) + marge constexpr float ENTRY_OFFSET = (SHIP_MAX_RADIUS * ENTRY_SCALE_START) + ENTRY_OFFSET_MARGIN; -// Vec2 de fuga (centre per a l'animació de sortida) +// Vec2 de fuga (centro para l'animación de salida) constexpr float VANISHING_POINT_X = CENTER_X; // 320.0f constexpr float VANISHING_POINT_Y = CENTER_Y; // 240.0f @@ -472,11 +472,11 @@ constexpr float VANISHING_POINT_Y = CENTER_Y; // 240.0f // ANIMACIONS (durades, oscil·lacions, delays) // ============================================================ -// Durades d'animació +// Durades de animación constexpr float ENTRY_DURATION = 2.0F; // Entrada (segons) -constexpr float EXIT_DURATION = 1.0F; // Sortida (segons) +constexpr float EXIT_DURATION = 1.0F; // Salida (segons) -// Flotació (oscil·lació reduïda i diferenciada per ship) +// Flotació (oscil·lació reduïda y diferenciada per ship) constexpr float FLOAT_AMPLITUDE_X = 4.0F; // Amplitud X (píxels) constexpr float FLOAT_AMPLITUDE_Y = 2.5F; // Amplitud Y (píxels) @@ -485,21 +485,21 @@ constexpr float FLOAT_FREQUENCY_X_BASE = 0.5F; // Hz constexpr float FLOAT_FREQUENCY_Y_BASE = 0.7F; // Hz constexpr float FLOAT_PHASE_OFFSET = 1.57F; // π/2 (90°) -// Delays d'entrada (per a entrada escalonada) +// Delays de entrada (per a entrada escalonada) constexpr float P1_ENTRY_DELAY = 0.0F; // P1 entra immediatament -constexpr float P2_ENTRY_DELAY = 0.5F; // P2 entra 0.5s després +constexpr float P2_ENTRY_DELAY = 0.5F; // P2 entra 0.5s después -// Delay global abans d'iniciar l'animació d'entrada al state MAIN -constexpr float ENTRANCE_DELAY = 5.0F; // Temps d'espera abans que les naus entrin +// Delay global antes de start l'animación de entrada al state MAIN +constexpr float ENTRANCE_DELAY = 5.0F; // Temps de espera antes que las naves entrin -// Multiplicadors de freqüència per a cada ship (variació sutil ±12%) +// Multiplicadors de freqüència para cada ship (variació sutil ±12%) constexpr float P1_FREQUENCY_MULTIPLIER = 0.88F; // 12% més lenta constexpr float P2_FREQUENCY_MULTIPLIER = 1.12F; // 12% més ràpida } // namespace Ships namespace Layout { -// Posicions verticals (anclatges des del TOP de pantalla lògica, 0.0-1.0) +// Posicions verticals (anclatges des del TOP de pantalla lógica, 0.0-1.0) constexpr float LOGO_POS = 0.20F; // Logo "ORNI" constexpr float PRESS_START_POS = 0.75F; // "PRESS START TO PLAY" constexpr float COPYRIGHT1_POS = 0.90F; // Primera línia copyright @@ -508,21 +508,21 @@ constexpr float COPYRIGHT1_POS = 0.90F; // Primera línia copyright constexpr float LOGO_LINE_SPACING = 0.02F; // Entre "ORNI" i "ATTACK!" (10px) constexpr float COPYRIGHT_LINE_SPACING = 0.0F; // Entre línies copyright (5px) -// Factors d'scale +// Factors de scale constexpr float LOGO_SCALE = 0.6F; // Escala "ORNI ATTACK!" constexpr float PRESS_START_SCALE = 1.0F; // Escala "PRESS START TO PLAY" constexpr float COPYRIGHT_SCALE = 0.5F; // Escala copyright -// Espaiat entre caràcters (usat per VectorText) +// Espaiat entre caràcters (usado per VectorText) constexpr float TEXT_SPACING = 2.0F; } // namespace Layout } // namespace Title -// Floating score numbers (números flotants de puntuació) +// Floating score numbers (números flotantes de puntuación) namespace FloatingScore { constexpr float LIFETIME = 2.0F; // Duració màxima (segons) -constexpr float VELOCITY_Y = -30.0F; // Velocitat vertical (px/s, negatiu = amunt) -constexpr float VELOCITY_X = 0.0F; // Velocitat horizontal (px/s) +constexpr float VELOCITY_Y = -30.0F; // Velocidad vertical (px/s, negatiu = amunt) +constexpr float VELOCITY_X = 0.0F; // Velocidad horizontal (px/s) constexpr float SCALE = 0.45F; // Escala del text (0.6 = 60% del marcador) constexpr float SPACING = 0.0F; // Espaiat entre caràcters constexpr int MAX_CONCURRENT = 15; // Pool size (= MAX_ORNIS) diff --git a/source/core/entities/entity.hpp b/source/core/entities/entity.hpp index 52b085e..ff27c1b 100644 --- a/source/core/entities/entity.hpp +++ b/source/core/entities/entity.hpp @@ -1,5 +1,5 @@ -// entitat.hpp - Classe base abstracta per a totes les entitats del joc -// © 2025 Orni Attack - Arquitectura d'entitats +// entity.hpp - Clase base abstracta para todas las entidades del juego +// © 2025 Orni Attack - Arquitectura de entidades #pragma once @@ -22,25 +22,25 @@ class Entity { virtual void draw() const = 0; [[nodiscard]] virtual bool isActive() const = 0; - // Interfície de col·lisió (override opcional) + // Interfície de colisión (override opcional) [[nodiscard]] virtual float getCollisionRadius() const { return 0.0F; } [[nodiscard]] virtual bool isCollidable() const { return false; } - // Getters comuns (inline, sense overhead) + // Getters comuns (inline, sin overhead) [[nodiscard]] const Vec2& getCenter() const { return center_; } [[nodiscard]] float getAngle() const { return angle_; } [[nodiscard]] float getBrightness() const { return brightness_; } [[nodiscard]] const std::shared_ptr& getShape() const { return shape_; } protected: - // Estat comú (accés directe, sense overhead) + // Estat comú (accés directe, sin overhead) SDL_Renderer* renderer_; std::shared_ptr shape_; Vec2 center_; float angle_{0.0F}; float brightness_{1.0F}; - // Constructor protegit (classe abstracta) + // Constructor protegit (clase abstracta) Entity(SDL_Renderer* renderer = nullptr) : renderer_(renderer), center_({.x = 0.0F, .y = 0.0F}) {} diff --git a/source/core/graphics/shape.cpp b/source/core/graphics/shape.cpp index c165a34..a647864 100644 --- a/source/core/graphics/shape.cpp +++ b/source/core/graphics/shape.cpp @@ -1,5 +1,5 @@ // shape.cpp - Implementació del sistema de formes vectorials -// © 2025 Port a C++20 amb SDL3 +// © 2025 Port a C++20 con SDL3 #include "core/graphics/shape.hpp" @@ -18,14 +18,14 @@ Shape::Shape(const std::string& filepath) } bool Shape::load(const std::string& filepath) { - // Llegir fitxer + // Llegir file std::ifstream file(filepath); if (!file.is_open()) { std::cerr << "[Shape] Error: no es pot obrir " << filepath << '\n'; return false; } - // Llegir tot el contingut + // Llegir todo el contingut std::stringstream buffer; buffer << file.rdbuf(); std::string contingut = buffer.str(); @@ -65,7 +65,7 @@ bool Shape::parseFile(const std::string& contingut) { if (points.size() >= 2) { primitives_.push_back({PrimitiveType::POLYLINE, points}); } else { - std::cerr << "[Shape] Warning: polyline amb menys de 2 points ignorada" + std::cerr << "[Shape] Warning: polyline con menys de 2 points ignorada" << '\n'; } } else if (starts_with(line, "line:")) { @@ -81,7 +81,7 @@ bool Shape::parseFile(const std::string& contingut) { } if (primitives_.empty()) { - std::cerr << "[Shape] Error: cap primitiva carregada" << '\n'; + std::cerr << "[Shape] Error: sin primitiva carregada" << '\n'; return false; } @@ -127,7 +127,7 @@ void Shape::parse_center(const std::string& value) { center_.x = std::stof(trim(val.substr(0, comma))); center_.y = std::stof(trim(val.substr(comma + 1))); } catch (...) { - std::cerr << "[Shape] Warning: centre invàlid, usant (0,0)" << '\n'; + std::cerr << "[Shape] Warning: centro invàlid, usant (0,0)" << '\n'; center_ = {.x = 0.0F, .y = 0.0F}; } } diff --git a/source/core/graphics/shape.hpp b/source/core/graphics/shape.hpp index c848b19..7836328 100644 --- a/source/core/graphics/shape.hpp +++ b/source/core/graphics/shape.hpp @@ -1,5 +1,5 @@ // shape.hpp - Sistema de formes vectorials -// © 2025 Port a C++20 amb SDL3 +// © 2025 Port a C++20 con SDL3 #pragma once @@ -10,9 +10,9 @@ namespace Graphics { -// Tipus de primitiva dins d'una shape +// Tipo de primitiva dins de una shape enum class PrimitiveType { - POLYLINE, // Seqüència de points connectats + POLYLINE, // Secuencia de points connectats LINE // Línia individual (2 points) }; @@ -22,17 +22,17 @@ struct ShapePrimitive { std::vector points; // 2+ points per polyline, exactament 2 per line }; -// Classe Shape - representa una shape vectorial carregada des de .shp +// Clase Shape - representa una shape vectorial carregada desde .shp class Shape { public: // Constructors Shape() = default; explicit Shape(const std::string& filepath); - // Carregar shape des de fitxer .shp + // Carregar shape desde file .shp bool load(const std::string& filepath); - // Parsejar shape des de buffer de memòria (per al sistema de recursos) + // Parsejar shape desde buffer de memòria (per al sistema de recursos) bool parseFile(const std::string& contingut); // Getters @@ -49,7 +49,7 @@ class Shape { private: std::vector primitives_; - Vec2 center_; // Centre/origen de la shape + Vec2 center_; // Centro/origin de la shape float escala_defecte_; // Escala per defecte (normalment 1.0) std::string nom_; // Nom de la shape (per depuració) diff --git a/source/core/graphics/shape_loader.cpp b/source/core/graphics/shape_loader.cpp index cd68f6a..27f74e2 100644 --- a/source/core/graphics/shape_loader.cpp +++ b/source/core/graphics/shape_loader.cpp @@ -1,5 +1,5 @@ -// shape_loader.cpp - Implementació del carregador amb caché -// © 2025 Port a C++20 amb SDL3 +// shape_loader.cpp - Implementació del carregador con caché +// © 2025 Port a C++20 con SDL3 #include "core/graphics/shape_loader.hpp" @@ -9,7 +9,7 @@ namespace Graphics { -// Inicialització de variables estàtiques +// Inicialización de variables estàtiques std::unordered_map> ShapeLoader::cache_; std::string ShapeLoader::base_path_ = "data/shapes/"; @@ -69,17 +69,17 @@ void ShapeLoader::clear_cache() { size_t ShapeLoader::get_cache_size() { return cache_.size(); } std::string ShapeLoader::resolve_path(const std::string& filename) { - // Si és un path absolut (comença amb '/'), usar-lo directament + // Si es un path absolut (comença con '/'), usar-lo directament if (!filename.empty() && filename[0] == '/') { return filename; } - // Si ja conté el prefix base_path, usar-lo directament + // Si ya conté el prefix base_path, usar-lo directament if (filename.starts_with(base_path_)) { return filename; } - // Altrament, afegir base_path (ara suporta subdirectoris) + // Altrament, añadir base_path (ara suporta subdirectoris) return base_path_ + filename; } diff --git a/source/core/graphics/shape_loader.hpp b/source/core/graphics/shape_loader.hpp index 5f94d67..9f14c4c 100644 --- a/source/core/graphics/shape_loader.hpp +++ b/source/core/graphics/shape_loader.hpp @@ -1,5 +1,5 @@ -// shape_loader.hpp - Carregador estàtic de formes amb caché -// © 2025 Port a C++20 amb SDL3 +// shape_loader.hpp - Carregador estàtic de formes con caché +// © 2025 Port a C++20 con SDL3 #pragma once @@ -11,13 +11,13 @@ namespace Graphics { -// Carregador estàtic de formes amb caché +// Carregador estàtic de formes con caché class ShapeLoader { public: // No instanciable (tot estàtic) ShapeLoader() = delete; - // Carregar shape des de fitxer (amb caché) + // Carregar shape desde file (con caché) // Retorna punter compartit (nullptr si error) // Exemple: load("ship.shp") → busca a "data/shapes/ship.shp" static std::shared_ptr load(const std::string& filename); diff --git a/source/core/graphics/starfield.cpp b/source/core/graphics/starfield.cpp index 02fec0e..ce0fdff 100644 --- a/source/core/graphics/starfield.cpp +++ b/source/core/graphics/starfield.cpp @@ -1,4 +1,4 @@ -// starfield.cpp - Implementació del sistema d'estrelles de fons +// starfield.cpp - Implementació del sistema de estrelles de fons // © 2025 Orni Attack #include "core/graphics/starfield.hpp" @@ -22,7 +22,7 @@ Starfield::Starfield(SDL_Renderer* renderer, punt_fuga_(punt_fuga), area_(area), densitat_(densitat) { - // Carregar shape d'estrella amb ShapeLoader + // Carregar shape de estrella con ShapeLoader shape_estrella_ = ShapeLoader::load("star.shp"); if (!shape_estrella_ || !shape_estrella_->isValid()) { @@ -30,22 +30,22 @@ Starfield::Starfield(SDL_Renderer* renderer, return; } - // Configurar 3 capes amb diferents velocitats i escales - // Capa 0: Fons llunyà (lenta, petita) + // Configurar 3 capes con diferents velocitats i escales + // Capa 0: Fons llunyà (lenta, pequeña) capes_.push_back({20.0F, 0.3F, 0.8F, densitat / 3}); // Capa 1: Profunditat mitjana capes_.push_back({40.0F, 0.5F, 1.2F, densitat / 3}); - // Capa 2: Primer pla (ràpida, gran) + // Capa 2: Primer pla (ràpida, grande) capes_.push_back({80.0F, 0.8F, 2.0F, densitat / 3}); - // Calcular radi màxim (distància del centre al racó més llunyà) + // Calcular radi màxim (distancia del centro al racó més llunyà) float dx = std::max(punt_fuga_.x, area_.w - punt_fuga_.x); float dy = std::max(punt_fuga_.y, area_.h - punt_fuga_.y); radi_max_ = std::sqrt((dx * dx) + (dy * dy)); - // Inicialitzar estrelles amb posicions distribuïdes (pre-omplir pantalla) + // Inicialitzar estrelles con posicions distribuïdes (pre-omplir pantalla) for (int capa_idx = 0; capa_idx < 3; capa_idx++) { int num = capes_[capa_idx].num_estrelles; for (int i = 0; i < num; i++) { @@ -55,10 +55,10 @@ Starfield::Starfield(SDL_Renderer* renderer, // Angle aleatori estrella.angle = (static_cast(rand()) / RAND_MAX) * 2.0F * Defaults::Math::PI; - // Distància aleatòria (0.0 a 1.0) per omplir tota la pantalla + // Distancia aleatòria (0.0 a 1.0) per omplir toda la pantalla estrella.distancia_centre = static_cast(rand()) / RAND_MAX; - // Calcular posició des de la distància + // Calcular posición desde la distancia float radi = estrella.distancia_centre * radi_max_; estrella.position.x = punt_fuga_.x + (radi * std::cos(estrella.angle)); estrella.position.y = punt_fuga_.y + (radi * std::sin(estrella.angle)); @@ -68,21 +68,21 @@ Starfield::Starfield(SDL_Renderer* renderer, } } -// Inicialitzar una estrella (nova o regenerada) +// Inicialitzar una estrella (nueva o regenerada) void Starfield::inicialitzar_estrella(Estrella& estrella) const { - // Angle aleatori des del point de fuga cap a fora + // Angle aleatori des del point de fuga hacia fuera estrella.angle = (static_cast(rand()) / RAND_MAX) * 2.0F * Defaults::Math::PI; - // Distància inicial petita (5% del radi màxim) - neix prop del centre + // Distancia inicial pequeña (5% del radi màxim) - neix prop del centro estrella.distancia_centre = 0.05F; - // Posició inicial: molt prop del point de fuga + // Posición inicial: mucho prop del point de fuga float radi = estrella.distancia_centre * radi_max_; estrella.position.x = punt_fuga_.x + (radi * std::cos(estrella.angle)); estrella.position.y = punt_fuga_.y + (radi * std::sin(estrella.angle)); } -// Verificar si una estrella està fora de l'àrea +// Verificar si una estrella está fuera de l'àrea bool Starfield::fora_area(const Estrella& estrella) const { return (estrella.position.x < area_.x || estrella.position.x > area_.x + area_.w || @@ -90,20 +90,20 @@ bool Starfield::fora_area(const Estrella& estrella) const { estrella.position.y > area_.y + area_.h); } -// Calcular scale dinàmica segons distància del centre +// Calcular scale dinàmica segons distancia del centro float Starfield::calcular_escala(const Estrella& estrella) const { const CapaConfig& capa = capes_[estrella.capa]; - // Interpolació lineal basada en distància del centre - // distancia_centre: 0.0 (centre) → 1.0 (vora) + // Interpolació lineal basada en distancia del centro + // distancia_centre: 0.0 (centro) → 1.0 (vora) return capa.escala_min + ((capa.escala_max - capa.escala_min) * estrella.distancia_centre); } -// Calcular brightness dinàmica segons distància del centre +// Calcular brightness dinàmica segons distancia del centro float Starfield::calcular_brightness(const Estrella& estrella) const { // Interpolació lineal: estrelles properes (vora) més brillants - // distancia_centre: 0.0 (centre, llunyanes) → 1.0 (vora, properes) + // distancia_centre: 0.0 (centro, llunyanes) → 1.0 (vora, properes) float brightness_base = Defaults::Brightness::STARFIELD_MIN + ((Defaults::Brightness::STARFIELD_MAX - Defaults::Brightness::STARFIELD_MIN) * estrella.distancia_centre); @@ -112,13 +112,13 @@ float Starfield::calcular_brightness(const Estrella& estrella) const { return std::min(1.0F, brightness_base * multiplicador_brightness_); } -// Actualitzar posicions de les estrelles +// Actualitzar posicions de las estrelles void Starfield::update(float delta_time) { for (auto& estrella : estrelles_) { - // Obtenir configuració de la capa + // Obtenir configuración de la capa const CapaConfig& capa = capes_[estrella.capa]; - // Moure cap a fora des del centre + // Moure hacia fuera des del centro float velocity = capa.velocitat_base; float dx = velocity * std::cos(estrella.angle) * delta_time; float dy = velocity * std::sin(estrella.angle) * delta_time; @@ -126,7 +126,7 @@ void Starfield::update(float delta_time) { estrella.position.x += dx; estrella.position.y += dy; - // Actualitzar distància del centre + // Actualitzar distancia del centro float dx_centre = estrella.position.x - punt_fuga_.x; float dy_centre = estrella.position.y - punt_fuga_.y; float dist_px = std::sqrt((dx_centre * dx_centre) + (dy_centre * dy_centre)); @@ -144,7 +144,7 @@ void Starfield::set_brightness(float multiplier) { multiplicador_brightness_ = std::max(0.0F, multiplier); // Evitar valors negatius } -// Dibuixar totes les estrelles +// Dibuixar todas las estrelles void Starfield::draw() { if (!shape_estrella_->isValid()) { return; @@ -155,14 +155,14 @@ void Starfield::draw() { float scale = calcular_escala(estrella); float brightness = calcular_brightness(estrella); - // Renderitzar estrella sense rotació + // Renderizar estrella sin rotación Rendering::render_shape( renderer_, shape_estrella_, estrella.position, - 0.0F, // angle (les estrelles no giren) + 0.0F, // angle (las estrelles no giren) scale, // scale dinàmica - 1.0F, // progress (sempre visible) + 1.0F, // progress (siempre visible) brightness // brightness dinàmica ); } diff --git a/source/core/graphics/starfield.hpp b/source/core/graphics/starfield.hpp index 0c772fe..c95de8d 100644 --- a/source/core/graphics/starfield.hpp +++ b/source/core/graphics/starfield.hpp @@ -1,4 +1,4 @@ -// starfield.hpp - Sistema d'estrelles de fons amb efecte de profunditat +// starfield.hpp - Sistema de estrelles de fons con efecte de profunditat // © 2025 Orni Attack #pragma once @@ -13,69 +13,69 @@ namespace Graphics { -// Configuració per cada capa de profunditat +// Configuración per cada capa de profunditat struct CapaConfig { - float velocitat_base; // Velocitat base d'aquesta capa (px/s) - float escala_min; // Escala mínima prop del centre + float velocitat_base; // Velocidad base de esta capa (px/s) + float escala_min; // Escala mínima prop del centro float escala_max; // Escala màxima al límit de pantalla - int num_estrelles; // Nombre d'estrelles en aquesta capa + int num_estrelles; // Nombre de estrelles en esta capa }; -// Classe Starfield - camp d'estrelles animat amb efecte de profunditat +// Clase Starfield - camp de estrelles animat con efecte de profunditat class Starfield { public: // Constructor // - renderer: SDL renderer - // - punt_fuga: point d'origen/fuga des d'on surten les estrelles - // - area: rectangle on actuen les estrelles (SDL_FRect) - // - densitat: nombre total d'estrelles (es divideix entre capes) + // - punt_fuga: point de origin/fuga des de on surten las estrelles + // - area: rectangle on actuen las estrelles (SDL_FRect) + // - densitat: nombre total de estrelles (es divideix entre capes) Starfield(SDL_Renderer* renderer, const Vec2& punt_fuga, const SDL_FRect& area, int densitat = 150); - // Actualitzar posicions de les estrelles + // Actualitzar posicions de las estrelles void update(float delta_time); - // Dibuixar totes les estrelles + // Dibuixar todas las estrelles void draw(); - // Setters per ajustar paràmetres en time real + // Setters per ajustar parámetros en time real void set_punt_fuga(const Vec2& point) { punt_fuga_ = point; } void set_brightness(float multiplier); private: // Estructura interna per cada estrella struct Estrella { - Vec2 position; // Posició actual - float angle; // Angle de moviment (radians) - float distancia_centre; // Distància normalitzada del centre (0.0-1.0) + Vec2 position; // Posición actual + float angle; // Angle de movement (radians) + float distancia_centre; // Distancia normalitzada del centro (0.0-1.0) int capa; // Índex de capa (0=lluny, 1=mitjà, 2=prop) }; - // Inicialitzar una estrella (nova o regenerada) + // Inicialitzar una estrella (nueva o regenerada) void inicialitzar_estrella(Estrella& estrella) const; - // Verificar si una estrella està fora de l'àrea + // Verificar si una estrella está fuera de l'àrea [[nodiscard]] bool fora_area(const Estrella& estrella) const; - // Calcular scale dinàmica segons distància del centre + // Calcular scale dinàmica segons distancia del centro [[nodiscard]] float calcular_escala(const Estrella& estrella) const; - // Calcular brightness dinàmica segons distància del centre + // Calcular brightness dinàmica segons distancia del centro [[nodiscard]] float calcular_brightness(const Estrella& estrella) const; // Dades std::vector estrelles_; - std::vector capes_; // Configuració de les 3 capes + std::vector capes_; // Configuración de las 3 capes std::shared_ptr shape_estrella_; SDL_Renderer* renderer_; - // Configuració - Vec2 punt_fuga_; // Vec2 d'origen de les estrelles + // Configuración + Vec2 punt_fuga_; // Vec2 de origin de las estrelles SDL_FRect area_; // Àrea activa - float radi_max_; // Distància màxima del centre al límit de pantalla - int densitat_; // Nombre total d'estrelles + float radi_max_; // Distancia màxima del centro al límit de pantalla + int densitat_; // Nombre total de estrelles float multiplicador_brightness_{1.0F}; // Multiplicador de brightness (1.0 = default) }; diff --git a/source/core/graphics/vector_text.cpp b/source/core/graphics/vector_text.cpp index 88e6452..1648e97 100644 --- a/source/core/graphics/vector_text.cpp +++ b/source/core/graphics/vector_text.cpp @@ -1,5 +1,5 @@ // vector_text.cpp - Implementació del sistema de text vectorial -// © 2025 Port a C++20 amb SDL3 +// © 2025 Port a C++20 con SDL3 // Test pre-commit hook #include "core/graphics/vector_text.hpp" @@ -11,7 +11,7 @@ namespace Graphics { -// Constants per a mides base dels caràcters +// Constants para mides base dels caràcters constexpr float char_width = 20.0F; // Amplada base del caràcter constexpr float char_height = 40.0F; // Altura base del caràcter @@ -63,7 +63,7 @@ void VectorText::load_charset() { } // Cargar símbolo de copyright (©) - UTF-8 U+00A9 - // Usem el segon byte (0xA9) com a key interna + // Usem el segon byte (0xA9) como a key interna { char c = '\xA9'; // 169 decimal std::string filename = "font/char_copyright.shp"; @@ -82,7 +82,7 @@ void VectorText::load_charset() { } std::string VectorText::get_shape_filename(char c) const { - // Mapeo carácter → nombre de archivo (amb prefix "font/") + // Mapeo carácter → nombre de archivo (con prefix "font/") switch (c) { case '0': case '1': @@ -168,7 +168,7 @@ std::string VectorText::get_shape_filename(char c) const { case '?': return "font/char_question.shp"; case ' ': - return ""; // Espai es maneja sense load shape + return ""; // Espai es maneja sin load shape case '\xA9': // Copyright symbol (©) - UTF-8 U+00A9 return "font/char_copyright.shp"; @@ -207,7 +207,7 @@ void VectorText::render(const std::string& text, const Vec2& position, float sca // Detectar copyright UTF-8 (0xC2 0xA9) if (c == 0xC2 && i + 1 < text.length() && static_cast(text[i + 1]) == 0xA9) { - c = 0xA9; // Usar segon byte com a key + c = 0xA9; // Usar segon byte como a key i++; // Saltar el següent byte } @@ -242,13 +242,13 @@ void VectorText::renderCentered(const std::string& text, const Vec2& centre_punt float text_width = get_text_width(text, scale, spacing); float text_height = get_text_height(scale); - // Calcular posició de l'esquina superior esquerra - // restant la meitat de les dimensions del point central + // Calcular posición de l'esquina superior izquierda + // restant la meitat de las dimensions del point central Vec2 posicio_esquerra = { .x = centre_punt.x - (text_width / 2.0F), .y = centre_punt.y - (text_height / 2.0F)}; - // Delegar al mètode render() existent + // Delegar al método render() existent render(text, posicio_esquerra, scale, spacing, brightness); } diff --git a/source/core/graphics/vector_text.hpp b/source/core/graphics/vector_text.hpp index aeb30f0..5650fa3 100644 --- a/source/core/graphics/vector_text.hpp +++ b/source/core/graphics/vector_text.hpp @@ -1,5 +1,5 @@ // vector_text.hpp - Sistema de texto vectorial con display de 7-segmentos -// © 2025 Port a C++20 amb SDL3 +// © 2025 Port a C++20 con SDL3 #pragma once diff --git a/source/core/input/mouse.cpp b/source/core/input/mouse.cpp index 2338f95..239264e 100644 --- a/source/core/input/mouse.cpp +++ b/source/core/input/mouse.cpp @@ -12,7 +12,7 @@ bool cursor_visible = false; // Estado del cursor (inicia ocult) // SDLManager controla esto mediante llamadas a setForceHidden(). bool force_hidden = false; -// Temps d'inicialització per ignorar esdeveniments fantasma de SDL +// Temps de inicialización per ignorar esdeveniments fantasma de SDL Uint32 initialization_time = 0; constexpr Uint32 IGNORE_MOTION_DURATION = 1000; // Ignorar primers 1000ms @@ -24,7 +24,7 @@ void forceHide() { cursor_visible = false; last_mouse_move_time = 0; initialization_time = SDL_GetTicks(); // Marcar time per ignorar esdeveniments inicials - std::cout << "[Mouse::forceHide] Ignorant moviments durant " << IGNORE_MOTION_DURATION << "ms" << '\n'; + std::cout << "[Mouse::forceHide] Ignorant moviments durante " << IGNORE_MOTION_DURATION << "ms" << '\n'; } void setForceHidden(bool force) { @@ -56,16 +56,16 @@ void handleEvent(const SDL_Event& event) { if (event.type == SDL_EVENT_MOUSE_MOTION) { Uint32 current_time = SDL_GetTicks(); - // Ignorar esdeveniments fantasma de SDL durant el període inicial + // Ignorar esdeveniments fantasma de SDL durante el període inicial if (initialization_time > 0 && (current_time - initialization_time < IGNORE_MOTION_DURATION)) { - std::cout << "[Mouse::handleEvent] Ignorant moviment fantasma de SDL. time=" << current_time - << " (inicialització fa " << (current_time - initialization_time) << "ms)" << '\n'; + std::cout << "[Mouse::handleEvent] Ignorant movement fantasma de SDL. time=" << current_time + << " (inicialización hace " << (current_time - initialization_time) << "ms)" << '\n'; return; } last_mouse_move_time = current_time; if (!cursor_visible) { - std::cout << "[Mouse::handleEvent] Mostrant cursor per moviment REAL. time=" << last_mouse_move_time << '\n'; + std::cout << "[Mouse::handleEvent] Mostrant cursor per movement REAL. time=" << last_mouse_move_time << '\n'; SDL_ShowCursor(); cursor_visible = true; } diff --git a/source/core/math/easing.hpp b/source/core/math/easing.hpp index 1b6d239..5c135b2 100644 --- a/source/core/math/easing.hpp +++ b/source/core/math/easing.hpp @@ -1,4 +1,4 @@ -// easing.hpp - Funcions d'interpolació i easing +// easing.hpp - Funciones de interpolació i easing // © 2025 Orni Attack #pragma once @@ -7,21 +7,21 @@ namespace Easing { // Ease-out quadratic: empieza rápido, desacelera suavemente // t = progreso normalizado [0.0 - 1.0] -// retorna valor interpolado [0.0 - 1.0] +// retorna value interpolado [0.0 - 1.0] inline float ease_out_quad(float t) { return 1.0F - ((1.0F - t) * (1.0F - t)); } // Ease-in quadratic: empieza lento, acelera // t = progreso normalizado [0.0 - 1.0] -// retorna valor interpolado [0.0 - 1.0] +// retorna value interpolado [0.0 - 1.0] inline float ease_in_quad(float t) { return t * t; } // Ease-in-out quadratic: acelera al inicio, desacelera al final // t = progreso normalizado [0.0 - 1.0] -// retorna valor interpolado [0.0 - 1.0] +// retorna value interpolado [0.0 - 1.0] inline float ease_in_out_quad(float t) { return (t < 0.5F) ? 2.0F * t * t @@ -30,7 +30,7 @@ inline float ease_in_out_quad(float t) { // Ease-out cubic: desaceleración más suave que quadratic // t = progreso normalizado [0.0 - 1.0] -// retorna valor interpolado [0.0 - 1.0] +// retorna value interpolado [0.0 - 1.0] inline float ease_out_cubic(float t) { float t1 = 1.0F - t; return 1.0F - (t1 * t1 * t1); diff --git a/source/core/physics/collision.hpp b/source/core/physics/collision.hpp index 0891fd4..4152d20 100644 --- a/source/core/physics/collision.hpp +++ b/source/core/physics/collision.hpp @@ -1,4 +1,4 @@ -// collision.hpp - Utilitats de detecció de col·lisions +// collision.hpp - Utilitats de detecció de colisiones // © 2025 Orni Attack - Sistema de física #pragma once @@ -8,18 +8,18 @@ namespace Physics { -// Comprovació genèrica de col·lisió entre dues entitats +// Comprobación genèrica de colisión entre dues entidades inline bool check_collision(const Entities::Entity& a, const Entities::Entity& b, float amplifier = 1.0F) { // Comprovar si ambdós són col·lisionables if (!a.isCollidable() || !b.isCollidable()) { return false; } - // Calcular radi combinat (amb amplificador per hitbox generós) + // Calcular radi combinat (con amplificador per hitbox generós) float suma_radis = (a.getCollisionRadius() + b.getCollisionRadius()) * amplifier; float suma_radis_sq = suma_radis * suma_radis; - // Comprovació distància al quadrat (sense sqrt) + // Comprobación distancia al cuadrado (sin sqrt) const Vec2& pos_a = a.getCenter(); const Vec2& pos_b = b.getCenter(); float dx = pos_a.x - pos_b.x; diff --git a/source/core/rendering/color_oscillator.cpp b/source/core/rendering/color_oscillator.cpp index ca1df1a..f88e1f5 100644 --- a/source/core/rendering/color_oscillator.cpp +++ b/source/core/rendering/color_oscillator.cpp @@ -1,5 +1,5 @@ -// color_oscillator.cpp - Implementació d'oscil·lació de color -// © 2025 Port a C++20 amb SDL3 +// color_oscillator.cpp - Implementació de oscil·lació de color +// © 2025 Port a C++20 con SDL3 #include "core/rendering/color_oscillator.hpp" @@ -11,7 +11,7 @@ namespace Rendering { ColorOscillator::ColorOscillator() : accumulated_time_(0.0F) { - // Inicialitzar amb el color mínim + // Inicialitzar con el color mínim current_line_color_ = {.r = Defaults::Color::LINE_MIN_R, .g = Defaults::Color::LINE_MIN_G, .b = Defaults::Color::LINE_MIN_B, diff --git a/source/core/rendering/color_oscillator.hpp b/source/core/rendering/color_oscillator.hpp index d2a6bc1..3b65912 100644 --- a/source/core/rendering/color_oscillator.hpp +++ b/source/core/rendering/color_oscillator.hpp @@ -1,5 +1,5 @@ -// color_oscillator.hpp - Sistema d'oscil·lació de color per efecte CRT -// © 2025 Port a C++20 amb SDL3 +// color_oscillator.hpp - Sistema de oscil·lació de color per efecte CRT +// © 2025 Port a C++20 con SDL3 #pragma once #include diff --git a/source/core/rendering/coordinate_transform.cpp b/source/core/rendering/coordinate_transform.cpp index b3e04b0..1e1f58d 100644 --- a/source/core/rendering/coordinate_transform.cpp +++ b/source/core/rendering/coordinate_transform.cpp @@ -1,11 +1,11 @@ -// coordinate_transform.cpp - Inicialització de variables globals -// © 2025 Port a C++20 amb SDL3 +// coordinate_transform.cpp - Inicialización de variables globals +// © 2025 Port a C++20 con SDL3 #include "core/rendering/coordinate_transform.hpp" namespace Rendering { -// Factor d'scale global (inicialitzat a 1.0 per defecte) +// Factor de scale global (inicialitzat a 1.0 per defecte) float g_current_scale_factor = 1.0F; } // namespace Rendering diff --git a/source/core/rendering/coordinate_transform.hpp b/source/core/rendering/coordinate_transform.hpp index 0d06597..724e7c0 100644 --- a/source/core/rendering/coordinate_transform.hpp +++ b/source/core/rendering/coordinate_transform.hpp @@ -1,5 +1,5 @@ // coordinate_transform.hpp - Transformació de coordenades lògiques a físiques -// © 2025 Port a C++20 amb SDL3 +// © 2025 Port a C++20 con SDL3 #pragma once @@ -7,10 +7,10 @@ namespace Rendering { -// Factor d'scale global (actualitzat cada frame per SDLManager) +// Factor de scale global (actualitzat cada frame per SDLManager) extern float g_current_scale_factor; -// Transforma coordenada lògica a física amb arrodoniment +// Transforma coordenada lógica a física con arrodoniment inline int transform_x(int logical_x, float scale) { return static_cast(std::round(logical_x * scale)); } @@ -19,7 +19,7 @@ inline int transform_y(int logical_y, float scale) { return static_cast(std::round(logical_y * scale)); } -// Variant que usa el factor d'scale global +// Variant que usa el factor de scale global inline int transform_x(int logical_x) { return transform_x(logical_x, g_current_scale_factor); } diff --git a/source/core/rendering/line_renderer.cpp b/source/core/rendering/line_renderer.cpp index 956e499..6d50258 100644 --- a/source/core/rendering/line_renderer.cpp +++ b/source/core/rendering/line_renderer.cpp @@ -1,6 +1,6 @@ -// line_renderer.cpp - Implementació de renderitzat de línies -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 +// line_renderer.cpp - Implementació de renderizado de línies +// © 1999 Visente i Sergi (versión Pascal) +// © 2025 Port a C++20 con SDL3 #include "core/rendering/line_renderer.hpp" diff --git a/source/core/rendering/line_renderer.hpp b/source/core/rendering/line_renderer.hpp index 904a1e2..c800781 100644 --- a/source/core/rendering/line_renderer.hpp +++ b/source/core/rendering/line_renderer.hpp @@ -1,6 +1,6 @@ -// line_renderer.hpp - Renderitzat de línies -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 +// line_renderer.hpp - Renderizado de línies +// © 1999 Visente i Sergi (versión Pascal) +// © 2025 Port a C++20 con SDL3 #pragma once #include @@ -11,7 +11,7 @@ namespace Rendering { // brightness: factor de brightness (0.0-1.0, default 1.0 = màxima brightness). void linea(SDL_Renderer* renderer, int x1, int y1, int x2, int y2, float brightness = 1.0F); -// Estableix el color global de les línies (utilitzat per ColorOscillator). +// Estableix el color global de las línies (utilitzat per ColorOscillator). void setLineColor(SDL_Color color); } // namespace Rendering diff --git a/source/core/rendering/sdl_manager.cpp b/source/core/rendering/sdl_manager.cpp index 12614d5..0e82f98 100644 --- a/source/core/rendering/sdl_manager.cpp +++ b/source/core/rendering/sdl_manager.cpp @@ -1,5 +1,5 @@ // sdl_manager.cpp - Implementació del gestor SDL3 -// © 2025 Port a C++20 amb SDL3 +// © 2025 Port a C++20 con SDL3 #include "sdl_manager.hpp" @@ -38,13 +38,13 @@ SDLManager::SDLManager() // Calcular mida màxima des del display calculateMaxWindowSize(); - // Construir títol dinàmic + // Construir título dinàmic std::string window_title = std::format("{} v{} ({})", Project::LONG_NAME, Project::VERSION, Project::COPYRIGHT); - // Crear finestra CENTRADA (SDL ho fa automàticament amb CENTERED) + // Crear finestra CENTRADA (SDL ho hace automàticament con CENTERED) finestra_ = SDL_CreateWindow(window_title.c_str(), current_width_, current_height_, - SDL_WINDOW_RESIZABLE // Permetre resize manual també + SDL_WINDOW_RESIZABLE // Permetre resize manual también ); if (finestra_ == nullptr) { @@ -56,7 +56,7 @@ SDLManager::SDLManager() // IMPORTANT: Centrar explícitament la finestra SDL_SetWindowPosition(finestra_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); - // Crear renderer amb acceleració + // Crear renderer con aceleración renderer_ = SDL_CreateRenderer(finestra_, nullptr); if (renderer_ == nullptr) { @@ -66,7 +66,7 @@ SDLManager::SDLManager() return; } - // Aplicar configuració de V-Sync + // Aplicar configuración de V-Sync SDL_SetRenderVSync(renderer_, Options::rendering.vsync); // CRÍTIC: Configurar viewport scaling @@ -77,7 +77,7 @@ SDLManager::SDLManager() << Defaults::Game::HEIGHT << ")" << '\n'; } -// Constructor amb configuració +// Constructor con configuración SDLManager::SDLManager(int width, int height, bool fullscreen) : finestra_(nullptr), renderer_(nullptr), @@ -102,7 +102,7 @@ SDLManager::SDLManager(int width, int height, bool fullscreen) // Calcular mida màxima des del display calculateMaxWindowSize(); - // Construir títol dinàmic + // Construir título dinàmic std::string window_title = std::format("{} v{} ({})", Project::LONG_NAME, Project::VERSION, Project::COPYRIGHT); // Configurar flags de la finestra @@ -120,12 +120,12 @@ SDLManager::SDLManager(int width, int height, bool fullscreen) return; } - // Centrar explícitament la finestra (si no és fullscreen) + // Centrar explícitament la finestra (si no es fullscreen) if (!is_fullscreen_) { SDL_SetWindowPosition(finestra_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); } - // Crear renderer amb acceleració + // Crear renderer con aceleración renderer_ = SDL_CreateRenderer(finestra_, nullptr); if (renderer_ == nullptr) { @@ -135,7 +135,7 @@ SDLManager::SDLManager(int width, int height, bool fullscreen) return; } - // Aplicar configuració de V-Sync + // Aplicar configuración de V-Sync SDL_SetRenderVSync(renderer_, Options::rendering.vsync); // Configurar viewport scaling @@ -176,7 +176,7 @@ void SDLManager::calculateMaxWindowSize() { const SDL_DisplayMode* mode = SDL_GetCurrentDisplayMode(display); if (mode != nullptr) { - // Deixar marge de 100px per a decoracions de l'OS + // Deixar marge de 100px para decoracions de l'OS max_width_ = mode->w - 100; max_height_ = mode->h - 100; std::cout << "Display detectat: " << mode->w << "x" << mode->h @@ -253,9 +253,9 @@ void SDLManager::applyZoom(float new_zoom) { } void SDLManager::updateLogicalPresentation() { - // CANVIAT: Ja no usem SDL_SetRenderLogicalPresentation + // CANVIAT: Ya no usem SDL_SetRenderLogicalPresentation // Ara renderitzem directament a resolució física per evitar pixelació irregular - // El viewport amb letterbox es configura a updateViewport() + // El viewport con letterbox es configura a updateViewport() updateViewport(); } @@ -265,7 +265,7 @@ void SDLManager::updateViewport() { int scaled_width = static_cast(std::round(Defaults::Game::WIDTH * scale)); int scaled_height = static_cast(std::round(Defaults::Game::HEIGHT * scale)); - // Càlcul de letterbox (centrar l'àrea escalada) + // Cálculo de letterbox (centrar l'àrea scaled) int offset_x = (current_width_ - scaled_width) / 2; int offset_y = (current_height_ - scaled_height) / 2; @@ -273,7 +273,7 @@ void SDLManager::updateViewport() { offset_x = std::max(offset_x, 0); offset_y = std::max(offset_y, 0); - // Configurar viewport per al renderitzat + // Configurar viewport per al renderizado SDL_Rect viewport = {offset_x, offset_y, scaled_width, scaled_height}; SDL_SetRenderViewport(renderer_, &viewport); @@ -283,7 +283,7 @@ void SDLManager::updateViewport() { } void SDLManager::updateRenderingContext() const { - // Actualitzar el factor d'scale global per a totes les funcions de renderitzat + // Actualitzar el factor de scale global para todas las funciones de renderizado Rendering::g_current_scale_factor = zoom_factor_; } @@ -310,7 +310,7 @@ void SDLManager::decreaseWindowSize() { } void SDLManager::applyWindowSize(int new_width, int new_height) { - // Obtenir posició actual ABANS del resize + // Obtenir posición actual ABANS del resize int old_x; int old_y; SDL_GetWindowPosition(finestra_, &old_x, &old_y); @@ -324,7 +324,7 @@ void SDLManager::applyWindowSize(int new_width, int new_height) { current_height_ = new_height; // CENTRADO INTEL·LIGENT (algoritme de pollo) - // Calcular nova posició per mantenir la finestra centrada sobre si mateixa + // Calcular nueva posición per mantenir la finestra centrada sobre si misma int delta_width = old_width - new_width; int delta_height = old_height - new_height; @@ -332,13 +332,13 @@ void SDLManager::applyWindowSize(int new_width, int new_height) { int new_y = old_y + (delta_height / 2); // Evitar que la finestra surti de la pantalla - constexpr int TITLEBAR_HEIGHT = 35; // Alçada aproximada de la barra de títol + constexpr int TITLEBAR_HEIGHT = 35; // Alçada aproximada de la barra de título new_x = std::max(new_x, 0); new_y = std::max(new_y, TITLEBAR_HEIGHT); SDL_SetWindowPosition(finestra_, new_x, new_y); - // Actualitzar viewport després del resize + // Actualitzar viewport después del resize updateViewport(); } @@ -368,7 +368,7 @@ void SDLManager::toggleFullscreen() { Options::window.fullscreen = is_fullscreen_; // Notificar al mòdul Mouse: Fullscreen requereix ocultació permanent del cursor. - // Quan es surt de fullscreen, restaurar el comportament normal d'auto-ocultació. + // Cuando es surt de fullscreen, restaurar el comportament normal de auto-ocultació. Mouse::setForceHidden(is_fullscreen_); } @@ -387,7 +387,7 @@ bool SDLManager::handleWindowEvent(const SDL_Event& event) { windowed_height_ = current_height_; } - // Actualitzar viewport després del resize manual + // Actualitzar viewport después del resize manual updateViewport(); std::cout << "Finestra redimensionada: " << current_width_ @@ -398,12 +398,12 @@ bool SDLManager::handleWindowEvent(const SDL_Event& event) { return false; } -void SDLManager::neteja(uint8_t r, uint8_t g, uint8_t b) { +void SDLManager::clear(uint8_t r, uint8_t g, uint8_t b) { if (renderer_ == nullptr) { return; } - // [MODIFICAT] Usar color oscil·lat del fons en lloc dels paràmetres + // [MODIFICAT] Usar color oscil·lat del fons en lloc dels parámetros (void)r; (void)g; (void)b; // Suprimir warnings @@ -412,7 +412,7 @@ void SDLManager::neteja(uint8_t r, uint8_t g, uint8_t b) { SDL_RenderClear(renderer_); } -void SDLManager::presenta() { +void SDLManager::present() { if (renderer_ == nullptr) { return; } @@ -420,7 +420,7 @@ void SDLManager::presenta() { SDL_RenderPresent(renderer_); } -// [NUEVO] Actualitzar colors amb oscil·lació +// [NUEVO] Actualitzar colors con oscil·lació void SDLManager::updateColors(float delta_time) { color_oscillator_.update(delta_time); @@ -428,7 +428,7 @@ void SDLManager::updateColors(float delta_time) { Rendering::setLineColor(color_oscillator_.getCurrentLineColor()); } -// [NUEVO] Actualitzar comptador de FPS +// [NUEVO] Actualitzar counter de FPS void SDLManager::updateFPS(float delta_time) { // Acumular time i frames fps_accumulator_ += delta_time; @@ -440,7 +440,7 @@ void SDLManager::updateFPS(float delta_time) { fps_frame_count_ = 0; fps_accumulator_ = 0.0F; - // Actualitzar títol de la finestra + // Actualitzar título de la finestra std::string vsync_state = (Options::rendering.vsync == 1) ? "ON" : "OFF"; std::string title = std::format("{} v{} ({}) - {} FPS - VSync: {}", Project::LONG_NAME, @@ -455,7 +455,7 @@ void SDLManager::updateFPS(float delta_time) { } } -// [NUEVO] Actualitzar títol de la finestra +// [NUEVO] Actualitzar título de la finestra void SDLManager::setWindowTitle(const std::string& title) { if (finestra_ != nullptr) { SDL_SetWindowTitle(finestra_, title.c_str()); @@ -476,6 +476,6 @@ void SDLManager::toggleVSync() { fps_accumulator_ = 0.0F; fps_frame_count_ = 0; - // Guardar configuració + // Guardar configuración Options::saveToFile(); } diff --git a/source/core/rendering/sdl_manager.hpp b/source/core/rendering/sdl_manager.hpp index fffcd73..9bd8ab1 100644 --- a/source/core/rendering/sdl_manager.hpp +++ b/source/core/rendering/sdl_manager.hpp @@ -1,8 +1,7 @@ -// sdl_manager.hpp - Gestor d'inicialització de SDL3 -// © 2025 Port a C++20 amb SDL3 +// sdl_manager.hpp - Gestor de inicialización de SDL3 +// © 2025 Port a C++20 con SDL3 -#ifndef SDL_MANAGER_HPP -#define SDL_MANAGER_HPP +#pragma once #include @@ -14,7 +13,7 @@ class SDLManager { public: SDLManager(); // Constructor per defecte (usa Defaults::) - SDLManager(int width, int height, bool fullscreen); // Constructor amb configuració + SDLManager(int width, int height, bool fullscreen); // Constructor con configuración ~SDLManager(); // No permetre còpia ni assignació @@ -28,24 +27,24 @@ class SDLManager { void toggleVSync(); // F4 bool handleWindowEvent(const SDL_Event& event); // Per a SDL_EVENT_WINDOW_RESIZED - // Funcions principals (renderitzat) - void neteja(uint8_t r = 0, uint8_t g = 0, uint8_t b = 0); - void presenta(); + // Funciones principals (renderizado) + void clear(uint8_t r = 0, uint8_t g = 0, uint8_t b = 0); + void present(); // [NUEVO] Actualització de colors (oscil·lació) void updateColors(float delta_time); - // [NUEVO] Actualitzar comptador de FPS + // [NUEVO] Actualitzar counter de FPS void updateFPS(float delta_time); // Getters SDL_Renderer* getRenderer() { return renderer_; } [[nodiscard]] float getScaleFactor() const { return zoom_factor_; } - // [NUEVO] Actualitzar títol de la finestra + // [NUEVO] Actualitzar título de la finestra void setWindowTitle(const std::string& title); - // [NUEVO] Actualitzar context de renderitzat (factor d'scale global) + // [NUEVO] Actualitzar context de renderizado (factor de scale global) void updateRenderingContext() const; private: @@ -70,16 +69,14 @@ class SDLManager { int windowed_height_; // Saved size before fullscreen float max_zoom_; // Maximum zoom (calculated from display) - // [NUEVO] Funcions internes + // [NUEVO] Funciones internes void calculateMaxWindowSize(); // Llegir resolució del display void calculateMaxZoom(); // Calculate max zoom from display void applyZoom(float new_zoom); // Apply zoom and resize window void applyWindowSize(int width, int height); // Canviar mida + centrar void updateLogicalPresentation(); // Actualitzar viewport - void updateViewport(); // Configurar viewport amb letterbox + void updateViewport(); // Configurar viewport con letterbox // [NUEVO] Oscil·lador de colors Rendering::ColorOscillator color_oscillator_; }; - -#endif // SDL_MANAGER_HPP diff --git a/source/core/rendering/shape_renderer.cpp b/source/core/rendering/shape_renderer.cpp index f83c208..af81e56 100644 --- a/source/core/rendering/shape_renderer.cpp +++ b/source/core/rendering/shape_renderer.cpp @@ -1,5 +1,5 @@ -// shape_renderer.cpp - Implementació del renderitzat de formes -// © 2025 Port a C++20 amb SDL3 +// shape_renderer.cpp - Implementació del renderizado de formes +// © 2025 Port a C++20 con SDL3 #include "core/rendering/shape_renderer.hpp" @@ -10,65 +10,65 @@ namespace Rendering { -// Helper: aplicar rotació 3D a un point 2D (assumeix Z=0) +// Helper: aplicar rotación 3D a un point 2D (assumeix Z=0) static Vec2 apply_3d_rotation(float x, float y, const Rotation3D& rot) { - float z = 0.0F; // Tots els points 2D comencen a Z=0 + float z = 0.0F; // Todos los points 2D comencen a Z=0 - // Pitch (rotació eix X): cabeceo arriba/baix + // Pitch (rotación eix X): cabeceo arriba/baix float cos_pitch = std::cos(rot.pitch); float sin_pitch = std::sin(rot.pitch); float y1 = (y * cos_pitch) - (z * sin_pitch); float z1 = (y * sin_pitch) + (z * cos_pitch); - // Yaw (rotació eix Y): guiñada esquerra/dreta + // Yaw (rotación eix Y): guiñada izquierda/derecha float cos_yaw = std::cos(rot.yaw); float sin_yaw = std::sin(rot.yaw); float x2 = (x * cos_yaw) + (z1 * sin_yaw); float z2 = (-x * sin_yaw) + (z1 * cos_yaw); - // Roll (rotació eix Z): alabeo lateral + // Roll (rotación eix Z): alabeo lateral float cos_roll = std::cos(rot.roll); float sin_roll = std::sin(rot.roll); float x3 = (x2 * cos_roll) - (y1 * sin_roll); float y3 = (x2 * sin_roll) + (y1 * cos_roll); // Proyecció perspectiva (Z-divide simple) - // Naus volen cap al point de fuga (320, 240) a "infinit" (Z → +∞) - // Z més gran = més lluny = més petit a pantalla + // Naves quieren hacia el point de fuga (320, 240) a "infinit" (Z → +∞) + // Z més grande = més lluny = més pequeño a pantalla constexpr float perspective_factor = 500.0F; float scale_factor = perspective_factor / (perspective_factor + z2); return {.x = x3 * scale_factor, .y = y3 * scale_factor}; } -// Helper: transformar un point amb rotació, scale i trasllació +// Helper: transformar un point con rotación, scale i traslación static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const Vec2& position, float angle, float scale, const Rotation3D* rotation_3d) { - // 1. Centrar el point respecte al centre de la shape + // 1. Centrar el point respecte al centro de la shape float centered_x = point.x - shape_centre.x; float centered_y = point.y - shape_centre.y; - // 2. Aplicar rotació 3D (si es proporciona) + // 2. Aplicar rotación 3D (si es proporciona) if ((rotation_3d != nullptr) && rotation_3d->has_rotation()) { Vec2 rotated_3d = apply_3d_rotation(centered_x, centered_y, *rotation_3d); centered_x = rotated_3d.x; centered_y = rotated_3d.y; } - // 3. Aplicar scale al point (després de rotació 3D) + // 3. Aplicar scale al point (después de rotación 3D) float scaled_x = centered_x * scale; float scaled_y = centered_y * scale; - // 4. Aplicar rotació 2D (Z-axis, tradicional) - // IMPORTANT: En el sistema original, angle=0 apunta AMUNT (no dreta) + // 4. Aplicar rotación 2D (Z-axis, tradicional) + // IMPORTANT: En el sistema original, angle=0 apunta AMUNT (no derecha) // Per això usem (angle - PI/2) per compensar - // Però aquí angle ja ve en el sistema correcte del joc + // Pero aquí angle ya ve en el sistema correcte del juego float cos_a = std::cos(angle); float sin_a = std::sin(angle); float rotated_x = (scaled_x * cos_a) - (scaled_y * sin_a); float rotated_y = (scaled_x * sin_a) + (scaled_y * cos_a); - // 5. Aplicar trasllació a posició mundial + // 5. Aplicar traslación a posición mundial return {.x = rotated_x + position.x, .y = rotated_y + position.y}; } @@ -80,7 +80,7 @@ void render_shape(SDL_Renderer* renderer, float progress, float brightness, const Rotation3D* rotation_3d) { - // Verificar que la shape és vàlida + // Verificar que la shape es vàlida if (!shape || !shape->isValid()) { return; } @@ -90,10 +90,10 @@ void render_shape(SDL_Renderer* renderer, return; } - // Obtenir el centre de la shape per a transformacions + // Obtenir el centro de la shape para transformacions const Vec2& shape_centre = shape->getCenter(); - // Iterar sobre totes les primitives + // Iterar sobre todas las primitives for (const auto& primitive : shape->get_primitives()) { if (primitive.type == Graphics::PrimitiveType::POLYLINE) { // POLYLINE: connectar points consecutius diff --git a/source/core/rendering/shape_renderer.hpp b/source/core/rendering/shape_renderer.hpp index c15fe91..f894c98 100644 --- a/source/core/rendering/shape_renderer.hpp +++ b/source/core/rendering/shape_renderer.hpp @@ -1,5 +1,5 @@ -// shape_renderer.hpp - Renderitzat de formes vectorials -// © 2025 Port a C++20 amb SDL3 +// shape_renderer.hpp - Renderizado de formes vectorials +// © 2025 Port a C++20 con SDL3 #pragma once @@ -14,9 +14,9 @@ namespace Rendering { // Estructura per rotacions 3D (pitch, yaw, roll) struct Rotation3D { - float pitch; // Rotació eix X (cabeceo arriba/baix) - float yaw; // Rotació eix Y (guiñada esquerra/dreta) - float roll; // Rotació eix Z (alabeo lateral) + float pitch; // Rotación eix X (cabeceo arriba/baix) + float yaw; // Rotación eix Y (guiñada izquierda/derecha) + float roll; // Rotación eix Z (alabeo lateral) Rotation3D() : pitch(0.0F), @@ -32,13 +32,13 @@ struct Rotation3D { } }; -// Renderitzar shape amb transformacions +// Renderizar shape con transformacions // - renderer: SDL renderer // - shape: shape vectorial a draw -// - position: posició del centre en coordenades mundials -// - angle: rotació en radians (0 = amunt, sentit horari) -// - scale: factor d'scale (1.0 = mida original) -// - progress: progrés de l'animació (0.0-1.0, default 1.0 = tot visible) +// - position: posición del centro en coordenades mundials +// - angle: rotación en radians (0 = amunt, sentit horari) +// - scale: factor de scale (1.0 = mida original) +// - progress: progrés de l'animación (0.0-1.0, default 1.0 = tot visible) // - brightness: factor de brightness (0.0-1.0, default 1.0 = màxima brightness) void render_shape(SDL_Renderer* renderer, const std::shared_ptr& shape, diff --git a/source/core/resources/resource_helper.cpp b/source/core/resources/resource_helper.cpp index 4c8e09c..50c37fb 100644 --- a/source/core/resources/resource_helper.cpp +++ b/source/core/resources/resource_helper.cpp @@ -1,5 +1,5 @@ -// resource_helper.cpp - Implementació de funcions d'ajuda -// © 2025 Port a C++20 amb SDL3 +// resource_helper.cpp - Implementació de funciones de ajuda +// © 2025 Port a C++20 con SDL3 #include "resource_helper.hpp" @@ -15,7 +15,7 @@ bool initializeResourceSystem(const std::string& pack_file, bool fallback) { return Loader::get().initialize(pack_file, fallback); } -// Carregar un fitxer +// Carregar un file std::vector loadFile(const std::string& filepath) { // Normalitzar la ruta std::string normalized = normalizePath(filepath); @@ -24,7 +24,7 @@ std::vector loadFile(const std::string& filepath) { return Loader::get().loadResource(normalized); } -// Comprovar si existeix un fitxer +// Comprovar si existeix un file bool fileExists(const std::string& filepath) { std::string normalized = normalizePath(filepath); return Loader::get().resourceExists(normalized); @@ -37,7 +37,7 @@ std::string getPackPath(const std::string& asset_path) { // Eliminar rutes absolutes (detectar / o C:\ al principi) if (!path.empty() && path[0] == '/') { - // Buscar "data/" i agafar el que ve després + // Buscar "data/" i agafar el que ve después size_t data_pos = path.find("/data/"); if (data_pos != std::string::npos) { path = path.substr(data_pos + 6); // Saltar "/data/" @@ -73,7 +73,7 @@ std::string normalizePath(const std::string& path) { return getPackPath(path); } -// Comprovar si hi ha paquet carregat +// Comprovar si hay paquet carregat bool isPackLoaded() { return Loader::get().isPackLoaded(); } diff --git a/source/core/resources/resource_helper.hpp b/source/core/resources/resource_helper.hpp index 1c64f02..dbb30ee 100644 --- a/source/core/resources/resource_helper.hpp +++ b/source/core/resources/resource_helper.hpp @@ -1,5 +1,5 @@ -// resource_helper.hpp - Funcions d'ajuda per gestió de recursos -// © 2025 Port a C++20 amb SDL3 +// resource_helper.hpp - Funciones de ajuda per gestió de recursos +// © 2025 Port a C++20 con SDL3 // API simplificada i normalització de rutes #pragma once @@ -10,10 +10,10 @@ namespace Resource::Helper { -// Inicialització del sistema +// Inicialización del sistema bool initializeResourceSystem(const std::string& pack_file, bool fallback); -// Càrrega de fitxers +// Càrrega de archivos std::vector loadFile(const std::string& filepath); bool fileExists(const std::string& filepath); diff --git a/source/core/resources/resource_loader.cpp b/source/core/resources/resource_loader.cpp index ffcb8f1..af8113b 100644 --- a/source/core/resources/resource_loader.cpp +++ b/source/core/resources/resource_loader.cpp @@ -1,5 +1,5 @@ // resource_loader.cpp - Implementació del carregador de recursos -// © 2025 Port a C++20 amb SDL3 +// © 2025 Port a C++20 con SDL3 #include "resource_loader.hpp" @@ -25,12 +25,12 @@ bool Loader::initialize(const std::string& pack_file, bool enable_fallback) { if (!pack_->loadPack(pack_file)) { if (!fallback_enabled_) { std::cerr << "[ResourceLoader] ERROR FATAL: No es pot load " << pack_file - << " i el fallback està desactivat\n"; + << " y el fallback está desactivat\n"; return false; } - std::cout << "[ResourceLoader] Paquet no trobat, usant fallback al sistema de fitxers\n"; - pack_.reset(); // No hi ha paquet + std::cout << "[ResourceLoader] Paquet no trobat, usant fallback al sistema de archivos\n"; + pack_.reset(); // No hay paquet return true; } @@ -51,7 +51,7 @@ std::vector Loader::loadResource(const std::string& filename) { << "\n"; } - // Si no està al paquet i no hi ha fallback, falla + // Si no está al paquet y no hay fallback, falla if (!fallback_enabled_) { std::cerr << "[ResourceLoader] ERROR: Recurs no trobat al paquet i fallback desactivat: " << filename << "\n"; @@ -59,7 +59,7 @@ std::vector Loader::loadResource(const std::string& filename) { } } - // Fallback al sistema de fitxers + // Fallback al sistema de archivos if (fallback_enabled_) { return loadFromFilesystem(filename); } @@ -74,7 +74,7 @@ bool Loader::resourceExists(const std::string& filename) { return true; } - // Comprovar al sistema de fitxers si està activat el fallback + // Comprovar al sistema de archivos si está activat el fallback if (fallback_enabled_) { std::string fullpath = base_path_.empty() ? "data/" + filename : base_path_ + "/data/" + filename; return std::filesystem::exists(fullpath); @@ -86,14 +86,14 @@ bool Loader::resourceExists(const std::string& filename) { // Validar el paquet bool Loader::validatePack() { if (!pack_) { - std::cerr << "[ResourceLoader] Advertència: no hi ha paquet carregat per validar\n"; + std::cerr << "[ResourceLoader] Advertència: no hay paquet carregat per validar\n"; return false; } return pack_->validatePack(); } -// Comprovar si hi ha paquet carregat +// Comprovar si hay paquet carregat bool Loader::isPackLoaded() const { return pack_ != nullptr; } @@ -109,7 +109,7 @@ std::string Loader::getBasePath() const { return base_path_; } -// Carregar des del sistema de fitxers (fallback) +// Carregar des del sistema de archivos (fallback) std::vector Loader::loadFromFilesystem(const std::string& filename) { // The filename is already normalized (e.g., "shapes/logo/letra_j.shp") // We need to prepend base_path + "data/" @@ -136,7 +136,7 @@ std::vector Loader::loadFromFilesystem(const std::string& filename) { return {}; } - std::cout << "[ResourceLoader] Carregat des del sistema de fitxers: " << fullpath << "\n"; + std::cout << "[ResourceLoader] Carregat des del sistema de archivos: " << fullpath << "\n"; return data; } diff --git a/source/core/resources/resource_loader.hpp b/source/core/resources/resource_loader.hpp index 3d501ab..08fcfa3 100644 --- a/source/core/resources/resource_loader.hpp +++ b/source/core/resources/resource_loader.hpp @@ -1,6 +1,6 @@ // resource_loader.hpp - Carregador de recursos (Singleton) -// © 2025 Port a C++20 amb SDL3 -// Coordina càrrega des del paquet i/o sistema de fitxers +// © 2025 Port a C++20 con SDL3 +// Coordina càrrega des del paquet i/o sistema de archivos #pragma once @@ -18,7 +18,7 @@ class Loader { // Singleton static Loader& get(); - // Inicialització + // Inicialización bool initialize(const std::string& pack_file, bool enable_fallback); // Càrrega de recursos @@ -46,7 +46,7 @@ class Loader { bool fallback_enabled_ = false; std::string base_path_; - // Funcions auxiliars + // Funciones auxiliars std::vector loadFromFilesystem(const std::string& filename); }; diff --git a/source/core/resources/resource_pack.cpp b/source/core/resources/resource_pack.cpp index 4c4adbd..8d9d506 100644 --- a/source/core/resources/resource_pack.cpp +++ b/source/core/resources/resource_pack.cpp @@ -1,5 +1,5 @@ -// resource_pack.cpp - Implementació del sistema d'empaquetament -// © 2025 Port a C++20 amb SDL3 +// resource_pack.cpp - Implementació del sistema de empaquetament +// © 2025 Port a C++20 con SDL3 #include "resource_pack.hpp" @@ -30,11 +30,11 @@ void Pack::encryptData(std::vector& data, const std::string& key) { } void Pack::decryptData(std::vector& data, const std::string& key) { - // XOR és simètric + // XOR es simètric encryptData(data, key); } -// Llegir fitxer complet a memòria +// Llegir file complet a memòria std::vector Pack::readFile(const std::string& filepath) { std::ifstream file(filepath, std::ios::binary | std::ios::ate); if (!file) { @@ -54,7 +54,7 @@ std::vector Pack::readFile(const std::string& filepath) { return data; } -// Afegir un fitxer individual al paquet +// Añadir un file individual al paquet bool Pack::addFile(const std::string& filepath, const std::string& pack_name) { auto file_data = readFile(filepath); if (file_data.empty()) { @@ -67,17 +67,17 @@ bool Pack::addFile(const std::string& filepath, const std::string& pack_name) { .size = file_data.size(), .checksum = calculateChecksum(file_data)}; - // Afegir dades al bloc de dades + // Añadir dades al bloc de dades data_.insert(data_.end(), file_data.begin(), file_data.end()); resources_[pack_name] = entry; - std::cout << "[ResourcePack] Afegit: " << pack_name << " (" << file_data.size() + std::cout << "[ResourcePack] Añadido: " << pack_name << " (" << file_data.size() << " bytes)\n"; return true; } -// Afegir tots els fitxers d'un directori recursivament +// Añadir todos los archivos de un directori recursivament bool Pack::addDirectory(const std::string& dir_path, const std::string& base_path) { namespace fs = std::filesystem; @@ -100,7 +100,7 @@ bool Pack::addDirectory(const std::string& dir_path, // Convertir barres invertides a normals (Windows) std::ranges::replace(relative_path, '\\', '/'); - // Saltar fitxers de desenvolupament + // Saltar archivos de desenvolupament if (relative_path.find(".world") != std::string::npos || relative_path.find(".tsx") != std::string::npos || relative_path.find(".DS_Store") != std::string::npos || @@ -134,7 +134,7 @@ bool Pack::savePack(const std::string& pack_file) { // Escriure metadades de recursos for (const auto& [name, entry] : resources_) { - // Nom del fitxer + // Nom del file auto name_len = static_cast(entry.filename.length()); file.write(reinterpret_cast(&name_len), sizeof(name_len)); file.write(entry.filename.c_str(), name_len); @@ -149,7 +149,7 @@ bool Pack::savePack(const std::string& pack_file) { std::vector encrypted_data = data_; encryptData(encrypted_data, DEFAULT_ENCRYPT_KEY); - // Escriure mida de dades i dades encriptades + // Escriure mida de dades y dades encriptades auto data_size = static_cast(encrypted_data.size()); file.write(reinterpret_cast(&data_size), sizeof(data_size)); file.write(reinterpret_cast(encrypted_data.data()), encrypted_data.size()); @@ -160,7 +160,7 @@ bool Pack::savePack(const std::string& pack_file) { return true; } -// Carregar paquet des de disc +// Carregar paquet desde disc bool Pack::loadPack(const std::string& pack_file) { std::ifstream file(pack_file, std::ios::binary); if (!file) { @@ -180,7 +180,7 @@ bool Pack::loadPack(const std::string& pack_file) { uint32_t version; file.read(reinterpret_cast(&version), sizeof(version)); if (version != VERSION) { - std::cerr << "[ResourcePack] Error: versió incompatible (esperava " << VERSION + std::cerr << "[ResourcePack] Error: versión incompatible (esperava " << VERSION << ", trobat " << version << ")\n"; return false; } @@ -192,7 +192,7 @@ bool Pack::loadPack(const std::string& pack_file) { // Llegir metadades de recursos resources_.clear(); for (uint32_t i = 0; i < resource_count; ++i) { - // Nom del fitxer + // Nom del file uint32_t name_len; file.read(reinterpret_cast(&name_len), sizeof(name_len)); @@ -250,7 +250,7 @@ std::vector Pack::getResource(const std::string& filename) { std::cerr << "[ResourcePack] ADVERTÈNCIA: checksum invàlid per " << filename << " (esperat " << entry.checksum << ", calculat " << computed_checksum << ")\n"; - // No falla, però adverteix + // No falla, pero adverteix } return resource_data; @@ -261,7 +261,7 @@ bool Pack::hasResource(const std::string& filename) const { return resources_.contains(filename); } -// Obtenir llista de tots els recursos +// Obtenir list de todos los recursos std::vector Pack::getResourceList() const { std::vector list; list.reserve(resources_.size()); diff --git a/source/core/resources/resource_pack.hpp b/source/core/resources/resource_pack.hpp index 63869e7..84ba874 100644 --- a/source/core/resources/resource_pack.hpp +++ b/source/core/resources/resource_pack.hpp @@ -1,6 +1,6 @@ -// resource_pack.hpp - Sistema d'empaquetament de recursos -// © 2025 Port a C++20 amb SDL3 -// Basat en el sistema de "pollo" amb adaptacions per Orni Attack +// resource_pack.hpp - Sistema de empaquetament de recursos +// © 2025 Port a C++20 con SDL3 +// Basat en el sistema de "pollo" con adaptacions per Orni Attack #pragma once @@ -11,27 +11,27 @@ namespace Resource { -// Capçalera del fitxer de paquet +// Capçalera del file de paquet struct PackHeader { char magic[4]; // "ORNI" - uint32_t version; // Versió del format (1) + uint32_t version; // Versión del format (1) }; // Entrada de recurs dins el paquet struct ResourceEntry { - std::string filename; // Nom del recurs (amb barres normals) - uint64_t offset; // Posició dins el bloc de dades + std::string filename; // Nom del recurs (con barres normals) + uint64_t offset; // Posición dins el bloc de dades uint64_t size; // Mida en bytes uint32_t checksum; // Checksum CRC32 per verificació }; -// Classe principal per gestionar paquets de recursos +// Clase principal per gestionar paquets de recursos class Pack { public: Pack() = default; ~Pack() = default; - // Afegir fitxers al paquet + // Añadir archivos al paquet bool addFile(const std::string& filepath, const std::string& pack_name); bool addDirectory(const std::string& dir_path, const std::string& base_path = ""); @@ -57,7 +57,7 @@ class Pack { std::unordered_map resources_; std::vector data_; - // Funcions auxiliars + // Funciones auxiliars std::vector readFile(const std::string& filepath); [[nodiscard]] uint32_t calculateChecksum(const std::vector& data) const; void encryptData(std::vector& data, const std::string& key); diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index b4879ad..4096a13 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -36,7 +36,7 @@ using SceneType = SceneContext::SceneType; Director::Director(std::vector const& args) { std::cout << "Orni Attack - Inici\n"; - // Inicialitzar opcions amb valors per defecte + // Inicialitzar opciones con valors per defecte Options::init(); // Comprovar arguments del programa @@ -50,28 +50,28 @@ Director::Director(std::vector const& args) { // Inicialitzar sistema de recursos #ifdef RELEASE_BUILD - // Mode release: paquet obligatori, sense fallback + // Mode release: paquet obligatori, sin fallback std::string pack_path = resource_base + "/resources.pack"; if (!Resource::Helper::initializeResourceSystem(pack_path, false)) { std::cerr << "ERROR FATAL: No es pot load " << pack_path << "\n"; - std::cerr << "El joc no pot continuar sense els recursos.\n"; + std::cerr << "El juego no pot continuar sin los recursos.\n"; std::exit(1); } // Validar integritat del paquet if (!Resource::Loader::get().validatePack()) { - std::cerr << "ERROR FATAL: El paquet de recursos està corromput\n"; + std::cerr << "ERROR FATAL: El paquet de recursos está corromput\n"; std::exit(1); } std::cout << "Sistema de recursos inicialitzat (mode release)\n"; #else - // Mode desenvolupament: intentar paquet amb fallback a data/ + // Mode desenvolupament: intentar paquet con fallback a data/ std::string pack_path = resource_base + "/resources.pack"; Resource::Helper::initializeResourceSystem(pack_path, true); if (Resource::Helper::isPackLoaded()) { - std::cout << "Sistema de recursos inicialitzat (mode dev amb paquet)\n"; + std::cout << "Sistema de recursos inicialitzat (mode dev con paquet)\n"; } else { std::cout << "Sistema de recursos inicialitzat (mode dev, fallback a data/)\n"; } @@ -84,21 +84,21 @@ Director::Director(std::vector const& args) { createSystemFolder("jailgames"); createSystemFolder(std::string("jailgames/") + Project::NAME); - // Establir ruta del fitxer de configuració + // Establir ruta del file de configuración Options::setConfigFile(system_folder_ + "/config.yaml"); - // Carregar o crear configuració + // Carregar o crear configuración Options::loadFromFile(); - // Inicialitzar sistema d'input + // Inicialitzar sistema de input Input::init("data/gamecontrollerdb.txt"); - // Aplicar configuració de controls dels jugadors + // Aplicar configuración de controls dels jugadors Input::get()->applyPlayer1BindingsFromOptions(); Input::get()->applyPlayer2BindingsFromOptions(); if (Options::console) { - std::cout << "Configuració carregada\n"; + std::cout << "Configuración carregada\n"; std::cout << " Finestra: " << Options::window.width << "×" << Options::window.height << '\n'; std::cout << " Física: rotation=" << Options::physics.rotation_speed @@ -111,7 +111,7 @@ Director::Director(std::vector const& args) { } Director::~Director() { - // Guardar opcions + // Guardar opciones Options::saveToFile(); // Cleanup input @@ -138,7 +138,7 @@ auto Director::checkProgramArguments(std::vector const& args) } else if (argument == "--reset-config") { Options::init(); Options::saveToFile(); - std::cout << "Configuració restablida als valors per defecte\n"; + std::cout << "Configuración restablida als valors per defecte\n"; } } @@ -188,7 +188,7 @@ void Director::createSystemFolder(const std::string& folder) { exit(EXIT_FAILURE); case EEXIST: - // La carpeta ja existeix (race condition), continuar + // La carpeta ya existeix (race condition), continuar break; case ENAMETOOLONG: @@ -207,7 +207,7 @@ void Director::createSystemFolder(const std::string& folder) { } } -// Bucle principal del joc +// Bucle principal del juego auto Director::run() -> int { // Calculate initial size from saved zoom_factor int initial_width = static_cast(std::round( @@ -215,16 +215,16 @@ auto Director::run() -> int { int initial_height = static_cast(std::round( Defaults::Window::HEIGHT * Options::window.zoom_factor)); - // Crear gestor SDL amb configuració de Options + // Crear gestor SDL con configuración de Options SDLManager sdl(initial_width, initial_height, Options::window.fullscreen); - // CRÍTIC: Forçar ocultació del cursor DESPRÉS de tota la inicialització SDL - // Això evita que SDL mostre el cursor automàticament durant la creació de la finestra + // CRÍTIC: Forçar ocultació del cursor DESPRÉS de toda la inicialización SDL + // Això evita que SDL mostre el cursor automàticament durante la creació de la finestra if (!Options::window.fullscreen) { Mouse::forceHide(); } - // Inicialitzar sistema d'audio + // Inicialitzar sistema de audio Audio::init(); Audio::get()->setMusicVolume(1.0); Audio::get()->setSoundVolume(0.4); @@ -234,10 +234,10 @@ auto Director::run() -> int { AudioCache::getMusic("game.ogg"); if (Options::console) { std::cout << "Música precachejada: " - << AudioCache::getMusicCacheSize() << " fitxers\n"; + << AudioCache::getMusicCacheSize() << " archivos\n"; } - // Crear context d'escenes + // Crear context de escenes SceneContext context; #ifdef _DEBUG context.setNextScene(SceneType::TITLE); @@ -245,10 +245,10 @@ auto Director::run() -> int { context.setNextScene(SceneType::LOGO); #endif - // Bucle principal de gestió d'escenes + // Bucle principal de gestió de escenes while (context.nextScene() != SceneType::EXIT) { - // Sincronitzar SceneManager::actual amb context - // (altres sistemes encara poden llegir SceneManager::actual) + // Sincronitzar SceneManager::actual con context + // (altres sistemes aún poden llegir SceneManager::actual) SceneManager::actual = context.nextScene(); switch (context.nextScene()) { @@ -265,8 +265,8 @@ auto Director::run() -> int { } case SceneType::GAME: { - GameScene joc(sdl, context); - joc.run(); + GameScene juego(sdl, context); + juego.run(); break; } @@ -275,7 +275,7 @@ auto Director::run() -> int { } } - // Sincronitzar final amb SceneManager::actual + // Sincronitzar final con SceneManager::actual SceneManager::actual = SceneType::EXIT; return 0; diff --git a/source/core/system/game_config.hpp b/source/core/system/game_config.hpp index 59ccf8c..72454a4 100644 --- a/source/core/system/game_config.hpp +++ b/source/core/system/game_config.hpp @@ -4,32 +4,32 @@ namespace GameConfig { -// Mode de joc +// Mode de juego enum class Mode { NORMAL, // Partida normal DEMO // Mode demostració (futur) }; -// Configuració d'una match +// Configuración de una match struct MatchConfig { - bool jugador1_actiu{false}; // És active el player 1? - bool jugador2_actiu{false}; // És active el player 2? - Mode mode{Mode::NORMAL}; // Mode de joc + bool jugador1_actiu{false}; // Es active el player 1? + bool jugador2_actiu{false}; // Es active el player 2? + Mode mode{Mode::NORMAL}; // Mode de juego - // Mètodes auxiliars + // Métodos auxiliars - // Retorna true si només hi ha un player active + // Retorna true si solo hay un player active [[nodiscard]] bool es_un_jugador() const { return (jugador1_actiu && !jugador2_actiu) || (!jugador1_actiu && jugador2_actiu); } - // Retorna true si hi ha dos jugadors active + // Retorna true si hay dos jugadors active [[nodiscard]] bool son_dos_jugadors() const { return jugador1_actiu && jugador2_actiu; } - // Retorna true si no hi ha cap player active + // Retorna true si no hay sin player active [[nodiscard]] bool cap_jugador() const { return !jugador1_actiu && !jugador2_actiu; } @@ -40,7 +40,7 @@ struct MatchConfig { } // Retorna l'ID de l'únic player active (0 o 1) - // Només vàlid si es_un_jugador() retorna true + // Solo vàlid si es_un_jugador() retorna true [[nodiscard]] uint8_t id_unic_jugador() const { if (jugador1_actiu && !jugador2_actiu) { return 0; @@ -48,7 +48,7 @@ struct MatchConfig { if (!jugador1_actiu && jugador2_actiu) { return 1; } - return 0; // Fallback (cal comprovar es_un_jugador() primer) + return 0; // Fallback (necesario comprovar es_un_jugador() primer) } }; diff --git a/source/core/system/global_events.hpp b/source/core/system/global_events.hpp index c52b014..c96fd0c 100644 --- a/source/core/system/global_events.hpp +++ b/source/core/system/global_events.hpp @@ -1,4 +1,4 @@ -// global_events.hpp - Events globals del joc +// global_events.hpp - Events globals del juego // Basat en el patró del projecte "pollo" // © 2025 Port a C++20 @@ -14,6 +14,6 @@ class SceneContext; namespace GlobalEvents { // Processa events globals (F1/F2/F3/ESC/QUIT) -// Retorna true si l'event ha state processat i no cal seguir processant-lo +// Retorna true si l'event ha state processat y no necesario seguir processant-lo bool handle(const SDL_Event& event, SDLManager& sdl, SceneManager::SceneContext& context); } // namespace GlobalEvents diff --git a/source/core/system/scene_context.hpp b/source/core/system/scene_context.hpp index 3163f65..b7a4b04 100644 --- a/source/core/system/scene_context.hpp +++ b/source/core/system/scene_context.hpp @@ -1,4 +1,4 @@ -// context_escenes.hpp - Sistema de gestió d'escenes i context de transicions +// scene_context.hpp - Sistema de gestió de escenes i context de transiciones // © 2025 Port a C++20 #pragma once @@ -7,29 +7,29 @@ namespace SceneManager { -// Context de transició entre escenes -// Conté l'escena destinació i opcions específiques per aquella escena +// Context de transición entre escenes +// Conté l'escena destinació i opciones específiques per aquella escena class SceneContext { public: - // Tipus d'escena del joc + // Tipo de escena del juego enum class SceneType { - LOGO, // Pantalla d'inici (logo JAILGAMES) - TITLE, // Pantalla de títol amb menú - GAME, // Joc principal (Asteroids) - EXIT // Sortir del programa + LOGO, // Pantalla de start (logo JAILGAMES) + TITLE, // Pantalla de título con menú + GAME, // Juego principal (Asteroids) + EXIT // Salir del programa }; - // Opcions específiques per a cada escena + // Opciones específiques para cada escena enum class Option { - NONE, // Sense opcions especials (comportament per defecte) + NONE, // Sin opciones especials (comportament per defecte) JUMP_TO_TITLE_MAIN, // TITLE: Saltar directament a MAIN (starfield instantani) - // MODE_DEMO, // GAME: Mode demostració amb IA (futur) + // MODE_DEMO, // GAME: Mode demostració con IA (futur) }; - // Constructor inicial amb escena LOGO i sense opcions + // Constructor inicial con escena LOGO i sin opciones SceneContext() = default; - // Canviar escena amb opció específica + // Canviar escena con opción específica void setNextScene(SceneType next_scene, Option option = Option::NONE) { next_scene_ = next_scene; option_ = option; @@ -40,42 +40,42 @@ class SceneContext { return next_scene_; } - // Consultar opció actual + // Consultar opción actual [[nodiscard]] auto option() const -> Option { return option_; } - // Consumir opció (retorna valor i reseteja a NONE) - // Utilitzar quan l'escena processa l'opció + // Consumir opción (retorna value i reseteja a NONE) + // Utilitzar cuando l'escena processa l'opción [[nodiscard]] auto consumeOption() -> Option { - Option valor = option_; + Option value = option_; option_ = Option::NONE; - return valor; + return value; } - // Reset opció a NONE (sense retornar valor) + // Reset opción a NONE (sin retornar value) void resetOption() { option_ = Option::NONE; } - // Configurar match abans de transicionar a GAME + // Configurar match antes de transicionar a GAME void setMatchConfig(const GameConfig::MatchConfig& config) { match_config_ = config; } - // Obtenir configuració de match (consumit per GameScene) + // Obtenir configuración de match (consumit per GameScene) [[nodiscard]] const GameConfig::MatchConfig& getMatchConfig() const { return match_config_; } private: SceneType next_scene_{SceneType::LOGO}; // SceneType a la qual transicionar - Option option_{Option::NONE}; // Opció específica per l'escena - GameConfig::MatchConfig match_config_; // Configuració de match (jugadors active, mode) + Option option_{Option::NONE}; // Opción específica per l'escena + GameConfig::MatchConfig match_config_; // Configuración de match (jugadors active, mode) }; // Variable global inline per gestionar l'escena actual (backward compatibility) -// Sincronitzada amb context.nextScene() pel Director +// Sincronitzada con context.nextScene() por el Director inline SceneContext::SceneType actual = SceneContext::SceneType::LOGO; } // namespace SceneManager diff --git a/source/core/utils/path_utils.cpp b/source/core/utils/path_utils.cpp index b74a7b7..2926503 100644 --- a/source/core/utils/path_utils.cpp +++ b/source/core/utils/path_utils.cpp @@ -1,5 +1,5 @@ // path_utils.cpp - Implementació de utilitats de rutes -// © 2025 Port a C++20 amb SDL3 +// © 2025 Port a C++20 con SDL3 #include "path_utils.hpp" @@ -13,10 +13,10 @@ namespace Utils { static std::string executable_path_; static std::string executable_directory_; -// Inicialitzar el sistema de rutes amb argv[0] +// Inicialitzar el sistema de rutes con argv[0] void initializePathSystem(const char* argv0) { if (argv0 == nullptr) { - std::cerr << "[PathUtils] ADVERTÈNCIA: argv[0] és nullptr\n"; + std::cerr << "[PathUtils] ADVERTÈNCIA: argv[0] es nullptr\n"; executable_path_ = ""; executable_directory_ = "."; return; @@ -50,7 +50,7 @@ bool isMacOSBundle() { #ifdef MACOS_BUNDLE return true; #else - // Detecció en time d'execució + // Detecció en time de execució // Cercar ".app/Contents/MacOS" a la ruta de l'executable std::string exe_dir = getExecutableDirectory(); return exe_dir.find(".app/Contents/MacOS") != std::string::npos; @@ -62,10 +62,10 @@ std::string getResourceBasePath() { std::string exe_dir = getExecutableDirectory(); if (isMacOSBundle()) { - // Bundle de macOS: recursos a ../Resources des de MacOS/ + // Bundle de macOS: recursos a ../Resources desde MacOS/ std::cout << "[PathUtils] Detectat bundle de macOS\n"; return exe_dir + "/../Resources"; - } // Executable normal: recursos al mateix directori + } // Executable normal: recursos al mismo directori return exe_dir; } @@ -76,7 +76,7 @@ std::string normalizePath(const std::string& path) { // Convertir barres invertides a normals std::ranges::replace(normalized, '\\', '/'); - // Simplificar rutes amb filesystem + // Simplificar rutes con filesystem try { std::filesystem::path fs_path(normalized); normalized = fs_path.lexically_normal().string(); diff --git a/source/core/utils/path_utils.hpp b/source/core/utils/path_utils.hpp index d4657e5..7819fad 100644 --- a/source/core/utils/path_utils.hpp +++ b/source/core/utils/path_utils.hpp @@ -1,5 +1,5 @@ // path_utils.hpp - Utilitats de gestió de rutes -// © 2025 Port a C++20 amb SDL3 +// © 2025 Port a C++20 con SDL3 // Detecció de directoris i bundles multiplataforma #pragma once @@ -8,7 +8,7 @@ namespace Utils { -// Inicialització amb argv[0] +// Inicialización con argv[0] void initializePathSystem(const char* argv0); // Obtenció de rutes diff --git a/source/external/fkyaml_node.hpp b/source/external/fkyaml_node.hpp index 8791774..b3aefb2 100644 --- a/source/external/fkyaml_node.hpp +++ b/source/external/fkyaml_node.hpp @@ -2,9 +2,9 @@ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_NODE_HPP @@ -25,9 +25,9 @@ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_MACROS_DEFINE_MACROS_HPP @@ -38,9 +38,9 @@ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT // Check version definitions if already defined. @@ -94,9 +94,9 @@ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_MACROS_CPP_CONFIG_MACROS_HPP @@ -109,7 +109,7 @@ // With the MSVC compilers, the value of __cplusplus is by default always // "199611L"(C++98). To avoid that, the library instead references _MSVC_LANG // which is always set a correct value. See -// https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ +// https://devblogs.microsoft.como/cppblog/msvc-now-correctly-reports-__cplusplus/ // for more details. #if defined(_MSVC_LANG) && !defined(__clang__) #define FK_YAML_CPLUSPLUS _MSVC_LANG @@ -265,9 +265,9 @@ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_ASSERT_HPP @@ -290,9 +290,9 @@ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_DOCUMENT_METAINFO_HPP @@ -308,9 +308,9 @@ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_META_NODE_TRAITS_HPP @@ -323,9 +323,9 @@ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_META_DETECT_HPP @@ -341,9 +341,9 @@ // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_META_STL_SUPPLEMENT_HPP @@ -373,13 +373,13 @@ FK_YAML_DETAIL_NAMESPACE_BEGIN /// @brief An alias template for std::add_pointer::type with C++11. /// @note std::add_pointer_t is available since C++14. -/// @sa https://en.cppreference.com/w/cpp/types/add_pointer +/// @sa https://en.cppreference.como/w/cpp/types/add_pointer /// @tparam T A type to be added a pointer. template using add_pointer_t = typename std::add_pointer::type; /// @brief An alias template for std::enable_if::type with C++11. /// @note std::enable_if_t is available since C++14. -/// @sa https://en.cppreference.com/w/cpp/types/enable_if +/// @sa https://en.cppreference.como/w/cpp/types/enable_if /// @tparam Condition A condition tested at compile time. /// @tparam T The type defined only if Condition is true. template @@ -387,7 +387,7 @@ using enable_if_t = typename std::enable_if::type; /// @brief A simple implementation to use std::is_null_pointer with C++11. /// @note std::is_null_pointer is available since C++14. -/// @sa https://en.cppreference.com/w/cpp/types/is_null_pointer +/// @sa https://en.cppreference.como/w/cpp/types/is_null_pointer /// @tparam T The type to be checked if it's equal to std::nullptr_t. template struct is_null_pointer @@ -395,20 +395,20 @@ struct is_null_pointer /// @brief An alias template for std::remove_cv::type with C++11. /// @note std::remove_cv_t is available since C++14. -/// @sa https://en.cppreference.com/w/cpp/types/remove_cv +/// @sa https://en.cppreference.como/w/cpp/types/remove_cv /// @tparam T A type from which const-volatile qualifiers are removed. template using remove_cv_t = typename std::remove_cv::type; /// @brief An alias template for std::remove_pointer::type with C++11. /// @note std::remove_pointer_t is available since C++14. -/// @sa https://en.cppreference.com/w/cpp/types/remove_pointer +/// @sa https://en.cppreference.como/w/cpp/types/remove_pointer /// @tparam T A type from which a pointer is removed. template using remove_pointer_t = typename std::remove_pointer::type; /// @brief An alias template for std::remove_reference::type with C++11. /// @note std::remove_reference_t is available since C++14. -/// @sa https://en.cppreference.com/w/cpp/types/remove_reference +/// @sa https://en.cppreference.como/w/cpp/types/remove_reference /// @tparam T A type from which a reference is removed. template using remove_reference_t = typename std::remove_reference::type; @@ -498,7 +498,7 @@ template using bool_constant = std::integral_constant; /// @note /// std::conjunction is available since C++17. /// This is applied when no traits are specified as inputs. -/// @sa https://en.cppreference.com/w/cpp/types/conjunction +/// @sa https://en.cppreference.como/w/cpp/types/conjunction /// @tparam Traits Type traits to be checked if their ::value are all true. template struct conjunction : std::true_type {}; @@ -519,7 +519,7 @@ struct conjunction /// @note /// std::disjunction is available since C++17. /// This is applied when no traits are specified as inputs. -/// @sa https://en.cppreference.com/w/cpp/types/disjunction +/// @sa https://en.cppreference.como/w/cpp/types/disjunction /// @tparam Traits Type traits to be checked if at least one of their ::value is /// true. template struct disjunction : std::false_type {}; @@ -539,7 +539,7 @@ struct disjunction /// @brief A simple implementation to use std::negation with C++11/C++14. /// @note std::negation is available since C++17. -/// @sa https://en.cppreference.com/w/cpp/types/negation +/// @sa https://en.cppreference.como/w/cpp/types/negation /// @tparam Trait Type trait whose ::value is negated. template struct negation : std::integral_constant {}; @@ -552,7 +552,7 @@ template struct make_void { /// @brief A simple implementation to use std::void_t with C++11/C++14. /// @note std::void_t is available since C++17. -/// @sa https://en.cppreference.com/w/cpp/types/void_t +/// @sa https://en.cppreference.como/w/cpp/types/void_t /// @tparam Types Any types to be transformed to void type. template using void_t = typename make_void::type; @@ -571,7 +571,7 @@ using std::void_t; /// @brief A simple implementation to use std::remove_cvref_t with /// C++11/C++14/C++17. /// @note std::remove_cvref & std::remove_cvref_t are available since C++20. -/// @sa https://en.cppreference.com/w/cpp/types/remove_cvref +/// @sa https://en.cppreference.como/w/cpp/types/remove_cvref /// @tparam T A type from which cv-qualifiers and reference are removed. template using remove_cvref_t = @@ -790,9 +790,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_META_TYPE_TRAITS_HPP @@ -890,9 +890,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_FKYAML_FWD_HPP @@ -1106,9 +1106,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_YAML_VERSION_TYPE_HPP @@ -1171,9 +1171,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_EXCEPTION_SAFE_ALLOCATION_HPP @@ -1278,9 +1278,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_INPUT_DESERIALIZER_HPP @@ -1299,9 +1299,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_INPUT_LEXICAL_ANALYZER_HPP @@ -1320,9 +1320,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_ENCODINGS_URI_ENCODING_HPP @@ -1453,9 +1453,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_ENCODINGS_UTF_ENCODINGS_HPP @@ -1471,9 +1471,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_EXCEPTION_HPP @@ -1491,9 +1491,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_STRING_FORMATTER_HPP @@ -1541,9 +1541,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_TYPES_NODE_T_HPP @@ -1558,9 +1558,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_NODE_TYPE_HPP @@ -2155,9 +2155,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_INPUT_BLOCK_SCALAR_HEADER_HPP @@ -2196,9 +2196,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_INPUT_POSITION_TRACKER_HPP @@ -2213,9 +2213,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_STR_VIEW_HPP @@ -3346,9 +3346,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_TYPES_LEXICAL_TOKEN_T_HPP @@ -4396,7 +4396,7 @@ private: if FK_YAML_UNLIKELY (cur_itr == m_end_itr) { // Without the following iterator update, lexer cannot reach the end of // input buffer and causes infinite loops from the next loop. - // (https://github.com/fktn-k/fkYAML/pull/410) + // (https://github.como/fktn-k/fkYAML/pull/410) m_cur_itr = m_end_itr; // If there's no non-empty line, the content indentation level is equal to @@ -4726,9 +4726,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_INPUT_SCALAR_PARSER_HPP @@ -4743,9 +4743,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT // **NOTE FOR LIBRARY DEVELOPERS**: @@ -5644,9 +5644,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_ENCODINGS_YAML_ESCAPER_HPP @@ -6005,9 +6005,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_INPUT_SCALAR_SCANNER_HPP @@ -6377,9 +6377,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_INPUT_TAG_T_HPP @@ -6948,7 +6948,7 @@ private: // conversion error from a scalar which is not tagged with !!int is // recovered by treating it as a string scalar. See - // https://github.com/fktn-k/fkYAML/issues/428. + // https://github.como/fktn-k/fkYAML/issues/428. return basic_node_type(string_type(token.begin(), token.end())); } case node_type::FLOAT: { @@ -6966,7 +6966,7 @@ private: // conversion error from a scalar which is not tagged with !!float is // recovered by treating it as a string scalar. See - // https://github.com/fktn-k/fkYAML/issues/428. + // https://github.como/fktn-k/fkYAML/issues/428. return basic_node_type(string_type(token.begin(), token.end())); } case node_type::STRING: @@ -7000,9 +7000,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_INPUT_TAG_RESOLVER_HPP @@ -7208,9 +7208,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_META_INPUT_ADAPTER_TRAITS_HPP @@ -7274,9 +7274,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_NODE_ATTRS_HPP @@ -7417,9 +7417,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_NODE_PROPERTY_HPP @@ -8019,7 +8019,7 @@ private: // (i.e., the properties are for a container node), the // application and the line advancement must happen here. // Otherwise, a false indent error will be emitted. See - // https://github.com/fktn-k/fkYAML/issues/368 for more details. + // https://github.como/fktn-k/fkYAML/issues/368 for more details. line = line_after_props; indent = lexer.get_last_token_begin_pos(); *mp_current_node = basic_node_type::mapping(); @@ -8910,9 +8910,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_INPUT_INPUT_ADAPTER_HPP @@ -8935,9 +8935,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_ENCODINGS_UTF_ENCODE_DETECTOR_HPP @@ -8953,9 +8953,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_ENCODINGS_UTF_ENCODE_T_HPP @@ -10496,9 +10496,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_ITERATOR_HPP @@ -10914,7 +10914,7 @@ namespace std { #ifdef __clang__ // clang emits warnings against mixed usage of class/struct for // tuple_size/tuple_element. see also: -// https://groups.google.com/a/isocpp.org/g/std-discussion/c/QC-AMb5oO1w +// https://groups.google.como/a/isocpp.org/g/std-discussion/c/QC-AMb5oO1w #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmismatched-tags" #endif @@ -10949,9 +10949,9 @@ struct tuple_element> { // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_MAP_RANGE_PROXY_HPP @@ -11139,9 +11139,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_NODE_REF_STORAGE_HPP @@ -11235,9 +11235,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_OUTPUT_SERIALIZER_HPP @@ -11255,9 +11255,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_CONVERSIONS_TO_STRING_HPP @@ -11337,7 +11337,7 @@ to_string(FloatType v, std::string &s) noexcept { // If `v` is actually an integer and no scientific notation is used for // serialization, ".0" must be appended. The result would cause a roundtrip - // issue otherwise. https://github.com/fktn-k/fkYAML/issues/405 + // issue otherwise. https://github.como/fktn-k/fkYAML/issues/405 const std::size_t pos = s.find_first_of(".e"); if (pos == std::string::npos) { s += ".0"; @@ -11744,9 +11744,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_REVERSE_ITERATOR_HPP @@ -12016,9 +12016,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_TYPES_YAML_VERSION_T_HPP @@ -12073,9 +12073,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_NODE_VALUE_CONVERTER_HPP @@ -12090,9 +12090,9 @@ FK_YAML_DETAIL_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_CONVERSIONS_FROM_NODE_HPP @@ -12875,9 +12875,9 @@ FK_YAML_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_DETAIL_CONVERSIONS_TO_NODE_HPP @@ -13262,9 +13262,9 @@ FK_YAML_NAMESPACE_END // | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML // library | __| _ < \_ _/| ___ | _ | |___ version 0.4.2 // |__| |_| \__| |_| |_| |_|___||___|______| -// https://github.com/fktn-k/fkYAML +// https://github.como/fktn-k/fkYAML // -// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani +// SPDX-FileCopyrightText: 2023-2025 Kensuke Fukutani // SPDX-License-Identifier: MIT #ifndef FK_YAML_ORDERED_MAP_HPP @@ -13875,7 +13875,7 @@ public: /// iterators into a basic_node object. /// @note /// Iterators must satisfy the LegacyInputIterator requirements. - /// See https://en.cppreference.com/w/cpp/named_req/InputIterator. + /// See https://en.cppreference.como/w/cpp/named_req/InputIterator. /// @tparam ItrType Type of a compatible iterator /// @param[in] begin An iterator to the first element of an input sequence. /// @param[in] end An iterator to the past-the-last element of an input @@ -15517,7 +15517,7 @@ inline namespace yaml_literals { // Whitespace before the literal operator identifier is deprecated in C++23 or // better but required in C++11. Ignore the warning as a workaround. -// https://github.com/fktn-k/fkYAML/pull/417 +// https://github.como/fktn-k/fkYAML/pull/417 #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated" diff --git a/source/game/constants.hpp b/source/game/constants.hpp index 5fd2b31..bb6aa2a 100644 --- a/source/game/constants.hpp +++ b/source/game/constants.hpp @@ -2,11 +2,11 @@ #include "core/defaults.hpp" -// Aliases per a backward compatibility amb codi existent +// Aliases para backward compatibility con codi existent // Permet usar Constants::MARGIN_LEFT en lloc de Defaults::Game::MARGIN_LEFT namespace Constants { -// Marges de l'àrea de joc (derivats de Defaults::Zones::GAME) +// Marges de l'àrea de juego (derivats de Defaults::Zones::GAME) constexpr int MARGIN_LEFT = static_cast(Defaults::Zones::PLAYAREA.x); constexpr int MARGIN_RIGHT = static_cast(Defaults::Zones::PLAYAREA.x + Defaults::Zones::PLAYAREA.w); @@ -14,7 +14,7 @@ constexpr int MARGIN_TOP = static_cast(Defaults::Zones::PLAYAREA.y); constexpr int MARGIN_BOTTOM = static_cast(Defaults::Zones::PLAYAREA.y + Defaults::Zones::PLAYAREA.h); -// Límits d'objectes +// Límits de objectes constexpr int MAX_ORNIS = Defaults::Entities::MAX_ORNIS; constexpr int MAX_BALES = Defaults::Entities::MAX_BALES; @@ -39,7 +39,7 @@ inline void obtenir_limits_zona(float& min_x, float& max_x, float& min_y, float& max_y = zona.y + zona.h; } -// Obtenir límits segurs (compensant radi de l'entitat) +// Obtenir límits segurs (compensant radi de l'entidad) inline void obtenir_limits_zona_segurs(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 @@ -50,7 +50,7 @@ inline void obtenir_limits_zona_segurs(float radi, float& min_x, float& max_x, f max_y = zona.y + zona.h - radi - MARGE_SEGURETAT; } -// Obtenir centre de l'àrea de joc +// Obtenir centro de l'àrea de juego inline void obtenir_centre_zona(float& centre_x, float& centre_y) { const auto& zona = Defaults::Zones::PLAYAREA; centre_x = zona.x + (zona.w / 2.0F); diff --git a/source/game/effects/debris.hpp b/source/game/effects/debris.hpp index fa70fcb..b8fd88d 100644 --- a/source/game/effects/debris.hpp +++ b/source/game/effects/debris.hpp @@ -1,33 +1,33 @@ -// debris.hpp - Fragment de línia volant (explosió de formes) -// © 2025 Port a C++20 amb SDL3 +// debris.hpp - Fragment de línia volant (explosión de formes) +// © 2025 Port a C++20 con SDL3 #pragma once #include "core/types.hpp" namespace Effects { -// Debris: un segment de línia que vola perpendicular a sí mateix -// Representa un fragment d'una shape destruïda (ship, enemy, bullet) +// Debris: un segment de línia que vola perpendicular a sí mismo +// Representa un fragment de una shape destruïda (ship, enemy, bullet) struct Debris { // Geometria del segment (2 points en coordenades mundials) Vec2 p1; // Vec2 inicial del segment Vec2 p2; // Vec2 final del segment // Física - Vec2 velocity; // Velocitat en px/s (components x, y) - float acceleration; // Acceleració negativa (fricció) en px/s² + Vec2 velocity; // Velocidad en px/s (components x, y) + float acceleration; // Aceleración negativa (fricció) en px/s² - // Rotació - float angle_rotacio; // Angle de rotació acumulat (radians) - float velocitat_rot; // Velocitat de rotació de TRAYECTORIA (rad/s) - float velocitat_rot_visual; // Velocitat de rotació VISUAL del segment (rad/s) + // Rotación + float angle_rotacio; // Angle de rotación acumulat (radians) + float velocitat_rot; // Velocidad de rotación de TRAYECTORIA (rad/s) + float velocitat_rot_visual; // Velocidad de rotación VISUAL del segment (rad/s) // Estat de vida float temps_vida; // Temps transcorregut (segons) float temps_max; // Temps de vida màxim (segons) - bool active; // Està active? + bool active; // Está active? - // Shrinking (reducció de distància entre points) + // Shrinking (reducció de distancia entre points) float factor_shrink; // Factor de reducció per segon (0.0-1.0) // Rendering diff --git a/source/game/effects/debris_manager.cpp b/source/game/effects/debris_manager.cpp index 4906a2e..fcdf2bc 100644 --- a/source/game/effects/debris_manager.cpp +++ b/source/game/effects/debris_manager.cpp @@ -1,5 +1,5 @@ // debris_manager.cpp - Implementació del gestor de fragments -// © 2025 Port a C++20 amb SDL3 +// © 2025 Port a C++20 con SDL3 #include "debris_manager.hpp" @@ -14,10 +14,10 @@ namespace Effects { -// Helper: transformar point amb rotació, scale i trasllació +// Helper: transformar point con rotación, scale i traslación // (Copiat de shape_renderer.cpp:12-34) static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const Vec2& position, float angle, float scale) { - // 1. Centrar el point respecte al centre de la shape + // 1. Centrar el point respecte al centro de la shape float centered_x = point.x - shape_centre.x; float centered_y = point.y - shape_centre.y; @@ -25,27 +25,27 @@ static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const V float scaled_x = centered_x * scale; float scaled_y = centered_y * scale; - // 3. Aplicar rotació + // 3. Aplicar rotación float cos_a = std::cos(angle); float sin_a = std::sin(angle); float rotated_x = (scaled_x * cos_a) - (scaled_y * sin_a); float rotated_y = (scaled_x * sin_a) + (scaled_y * cos_a); - // 4. Aplicar trasllació a posició mundial + // 4. Aplicar traslación a posición mundial return {.x = rotated_x + position.x, .y = rotated_y + position.y}; } DebrisManager::DebrisManager(SDL_Renderer* renderer) : renderer_(renderer) { - // Inicialitzar tots els debris com inactius + // Inicialitzar todos los debris como inactius for (auto& debris : debris_pool_) { debris.active = false; } } void DebrisManager::explode(const std::shared_ptr& shape, - const Vec2& centre, + const Vec2& centro, float angle, float scale, float velocitat_base, @@ -61,10 +61,10 @@ void DebrisManager::explode(const std::shared_ptr& shape, // Reproducir sonido de explosión Audio::get()->playSound(sound, Audio::Group::GAME); - // Obtenir centre de la shape per a transformacions + // Obtenir centro de la shape para transformacions const Vec2& shape_centre = shape->getCenter(); - // Iterar sobre totes les primitives de la shape + // Iterar sobre todas las primitives de la shape for (const auto& primitive : shape->get_primitives()) { // Processar cada segment de línia std::vector> segments; @@ -81,13 +81,13 @@ void DebrisManager::explode(const std::shared_ptr& shape, } } - // Crear debris per a cada segment + // Crear debris para cada segment for (const auto& [local_p1, local_p2] : segments) { // 1. Transformar points locals → coordenades mundials Vec2 world_p1 = - transform_point(local_p1, shape_centre, centre, angle, scale); + transform_point(local_p1, shape_centre, centro, angle, scale); Vec2 world_p2 = - transform_point(local_p2, shape_centre, centre, angle, scale); + transform_point(local_p2, shape_centre, centro, angle, scale); // 2. Trobar slot lliure Debris* debris = findFreeSlot(); @@ -100,10 +100,10 @@ void DebrisManager::explode(const std::shared_ptr& shape, debris->p1 = world_p1; debris->p2 = world_p2; - // 4. Calcular direcció d'explosió (radial, des del centre cap a fora) - Vec2 direccio = computeExplosionDirection(world_p1, world_p2, centre); + // 4. Calcular direcció de explosión (radial, des del centro hacia fuera) + Vec2 direccio = computeExplosionDirection(world_p1, world_p2, centro); - // 5. Velocitat inicial (base ± variació aleatòria + velocity heretada) + // 5. Velocidad inicial (base ± variació aleatòria + velocity heretada) float speed = velocitat_base + (((std::rand() / static_cast(RAND_MAX)) * 2.0F - 1.0F) * @@ -114,11 +114,11 @@ void DebrisManager::explode(const std::shared_ptr& shape, debris->velocity.y = (direccio.y * speed) + velocitat_objecte.y; debris->acceleration = Defaults::Physics::Debris::ACCELERACIO; - // 6. Herència de velocity angular amb cap + conversió d'excés + // 6. Herència de velocity angular con sin + conversió de excés - // 6a. Rotació de TRAYECTORIA amb cap + conversió tangencial + // 6a. Rotación de TRAYECTORIA con sin + conversió tangencial if (std::abs(velocitat_angular) > 0.01F) { - // FASE 1: Aplicar herència i variació (igual que abans) + // FASE 1: Aplicar herència i variació (igual que antes) float factor_herencia = Defaults::Physics::Debris::FACTOR_HERENCIA_MIN + ((std::rand() / static_cast(RAND_MAX)) * @@ -131,7 +131,7 @@ void DebrisManager::explode(const std::shared_ptr& shape, ((std::rand() / static_cast(RAND_MAX)) * 0.2F) - 0.1F; velocitat_ang_heretada *= (1.0F + variacio); - // FASE 2: Aplicar cap i calcular excés + // FASE 2: Aplicar sin i calcular excés constexpr float CAP = Defaults::Physics::Debris::VELOCITAT_ROT_MAX; float abs_ang = std::abs(velocitat_ang_heretada); float sign_ang = (velocitat_ang_heretada >= 0.0F) ? 1.0F : -1.0F; @@ -140,10 +140,10 @@ void DebrisManager::explode(const std::shared_ptr& shape, // Excés: convertir a velocity tangencial float excess = abs_ang - CAP; - // Radi de la shape (enemics = 20 px) + // Radi de la shape (enemigos = 20 px) float radius = 20.0F; - // Velocitat tangencial = ω_excés × radi + // Velocidad tangencial = ω_excés × radi float v_tangential = excess * radius; // Direcció tangencial: perpendicular a la radial (90° CCW) @@ -151,38 +151,38 @@ void DebrisManager::explode(const std::shared_ptr& shape, float tangent_x = -direccio.y; float tangent_y = direccio.x; - // Afegir velocity tangencial (suma vectorial) + // Añadir velocity tangencial (suma vectorial) debris->velocity.x += tangent_x * v_tangential; debris->velocity.y += tangent_y * v_tangential; - // Aplicar cap a velocity angular (preservar signe) + // Aplicar hacia velocity angular (preservar signe) debris->velocitat_rot = sign_ang * CAP; } else { - // Per sota del cap: comportament normal + // Per sota del sin: comportament normal debris->velocitat_rot = velocitat_ang_heretada; } } else { debris->velocitat_rot = 0.0F; // Nave: sin curvas } - // 6b. Rotació VISUAL (proporcional según factor_herencia_visual) + // 6b. Rotación VISUAL (proporcional según factor_herencia_visual) if (factor_herencia_visual > 0.01F && std::abs(velocitat_angular) > 0.01F) { // Heredar rotación visual con factor proporcional debris->velocitat_rot_visual = debris->velocitat_rot * factor_herencia_visual; - // Variació aleatòria petita (±5%) per naturalitat + // Variació aleatòria pequeña (±5%) per naturalitat float variacio_visual = ((std::rand() / static_cast(RAND_MAX)) * 0.1F) - 0.05F; debris->velocitat_rot_visual *= (1.0F + variacio_visual); } else { - // Rotació visual aleatòria (factor = 0.0 o sin velocidad angular) + // Rotación visual aleatòria (factor = 0.0 o sin velocidad angular) debris->velocitat_rot_visual = Defaults::Physics::Debris::ROTACIO_MIN + ((std::rand() / static_cast(RAND_MAX)) * (Defaults::Physics::Debris::ROTACIO_MAX - Defaults::Physics::Debris::ROTACIO_MIN)); - // 50% probabilitat de rotació en sentit contrari + // 50% probabilitat de rotación en sentit contrari if (std::rand() % 2 == 0) { debris->velocitat_rot_visual = -debris->velocitat_rot_visual; } @@ -220,7 +220,7 @@ void DebrisManager::update(float delta_time) { } // 2. Actualitzar velocity (desacceleració) - // Aplicar fricció en la direcció del moviment + // Aplicar fricció en la direcció del movement float speed = std::sqrt((debris.velocity.x * debris.velocity.x) + (debris.velocity.y * debris.velocity.y)); @@ -229,24 +229,24 @@ void DebrisManager::update(float delta_time) { float dir_x = debris.velocity.x / speed; float dir_y = debris.velocity.y / speed; - // Aplicar acceleració negativa (fricció) + // Aplicar aceleración negativa (fricció) float nova_speed = speed + (debris.acceleration * delta_time); nova_speed = std::max(nova_speed, 0.0F); debris.velocity.x = dir_x * nova_speed; debris.velocity.y = dir_y * nova_speed; } else { - // Velocitat molt baixa, aturar + // Velocidad mucho baixa, aturar debris.velocity.x = 0.0F; debris.velocity.y = 0.0F; } // 2b. Rotar vector de velocity (trayectoria curva) if (std::abs(debris.velocitat_rot) > 0.01F) { - // Calcular angle de rotació aquest frame + // Calcular angle de rotación este frame float dangle = debris.velocitat_rot * delta_time; - // Rotar vector de velocity usant matriu de rotació 2D + // Rotar vector de velocity usant matriu de rotación 2D float vel_x_old = debris.velocity.x; float vel_y_old = debris.velocity.y; @@ -270,35 +270,35 @@ void DebrisManager::update(float delta_time) { } } - // 3. Calcular centre del segment - Vec2 centre = {.x = (debris.p1.x + debris.p2.x) / 2.0F, + // 3. Calcular centro del segment + Vec2 centro = {.x = (debris.p1.x + debris.p2.x) / 2.0F, .y = (debris.p1.y + debris.p2.y) / 2.0F}; - // 4. Actualitzar posició del centre - centre.x += debris.velocity.x * delta_time; - centre.y += debris.velocity.y * delta_time; + // 4. Actualitzar posición del centro + centro.x += debris.velocity.x * delta_time; + centro.y += debris.velocity.y * delta_time; - // 5. Actualitzar rotació VISUAL + // 5. Actualitzar rotación VISUAL debris.angle_rotacio += debris.velocitat_rot_visual * delta_time; - // 6. Aplicar shrinking (reducció de distància entre points) + // 6. Aplicar shrinking (reducció de distancia entre points) float shrink_factor = 1.0F - (debris.factor_shrink * debris.temps_vida / debris.temps_max); shrink_factor = std::max(0.0F, shrink_factor); // No negatiu - // Calcular distància original entre points + // Calcular distancia original entre points float dx = debris.p2.x - debris.p1.x; float dy = debris.p2.y - debris.p1.y; - // 7. Reconstruir segment amb nova mida i rotació + // 7. Reconstruir segment con nueva mida i rotación float half_length = std::sqrt((dx * dx) + (dy * dy)) * shrink_factor / 2.0F; float original_angle = std::atan2(dy, dx); float new_angle = original_angle + debris.angle_rotacio; - debris.p1.x = centre.x - (half_length * std::cos(new_angle)); - debris.p1.y = centre.y - (half_length * std::sin(new_angle)); - debris.p2.x = centre.x + (half_length * std::cos(new_angle)); - debris.p2.y = centre.y + (half_length * std::sin(new_angle)); + debris.p1.x = centro.x - (half_length * std::cos(new_angle)); + debris.p1.y = centro.y - (half_length * std::sin(new_angle)); + debris.p2.x = centro.x + (half_length * std::cos(new_angle)); + debris.p2.y = centro.y + (half_length * std::sin(new_angle)); } } @@ -308,7 +308,7 @@ void DebrisManager::draw() const { continue; } - // Dibuixar segment de línia amb brightness heretat + // Dibuixar segment de línia con brightness heretat Rendering::linea(renderer_, static_cast(debris.p1.x), static_cast(debris.p1.y), @@ -330,19 +330,19 @@ Debris* DebrisManager::findFreeSlot() { Vec2 DebrisManager::computeExplosionDirection(const Vec2& p1, const Vec2& p2, const Vec2& centre_objecte) const { - // 1. Calcular centre del segment + // 1. Calcular centro del segment float centro_seg_x = (p1.x + p2.x) / 2.0F; float centro_seg_y = (p1.y + p2.y) / 2.0F; - // 2. Calcular vector des del centre de l'objecte cap al centre del segment - // Això garanteix que la direcció sempre apunte cap a fora (direcció radial) + // 2. Calcular vector des del centro de l'objecte hacia el centro del segment + // Això garanteix que la direcció siempre apunte hacia fuera (direcció radial) float dx = centro_seg_x - centre_objecte.x; float dy = centro_seg_y - centre_objecte.y; // 3. Normalitzar (obtenir vector unitari) float length = std::sqrt((dx * dx) + (dy * dy)); if (length < 0.001F) { - // Segment al centre (cas extrem molt improbable), retornar direcció aleatòria + // Segment al centro (cas extrem mucho improbable), retornar direcció aleatòria float angle_rand = (std::rand() / static_cast(RAND_MAX)) * 2.0F * Defaults::Math::PI; return {.x = std::cos(angle_rand), .y = std::sin(angle_rand)}; @@ -351,7 +351,7 @@ Vec2 DebrisManager::computeExplosionDirection(const Vec2& p1, dx /= length; dy /= length; - // 4. Afegir variació aleatòria petita (±15°) per varietat visual + // 4. Añadir variació aleatòria pequeña (±15°) per varietat visual float angle_variacio = ((std::rand() % 30) - 15) * Defaults::Math::PI / 180.0F; diff --git a/source/game/effects/debris_manager.hpp b/source/game/effects/debris_manager.hpp index 4fde843..1f79d88 100644 --- a/source/game/effects/debris_manager.hpp +++ b/source/game/effects/debris_manager.hpp @@ -1,5 +1,5 @@ -// debris_manager.hpp - Gestor de fragments d'explosions -// © 2025 Port a C++20 amb SDL3 +// debris_manager.hpp - Gestor de fragments de explosions +// © 2025 Port a C++20 con SDL3 #pragma once #include @@ -14,24 +14,24 @@ namespace Effects { -// Gestor de fragments d'explosions -// Manté un pool d'objectes Debris i gestiona el seu cicle de vida +// Gestor de fragments de explosions +// Manté un pool de objectes Debris i gestiona el seu cicle de vida class DebrisManager { public: explicit DebrisManager(SDL_Renderer* renderer); - // Crear explosió a partir d'una shape + // Crear explosión a partir de una shape // - shape: shape vectorial a explode - // - centre: posició del centre de l'objecte + // - centro: posición del centro de l'objecte // - angle: orientació de l'objecte (radians) // - scale: scale de l'objecte (1.0 = normal) // - velocitat_base: velocity inicial dels fragments (px/s) // - brightness: factor de brightness heretat (0.0-1.0, per defecte 1.0) // - velocitat_objecte: velocity de l'objecte que explota (px/s, per defecte 0) // - velocitat_angular: velocity angular heretada (rad/s, per defecte 0) - // - factor_herencia_visual: factor de herència rotació visual (0.0-1.0, per defecte 0.0) + // - factor_herencia_visual: factor de herència rotación visual (0.0-1.0, per defecte 0.0) void explode(const std::shared_ptr& shape, - const Vec2& centre, + const Vec2& centro, float angle, float scale, float velocitat_base, @@ -41,13 +41,13 @@ class DebrisManager { float factor_herencia_visual = 0.0F, const std::string& sound = Defaults::Sound::EXPLOSION); - // Actualitzar tots els fragments active + // Actualitzar todos los fragments active void update(float delta_time); - // Dibuixar tots els fragments active + // Dibuixar todos los fragments active void draw() const; - // Reiniciar tots els fragments (neteja) + // Reiniciar todos los fragments (clear) void reset(); // Obtenir número de fragments active @@ -57,8 +57,8 @@ class DebrisManager { SDL_Renderer* renderer_; // Pool de fragments (màxim concurrent) - // Un pentàgon té 5 línies, 15 enemics = 75 línies - // + ship (3 línies) + bales (5 línies * 3) = 93 línies màxim + // Un pentágono té 5 línies, 15 enemigos = 75 línies + // + ship (3 línies) + balas (5 línies * 3) = 93 línies màxim // Arrodonit a 100 per seguretat static constexpr int MAX_DEBRIS = 150; std::array debris_pool_; @@ -66,7 +66,7 @@ class DebrisManager { // Trobar primer slot inactiu Debris* findFreeSlot(); - // Calcular direcció d'explosió (radial, des del centre cap al segment) + // Calcular direcció de explosión (radial, des del centro hacia el segment) [[nodiscard]] Vec2 computeExplosionDirection(const Vec2& p1, const Vec2& p2, const Vec2& centre_objecte) const; }; diff --git a/source/game/effects/floating_score.hpp b/source/game/effects/floating_score.hpp index 61f7334..f56bd34 100644 --- a/source/game/effects/floating_score.hpp +++ b/source/game/effects/floating_score.hpp @@ -1,5 +1,5 @@ -// puntuacio_flotant.hpp - Número de puntuació que apareix i desapareix -// © 2025 Port a C++20 amb SDL3 +// floating_score.hpp - Número de puntuación que apareix y desapareix +// © 2025 Port a C++20 con SDL3 #pragma once @@ -9,19 +9,19 @@ namespace Effects { -// FloatingScore: text animat que mostra points guanyats -// S'activa quan es destrueix un enemy i s'esvaeix després d'un time +// FloatingScore: text animat que muestra points guanyats +// S'activa cuando es destrueix un enemy i s'esvaeix después de un time struct FloatingScore { // Text a mostrar (e.g., "100", "150", "200") std::string text; - // Posició actual (coordenades mundials) + // Posición actual (coordenades mundials) Vec2 position; - // Animació de moviment - Vec2 velocity; // px/s (normalment cap amunt: {0.0f, -30.0f}) + // Animación de movement + Vec2 velocity; // px/s (normalment sin amunt: {0.0f, -30.0f}) - // Animació de fade + // Animación de fade float temps_vida; // Temps transcorregut (segons) float temps_max; // Temps de vida màxim (segons) float brightness; // Brillantor calculada (0.0-1.0) diff --git a/source/game/effects/floating_score_manager.cpp b/source/game/effects/floating_score_manager.cpp index d8a500c..dc8ca56 100644 --- a/source/game/effects/floating_score_manager.cpp +++ b/source/game/effects/floating_score_manager.cpp @@ -1,5 +1,5 @@ -// gestor_puntuacio_flotant.cpp - Implementació del gestor de números flotants -// © 2025 Port a C++20 amb SDL3 +// floating_score_manager.cpp - Implementació del gestor de números flotantes +// © 2025 Port a C++20 con SDL3 #include "floating_score_manager.hpp" @@ -9,7 +9,7 @@ namespace Effects { FloatingScoreManager::FloatingScoreManager(SDL_Renderer* renderer) : text_(renderer) { - // Inicialitzar tots els slots com inactius + // Inicialitzar todos los slots como inactius for (auto& pf : pool_) { pf.active = false; } @@ -22,7 +22,7 @@ void FloatingScoreManager::crear(int points, const Vec2& position) { return; // Pool ple (improbable) } - // 2. Inicialitzar puntuació flotant + // 2. Inicialitzar puntuación flotante pf->text = std::to_string(points); pf->position = position; pf->velocity = {.x = Defaults::FloatingScore::VELOCITY_X, @@ -39,7 +39,7 @@ void FloatingScoreManager::update(float delta_time) { continue; } - // 1. Actualitzar posició (deriva cap amunt) + // 1. Actualitzar posición (deriva sin amunt) pf.position.x += pf.velocity.x * delta_time; pf.position.y += pf.velocity.y * delta_time; @@ -50,7 +50,7 @@ void FloatingScoreManager::update(float delta_time) { float progress = pf.temps_vida / pf.temps_max; // 0.0 → 1.0 pf.brightness = 1.0F - progress; // 1.0 → 0.0 - // 4. Desactivar quan acaba el time + // 4. Desactivar cuando acaba el time if (pf.temps_vida >= pf.temps_max) { pf.active = false; } @@ -63,7 +63,7 @@ void FloatingScoreManager::draw() { continue; } - // Renderitzar centrat amb brightness (fade) + // Renderizar centrat con brightness (fade) constexpr float scale = Defaults::FloatingScore::SCALE; constexpr float spacing = Defaults::FloatingScore::SPACING; diff --git a/source/game/effects/floating_score_manager.hpp b/source/game/effects/floating_score_manager.hpp index b5cdfdc..45d7964 100644 --- a/source/game/effects/floating_score_manager.hpp +++ b/source/game/effects/floating_score_manager.hpp @@ -1,5 +1,5 @@ -// gestor_puntuacio_flotant.hpp - Gestor de números de puntuació flotants -// © 2025 Port a C++20 amb SDL3 +// floating_score_manager.hpp - Gestor de números de puntuación flotantes +// © 2025 Port a C++20 con SDL3 #pragma once @@ -14,24 +14,24 @@ namespace Effects { -// Gestor de números de puntuació flotants +// Gestor de números de puntuación flotantes // Manté un pool de FloatingScore i gestiona el seu cicle de vida class FloatingScoreManager { public: explicit FloatingScoreManager(SDL_Renderer* renderer); - // Crear número flotant - // - points: valor numèric (100, 150, 200) - // - position: on apareix (normalment centre d'enemy destruït) + // Crear número flotante + // - points: value numèric (100, 150, 200) + // - position: on apareix (normalment centro de enemy destruït) void crear(int points, const Vec2& position); - // Actualitzar tots els números active + // Actualitzar todos los números active void update(float delta_time); - // Dibuixar tots els números active + // Dibuixar todos los números active void draw(); - // Reiniciar tots (neteja) + // Reiniciar tots (clear) void reset(); // Obtenir número active (debug) @@ -40,8 +40,8 @@ class FloatingScoreManager { private: Graphics::VectorText text_; // Sistema de text vectorial - // Pool de números flotants (màxim concurrent) - // Màxim 15 enemics simultanis = màxim 15 números + // Pool de números flotantes (màxim concurrent) + // Màxim 15 enemigos simultanis = màxim 15 números static constexpr int MAX_PUNTUACIONS = Defaults::FloatingScore::MAX_CONCURRENT; std::array pool_; diff --git a/source/game/entities/bullet.cpp b/source/game/entities/bullet.cpp index 09b9beb..f178c0d 100644 --- a/source/game/entities/bullet.cpp +++ b/source/game/entities/bullet.cpp @@ -1,6 +1,6 @@ // bullet.cpp - Implementació de projectils de la ship -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 +// © 1999 Visente i Sergi (versión Pascal) +// © 2025 Port a C++20 con SDL3 #include "game/entities/bullet.hpp" @@ -23,10 +23,10 @@ Bullet::Bullet(SDL_Renderer* renderer) esta_(false), owner_id_(0), grace_timer_(0.0F) { - // [NUEVO] Brightness específic per bales + // [NUEVO] Brightness específic per balas brightness_ = Defaults::Brightness::BALA; - // [NUEVO] Carregar shape compartida des de fitxer + // [NUEVO] Carregar shape compartida desde file shape_ = Graphics::ShapeLoader::load("bullet.shp"); if (!shape_ || !shape_->isValid()) { @@ -50,7 +50,7 @@ void Bullet::disparar(const Vec2& position, float angle, uint8_t owner_id) { // Activar bullet esta_ = true; - // Posició inicial = centre de la ship + // Posición inicial = centro de la ship center_.x = position.x; center_.y = position.y; @@ -60,7 +60,7 @@ void Bullet::disparar(const Vec2& position, float angle, uint8_t owner_id) { // Almacenar propietario (0=P1, 1=P2) owner_id_ = owner_id; - // Velocitat alta (el joc Pascal original usava 7 px/frame) + // Velocidad alta (el juego Pascal original usava 7 px/frame) // 7 px/frame × 20 FPS = 140 px/s velocity_ = 140.0F; @@ -86,7 +86,7 @@ void Bullet::update(float delta_time) { void Bullet::draw() const { if (esta_ && shape_) { // [NUEVO] Usar render_shape en lloc de rota_pol - // Les bales roten segons l'angle de trajectòria + // Les balas roten segons l'angle de trajectòria Rendering::render_shape(renderer_, shape_, center_, angle_, 1.0F, 1.0F, brightness_); } } @@ -96,20 +96,20 @@ void Bullet::mou(float delta_time) { // Basat en el codi Pascal original: procedure mou_bales // Copiat EXACTAMENT de joc_asteroides.cpp línies 396-419 - // Calcular nova posició (moviment polar time-based) - // velocity ja està en px/s (140 px/s), només cal multiplicar per delta_time + // Calcular nueva posición (movement polar time-based) + // velocity ya está en px/s (140 px/s), solo necesario multiplicar per delta_time float velocitat_efectiva = velocity_ * delta_time; // Calcular desplaçament (angle-PI/2 perquè angle=0 apunta amunt) float dy = velocitat_efectiva * std::sin(angle_ - (Constants::PI / 2.0F)); float dx = velocitat_efectiva * std::cos(angle_ - (Constants::PI / 2.0F)); - // Acumulació directa amb precisió subpíxel + // Acumulació directa con precisió subpíxel center_.y += dy; center_.x += dx; - // Desactivar si surt de la zona de joc (no rebota com els ORNIs) - // CORRECCIÓ: Usar límits segurs amb radi de la bullet + // Desactivar si surt de la zona de juego (no rebota como los ORNIs) + // CORRECCIÓ: Usar límits segurs con radi de la bullet float min_x; float max_x; float min_y; diff --git a/source/game/entities/bullet.hpp b/source/game/entities/bullet.hpp index a5160de..0cf5518 100644 --- a/source/game/entities/bullet.hpp +++ b/source/game/entities/bullet.hpp @@ -1,6 +1,6 @@ -// bullet.hpp - Classe per a projectils de la ship -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 +// bullet.hpp - Clase para projectils de la ship +// © 1999 Visente i Sergi (versión Pascal) +// © 2025 Port a C++20 con SDL3 #pragma once #include @@ -25,7 +25,7 @@ class Bullet : public Entities::Entity { // Override: Interfície d'Entity [[nodiscard]] bool isActive() const override { return esta_; } - // Override: Interfície de col·lisió + // Override: Interfície de colisión [[nodiscard]] float getCollisionRadius() const override { return Defaults::Entities::BULLET_RADIUS; } @@ -33,7 +33,7 @@ class Bullet : public Entities::Entity { return esta_ && grace_timer_ <= 0.0F; } - // Getters (API pública sense canvis) + // Getters (API pública sin canvis) [[nodiscard]] bool esta_activa() const { return esta_; } [[nodiscard]] uint8_t get_owner_id() const { return owner_id_; } [[nodiscard]] float get_grace_timer() const { return grace_timer_; } diff --git a/source/game/entities/enemy.cpp b/source/game/entities/enemy.cpp index 253ffe2..d0f5bc1 100644 --- a/source/game/entities/enemy.cpp +++ b/source/game/entities/enemy.cpp @@ -1,6 +1,6 @@ -// enemy.cpp - Implementació d'enemics (ORNIs) -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 +// enemy.cpp - Implementació de enemigos (ORNIs) +// © 1999 Visente i Sergi (versión Pascal) +// © 2025 Port a C++20 con SDL3 #include "game/entities/enemy.hpp" @@ -27,7 +27,7 @@ Enemy::Enemy(SDL_Renderer* renderer) ship_position_(nullptr), tracking_strength_(0.5F), // Default tracking strength timer_invulnerabilitat_(0.0F) { // Start vulnerable - // [NUEVO] Brightness específic per enemics + // [NUEVO] Brightness específic per enemigos brightness_ = Defaults::Brightness::ENEMIC; // [NUEVO] Forma es carrega a init() segons el type @@ -52,10 +52,10 @@ void Enemy::init(EnemyType type, const Vec2* ship_pos) { break; case EnemyType::QUADRAT: - shape_file = Defaults::Enemies::Quadrat::SHAPE_FILE; - velocity_ = Defaults::Enemies::Quadrat::VELOCITAT; - drotacio_min = Defaults::Enemies::Quadrat::DROTACIO_MIN; - drotacio_max = Defaults::Enemies::Quadrat::DROTACIO_MAX; + shape_file = Defaults::Enemies::Cuadrado::SHAPE_FILE; + velocity_ = Defaults::Enemies::Cuadrado::VELOCITAT; + drotacio_min = Defaults::Enemies::Cuadrado::DROTACIO_MIN; + drotacio_max = Defaults::Enemies::Cuadrado::DROTACIO_MAX; tracking_timer_ = 0.0F; break; @@ -83,7 +83,7 @@ void Enemy::init(EnemyType type, const Vec2* ship_pos) { std::cerr << "[Enemy] Error: no s'ha pogut load " << shape_file << '\n'; } - // [MODIFIED] Posició aleatòria amb comprovació de seguretat + // [MODIFIED] Posición aleatòria con comprobación de seguretat float min_x; float max_x; float min_y; @@ -117,7 +117,7 @@ void Enemy::init(EnemyType type, const Vec2* ship_pos) { 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] Advertència: spawn sense zona segura després de " + std::cout << "[Enemy] Advertència: spawn sin zona segura después de " << Defaults::Enemies::Spawn::MAX_SPAWN_ATTEMPTS << " intents" << '\n'; } } else { @@ -128,15 +128,15 @@ void Enemy::init(EnemyType type, const Vec2* ship_pos) { center_.y = static_cast((std::rand() % range_y) + static_cast(min_y)); } - // Angle aleatori de moviment + // Angle aleatori de movement angle_ = (std::rand() % 360) * Constants::PI / 180.0F; - // Rotació visual aleatòria (rad/s) dins del rang del type + // Rotación visual aleatòria (rad/s) dins del rang del type float drotacio_range = drotacio_max - drotacio_min; drotacio_ = drotacio_min + ((static_cast(std::rand()) / RAND_MAX) * drotacio_range); rotacio_ = 0.0F; - // Inicialitzar state d'animació + // Inicialitzar state de animación animacio_ = EnemyAnimation(); // Reset to defaults animacio_.drotacio_base = drotacio_; animacio_.drotacio_objetivo = drotacio_; @@ -171,10 +171,10 @@ void Enemy::update(float delta_time) { // Moviment autònom mou(delta_time); - // Actualitzar animacions (palpitació, rotació accelerada) + // Actualitzar animaciones (palpitació, rotación accelerada) actualitzar_animacio(delta_time); - // Rotació visual (time-based: drotacio_ està en rad/s) + // Rotación visual (time-based: drotacio_ está en rad/s) rotacio_ += drotacio_ * delta_time; } } @@ -210,7 +210,7 @@ void Enemy::mou(float delta_time) { void Enemy::comportament_pentagon(float delta_time) { // Pentagon: zigzag esquivador (frequent direction changes) - // Similar a comportament original però amb probabilitat més alta + // Similar a comportament original pero con probabilitat més alta float velocitat_efectiva = velocity_ * delta_time; @@ -232,11 +232,11 @@ void Enemy::comportament_pentagon(float delta_time) { min_y, max_y); - // Zigzag: canvi d'angle més freqüent en tocar límits + // Zigzag: canvi de angle més freqüent en tocar límits if (new_y >= min_y && new_y <= max_y) { center_.y = new_y; } else { - // Probabilitat més alta de canvi d'angle + // Probabilitat més alta de canvi de angle if (static_cast(std::rand()) / RAND_MAX < Defaults::Enemies::Pentagon::CANVI_ANGLE_PROB) { float rand_angle = (static_cast(std::rand()) / RAND_MAX) * Defaults::Enemies::Pentagon::CANVI_ANGLE_MAX; @@ -256,13 +256,13 @@ void Enemy::comportament_pentagon(float delta_time) { } void Enemy::comportament_quadrat(float delta_time) { - // Quadrat: perseguidor (tracks player position) + // Cuadrado: perseguidor (tracks player position) // Update tracking timer tracking_timer_ += delta_time; // Periodically update angle toward ship - if (tracking_timer_ >= Defaults::Enemies::Quadrat::TRACKING_INTERVAL) { + if (tracking_timer_ >= Defaults::Enemies::Cuadrado::TRACKING_INTERVAL) { tracking_timer_ = 0.0F; if (ship_position_ != nullptr) { @@ -488,7 +488,7 @@ float Enemy::calcular_escala_actual() const { constexpr float END = Defaults::Enemies::Spawn::INVULNERABILITY_SCALE_END; scale = START + ((END - START) * smooth_t); } else if (animacio_.palpitacio_activa) { - // [EXISTING] Palpitació només quan no invulnerable + // [EXISTING] Palpitació solo cuando no invulnerable scale += animacio_.palpitacio_amplitud * std::sin(animacio_.palpitacio_fase); } @@ -502,7 +502,7 @@ float Enemy::get_base_velocity() const { case EnemyType::PENTAGON: return Defaults::Enemies::Pentagon::VELOCITAT; case EnemyType::QUADRAT: - return Defaults::Enemies::Quadrat::VELOCITAT; + return Defaults::Enemies::Cuadrado::VELOCITAT; case EnemyType::MOLINILLO: return Defaults::Enemies::Molinillo::VELOCITAT; default: @@ -544,8 +544,8 @@ bool Enemy::intent_spawn_safe(const Vec2& ship_pos, float& out_x, float& out_y) // Check Euclidean distance to ship float dx = out_x - ship_pos.x; float dy = out_y - ship_pos.y; - float distancia = std::sqrt((dx * dx) + (dy * dy)); + float distance = std::sqrt((dx * dx) + (dy * dy)); // Return true if position is safe (>= 36px from ship) - return distancia >= Defaults::Enemies::Spawn::SAFETY_DISTANCE; + return distance >= Defaults::Enemies::Spawn::SAFETY_DISTANCE; } diff --git a/source/game/entities/enemy.hpp b/source/game/entities/enemy.hpp index ef126e7..acbd292 100644 --- a/source/game/entities/enemy.hpp +++ b/source/game/entities/enemy.hpp @@ -1,6 +1,6 @@ -// enemy.hpp - Classe per a enemics (ORNIs pentàgons) -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 +// enemy.hpp - Clase para enemigos (ORNIs pentágonos) +// © 1999 Visente i Sergi (versión Pascal) +// © 2025 Port a C++20 con SDL3 #pragma once #include @@ -13,14 +13,14 @@ #include "core/types.hpp" #include "game/constants.hpp" -// Tipus d'enemy +// Tipo de enemy enum class EnemyType : uint8_t { - PENTAGON = 0, // Pentàgon esquivador (zigzag) - QUADRAT = 1, // Quadrat perseguidor (tracks ship) + PENTAGON = 0, // Pentágono esquivador (zigzag) + QUADRAT = 1, // Cuadrado perseguidor (tracks ship) MOLINILLO = 2 // Molinillo agressiu (fast, spinning) }; -// Estat d'animació (palpitació i rotació accelerada) +// Estat de animación (palpitació i rotación accelerada) struct EnemyAnimation { // Palpitation (breathing effect) bool palpitacio_activa = false; @@ -50,7 +50,7 @@ class Enemy : public Entities::Entity { // Override: Interfície d'Entity [[nodiscard]] bool isActive() const override { return esta_; } - // Override: Interfície de col·lisió + // Override: Interfície de colisión [[nodiscard]] float getCollisionRadius() const override { return Defaults::Entities::ENEMY_RADIUS; } @@ -58,7 +58,7 @@ class Enemy : public Entities::Entity { return esta_ && timer_invulnerabilitat_ <= 0.0F; } - // Getters (API pública sense canvis) + // Getters (API pública sin canvis) void destruir() { esta_ = false; } [[nodiscard]] float get_drotacio() const { return drotacio_; } [[nodiscard]] Vec2 getVelocityVector() const { @@ -90,8 +90,8 @@ class Enemy : public Entities::Entity { private: // Membres específics d'Enemy (heretats: renderer_, shape_, center_, angle_, brightness_) float velocity_; - float drotacio_; // Delta rotació visual (rad/s) - float rotacio_; // Rotació visual acumulada + float drotacio_; // Delta rotación visual (rad/s) + float rotacio_; // Rotación visual acumulada bool esta_; // [NEW] Enemy type and configuration @@ -101,9 +101,9 @@ class Enemy : public Entities::Entity { EnemyAnimation animacio_; // [NEW] Behavior state (type-specific) - float tracking_timer_; // For Quadrat: time since last angle update + float tracking_timer_; // For Cuadrado: time since last angle update const Vec2* ship_position_; // Pointer to ship position (for tracking) - float tracking_strength_; // For Quadrat: tracking intensity (0.0-1.5), default 0.5 + float tracking_strength_; // For Cuadrado: tracking intensity (0.0-1.5), default 0.5 // [NEW] Invulnerability state float timer_invulnerabilitat_; // Countdown timer (seconds), 0.0f = vulnerable diff --git a/source/game/entities/ship.cpp b/source/game/entities/ship.cpp index 0a5a650..2500084 100644 --- a/source/game/entities/ship.cpp +++ b/source/game/entities/ship.cpp @@ -1,6 +1,6 @@ // ship.cpp - Implementació de la nave del player -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 +// © 1999 Visente i Sergi (versión Pascal) +// © 2025 Port a C++20 con SDL3 #include "game/entities/ship.hpp" @@ -25,10 +25,10 @@ Ship::Ship(SDL_Renderer* renderer, const char* shape_file) velocity_(0.0F), is_hit_(false), invulnerable_timer_(0.0F) { - // [NUEVO] Brightness específic per naus + // [NUEVO] Brightness específic per naves brightness_ = Defaults::Brightness::NAU; - // [NUEVO] Carregar shape compartida des de fitxer + // [NUEVO] Carregar shape compartida desde file shape_ = Graphics::ShapeLoader::load(shape_file); if (!shape_ || !shape_->isValid()) { @@ -37,12 +37,12 @@ Ship::Ship(SDL_Renderer* renderer, const char* shape_file) } void Ship::init(const Vec2* spawn_point, bool activar_invulnerabilitat) { - // Inicialització de la ship (triangle) + // Inicialización de la ship (triangle) // Basat en el codi Pascal original: lines 380-384 // Copiat de joc_asteroides.cpp línies 30-44 - // [NUEVO] Ja no cal configurar points polars - la geometria es carrega del - // fitxer Només inicialitzem l'state de la instància + // [NUEVO] Ya no necesario configure points polars - la geometria es carrega del + // file Solo inicialitzem l'state de la instància // Use custom spawn point if provided, otherwise use center if (spawn_point != nullptr) { @@ -72,9 +72,9 @@ void Ship::init(const Vec2* spawn_point, bool activar_invulnerabilitat) { } void Ship::processInput(float delta_time, uint8_t player_id) { - // Processar input continu (com teclapuls() del Pascal original) + // Processar input continu (como teclapuls() del Pascal original) // Basat en joc_asteroides.cpp línies 66-85 - // Només processa input si la ship està viva + // Solo processa input si la ship está viva if (is_hit_) { return; } @@ -118,7 +118,7 @@ void Ship::processInput(float delta_time, uint8_t player_id) { } void Ship::update(float delta_time) { - // Només update si la ship està viva + // Solo update si la ship está viva if (is_hit_) { return; } @@ -129,12 +129,12 @@ void Ship::update(float delta_time) { invulnerable_timer_ = std::max(invulnerable_timer_, 0.0F); } - // Aplicar física (moviment + fricció) + // Aplicar física (movement + fricció) applyPhysics(delta_time); } void Ship::draw() const { - // Només draw si la ship està viva + // Solo draw si la ship está viva if (is_hit_) { return; } @@ -156,9 +156,9 @@ void Ship::draw() const { return; } - // Escalar velocity per l'efecte visual (200 px/s → ~6 px d'efecte) + // Escalar velocity per l'efecte visual (200 px/s → ~6 px de efecte) // El codi Pascal original sumava velocity (0-6) al radi per donar - // sensació de "empenta". Ara velocity està en px/s (0-200). + // sensació de "empenta". Ara velocity está en px/s (0-200). // Basat en joc_asteroides.cpp línies 127-134 // // [NUEVO] Convertir suma de velocitat_visual a scale multiplicativa @@ -171,12 +171,12 @@ void Ship::draw() const { } void Ship::applyPhysics(float delta_time) { - // Aplicar física de moviment + // Aplicar física de movement // Basat en joc_asteroides.cpp línies 87-113 - // Calcular nova posició basada en velocity i angle - // S'usa (angle - PI/2) perquè angle=0 apunta cap amunt, no cap a la dreta - // velocity_ està en px/s, així que multipliquem per delta_time + // Calcular nueva posición basada en velocity i angle + // S'usa (angle - PI/2) perquè angle=0 apunta sin amunt, no hacia la derecha + // velocity_ está en px/s, así que multipliquem per delta_time float dy = ((velocity_ * delta_time) * std::sin(angle_ - (Constants::PI / 2.0F))) + center_.y; @@ -184,7 +184,7 @@ void Ship::applyPhysics(float delta_time) { ((velocity_ * delta_time) * std::cos(angle_ - (Constants::PI / 2.0F))) + center_.x; - // Boundary checking amb radi de la ship + // Boundary checking con radi de la ship // CORRECCIÓ: Usar límits segurs i inequalitats inclusives float min_x; float max_x; diff --git a/source/game/entities/ship.hpp b/source/game/entities/ship.hpp index eb1574e..5a4aa06 100644 --- a/source/game/entities/ship.hpp +++ b/source/game/entities/ship.hpp @@ -1,6 +1,6 @@ -// ship.hpp - Classe per a la nave del player -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 +// ship.hpp - Clase para la nave del player +// © 1999 Visente i Sergi (versión Pascal) +// © 2025 Port a C++20 con SDL3 #pragma once #include @@ -28,7 +28,7 @@ class Ship : public Entities::Entity { // Override: Interfície d'Entity [[nodiscard]] bool isActive() const override { return !is_hit_; } - // Override: Interfície de col·lisió + // Override: Interfície de colisión [[nodiscard]] float getCollisionRadius() const override { return Defaults::Entities::SHIP_RADIUS; } @@ -36,7 +36,7 @@ class Ship : public Entities::Entity { return !is_hit_ && invulnerable_timer_ <= 0.0F; } - // Getters (API pública sense canvis) + // Getters (API pública sin canvis) [[nodiscard]] bool isAlive() const { return !is_hit_; } [[nodiscard]] bool isHit() const { return is_hit_; } [[nodiscard]] bool isInvulnerable() const { return invulnerable_timer_ > 0.0F; } @@ -49,12 +49,12 @@ class Ship : public Entities::Entity { // Setters void setCenter(const Vec2& nou_centre) { center_ = nou_centre; } - // Col·lisions (Fase 10) + // Colisiones (Fase 10) void markHit() { is_hit_ = true; } private: // Membres específics de Ship (heretats: renderer_, shape_, center_, angle_, brightness_) - float velocity_; // Velocitat (px/s) + float velocity_; // Velocidad (px/s) bool is_hit_; float invulnerable_timer_; // 0.0f = vulnerable, >0.0f = invulnerable diff --git a/source/game/options.cpp b/source/game/options.cpp index f3aaec6..21e627d 100644 --- a/source/game/options.cpp +++ b/source/game/options.cpp @@ -135,8 +135,8 @@ static const std::unordered_map BUTTON_TO_STRING = { {SDL_GAMEPAD_BUTTON_DPAD_DOWN, "DPAD_DOWN"}, {SDL_GAMEPAD_BUTTON_DPAD_LEFT, "DPAD_LEFT"}, {SDL_GAMEPAD_BUTTON_DPAD_RIGHT, "DPAD_RIGHT"}, - {100, "L2_AS_BUTTON"}, // Trigger L2 com a botó digital - {101, "R2_AS_BUTTON"} // Trigger R2 com a botó digital + {100, "L2_AS_BUTTON"}, // Trigger L2 como a botó digital + {101, "R2_AS_BUTTON"} // Trigger R2 como a botó digital }; // Mapa invers: string a botó de gamepad @@ -178,7 +178,7 @@ static auto stringToButton(const std::string& str) -> int { // ========== FI FUNCIONS AUXILIARS ========== -// Inicialitzar opcions amb valors per defecte de Defaults:: +// Inicialitzar opciones con valors per defecte de Defaults:: void init() { #ifdef _DEBUG console = true; @@ -219,10 +219,10 @@ void init() { version = std::string(Project::VERSION); } -// Establir la ruta del fitxer de configuració +// Establir la ruta del file de configuración void setConfigFile(const std::string& path) { config_file_path = path; } -// Funcions auxiliars per load seccions del YAML +// Funciones auxiliars per load seccions del YAML static void loadWindowConfigFromYaml(const fkyaml::node& yaml) { if (yaml.contains("window")) { @@ -372,7 +372,7 @@ static void loadRenderingConfigFromYaml(const fkyaml::node& yaml) { if (rend.contains("vsync")) { try { int val = rend["vsync"].get_value(); - // Validar: només 0 o 1 + // Validar: solo 0 o 1 rendering.vsync = (val == 0 || val == 1) ? val : Defaults::Rendering::VSYNC_DEFAULT; } catch (...) { rendering.vsync = Defaults::Rendering::VSYNC_DEFAULT; @@ -446,7 +446,7 @@ static void loadAudioConfigFromYaml(const fkyaml::node& yaml) { } } -// Carregar controls del player 1 des de YAML +// Carregar controls del player 1 desde YAML static void loadPlayer1ControlsFromYaml(const fkyaml::node& yaml) { if (!yaml.contains("player1")) { return; @@ -494,7 +494,7 @@ static void loadPlayer1ControlsFromYaml(const fkyaml::node& yaml) { } } -// Carregar controls del player 2 des de YAML +// Carregar controls del player 2 desde YAML static void loadPlayer2ControlsFromYaml(const fkyaml::node& yaml) { if (!yaml.contains("player2")) { return; @@ -542,22 +542,22 @@ static void loadPlayer2ControlsFromYaml(const fkyaml::node& yaml) { } } -// Carregar configuració des del fitxer YAML +// Carregar configuración des del file YAML auto loadFromFile() -> bool { const std::string CONFIG_VERSION = std::string(Project::VERSION); std::ifstream file(config_file_path); if (!file.good()) { - // El fitxer no existeix → crear-ne un de nou amb valors per defecte + // El file no existeix → crear-ne un de nuevo con valors per defecte if (console) { - std::cout << "Fitxer de config no trobat, creant-ne un de nou: " + std::cout << "Archivo de config no trobat, creant-ne un de nuevo: " << config_file_path << '\n'; } saveToFile(); return true; } - // Llegir tot el contingut del fitxer + // Llegir todo el contingut del file std::string content((std::istreambuf_iterator(file)), std::istreambuf_iterator()); file.close(); @@ -566,15 +566,15 @@ auto loadFromFile() -> bool { // Parsejar YAML auto yaml = fkyaml::node::deserialize(content); - // Validar versió + // Validar versión if (yaml.contains("version")) { version = yaml["version"].get_value(); } if (CONFIG_VERSION != version) { - // Versió incompatible → regenerar config + // Versión incompatible → regenerar config if (console) { - std::cout << "Versió de config incompatible (esperada: " + std::cout << "Versión de config incompatible (esperada: " << CONFIG_VERSION << ", trobada: " << version << "), regenerant config\n"; } @@ -593,7 +593,7 @@ auto loadFromFile() -> bool { loadPlayer2ControlsFromYaml(yaml); if (console) { - std::cout << "Config carregada correctament des de: " << config_file_path + std::cout << "Config carregada correctament desde: " << config_file_path << '\n'; } @@ -603,7 +603,7 @@ auto loadFromFile() -> bool { // Error de parsejat YAML → regenerar config if (console) { std::cerr << "Error parsejant YAML: " << e.what() << '\n'; - std::cerr << "Creant config nou amb valors per defecte\n"; + std::cerr << "Creant config nuevo con valors per defecte\n"; } init(); saveToFile(); @@ -645,19 +645,19 @@ static void savePlayer2ControlsToYaml(std::ofstream& file) { file << " gamepad_name: \"" << player2.gamepad_name << "\" # Buit = segon disponible\n\n"; } -// Guardar configuració al fitxer YAML +// Guardar configuración al file YAML auto saveToFile() -> bool { std::ofstream file(config_file_path); if (!file.is_open()) { if (console) { - std::cerr << "No s'ha pogut obrir el fitxer de config per escriure: " + std::cerr << "No s'ha pogut obrir el file de config per escriure: " << config_file_path << '\n'; } return false; } // Escriure manualment per controlar format i comentaris - file << "# Orni Attack - Fitxer de Configuració\n"; + file << "# Orni Attack - Archivo de Configuración\n"; file << "# Auto-generat. Les edicions manuals es preserven si són " "vàlides.\n\n"; @@ -670,7 +670,7 @@ auto saveToFile() -> bool { file << " fullscreen: " << (window.fullscreen ? "true" : "false") << "\n"; file << " zoom_factor: " << window.zoom_factor << " # 0.5x-max (0.1 increments)\n\n"; - file << "# FÍSICA (tots els valors en px/s, rad/s, etc.)\n"; + file << "# FÍSICA (todos los valors en px/s, rad/s, etc.)\n"; file << "physics:\n"; file << " rotation_speed: " << physics.rotation_speed << " # rad/s\n"; file << " acceleration: " << physics.acceleration << " # px/s²\n"; diff --git a/source/game/options.hpp b/source/game/options.hpp index c226ee9..65af46e 100644 --- a/source/game/options.hpp +++ b/source/game/options.hpp @@ -6,7 +6,7 @@ namespace Options { -// Estructures de configuració +// Estructures de configuración struct Window { int width{640}; @@ -75,7 +75,7 @@ struct PlayerControls { // Variables globals (inline per evitar ODR violations) -inline std::string version{}; // Versió del config per validació +inline std::string version{}; // Versión del config per validació inline bool console{false}; // Eixida de debug inline Window window{}; inline Physics physics{}; @@ -104,17 +104,17 @@ inline PlayerControls player2{ .gamepad_name = "" // Segon gamepad disponible }; -// Per compatibilitat amb pollo (no utilitzat en orni, però necessari per Input) +// Per compatibilitat con pollo (no utilitzat en orni, pero necessari per Input) inline KeyboardControls keyboard_controls{}; inline GamepadControls gamepad_controls{}; inline std::string config_file_path{}; // Establert per setConfigFile() -// Funcions públiques +// Funciones públiques -void init(); // Inicialitzar amb valors per defecte +void init(); // Inicialitzar con valors per defecte void setConfigFile( - const std::string& path); // Establir ruta del fitxer de config + const std::string& path); // Establir ruta del file de config auto loadFromFile() -> bool; // Carregar config YAML auto saveToFile() -> bool; // Guardar config YAML diff --git a/source/game/scenes/game_scene.cpp b/source/game/scenes/game_scene.cpp index 439a6b3..418851d 100644 --- a/source/game/scenes/game_scene.cpp +++ b/source/game/scenes/game_scene.cpp @@ -1,6 +1,6 @@ -// escena_joc.cpp - Implementació de la lògica del joc -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 +// game_scene.cpp - Implementació de la lógica del juego +// © 1999 Visente i Sergi (versión Pascal) +// © 2025 Port a C++20 con SDL3 #include "game_scene.hpp" @@ -34,39 +34,39 @@ GameScene::GameScene(SDLManager& sdl, SceneContext& context) floating_score_manager_(sdl.getRenderer()), text_(sdl.getRenderer()), init_hud_rect_sound_played_(false) { - // Recuperar configuració de match des del context + // Recuperar configuración de match des del context match_config_ = context_.getMatchConfig(); - // Debug output de la configuració - std::cout << "[GameScene] Configuració de match - P1: " + // Debug output de la configuración + std::cout << "[GameScene] Configuración de match - P1: " << (match_config_.jugador1_actiu ? "ACTIU" : "INACTIU") << ", P2: " << (match_config_.jugador2_actiu ? "ACTIU" : "INACTIU") << '\n'; - // Consumir opcions (preparació per MODE_DEMO futur) + // Consumir opciones (preparació per MODE_DEMO futur) auto option = context_.consumeOption(); (void)option; // Suprimir warning de variable no usada - // Inicialitzar naus amb renderer (P1=ship.shp, P2=ship2.shp) + // Inicialitzar naves con renderer (P1=ship.shp, P2=ship2.shp) ships_[0] = Ship(sdl.getRenderer(), "ship.shp"); // Jugador 1: nave estàndar - ships_[1] = Ship(sdl.getRenderer(), "ship2.shp"); // Jugador 2: interceptor amb ales + ships_[1] = Ship(sdl.getRenderer(), "ship2.shp"); // Jugador 2: interceptor con ales - // Inicialitzar bales amb renderer + // Inicialitzar balas con renderer for (auto& bullet : bullets_) { bullet = Bullet(sdl.getRenderer()); } - // Inicialitzar enemics amb renderer + // Inicialitzar enemigos con renderer for (auto& enemy : enemies_) { enemy = Enemy(sdl.getRenderer()); } } void GameScene::run() { - std::cout << "SceneType Joc: Inicialitzant...\n"; + std::cout << "SceneType Juego: Inicialitzant...\n"; - // Inicialitzar state del joc + // Inicialitzar state del juego init(); SDL_Event event; @@ -78,16 +78,16 @@ void GameScene::run() { float delta_time = (current_time - last_time) / 1000.0F; last_time = current_time; - // Limitar delta_time per evitar grans salts + // Limitar delta_time per evitar grandes salts delta_time = std::min(delta_time, 0.05F); - // Actualitzar comptador de FPS + // Actualitzar counter de FPS sdl_.updateFPS(delta_time); // Actualitzar visibilitat del cursor (auto-ocultar) Mouse::updateCursorVisibility(); - // Actualitzar sistema d'input ABANS del event loop + // Actualitzar sistema de input ABANS del event loop Input::get()->update(); // Processar events SDL @@ -101,29 +101,29 @@ void GameScene::run() { GlobalEvents::handle(event, sdl_, context_); } - // Actualitzar física del joc amb delta_time real + // Actualitzar física del juego con delta_time real update(delta_time); - // Actualitzar sistema d'audio + // Actualitzar sistema de audio Audio::update(); // Actualitzar colors oscil·lats sdl_.updateColors(delta_time); // Netejar pantalla (usa color oscil·lat) - sdl_.neteja(0, 0, 0); + sdl_.clear(0, 0, 0); - // Actualitzar context de renderitzat (factor d'scale global) + // Actualitzar context de renderizado (factor de scale global) sdl_.updateRenderingContext(); - // Dibuixar joc + // Dibuixar juego draw(); // Presentar renderer (swap buffers) - sdl_.presenta(); + sdl_.present(); } - std::cout << "SceneType Joc: Finalitzant...\n"; + std::cout << "SceneType Juego: Finalitzant...\n"; } void GameScene::init() { @@ -145,7 +145,7 @@ void GameScene::init() { stage_manager_->init(); // [NEW] Set ship position reference for safe spawn (P1 for now, TODO: dual tracking) - stage_manager_->get_spawn_controller().set_ship_position(&ships_[0].getCenter()); + stage_manager_->getSpawnController().set_ship_position(&ships_[0].getCenter()); // Inicialitzar timers de muerte per player hit_timer_per_player_[0] = 0.0F; @@ -165,12 +165,12 @@ void GameScene::init() { score_per_player_[1] = 0; floating_score_manager_.reset(); - // DEPRECATED: spawn_position_ ja no s'usa, es calcula dinàmicament amb obtenir_punt_spawn(player_id) + // DEPRECATED: spawn_position_ ya no s'usa, es calcula dinàmicament con obtenir_punt_spawn(player_id) // const SDL_FRect& zona = Defaults::Zones::PLAYAREA; // spawn_position_.x = zona.x + zona.w * 0.5f; // spawn_position_.y = zona.y + zona.h * Defaults::Game::INIT_HUD_SHIP_START_Y_RATIO; - // Inicialitzar naus segons configuració (només jugadors active) + // 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; @@ -180,10 +180,10 @@ void GameScene::init() { ships_[i].init(&spawn_pos, false); // No invulnerability at start std::cout << "[GameScene] Jugador " << (i + 1) << " inicialitzat\n"; } else { - // Jugador inactiu: marcar com a mort permanent + // 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; // Sense vides + lives_per_player_[i] = 0; // Sin vides std::cout << "[GameScene] Jugador " << (i + 1) << " inactiu\n"; } } @@ -195,16 +195,16 @@ void GameScene::init() { // DON'T call enemy.init() here - stage system handles spawning } - // Inicialitzar bales (now 6 instead of 3) + // Inicialitzar balas (now 6 instead of 3) for (auto& bullet : bullets_) { bullet.init(); } - // [ELIMINAT] Iniciar música de joc (ara es gestiona en stage_manager) - // La música s'inicia quan es transiciona de INIT_HUD a LEVEL_START + // [ELIMINAT] Iniciar música de juego (ara es gestiona en stage_manager) + // La música s'inicia cuando es transiciona de INIT_HUD a LEVEL_START // Audio::get()->playMusic("game.ogg"); - // Reset flag de sons d'animació + // Reset flag de sons de animación init_hud_rect_sound_played_ = false; } @@ -213,14 +213,14 @@ void GameScene::update(float delta_time) { if (game_over_state_ == GameOverState::NONE) { auto* input = Input::get(); - // Jugador 1 dispara (només si està active) + // Jugador 1 dispara (solo si está active) if (match_config_.jugador1_actiu) { if (input->checkActionPlayer1(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) { disparar_bala(0); } } - // Jugador 2 dispara (només si està active) + // Jugador 2 dispara (solo si está active) if (match_config_.jugador2_actiu) { if (input->checkActionPlayer2(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) { disparar_bala(1); @@ -287,9 +287,9 @@ void GameScene::update(float delta_time) { game_over_timer_ -= delta_time; if (game_over_timer_ <= 0.0F) { - // Aturar música de joc abans de tornar al títol + // Aturar música de juego antes de tornar al título Audio::get()->stopMusic(); - // Transició a pantalla de títol + // Transición a pantalla de título context_.setNextScene(SceneType::TITLE); SceneManager::actual = SceneType::TITLE; return; @@ -374,8 +374,8 @@ void GameScene::update(float delta_time) { // Update stage manager timer (pot canviar l'state!) stage_manager_->update(delta_time); - // [FIX] Si l'state ha canviat durant update(), sortir immediatament - // per evitar recalcular la posició de la ship amb el nou timer + // [FIX] Si l'state ha canviat durante update(), salir immediatament + // per evitar recalcular la posición de la ship con el nuevo timer if (stage_manager_->get_estat() != StageSystem::EstatStage::INIT_HUD) { break; } @@ -395,7 +395,7 @@ void GameScene::update(float delta_time) { Defaults::Game::INIT_HUD_SHIP2_RATIO_INIT, Defaults::Game::INIT_HUD_SHIP2_RATIO_END); - // [MODIFICAT] Animar AMBAS naus con sus progress respectivos + // [MODIFICAT] Animar AMBAS naves con sus progress respectivos if (match_config_.jugador1_actiu && ship1_progress < 1.0F) { Vec2 pos_p1 = calcular_posicio_nau_init_hud(ship1_progress, 0); ships_[0].setCenter(pos_p1); @@ -406,8 +406,8 @@ void GameScene::update(float delta_time) { ships_[1].setCenter(pos_p2); } - // Una vegada l'animació acaba, permetre control normal - // però mantenir la posició inicial especial fins LEVEL_START + // Una vez l'animación acaba, permetre control normal + // pero mantenir la posición inicial especial hasta LEVEL_START break; } @@ -444,13 +444,13 @@ void GameScene::update(float delta_time) { case StageSystem::EstatStage::PLAYING: { // [NEW] Update stage manager (spawns enemies, pause if BOTH dead) - bool pausar_spawn = (hit_timer_per_player_[0] > 0.0F && hit_timer_per_player_[1] > 0.0F); - stage_manager_->get_spawn_controller().update(delta_time, enemies_, pausar_spawn); + bool pause_spawn = (hit_timer_per_player_[0] > 0.0F && hit_timer_per_player_[1] > 0.0F); + stage_manager_->getSpawnController().update(delta_time, enemies_, pause_spawn); // [NEW] Check stage completion (only when at least one player alive) bool algun_jugador_viu = (hit_timer_per_player_[0] == 0.0F || hit_timer_per_player_[1] == 0.0F); if (algun_jugador_viu) { - auto& spawn_ctrl = stage_manager_->get_spawn_controller(); + auto& spawn_ctrl = stage_manager_->getSpawnController(); if (spawn_ctrl.tots_enemics_destruits(enemies_)) { stage_manager_->stage_completat(); Audio::get()->playSound(Defaults::Sound::GOOD_JOB_COMMANDER, Audio::Group::GAME); @@ -552,7 +552,7 @@ void GameScene::draw() { constexpr float scale = Defaults::Game::GameOverScreen::TEXT_SCALE; constexpr float spacing = Defaults::Game::GameOverScreen::TEXT_SPACING; - // Calcular centre de l'àrea de joc usant constants + // Calcular centro de l'àrea de juego usant constants 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); @@ -568,7 +568,7 @@ void GameScene::draw() { switch (state) { case StageSystem::EstatStage::INIT_HUD: { - // Calcular progrés de cada animació independent + // Calcular progrés de cada animación independent float timer = stage_manager_->get_timer_transicio(); float total_time = Defaults::Game::INIT_HUD_DURATION; float global_progress = 1.0F - (timer / total_time); @@ -596,7 +596,7 @@ void GameScene::draw() { // Dibuixar elements animats if (rect_progress > 0.0F) { - // [NOU] Reproduir so quan comença l'animació del rectangle + // [NOU] Reproduir so cuando comença l'animación del rectangle if (!init_hud_rect_sound_played_) { Audio::get()->playSound(Defaults::Sound::INIT_HUD, Audio::Group::GAME); init_hud_rect_sound_played_ = true; @@ -609,7 +609,7 @@ void GameScene::draw() { dibuixar_marcador_animat(score_progress); } - // [MODIFICAT] Dibuixar naus amb progress independent + // [MODIFICAT] Dibuixar naves con progress independent if (ship1_progress > 0.0F && match_config_.jugador1_actiu && !ships_[0].isHit()) { ships_[0].draw(); } @@ -735,7 +735,7 @@ void GameScene::tocado(uint8_t player_id) { } void GameScene::dibuixar_marges() const { - // Dibuixar rectangle de la zona de joc + // Dibuixar rectangle de la zona de juego const SDL_FRect& zona = Defaults::Zones::PLAYAREA; // Coordenades dels cantons @@ -755,22 +755,22 @@ void GameScene::dibuixar_marcador() { // Construir text del marcador std::string text = buildScoreboard(); - // Paràmetres de renderització + // Parámetros de renderització const float scale = 0.85F; const float spacing = 0.0F; - // Calcular centre de la zona del marcador + // Calcular centro de la zona del marcador const SDL_FRect& scoreboard = Defaults::Zones::SCOREBOARD; float centre_x = scoreboard.w / 2.0F; float centre_y = scoreboard.y + (scoreboard.h / 2.0F); - // Renderitzar centrat + // Renderizar centrat text_.renderCentered(text, {.x = centre_x, .y = centre_y}, scale, spacing); } void GameScene::dibuixar_marges_animat(float progress) const { - // Animació seqüencial del rectangle amb efecte de "pinzell" - // Dos pinzells comencen al centre superior i baixen pels laterals + // Animación seqüencial del rectangle con efecte de "pinzell" + // Dos pinzells comencen al centro superior i baixen por los laterals const SDL_FRect& zona = Defaults::Zones::PLAYAREA; @@ -792,11 +792,11 @@ void GameScene::dibuixar_marges_animat(float progress) const { if (eased_progress > 0.0F) { float phase1_progress = std::min(eased_progress / PHASE_1_END, 1.0F); - // Línia esquerra: creix des del centre cap a l'esquerra + // Línia izquierda: creix des del centro hacia l'izquierda int x1_phase1 = static_cast(cx - ((cx - x1) * phase1_progress)); Rendering::linea(sdl_.getRenderer(), cx, y1, x1_phase1, y1); - // Línia dreta: creix des del centre cap a la dreta + // Línia derecha: creix des del centro hacia la derecha int x2_phase1 = static_cast(cx + ((x2 - cx) * phase1_progress)); Rendering::linea(sdl_.getRenderer(), cx, y1, x2_phase1, y1); } @@ -805,11 +805,11 @@ void GameScene::dibuixar_marges_animat(float progress) const { if (eased_progress > PHASE_1_END) { float phase2_progress = std::min((eased_progress - PHASE_1_END) / (PHASE_2_END - PHASE_1_END), 1.0F); - // Línia esquerra: creix des de dalt cap a baix + // Línia izquierda: creix desde dalt hacia baix int y2_phase2 = static_cast(y1 + ((y2 - y1) * phase2_progress)); Rendering::linea(sdl_.getRenderer(), x1, y1, x1, y2_phase2); - // Línia dreta: creix des de dalt cap a baix + // Línia derecha: creix desde dalt hacia baix Rendering::linea(sdl_.getRenderer(), x2, y1, x2, y2_phase2); } @@ -817,46 +817,46 @@ void GameScene::dibuixar_marges_animat(float progress) const { if (eased_progress > PHASE_2_END) { float phase3_progress = (eased_progress - PHASE_2_END) / (1.0F - PHASE_2_END); - // Línia esquerra: creix des de l'esquerra cap al centre + // Línia izquierda: creix desde l'izquierda hacia el centro int x_left_phase3 = static_cast(x1 + ((cx - x1) * phase3_progress)); Rendering::linea(sdl_.getRenderer(), x1, y2, x_left_phase3, y2); - // Línia dreta: creix des de la dreta cap al centre + // Línia derecha: creix desde la derecha hacia el centro int x_right_phase3 = static_cast(x2 - ((x2 - cx) * phase3_progress)); Rendering::linea(sdl_.getRenderer(), x2, y2, x_right_phase3, y2); } } void GameScene::dibuixar_marcador_animat(float progress) { - // Animació del marcador pujant des de baix amb easing + // Animación del marcador pujant desde baix con easing - // Calcular progrés amb easing + // Calcular progrés con easing float eased_progress = Easing::ease_out_quad(progress); // Construir text std::string text = buildScoreboard(); - // Paràmetres + // Parámetros const float scale = 0.85F; const float spacing = 0.0F; - // Calcular centre de la zona del marcador + // Calcular centro de la zona del marcador const SDL_FRect& scoreboard = Defaults::Zones::SCOREBOARD; float centre_x = scoreboard.w / 2.0F; float centre_y_final = scoreboard.y + (scoreboard.h / 2.0F); - // Posició Y inicial (offscreen, sota de la pantalla) + // Posición Y inicial (offscreen, sota de la pantalla) auto centre_y_inicial = static_cast(Defaults::Game::HEIGHT); - // Interpolació amb easing + // Interpolació con easing float centre_y_animada = centre_y_inicial + ((centre_y_final - centre_y_inicial) * eased_progress); - // Renderitzar centrat en posició animada + // Renderizar centrat en posición animada text_.renderCentered(text, {.x = centre_x, .y = centre_y_animada}, scale, spacing); } Vec2 GameScene::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const { - // Animació de la ship pujant des de baix amb easing + // Animación de la ship pujant desde baix con easing // [MODIFICAT] Ambas naves usan ease_out_quad (desfase temporal via INIT/END) // Aplicar easing (uniforme para ambas naves) @@ -864,16 +864,16 @@ Vec2 GameScene::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const SDL_FRect& zona = Defaults::Zones::PLAYAREA; - // Calcular posició final segons player (reutilitza obtenir_punt_spawn) + // Calcular posición final segons player (reutilitza obtenir_punt_spawn) Vec2 spawn_final = obtenir_punt_spawn(player_id); float x_final = spawn_final.x; float y_final = spawn_final.y; - // Y inicial: offscreen, 50px sota la zona de joc + // Y inicial: offscreen, 50px sota la zona de juego float y_inicial = zona.y + zona.h + 50.0F; // X no canvia (destí segons player_id) - // Y interpola amb easing + // Y interpola con easing float y_animada = y_inicial + ((y_final - y_inicial) * eased_progress); return {.x = x_final, .y = y_animada}; @@ -905,7 +905,7 @@ float GameScene::calcular_progress_rango(float global_progress, float ratio_init } std::string GameScene::buildScoreboard() const { - // Puntuació P1 (6 dígits) - mostrar zeros si inactiu + // Puntuación P1 (6 dígits) - mostrar zeros si inactiu std::string score_p1; std::string vides_p1; if (match_config_.jugador1_actiu) { @@ -919,12 +919,12 @@ std::string GameScene::buildScoreboard() const { vides_p1 = "00"; } - // Nivell (2 dígits) + // Nivel (2 dígits) uint8_t stage_num = stage_manager_->get_stage_actual(); std::string stage_str = (stage_num < 10) ? "0" + std::to_string(stage_num) : std::to_string(stage_num); - // Puntuació P2 (6 dígits) - mostrar zeros si inactiu + // Puntuación P2 (6 dígits) - mostrar zeros si inactiu std::string score_p2; std::string vides_p2; if (match_config_.jugador2_actiu) { @@ -939,7 +939,7 @@ std::string GameScene::buildScoreboard() const { } // Format: "123456 03 LEVEL 01 654321 02" - // Nota: dos espais entre seccions, mantenir ambdós slots sempre visibles + // Nota: dos espais entre seccions, mantenir ambdós slots siempre visibles return score_p1 + " " + vides_p1 + " LEVEL " + stage_str + " " + score_p2 + " " + vides_p2; } @@ -947,13 +947,13 @@ void GameScene::detectar_col·lisions_bales_enemics() { // Amplificador per hitbox més generós (115%) constexpr float AMPLIFIER = Defaults::Game::COLLISION_BULLET_ENEMY_AMPLIFIER; - // Velocitat d'explosió reduïda per efecte suau + // Velocidad de explosión reduïda per efecte suau constexpr float VELOCITAT_EXPLOSIO = 80.0F; // px/s (en lloc de 80.0f per defecte) - // Iterar per totes les bales i enemics + // Iterar per todas las balas i enemigos for (auto& bullet : bullets_) { for (auto& enemy : enemies_) { - // Comprovar col·lisió utilitzant la interfície genèrica + // Comprovar colisión utilitzant la interfície genèrica if (Physics::check_collision(bullet, enemy, AMPLIFIER)) { // *** COL·LISIÓ DETECTADA *** @@ -980,17 +980,17 @@ void GameScene::detectar_col·lisions_bales_enemics() { // 3. Create floating score number floating_score_manager_.crear(points, pos_enemic); - // 4. Destruir enemy (marca com inactiu) + // 4. Destruir enemy (marca como inactiu) enemy.destruir(); - // 2. Crear explosió de fragments + // 2. Crear explosión de fragments Vec2 vel_enemic = enemy.getVelocityVector(); debris_manager_.explode( - enemy.getShape(), // Forma vectorial del pentàgon - pos_enemic, // Posició central - 0.0F, // Angle (enemy té rotació interna) + enemy.getShape(), // Forma vectorial del pentágono + pos_enemic, // Posición central + 0.0F, // Angle (enemy té rotación interna) 1.0F, // Escala normal - VELOCITAT_EXPLOSIO, // 50 px/s (explosió suau) + VELOCITAT_EXPLOSIO, // 50 px/s (explosión suau) enemy.getBrightness(), // Heredar brightness vel_enemic, // Heredar velocity enemy.get_drotacio(), // Heredar velocity angular (trayectorias curvas) @@ -1000,7 +1000,7 @@ void GameScene::detectar_col·lisions_bales_enemics() { // 3. Desactivar bullet bullet.desactivar(); - // 4. Eixir del bucle intern (bullet només destrueix 1 enemy) + // 4. Eixir del bucle intern (bullet solo destrueix 1 enemy) break; } } @@ -1031,7 +1031,7 @@ void GameScene::detectar_col·lisio_naus_enemics() { continue; } - // Comprovar col·lisió utilitzant la interfície genèrica + // Comprovar colisión utilitzant la interfície genèrica if (Physics::check_collision(ships_[i], enemy, AMPLIFIER)) { tocado(i); // Trigger death sequence for player i break; // Only one collision per player per frame @@ -1082,7 +1082,7 @@ void GameScene::detectar_col·lisions_bales_jugadors() { continue; } - // Comprovar col·lisió utilitzant la interfície genèrica + // Comprovar colisión utilitzant la interfície genèrica if (Physics::check_collision(bullet, ships_[player_id], AMPLIFIER)) { // *** FRIENDLY FIRE HIT *** @@ -1095,7 +1095,7 @@ void GameScene::detectar_col·lisions_bales_jugadors() { // Victim loses 1 life tocado(player_id); - // Attacker gains 1 life (no cap) + // Attacker gains 1 life (no sin) lives_per_player_[bullet_owner]++; } @@ -1187,7 +1187,7 @@ Vec2 GameScene::obtenir_punt_spawn(uint8_t player_id) const { float x_ratio; if (match_config_.es_un_jugador()) { - // Un sol player: spawn al centre (50%) + // Un sol player: spawn al centro (50%) x_ratio = 0.5F; } else { // Dos jugadors: spawn a posicions separades diff --git a/source/game/scenes/game_scene.hpp b/source/game/scenes/game_scene.hpp index 0c87642..1169d2b 100644 --- a/source/game/scenes/game_scene.hpp +++ b/source/game/scenes/game_scene.hpp @@ -1,9 +1,8 @@ -// escena_joc.hpp - Lògica principal del joc -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 +// game_scene.hpp - Lógica principal del juego +// © 1999 Visente i Sergi (versión Pascal) +// © 2025 Port a C++20 con SDL3 -#ifndef ESCENA_JOC_HPP -#define ESCENA_JOC_HPP +#pragma once #include #include @@ -31,7 +30,7 @@ enum class GameOverState { GAME_OVER // Final game over (returning to title) }; -// Classe principal del joc (escena) +// Clase principal del juego (escena) class GameScene { public: explicit GameScene(SDLManager& sdl, SceneManager::SceneContext& context); @@ -45,13 +44,13 @@ class GameScene { private: SDLManager& sdl_; SceneManager::SceneContext& context_; - GameConfig::MatchConfig match_config_; // Configuració de jugadors active + GameConfig::MatchConfig match_config_; // Configuración de jugadors active // Efectes visuals Effects::DebrisManager debris_manager_; Effects::FloatingScoreManager floating_score_manager_; - // Estat del joc + // Estat del juego std::array ships_; // [0]=P1, [1]=P2 std::array enemies_; std::array bullets_; // 6 balas: P1=[0,1,2], P2=[3,4,5] @@ -74,16 +73,16 @@ class GameScene { std::unique_ptr stage_config_; std::unique_ptr stage_manager_; - // Control de sons d'animació INIT_HUD + // Control de sons de animación INIT_HUD bool init_hud_rect_sound_played_; // Flag para evitar repetir sonido del rectángulo - // Funcions privades + // Funciones privades void tocado(uint8_t player_id); - void detectar_col·lisions_bales_enemics(); // Col·lisions bullet-enemy + void detectar_col·lisions_bales_enemics(); // Colisiones bullet-enemy void detectar_col·lisio_naus_enemics(); // Ship-enemy collision detection (plural) void detectar_col·lisions_bales_jugadors(); // Bullet-player collision detection (friendly fire) - void dibuixar_marges() const; // Dibuixar vores de la zona de joc - void dibuixar_marcador(); // Dibuixar marcador de puntuació + void dibuixar_marges() const; // Dibuixar vores de la zona de juego + void dibuixar_marcador(); // Dibuixar marcador de puntuación void disparar_bala(uint8_t player_id); // Shoot bullet from player [[nodiscard]] Vec2 obtenir_punt_spawn(uint8_t player_id) const; // Get spawn position for player @@ -97,16 +96,14 @@ class GameScene { // [NEW] Stage system helpers void dibuixar_missatge_stage(const std::string& message); - // [NEW] Funcions d'animació per INIT_HUD - void dibuixar_marges_animat(float progress) const; // Rectangle amb creixement uniforme - void dibuixar_marcador_animat(float progress); // Marcador que puja des de baix - [[nodiscard]] Vec2 calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const; // Posició animada de la ship + // [NEW] Funciones de animación per INIT_HUD + void dibuixar_marges_animat(float progress) const; // Rectangle con creixement uniforme + void dibuixar_marcador_animat(float progress); // Marcador que puja desde baix + [[nodiscard]] Vec2 calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const; // Posición animada de la ship // [NEW] Función helper del sistema de animación INIT_HUD [[nodiscard]] float calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const; - // [NEW] Funció helper del marcador + // [NEW] Función helper del marcador [[nodiscard]] std::string buildScoreboard() const; }; - -#endif // ESCENA_JOC_HPP diff --git a/source/game/scenes/logo_scene.cpp b/source/game/scenes/logo_scene.cpp index a91098e..4bc4f90 100644 --- a/source/game/scenes/logo_scene.cpp +++ b/source/game/scenes/logo_scene.cpp @@ -1,4 +1,4 @@ -// escena_logo.cpp - Implementació de l'escena logo +// logo_scene.cpp - Implementació de l'escena logo // © 2025 Port a C++20 #include "logo_scene.hpp" @@ -22,8 +22,8 @@ using SceneManager::SceneContext; using SceneType = SceneContext::SceneType; using Option = SceneContext::Option; -// Helper: calcular el progrés individual d'una lletra -// en funció del progrés global (efecte seqüencial) +// Helper: calcular el progrés individual de una lletra +// en función del progrés global (efecte seqüencial) static float calcular_progress_letra(size_t letra_index, size_t num_letras, float global_progress, float threshold) { if (num_letras == 0) { return 1.0F; @@ -37,7 +37,7 @@ static float calcular_progress_letra(size_t letra_index, size_t num_letras, floa // Interpolar progrés if (global_progress < start) { - return 0.0F; // Encara no ha començat + return 0.0F; // Aún no ha començat } if (global_progress >= end) { return 1.0F; // Completament apareguda @@ -55,7 +55,7 @@ LogoScene::LogoScene(SDLManager& sdl, SceneContext& context) temps_des_ultima_explosio_(0.0F) { std::cout << "SceneType Logo: Inicialitzant...\n"; - // Consumir opcions (LOGO no processa opcions actualment) + // Consumir opciones (LOGO no processa opciones actualment) auto option = context_.consumeOption(); (void)option; // Suprimir warning @@ -64,9 +64,9 @@ LogoScene::LogoScene(SDLManager& sdl, SceneContext& context) } LogoScene::~LogoScene() { - // Aturar tots els sons i la música + // Aturar todos los sons y la música Audio::get()->stopAllSounds(); - std::cout << "SceneType Logo: Sons aturats\n"; + std::cout << "SceneType Logo: Sons parados\n"; } void LogoScene::run() { @@ -79,16 +79,16 @@ void LogoScene::run() { float delta_time = (current_time - last_time) / 1000.0F; last_time = current_time; - // Limitar delta_time per evitar grans salts + // Limitar delta_time per evitar grandes salts delta_time = std::min(delta_time, 0.05F); - // Actualitzar comptador de FPS + // Actualitzar counter de FPS sdl_.updateFPS(delta_time); // Actualitzar visibilitat del cursor (auto-ocultar) Mouse::updateCursorVisibility(); - // Actualitzar sistema d'input ABANS del event loop + // Actualitzar sistema de input ABANS del event loop Input::get()->update(); // Processar events SDL @@ -103,17 +103,17 @@ void LogoScene::run() { continue; } - // Processar events de l'escena (qualsevol tecla/clic salta al joc) + // Processar events de l'escena (qualsevol tecla/clic salta al juego) processar_events(event); } - // Actualitzar lògica + // Actualitzar lógica update(delta_time); // Actualitzar colors oscil·lats (efecte verd global) sdl_.updateColors(delta_time); - // Actualitzar context de renderitzat (factor d'scale global) + // Actualitzar context de renderizado (factor de scale global) sdl_.updateRenderingContext(); // Dibuixar @@ -126,8 +126,8 @@ void LogoScene::run() { void LogoScene::inicialitzar_lletres() { using namespace Graphics; - // Llista de fitxers .shp (A repetida per a les dues A's) - std::vector fitxers = { + // Llista de archivos .shp (A repetida para las dues A's) + std::vector archivos = { "logo/letra_j.shp", "logo/letra_a.shp", "logo/letra_i.shp", @@ -138,13 +138,13 @@ void LogoScene::inicialitzar_lletres() { "logo/letra_e.shp", "logo/letra_s.shp"}; - // Pas 1: Carregar totes les formes i calcular amplades + // Pas 1: Carregar todas las formes i calcular amplades float ancho_total = 0.0F; - for (const auto& fitxer : fitxers) { - auto shape = ShapeLoader::load(fitxer); + for (const auto& file : archivos) { + auto shape = ShapeLoader::load(file); if (!shape || !shape->isValid()) { - std::cerr << "[LogoScene] Error carregant " << fitxer << '\n'; + std::cerr << "[LogoScene] Error carregant " << file << '\n'; continue; } @@ -161,23 +161,23 @@ void LogoScene::inicialitzar_lletres() { float ancho_sin_escalar = max_x - min_x; - // IMPORTANT: Escalar ancho i offset amb ESCALA_FINAL - // per que les posicions finals coincideixin amb la mida real de les lletres + // IMPORTANT: Escalar ancho i offset con ESCALA_FINAL + // per que las posicions finals coincideixin con la mida real de las lletres float ancho = ancho_sin_escalar * ESCALA_FINAL; float offset_centre = (shape->getCenter().x - min_x) * ESCALA_FINAL; lletres_.push_back({shape, - {.x = 0.0F, .y = 0.0F}, // Posició es calcularà després + {.x = 0.0F, .y = 0.0F}, // Posición es calcularà después ancho, offset_centre}); ancho_total += ancho; } - // Pas 2: Afegir espaiat entre lletres + // Pas 2: Añadir espaiat entre lletres ancho_total += ESPAI_ENTRE_LLETRES * (lletres_.size() - 1); - // Pas 3: Calcular posició inicial (centrat horitzontal) + // Pas 3: Calcular posición inicial (centrat horitzontal) constexpr float PANTALLA_ANCHO = 640.0F; constexpr float PANTALLA_ALTO = 480.0F; @@ -188,13 +188,13 @@ void LogoScene::inicialitzar_lletres() { float x_actual = x_inicial; for (auto& lletra : lletres_) { - // Posicionar el centre de la shape (shape_centre) en pantalla + // Posicionar el centro de la shape (shape_centre) en pantalla // Usar offset_centre en lloc de ancho/2 perquè shape_centre // pot no estar exactament al mig del bounding box lletra.position.x = x_actual + lletra.offset_centre; lletra.position.y = y_centre; - // Avançar per a següent lletra + // Avançar para següent lletra x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES; } @@ -206,12 +206,12 @@ void LogoScene::canviar_estat(AnimationState nou_estat) { estat_actual_ = nou_estat; temps_estat_actual_ = 0.0F; // Reset time - // Inicialitzar state d'explosió + // Inicialitzar state de explosión if (nou_estat == AnimationState::EXPLOSION) { lletra_explosio_index_ = 0; temps_des_ultima_explosio_ = 0.0F; - // Generar ordre aleatori d'explosions + // Generar ordre aleatori de explosions ordre_explosio_.clear(); for (size_t i = 0; i < lletres_.size(); i++) { ordre_explosio_.push_back(i); @@ -228,14 +228,14 @@ void LogoScene::canviar_estat(AnimationState nou_estat) { } bool LogoScene::totes_lletres_completes() const { - // Quan global_progress = 1.0, totes les lletres tenen letra_progress = 1.0 + // Cuando global_progress = 1.0, todas las lletres tenen letra_progress = 1.0 return temps_estat_actual_ >= DURACIO_ZOOM; } void LogoScene::actualitzar_explosions(float delta_time) { temps_des_ultima_explosio_ += delta_time; - // Comprovar si és el moment d'explode la següent lletra + // Comprovar si es el moment de explode la següent lletra if (temps_des_ultima_explosio_ >= DELAY_ENTRE_EXPLOSIONS) { if (lletra_explosio_index_ < lletres_.size()) { // Explotar lletra actual (en ordre aleatori) @@ -244,12 +244,12 @@ void LogoScene::actualitzar_explosions(float delta_time) { debris_manager_->explode( lletra.shape, // Forma a explode - lletra.position, // Posició - 0.0F, // Angle (sense rotació) + lletra.position, // Posición + 0.0F, // Angle (sin rotación) ESCALA_FINAL, // Escala (lletres a scale final) - VELOCITAT_EXPLOSIO, // Velocitat base + VELOCITAT_EXPLOSIO, // Velocidad base 1.0F, // Brightness màxim (per defecte) - {.x = 0.0F, .y = 0.0F} // Sense velocity (per defecte) + {.x = 0.0F, .y = 0.0F} // Sin velocity (per defecte) ); std::cout << "[LogoScene] Explota lletra " << lletra_explosio_index_ << "\n"; @@ -258,7 +258,7 @@ void LogoScene::actualitzar_explosions(float delta_time) { lletra_explosio_index_++; temps_des_ultima_explosio_ = 0.0F; } else { - // Totes les lletres han explotat, transició a POST_EXPLOSION + // Todas las lletres han explotat, transición a POST_EXPLOSION canviar_estat(AnimationState::POST_EXPLOSION); } } @@ -275,7 +275,7 @@ void LogoScene::update(float delta_time) { break; case AnimationState::ANIMATION: { - // Reproduir so per cada lletra quan comença a aparèixer + // Reproduir so per cada lletra cuando comença a aparèixer float global_progress = std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0F); for (size_t i = 0; i < lletres_.size() && i < so_reproduit_.size(); i++) { @@ -286,7 +286,7 @@ void LogoScene::update(float delta_time) { global_progress, THRESHOLD_LETRA); - // Reproduir so quan la lletra comença a aparèixer (progress > 0) + // Reproduir so cuando la lletra comença a aparèixer (progress > 0) if (letra_progress > 0.0F) { Audio::get()->playSound(Defaults::Sound::LOGO, Audio::Group::GAME); so_reproduit_[i] = true; @@ -312,7 +312,7 @@ void LogoScene::update(float delta_time) { case AnimationState::POST_EXPLOSION: if (temps_estat_actual_ >= DURACIO_POST_EXPLOSION) { - // Transició a pantalla de títol + // Transición a pantalla de título context_.setNextScene(SceneType::TITLE); SceneManager::actual = SceneType::TITLE; } @@ -325,21 +325,21 @@ void LogoScene::update(float delta_time) { SceneManager::actual = SceneType::TITLE; } - // Actualitzar animacions de debris + // Actualitzar animaciones de debris debris_manager_->update(delta_time); } void LogoScene::draw() { // Fons negre - sdl_.neteja(0, 0, 0); + sdl_.clear(0, 0, 0); - // PRE_ANIMATION: Només pantalla negra + // PRE_ANIMATION: Solo pantalla negra if (estat_actual_ == AnimationState::PRE_ANIMATION) { - sdl_.presenta(); - return; // No renderitzar lletres + sdl_.present(); + return; // No renderizar lletres } - // ANIMATION o POST_ANIMATION: Dibuixar lletres amb animació + // ANIMATION o POST_ANIMATION: Dibuixar lletres con animación if (estat_actual_ == AnimationState::ANIMATION || estat_actual_ == AnimationState::POST_ANIMATION) { float global_progress = @@ -383,15 +383,15 @@ void LogoScene::draw() { } } - // EXPLOSION: Dibuixar només lletres que encara no han explotat + // EXPLOSION: Dibuixar solo lletres que aún no han explotat if (estat_actual_ == AnimationState::EXPLOSION) { - // Crear conjunt de lletres ja explotades + // Crear conjunt de lletres ya explotades std::set explotades; for (size_t i = 0; i < lletra_explosio_index_; i++) { explotades.insert(ordre_explosio_[i]); } - // Dibuixar només lletres que NO han explotat + // Dibuixar solo lletres que NO han explotat for (size_t i = 0; i < lletres_.size(); i++) { if (!explotades.contains(i)) { const auto& lletra = lletres_[i]; @@ -407,12 +407,12 @@ void LogoScene::draw() { } } - // POST_EXPLOSION: No draw lletres, només debris (a baix) + // POST_EXPLOSION: No draw lletres, solo debris (a baix) - // Sempre draw debris (si n'hi ha d'active) + // Siempre draw debris (si n'hay de active) debris_manager_->draw(); - sdl_.presenta(); + sdl_.present(); } auto LogoScene::checkSkipButtonPressed() -> bool { diff --git a/source/game/scenes/logo_scene.hpp b/source/game/scenes/logo_scene.hpp index addbf76..95fdc13 100644 --- a/source/game/scenes/logo_scene.hpp +++ b/source/game/scenes/logo_scene.hpp @@ -1,5 +1,5 @@ -// escena_logo.hpp - Pantalla d'inici del joc -// Mostra logo JAILGAMES animat amb zoom i salta al joc +// logo_scene.hpp - Pantalla de start del juego +// Muestra logo JAILGAMES animat con zoom i salta al juego // © 2025 Port a C++20 #pragma once @@ -25,59 +25,59 @@ class LogoScene { void run(); // Bucle principal de l'escena private: - // Màquina d'estats per l'animació + // Màquina de estats per l'animación enum class AnimationState { PRE_ANIMATION, // Pantalla negra inicial - ANIMATION, // Animació de zoom de lletres + ANIMATION, // Animación de zoom de lletres POST_ANIMATION, // Logo complet visible - EXPLOSION, // Explosió seqüencial de lletres - POST_EXPLOSION // Espera després de l'última explosió + EXPLOSION, // Explosión seqüencial de lletres + POST_EXPLOSION // Espera después de l'última explosión }; SDLManager& sdl_; SceneManager::SceneContext& context_; AnimationState estat_actual_; // Estat actual de la màquina float - temps_estat_actual_; // Temps en l'state actual (reset en cada transició) + temps_estat_actual_; // Temps en l'state actual (reset en cada transición) - // Gestor de fragments d'explosions + // Gestor de fragments de explosions std::unique_ptr debris_manager_; - // Seguiment d'explosions seqüencials + // Seguiment de explosions seqüencials size_t lletra_explosio_index_; // Índex de la següent lletra a explode - float temps_des_ultima_explosio_; // Temps des de l'última explosió - std::vector ordre_explosio_; // Ordre aleatori d'índexs de lletres + float temps_des_ultima_explosio_; // Temps desde l'última explosión + std::vector ordre_explosio_; // Ordre aleatori de índexs de lletres - // Estructura per a cada lletra del logo + // Estructura para cada lletra del logo struct LetraLogo { std::shared_ptr shape; - Vec2 position; // Posició final en pantalla + Vec2 position; // Posición final en pantalla float ancho; // Ancho del bounding box - float offset_centre; // Distància de min_x a shape_centre.x + float offset_centre; // Distancia de min_x a shape_centre.x }; std::vector lletres_; // 9 lletres: J-A-I-L-G-A-M-E-S // Seguiment de sons de lletres (evitar reproduccions repetides) - std::array so_reproduit_; // Track si cada lletra ja ha reproduit el so + std::array so_reproduit_; // Track si cada lletra ya ha reproduit el so - // Constants d'animació + // Constants de animación static constexpr float DURACIO_PRE = 1.5F; // Duració PRE_ANIMATION (pantalla negra) static constexpr float DURACIO_ZOOM = 4.0F; // Duració del zoom (segons) static constexpr float DURACIO_POST_ANIMATION = 3.0F; // Duració POST_ANIMATION (logo complet) static constexpr float DURACIO_POST_EXPLOSION = 3.0F; // Duració POST_EXPLOSION (espera final) static constexpr float DELAY_ENTRE_EXPLOSIONS = 0.1F; // Temps entre explosions de lletres - static constexpr float VELOCITAT_EXPLOSIO = 240.0F; // Velocitat base fragments (px/s) + static constexpr float VELOCITAT_EXPLOSIO = 240.0F; // Velocidad base fragments (px/s) static constexpr float ESCALA_INICIAL = 0.1F; // Escala inicial (10%) static constexpr float ESCALA_FINAL = 0.8F; // Escala final (80%) static constexpr float ESPAI_ENTRE_LLETRES = 10.0F; // Espaiat entre lletres - // Constants d'animació seqüencial + // Constants de animación seqüencial static constexpr float THRESHOLD_LETRA = 0.6F; // Umbral per activar següent lletra (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 - // Mètodes privats + // Métodos privats void inicialitzar_lletres(); void update(float delta_time); void actualitzar_explosions(float delta_time); @@ -85,7 +85,7 @@ class LogoScene { void processar_events(const SDL_Event& event); auto checkSkipButtonPressed() -> bool; - // Mètodes de gestió d'estats + // Métodos de gestió de estats void canviar_estat(AnimationState nou_estat); [[nodiscard]] bool totes_lletres_completes() const; }; diff --git a/source/game/scenes/title_scene.cpp b/source/game/scenes/title_scene.cpp index c1594eb..a62be14 100644 --- a/source/game/scenes/title_scene.cpp +++ b/source/game/scenes/title_scene.cpp @@ -1,4 +1,4 @@ -// escena_titol.cpp - Implementació de l'escena de títol +// title_scene.cpp - Implementació de l'escena de título // © 2025 Port a C++20 #include "title_scene.hpp" @@ -36,16 +36,16 @@ TitleScene::TitleScene(SDLManager& sdl, SceneContext& context) factor_lerp_(0.0F) { std::cout << "SceneType Titol: Inicialitzant...\n"; - // Inicialitzar configuració de match (cap player active per defecte) + // Inicialitzar configuración de match (sin player active per defecte) match_config_.jugador1_actiu = false; match_config_.jugador2_actiu = false; match_config_.mode = GameConfig::Mode::NORMAL; - // Processar opció del context + // Processar opción del context auto option = context_.consumeOption(); if (option == Option::JUMP_TO_TITLE_MAIN) { - std::cout << "SceneType Titol: Opció JUMP_TO_TITLE_MAIN activada\n"; + std::cout << "SceneType Titol: Opción JUMP_TO_TITLE_MAIN activada\n"; estat_actual_ = TitleState::MAIN; temps_estat_main_ = 0.0F; } @@ -68,16 +68,16 @@ TitleScene::TitleScene(SDLManager& sdl, SceneContext& context) 150 // densitat: 150 estrelles (50 per capa) ); - // Brightness depèn de l'opció + // Brightness depèn de l'opción if (estat_actual_ == TitleState::MAIN) { // Si saltem a MAIN, starfield instantàniament brillant starfield_->set_brightness(BRIGHTNESS_STARFIELD); } else { - // Flux normal: comença amb brightness 0.0 per fade-in + // Flux normal: comença con brightness 0.0 per fade-in starfield_->set_brightness(0.0F); } - // Inicialitzar animador de naus 3D + // Inicialitzar animador de naves 3D ship_animator_ = std::make_unique(sdl_.getRenderer()); ship_animator_->init(); @@ -90,17 +90,17 @@ TitleScene::TitleScene(SDLManager& sdl, SceneContext& context) ship_animator_->set_visible(false); } - // Inicialitzar lletres del títol "ORNI ATTACK!" + // Inicialitzar lletres del título "ORNI ATTACK!" inicialitzar_titol(); - // Iniciar música de títol si no està sonant + // Iniciar música de título si no está sonant if (Audio::get()->getMusicState() != Audio::MusicState::PLAYING) { Audio::get()->playMusic("title.ogg"); } } TitleScene::~TitleScene() { - // Aturar música de títol quan es destrueix l'escena + // Aturar música de título cuando es destrueix l'escena Audio::get()->stopMusic(); } @@ -117,10 +117,10 @@ void TitleScene::inicialitzar_titol() { // Pas 1: Carregar formes i calcular amplades per "ORNI" float ancho_total_orni = 0.0F; - for (const auto& fitxer : fitxers_orni) { - auto shape = ShapeLoader::load(fitxer); + for (const auto& file : fitxers_orni) { + auto shape = ShapeLoader::load(file); if (!shape || !shape->isValid()) { - std::cerr << "[TitleScene] Error carregant " << fitxer << '\n'; + std::cerr << "[TitleScene] Error carregant " << file << '\n'; continue; } @@ -142,7 +142,7 @@ void TitleScene::inicialitzar_titol() { float ancho_sin_escalar = max_x - min_x; float altura_sin_escalar = max_y - min_y; - // Escalar ancho, altura i offset amb LOGO_SCALE + // Escalar ancho, altura i offset con LOGO_SCALE float ancho = ancho_sin_escalar * Defaults::Title::Layout::LOGO_SCALE; float altura = altura_sin_escalar * Defaults::Title::Layout::LOGO_SCALE; float offset_centre = (shape->getCenter().x - min_x) * Defaults::Title::Layout::LOGO_SCALE; @@ -152,10 +152,10 @@ void TitleScene::inicialitzar_titol() { ancho_total_orni += ancho; } - // Afegir espaiat entre lletres + // Añadir espaiat entre lletres ancho_total_orni += ESPAI_ENTRE_LLETRES * (lletres_orni_.size() - 1); - // Calcular posició inicial (centrat horitzontal) per "ORNI" + // Calcular posición inicial (centrat horitzontal) per "ORNI" float x_inicial_orni = (Defaults::Game::WIDTH - ancho_total_orni) / 2.0F; float x_actual = x_inicial_orni; @@ -168,8 +168,8 @@ void TitleScene::inicialitzar_titol() { std::cout << "[TitleScene] Línia 1 (ORNI): " << lletres_orni_.size() << " lletres, ancho total: " << ancho_total_orni << " px\n"; - // === Calcular posició Y dinàmica per "ATTACK!" === - // Totes les lletres ORNI tenen la mateixa altura, utilitzem la primera + // === Calcular posición Y dinàmica per "ATTACK!" === + // Todas las lletres ORNI tenen la misma altura, utilitzem la primera float altura_orni = lletres_orni_.empty() ? 50.0F : lletres_orni_[0].altura; float y_orni = Defaults::Game::HEIGHT * Defaults::Title::Layout::LOGO_POS; float separacion_lineas = Defaults::Game::HEIGHT * Defaults::Title::Layout::LOGO_LINE_SPACING; @@ -191,10 +191,10 @@ void TitleScene::inicialitzar_titol() { // Pas 1: Carregar formes i calcular amplades per "ATTACK!" float ancho_total_attack = 0.0F; - for (const auto& fitxer : fitxers_attack) { - auto shape = ShapeLoader::load(fitxer); + for (const auto& file : fitxers_attack) { + auto shape = ShapeLoader::load(file); if (!shape || !shape->isValid()) { - std::cerr << "[TitleScene] Error carregant " << fitxer << '\n'; + std::cerr << "[TitleScene] Error carregant " << file << '\n'; continue; } @@ -216,7 +216,7 @@ void TitleScene::inicialitzar_titol() { float ancho_sin_escalar = max_x - min_x; float altura_sin_escalar = max_y - min_y; - // Escalar ancho, altura i offset amb LOGO_SCALE + // Escalar ancho, altura i offset con LOGO_SCALE float ancho = ancho_sin_escalar * Defaults::Title::Layout::LOGO_SCALE; float altura = altura_sin_escalar * Defaults::Title::Layout::LOGO_SCALE; float offset_centre = (shape->getCenter().x - min_x) * Defaults::Title::Layout::LOGO_SCALE; @@ -226,23 +226,23 @@ void TitleScene::inicialitzar_titol() { ancho_total_attack += ancho; } - // Afegir espaiat entre lletres + // Añadir espaiat entre lletres ancho_total_attack += ESPAI_ENTRE_LLETRES * (lletres_attack_.size() - 1); - // Calcular posició inicial (centrat horitzontal) per "ATTACK!" + // Calcular posición inicial (centrat horitzontal) per "ATTACK!" float x_inicial_attack = (Defaults::Game::WIDTH - ancho_total_attack) / 2.0F; x_actual = x_inicial_attack; for (auto& lletra : lletres_attack_) { lletra.position.x = x_actual + lletra.offset_centre; - lletra.position.y = y_attack_dinamica_; // Usar posició dinàmica + lletra.position.y = y_attack_dinamica_; // Usar posición dinàmica x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES; } std::cout << "[TitleScene] Línia 2 (ATTACK!): " << lletres_attack_.size() << " lletres, ancho total: " << ancho_total_attack << " px\n"; - // Guardar posicions originals per l'animació orbital + // Guardar posicions originals per l'animación orbital posicions_originals_orni_.clear(); for (const auto& lletra : lletres_orni_) { posicions_originals_orni_.push_back(lletra.position); @@ -253,7 +253,7 @@ void TitleScene::inicialitzar_titol() { posicions_originals_attack_.push_back(lletra.position); } - std::cout << "[TitleScene] Animació: Posicions originals guardades\n"; + std::cout << "[TitleScene] Animación: Posicions originals guardades\n"; } void TitleScene::run() { @@ -266,16 +266,16 @@ void TitleScene::run() { float delta_time = (current_time - last_time) / 1000.0F; last_time = current_time; - // Limitar delta_time per evitar grans salts + // Limitar delta_time per evitar grandes salts delta_time = std::min(delta_time, 0.05F); - // Actualitzar comptador de FPS + // Actualitzar counter de FPS sdl_.updateFPS(delta_time); // Actualitzar visibilitat del cursor (auto-ocultar) Mouse::updateCursorVisibility(); - // Actualitzar sistema d'input ABANS del event loop + // Actualitzar sistema de input ABANS del event loop Input::get()->update(); // Processar events SDL @@ -294,38 +294,38 @@ void TitleScene::run() { processar_events(event); } - // Actualitzar lògica + // Actualitzar lógica update(delta_time); - // Actualitzar sistema d'audio + // Actualitzar sistema de audio Audio::update(); // Actualitzar colors oscil·lats sdl_.updateColors(delta_time); // Netejar pantalla - sdl_.neteja(0, 0, 0); + sdl_.clear(0, 0, 0); - // Actualitzar context de renderitzat (factor d'scale global) + // Actualitzar context de renderizado (factor de scale global) sdl_.updateRenderingContext(); // Dibuixar draw(); // Presentar renderer (swap buffers) - sdl_.presenta(); + sdl_.present(); } std::cout << "SceneType Titol: Finalitzant...\n"; } void TitleScene::update(float delta_time) { - // Actualitzar starfield (sempre active) + // Actualitzar starfield (siempre active) if (starfield_) { starfield_->update(delta_time); } - // Actualitzar naus (quan visibles) + // Actualitzar naves (cuando visibles) if (ship_animator_ && (estat_actual_ == TitleState::STARFIELD_FADE_IN || estat_actual_ == TitleState::STARFIELD || @@ -345,11 +345,11 @@ void TitleScene::update(float delta_time) { float brightness_actual = progress * BRIGHTNESS_STARFIELD; starfield_->set_brightness(brightness_actual); - // Transició a STARFIELD quan el fade es completa + // Transición a STARFIELD cuando el fade es completa if (temps_acumulat_ >= DURACIO_FADE_IN) { estat_actual_ = TitleState::STARFIELD; temps_acumulat_ = 0.0F; // Reset timer per al següent state - starfield_->set_brightness(BRIGHTNESS_STARFIELD); // Assegurar valor final + starfield_->set_brightness(BRIGHTNESS_STARFIELD); // Assegurar value final } break; } @@ -360,16 +360,16 @@ void TitleScene::update(float delta_time) { estat_actual_ = TitleState::MAIN; temps_estat_main_ = 0.0F; // Reset timer al entrar a MAIN animacio_activa_ = false; // Comença estàtic - factor_lerp_ = 0.0F; // Sense animació encara + factor_lerp_ = 0.0F; // Sin animación aún - // Naus esperaran ENTRANCE_DELAY abans d'entrar (no iniciar aquí) + // Naves esperaran ENTRANCE_DELAY antes de entrar (no start aquí) } break; case TitleState::MAIN: { temps_estat_main_ += delta_time; - // Iniciar animació d'entrada de naus després del delay + // Iniciar animación de entrada de naves después del delay if (temps_estat_main_ >= Defaults::Title::Ships::ENTRANCE_DELAY) { if (ship_animator_ && !ship_animator_->is_visible()) { ship_animator_->set_visible(true); @@ -388,13 +388,13 @@ void TitleScene::update(float delta_time) { factor_lerp_ = temps_lerp / DURACIO_LERP; // 0.0 → 1.0 linealment animacio_activa_ = true; } - // Fase 3: Animació completa (12s+) + // Fase 3: Animación completa (12s+) else { factor_lerp_ = 1.0F; animacio_activa_ = true; } - // Actualitzar animació del logo + // Actualitzar animación del logo actualitzar_animacio_logo(delta_time); break; } @@ -402,10 +402,10 @@ void TitleScene::update(float delta_time) { case TitleState::PLAYER_JOIN_PHASE: temps_acumulat_ += delta_time; - // Continuar animació orbital durant la transició + // Continuar animación orbital durante la transición actualitzar_animacio_logo(delta_time); - // [NOU] Continuar comprovant si l'altre player vol unir-se durant la transició ("late join") + // [NOU] Continuar comprovant si l'altre player quiere unir-se durante la transición ("late join") { bool p1_actiu_abans = match_config_.jugador1_actiu; bool p2_actiu_abans = match_config_.jugador2_actiu; @@ -414,7 +414,7 @@ void TitleScene::update(float delta_time) { // Updates match_config_ if pressed, logs are in the method context_.setMatchConfig(match_config_); - // Trigger animació de sortida per la ship que acaba d'unir-se + // Trigger animación de salida per la ship que acaba de unir-se if (ship_animator_) { if (match_config_.jugador1_actiu && !p1_actiu_abans) { ship_animator_->trigger_exit_animation_for_player(1); @@ -426,10 +426,10 @@ void TitleScene::update(float delta_time) { } } - // Reproducir so de START quan el segon player s'uneix + // Reproducir so de START cuando el segon player s'uneix Audio::get()->playSound(Defaults::Sound::START, Audio::Group::GAME); - // Reiniciar el timer per allargar el time de transició + // Reiniciar el timer per allargar el time de transición temps_acumulat_ = 0.0F; std::cout << "[TitleScene] Segon player s'ha unit - so i timer reiniciats\n"; @@ -437,7 +437,7 @@ void TitleScene::update(float delta_time) { } if (temps_acumulat_ >= DURACIO_TRANSITION) { - // Transició a pantalla negra + // Transición a pantalla negra estat_actual_ = TitleState::BLACK_SCREEN; temps_acumulat_ = 0.0F; std::cout << "[TitleScene] Passant a BLACK_SCREEN\n"; @@ -449,7 +449,7 @@ void TitleScene::update(float delta_time) { // No animation, no input checking - just wait if (temps_acumulat_ >= DURACIO_BLACK_SCREEN) { - // Transició a escena GAME + // Transición a escena GAME SceneManager::actual = SceneType::GAME; std::cout << "[TitleScene] Canviant a escena GAME\n"; } @@ -464,26 +464,26 @@ void TitleScene::update(float delta_time) { starfield_->set_brightness(BRIGHTNESS_STARFIELD); temps_estat_main_ = 0.0F; - // Naus esperaran ENTRANCE_DELAY abans d'entrar (no iniciar aquí) + // Naves esperaran ENTRANCE_DELAY antes de entrar (no start aquí) } } - // Verificar boton START para iniciar match desde MAIN + // Verificar boton START para start match desde MAIN if (estat_actual_ == TitleState::MAIN) { // Guardar state anterior per detectar qui ha premut START AQUEST frame bool p1_actiu_abans = match_config_.jugador1_actiu; bool p2_actiu_abans = match_config_.jugador2_actiu; if (checkStartGameButtonPressed()) { - // Si START es prem durant el delay (naus encara invisibles), saltar-les a FLOATING + // Si START es prem durante el delay (naves aún invisibles), saltar-las a FLOATING if (ship_animator_ && !ship_animator_->is_visible()) { ship_animator_->set_visible(true); ship_animator_->skip_to_floating_state(); } - // Configurar match abans de canviar d'escena + // Configurar match antes de canviar de escena context_.setMatchConfig(match_config_); - std::cout << "[TitleScene] Configuració de match - P1: " + std::cout << "[TitleScene] Configuración de match - P1: " << (match_config_.jugador1_actiu ? "ACTIU" : "INACTIU") << ", P2: " << (match_config_.jugador2_actiu ? "ACTIU" : "INACTIU") @@ -493,7 +493,7 @@ void TitleScene::update(float delta_time) { estat_actual_ = TitleState::PLAYER_JOIN_PHASE; temps_acumulat_ = 0.0F; - // Trigger animació de sortida NOMÉS per les naus que han premut START + // Trigger animación de salida NOMÉS per las naves que han premut START if (ship_animator_) { if (match_config_.jugador1_actiu && !p1_actiu_abans) { ship_animator_->trigger_exit_animation_for_player(1); @@ -512,7 +512,7 @@ void TitleScene::update(float delta_time) { } void TitleScene::actualitzar_animacio_logo(float delta_time) { - // Només calcular i aplicar offsets si l'animació està activa + // Solo calcular i aplicar offsets si l'animación está activa if (animacio_activa_) { // Acumular time escalat temps_animacio_ += delta_time * factor_lerp_; @@ -527,13 +527,13 @@ void TitleScene::actualitzar_animacio_logo(float delta_time) { float offset_x = amplitude_x_actual * std::sin(2.0F * Defaults::Math::PI * frequency_x_actual * temps_animacio_); float offset_y = amplitude_y_actual * std::sin((2.0F * Defaults::Math::PI * frequency_y_actual * temps_animacio_) + ORBIT_PHASE_OFFSET); - // Aplicar offset a totes les lletres de "ORNI" + // Aplicar offset a todas las lletres de "ORNI" for (size_t i = 0; i < lletres_orni_.size(); ++i) { lletres_orni_[i].position.x = posicions_originals_orni_[i].x + static_cast(std::round(offset_x)); lletres_orni_[i].position.y = posicions_originals_orni_[i].y + static_cast(std::round(offset_y)); } - // Aplicar offset a totes les lletres de "ATTACK!" + // Aplicar offset a todas las lletres de "ATTACK!" for (size_t i = 0; i < lletres_attack_.size(); ++i) { lletres_attack_[i].position.x = posicions_originals_attack_[i].x + static_cast(std::round(offset_x)); lletres_attack_[i].position.y = posicions_originals_attack_[i].y + static_cast(std::round(offset_y)); @@ -542,12 +542,12 @@ void TitleScene::actualitzar_animacio_logo(float delta_time) { } void TitleScene::draw() { - // Dibuixar starfield de fons (en tots els estats excepte BLACK_SCREEN) + // Dibuixar starfield de fons (en todos los estats excepte BLACK_SCREEN) if (starfield_ && estat_actual_ != TitleState::BLACK_SCREEN) { starfield_->draw(); } - // Dibuixar naus (després starfield, abans logo) + // Dibuixar naves (después starfield, antes logo) if (ship_animator_ && (estat_actual_ == TitleState::STARFIELD_FADE_IN || estat_actual_ == TitleState::STARFIELD || @@ -556,15 +556,15 @@ void TitleScene::draw() { ship_animator_->draw(); } - // En els estats STARFIELD_FADE_IN i STARFIELD, només mostrar starfield (sense text) + // En los estats STARFIELD_FADE_IN i STARFIELD, solo mostrar starfield (sin text) if (estat_actual_ == TitleState::STARFIELD_FADE_IN || estat_actual_ == TitleState::STARFIELD) { return; } - // Estat MAIN i PLAYER_JOIN_PHASE: Dibuixar títol i text (sobre el starfield) - // BLACK_SCREEN: no draw res (fons negre ja està netejat) + // Estat MAIN i PLAYER_JOIN_PHASE: Dibuixar título i text (sobre el starfield) + // BLACK_SCREEN: no draw res (fons negre ya está netejat) if (estat_actual_ == TitleState::MAIN || estat_actual_ == TitleState::PLAYER_JOIN_PHASE) { - // === Calcular i renderitzar ombra (només si animació activa) === + // === Calcular i renderizar ombra (solo si animación activa) === if (animacio_activa_) { float temps_shadow = temps_animacio_ - SHADOW_DELAY; temps_shadow = std::max(temps_shadow, 0.0F); // Evitar time negatiu @@ -642,14 +642,14 @@ void TitleScene::draw() { } // === Text "PRESS START TO PLAY" === - // En state MAIN: sempre visible - // En state TRANSITION: parpellejant (blink amb sinusoide) + // En state MAIN: siempre visible + // En state TRANSITION: parpellejant (blink con sinusoide) const float spacing = Defaults::Title::Layout::TEXT_SPACING; bool mostrar_text = true; if (estat_actual_ == TitleState::PLAYER_JOIN_PHASE) { - // Parpelleig: sin oscil·la entre -1 i 1, volem ON quan > 0 + // Parpelleig: sin oscil·la entre -1 i 1, volem ON cuando > 0 float fase = temps_acumulat_ * BLINK_FREQUENCY * 2.0F * std::numbers::pi_v; // 2π × freq × time mostrar_text = (std::sin(fase) > 0.0F); } @@ -689,7 +689,7 @@ void TitleScene::draw() { float y_line1 = Defaults::Game::HEIGHT * Defaults::Title::Layout::COPYRIGHT1_POS; float y_line2 = y_line1 + copy_height + line_spacing; // Línea 2 debajo de línea 1 - // Renderitzar línees centrades + // Renderizar línees centrades float centre_x = Defaults::Game::WIDTH / 2.0F; text_.renderCentered(copyright_original, {.x = centre_x, .y = y_line1}, escala_copy, spacing); diff --git a/source/game/scenes/title_scene.hpp b/source/game/scenes/title_scene.hpp index 47194f3..cd8ad91 100644 --- a/source/game/scenes/title_scene.hpp +++ b/source/game/scenes/title_scene.hpp @@ -1,5 +1,5 @@ -// escena_titol.hpp - Pantalla de títol del joc -// Mostra message "PRESS BUTTON TO PLAY" i copyright +// title_scene.hpp - Pantalla de título del juego +// Muestra message "PRESS BUTTON TO PLAY" y copyright // © 2025 Port a C++20 #pragma once @@ -32,81 +32,81 @@ class TitleScene { void run(); // Bucle principal de l'escena private: - // Màquina d'estats per la pantalla de títol + // Màquina de estats per la pantalla de título enum class TitleState { STARFIELD_FADE_IN, // Fade-in del starfield (3.0s) - STARFIELD, // Pantalla amb camp d'estrelles (4.0s) - MAIN, // Pantalla de títol amb text (indefinit, fins START) - PLAYER_JOIN_PHASE, // Fase d'unió de jugadors: fade-out música + text parpellejant (2.5s) - BLACK_SCREEN // Pantalla negra de transició (2.0s) + STARFIELD, // Pantalla con camp de estrelles (4.0s) + MAIN, // Pantalla de título con text (indefinit, hasta START) + PLAYER_JOIN_PHASE, // Fase de unió de jugadors: fade-out música + text parpellejant (2.5s) + BLACK_SCREEN // Pantalla negra de transición (2.0s) }; - // Estructura per emmagatzemar informació de cada lletra del títol + // Estructura per emmagatzemar informació de cada lletra del título struct LetraLogo { std::shared_ptr shape; // Forma vectorial de la lletra - Vec2 position; // Posició en pantalla - float ancho; // Amplada escalada - float altura; // Altura escalada - float offset_centre; // Offset del centre per posicionament + Vec2 position; // Posición en pantalla + float ancho; // Amplada scaled + float altura; // Altura scaled + float offset_centre; // Offset del centro per posicionament }; SDLManager& sdl_; SceneManager::SceneContext& context_; - GameConfig::MatchConfig match_config_; // Configuració de jugadors active + GameConfig::MatchConfig match_config_; // Configuración de jugadors active Graphics::VectorText text_; // Sistema de text vectorial - std::unique_ptr starfield_; // Camp d'estrelles de fons - std::unique_ptr ship_animator_; // Naus 3D flotants + std::unique_ptr starfield_; // Camp de estrelles de fons + std::unique_ptr ship_animator_; // Naves 3D flotantes TitleState estat_actual_; // Estat actual de la màquina float temps_acumulat_; // Temps acumulat per l'state INIT - // Lletres del títol "ORNI ATTACK!" + // Lletres del título "ORNI ATTACK!" std::vector lletres_orni_; // Lletres de "ORNI" (línia 1) std::vector lletres_attack_; // Lletres de "ATTACK!" (línia 2) - float y_attack_dinamica_; // Posició Y calculada dinàmicament per "ATTACK!" + float y_attack_dinamica_; // Posición Y calculada dinàmicament per "ATTACK!" - // Estat d'animació del logo - float temps_animacio_; // Temps acumulat per animació orbital + // Estat de animación del logo + float temps_animacio_; // Temps acumulat per animación orbital std::vector posicions_originals_orni_; // Posicions originals de "ORNI" std::vector posicions_originals_attack_; // Posicions originals de "ATTACK!" - // Estat d'arrencada de l'animació + // Estat de arrencada de l'animación float temps_estat_main_; // Temps acumulat en state MAIN - bool animacio_activa_; // Flag: true quan animació està activa + bool animacio_activa_; // Flag: true cuando animación está activa float factor_lerp_; // Factor de lerp actual (0.0 → 1.0) // Constants static constexpr float BRIGHTNESS_STARFIELD = 1.2F; // Brightness del starfield (>1.0 = més brillant) static constexpr float DURACIO_FADE_IN = 3.0F; // Duració del fade-in del starfield (1.5 segons) static constexpr float DURACIO_INIT = 4.0F; // Duració de l'state INIT (2 segons) - static constexpr float DURACIO_TRANSITION = 2.5F; // Duració de la transició (1.5 segons) + static constexpr float DURACIO_TRANSITION = 2.5F; // Duració de la transición (1.5 segons) static constexpr float ESPAI_ENTRE_LLETRES = 10.0F; // Espai entre lletres static constexpr float BLINK_FREQUENCY = 3.0F; // Freqüència de parpelleig (3 Hz) static constexpr float DURACIO_BLACK_SCREEN = 2.0F; // Duració pantalla negra (2 segons) static constexpr int MUSIC_FADE = 1500; // Duracio del fade de la musica del titol al començar a jugar - // Constants d'animació del logo + // Constants de animación del logo static constexpr float ORBIT_AMPLITUDE_X = 4.0F; // Amplitud oscil·lació horitzontal (píxels) static constexpr float ORBIT_AMPLITUDE_Y = 3.0F; // Amplitud oscil·lació vertical (píxels) - static constexpr float ORBIT_FREQUENCY_X = 0.8F; // Velocitat oscil·lació horitzontal (Hz) - static constexpr float ORBIT_FREQUENCY_Y = 1.2F; // Velocitat oscil·lació vertical (Hz) + static constexpr float ORBIT_FREQUENCY_X = 0.8F; // Velocidad oscil·lació horitzontal (Hz) + static constexpr float ORBIT_FREQUENCY_Y = 1.2F; // Velocidad oscil·lació vertical (Hz) static constexpr float ORBIT_PHASE_OFFSET = 1.57F; // Desfasament entre X i Y (90° per circular) - // Constants d'ombra del logo + // Constants de ombra del logo static constexpr float SHADOW_DELAY = 0.5F; // Retard temporal de l'ombra (segons) static constexpr float SHADOW_BRIGHTNESS = 0.4F; // Multiplicador de brightness de l'ombra (0.0-1.0) static constexpr float SHADOW_OFFSET_X = 2.0F; // Offset espacial X fix (píxels) static constexpr float SHADOW_OFFSET_Y = 2.0F; // Offset espacial Y fix (píxels) - // Temporització de l'arrencada de l'animació - static constexpr float DELAY_INICI_ANIMACIO = 10.0F; // 10s estàtic abans d'animar + // Temporització de l'arrencada de l'animación + static constexpr float DELAY_INICI_ANIMACIO = 10.0F; // 10s estàtic antes de animar static constexpr float DURACIO_LERP = 2.0F; // 2s per arribar a amplitud completa - // Mètodes privats + // Métodos privats void update(float delta_time); - void actualitzar_animacio_logo(float delta_time); // Actualitza l'animació orbital del logo + void actualitzar_animacio_logo(float delta_time); // Actualitza l'animación orbital del logo void draw(); void processar_events(const SDL_Event& event); auto checkSkipButtonPressed() -> bool; auto checkStartGameButtonPressed() -> bool; - void inicialitzar_titol(); // Carrega i posiciona les lletres del títol + void inicialitzar_titol(); // Carrega i posiciona las lletres del título }; diff --git a/source/game/stage_system/spawn_controller.cpp b/source/game/stage_system/spawn_controller.cpp index ad654b1..cd687e2 100644 --- a/source/game/stage_system/spawn_controller.cpp +++ b/source/game/stage_system/spawn_controller.cpp @@ -21,13 +21,13 @@ SpawnController::SpawnController() index_spawn_actual_(0), ship_position_(nullptr) {} -void SpawnController::configurar(const StageConfig* config) { +void SpawnController::configure(const StageConfig* config) { config_ = config; } -void SpawnController::iniciar() { +void SpawnController::start() { if (config_ == nullptr) { - std::cerr << "[SpawnController] Error: config_ és null" << '\n'; + std::cerr << "[SpawnController] Error: config_ es null" << '\n'; return; } @@ -122,7 +122,7 @@ void SpawnController::generar_spawn_events() { return; } - for (uint8_t i = 0; i < config_->total_enemics; i++) { + for (uint8_t i = 0; i < config_->total_enemies; i++) { float spawn_time = config_->config_spawn.delay_inicial + (i * config_->config_spawn.interval_spawn); @@ -143,7 +143,7 @@ EnemyType SpawnController::seleccionar_tipus_aleatori() const { if (std::cmp_less(rand_val, config_->distribucio.pentagon)) { return EnemyType::PENTAGON; } - if (rand_val < config_->distribucio.pentagon + config_->distribucio.quadrat) { + if (rand_val < config_->distribucio.pentagon + config_->distribucio.cuadrado) { return EnemyType::QUADRAT; } return EnemyType::MOLINILLO; diff --git a/source/game/stage_system/spawn_controller.hpp b/source/game/stage_system/spawn_controller.hpp index 2f5923d..5f5cde6 100644 --- a/source/game/stage_system/spawn_controller.hpp +++ b/source/game/stage_system/spawn_controller.hpp @@ -1,4 +1,4 @@ -// spawn_controller.hpp - Controlador de spawn d'enemics +// spawn_controller.hpp - Controlador de spawn de enemigos // © 2025 Orni Attack #pragma once @@ -16,8 +16,8 @@ namespace StageSystem { // Informació de spawn planificat struct SpawnEvent { float temps_spawn; // Temps absolut (segons) per spawnejar - EnemyType type; // Tipus d'enemy - bool spawnejat; // Ja s'ha processat? + EnemyType type; // Tipo de enemy + bool spawnejat; // Ya s'ha processat? }; class SpawnController { @@ -25,8 +25,8 @@ class SpawnController { SpawnController(); // Configuration - void configurar(const StageConfig* config); // Set stage config - void iniciar(); // Generate spawn schedule + void configure(const StageConfig* config); // Set stage config + void start(); // Generate spawn schedule void reset(); // Clear all pending spawns // Update diff --git a/source/game/stage_system/stage_config.hpp b/source/game/stage_system/stage_config.hpp index 9e347c6..3b11429 100644 --- a/source/game/stage_system/stage_config.hpp +++ b/source/game/stage_system/stage_config.hpp @@ -1,4 +1,4 @@ -// stage_config.hpp - Estructures de dades per configuració d'stages +// stage_config.hpp - Estructures de dades per configuración de stages // © 2025 Orni Attack #pragma once @@ -10,24 +10,24 @@ namespace StageSystem { -// Tipus de mode de spawn +// Tipo de mode de spawn enum class ModeSpawn { - PROGRESSIVE, // Spawn progressiu amb intervals - IMMEDIATE, // Tots els enemics de cop - WAVE // Onades de 3-5 enemics (futura extensió) + PROGRESSIVE, // Spawn progressiu con intervals + IMMEDIATE, // Todos los enemigos de cop + WAVE // Onades de 3-5 enemigos (futura extensió) }; -// Configuració de spawn +// Configuración de spawn struct ConfigSpawn { ModeSpawn mode; - float delay_inicial; // Segons abans del primer spawn + float delay_inicial; // Segons antes del primer spawn float interval_spawn; // Segons entre spawns consecutius }; -// Distribució de type d'enemics (percentatges) +// Distribució de type de enemigos (percentatges) struct DistribucioEnemics { uint8_t pentagon; // 0-100 - uint8_t quadrat; // 0-100 + uint8_t cuadrado; // 0-100 uint8_t molinillo; // 0-100 // Suma ha de ser 100, validat en StageLoader }; @@ -36,20 +36,20 @@ struct DistribucioEnemics { struct MultiplicadorsDificultat { float velocity; // 0.5-2.0 típic float rotation; // 0.5-2.0 típic - float tracking_strength; // 0.0-1.5 (aplicat a Quadrat) + float tracking_strength; // 0.0-1.5 (aplicat a Cuadrado) }; -// Metadades del fitxer YAML +// Metadades del file YAML struct MetadataStages { std::string version; uint8_t total_stages; std::string descripcio; }; -// Configuració completa d'un stage +// Configuración completa de un stage struct StageConfig { uint8_t stage_id; // 1-10 - uint8_t total_enemics; // 5-15 + uint8_t total_enemies; // 5-15 ConfigSpawn config_spawn; DistribucioEnemics distribucio; MultiplicadorsDificultat multiplicadors; @@ -57,17 +57,17 @@ struct StageConfig { // Validació [[nodiscard]] bool es_valid() const { return stage_id >= 1 && stage_id <= 255 && - total_enemics > 0 && total_enemics <= 15 && - distribucio.pentagon + distribucio.quadrat + distribucio.molinillo == 100; + total_enemies > 0 && total_enemies <= 15 && + distribucio.pentagon + distribucio.cuadrado + distribucio.molinillo == 100; } }; -// Configuració completa del sistema (carregada des de YAML) +// Configuración completa del sistema (carregada desde YAML) struct StageSystemConfig { MetadataStages metadata; std::vector stages; // Índex [0] = stage 1 - // Obtenir configuració d'un stage específic + // Obtenir configuración de un stage específic [[nodiscard]] const StageConfig* obte_stage(uint8_t stage_id) const { if (stage_id < 1 || stage_id > stages.size()) { return nullptr; @@ -76,9 +76,9 @@ struct StageSystemConfig { } }; -// Constants per missatges de transició +// Constants per messages de transición namespace Constants { -// Pool de missatges per inici de level (selecció aleatòria) +// Pool de messages per start de level (selecció aleatòria) inline constexpr std::array MISSATGES_LEVEL_START = { "ORNI ALERT!", "INCOMING ORNIS!", diff --git a/source/game/stage_system/stage_loader.cpp b/source/game/stage_system/stage_loader.cpp index b233028..3a5b8fa 100644 --- a/source/game/stage_system/stage_loader.cpp +++ b/source/game/stage_system/stage_loader.cpp @@ -1,4 +1,4 @@ -// stage_loader.cpp - Implementació del carregador de configuració YAML +// stage_loader.cpp - Implementació del carregador de configuración YAML // © 2025 Orni Attack #include "stage_loader.hpp" @@ -58,7 +58,7 @@ std::unique_ptr StageLoader::load(const std::string& path) { } if (!yaml["stages"].is_sequence()) { - std::cerr << "[StageLoader] Error: 'stages' ha de ser una llista" << '\n'; + std::cerr << "[StageLoader] Error: 'stages' ha de ser una list" << '\n'; return nullptr; } @@ -70,7 +70,7 @@ std::unique_ptr StageLoader::load(const std::string& path) { config->stages.push_back(stage); } - // Validar configuració + // Validar configuración if (!validar_config(*config)) { return nullptr; } @@ -115,7 +115,7 @@ bool StageLoader::parse_stage(const fkyaml::node& yaml, StageConfig& stage) { } stage.stage_id = yaml["stage_id"].get_value(); - stage.total_enemics = yaml["total_enemies"].get_value(); + stage.total_enemies = yaml["total_enemies"].get_value(); if (!parse_spawn_config(yaml["spawn_config"], stage.config_spawn)) { return false; @@ -129,7 +129,7 @@ bool StageLoader::parse_stage(const fkyaml::node& yaml, StageConfig& stage) { if (!stage.es_valid()) { std::cerr << "[StageLoader] Error: stage " << static_cast(stage.stage_id) - << " no és vàlid" << '\n'; + << " no es vàlid" << '\n'; return false; } @@ -162,18 +162,18 @@ bool StageLoader::parse_spawn_config(const fkyaml::node& yaml, ConfigSpawn& conf bool StageLoader::parse_distribution(const fkyaml::node& yaml, DistribucioEnemics& dist) { try { - if (!yaml.contains("pentagon") || !yaml.contains("quadrat") || + if (!yaml.contains("pentagon") || !yaml.contains("cuadrado") || !yaml.contains("molinillo")) { std::cerr << "[StageLoader] Error: enemy_distribution incompleta" << '\n'; return false; } dist.pentagon = yaml["pentagon"].get_value(); - dist.quadrat = yaml["quadrat"].get_value(); + dist.cuadrado = yaml["cuadrado"].get_value(); dist.molinillo = yaml["molinillo"].get_value(); // Validar que suma 100 - int sum = dist.pentagon + dist.quadrat + dist.molinillo; + int sum = dist.pentagon + dist.cuadrado + dist.molinillo; if (sum != 100) { std::cerr << "[StageLoader] Error: distribució no suma 100 (suma=" << sum << ")" << '\n'; return false; @@ -200,13 +200,13 @@ bool StageLoader::parse_multipliers(const fkyaml::node& yaml, MultiplicadorsDifi // Validar rangs raonables if (mult.velocity < 0.1F || mult.velocity > 5.0F) { - std::cerr << "[StageLoader] Warning: speed_multiplier fora de rang (0.1-5.0)" << '\n'; + std::cerr << "[StageLoader] Warning: speed_multiplier fuera de rang (0.1-5.0)" << '\n'; } if (mult.rotation < 0.1F || mult.rotation > 5.0F) { - std::cerr << "[StageLoader] Warning: rotation_multiplier fora de rang (0.1-5.0)" << '\n'; + std::cerr << "[StageLoader] Warning: rotation_multiplier fuera de rang (0.1-5.0)" << '\n'; } if (mult.tracking_strength < 0.0F || mult.tracking_strength > 2.0F) { - std::cerr << "[StageLoader] Warning: tracking_strength fora de rang (0.0-2.0)" << '\n'; + std::cerr << "[StageLoader] Warning: tracking_strength fuera de rang (0.0-2.0)" << '\n'; } return true; @@ -233,13 +233,13 @@ ModeSpawn StageLoader::parse_spawn_mode(const std::string& mode_str) { bool StageLoader::validar_config(const StageSystemConfig& config) { if (config.stages.empty()) { - std::cerr << "[StageLoader] Error: cap stage carregat" << '\n'; + std::cerr << "[StageLoader] Error: sin stage carregat" << '\n'; return false; } if (config.stages.size() != config.metadata.total_stages) { std::cerr << "[StageLoader] Warning: nombre de stages (" << config.stages.size() - << ") no coincideix amb metadata.total_stages (" + << ") no coincideix con metadata.total_stages (" << static_cast(config.metadata.total_stages) << ")" << '\n'; } diff --git a/source/game/stage_system/stage_loader.hpp b/source/game/stage_system/stage_loader.hpp index f58a0cd..06d7c90 100644 --- a/source/game/stage_system/stage_loader.hpp +++ b/source/game/stage_system/stage_loader.hpp @@ -1,4 +1,4 @@ -// stage_loader.hpp - Carregador de configuració YAML +// stage_loader.hpp - Carregador de configuración YAML // © 2025 Orni Attack #pragma once @@ -13,8 +13,8 @@ namespace StageSystem { class StageLoader { public: - // Carregar configuració des de fitxer YAML - // Retorna nullptr si hi ha errors + // Carregar configuración desde file YAML + // Retorna nullptr si hay errors static std::unique_ptr load(const std::string& path); private: diff --git a/source/game/stage_system/stage_manager.cpp b/source/game/stage_system/stage_manager.cpp index 2ab2bc6..6a729e4 100644 --- a/source/game/stage_system/stage_manager.cpp +++ b/source/game/stage_system/stage_manager.cpp @@ -1,4 +1,4 @@ -// stage_manager.cpp - Implementació del gestor d'stages +// stage_manager.cpp - Implementació del gestor de stages // © 2025 Orni Attack #include "stage_manager.hpp" @@ -20,7 +20,7 @@ StageManager::StageManager(const StageSystemConfig* config) stage_actual_(1), timer_transicio_(0.0F) { if (config_ == nullptr) { - std::cerr << "[StageManager] Error: config és null" << '\n'; + std::cerr << "[StageManager] Error: config es null" << '\n'; } } @@ -33,7 +33,7 @@ void StageManager::init() { << '\n'; } -void StageManager::update(float delta_time, bool pausar_spawn) { +void StageManager::update(float delta_time, bool pause_spawn) { switch (estat_) { case EstatStage::INIT_HUD: processar_init_hud(delta_time); @@ -44,7 +44,7 @@ void StageManager::update(float delta_time, bool pausar_spawn) { break; case EstatStage::PLAYING: - processar_playing(delta_time, pausar_spawn); + processar_playing(delta_time, pause_spawn); break; case EstatStage::LEVEL_COMPLETED: @@ -86,14 +86,14 @@ void StageManager::canviar_estat(EstatStage nou_estat) { size_t index = static_cast(std::rand()) % Constants::MISSATGES_LEVEL_START.size(); missatge_level_start_actual_ = Constants::MISSATGES_LEVEL_START[index]; - // [NOU] Iniciar música al entrar en LEVEL_START (després de INIT_HUD) - // Només si no està sonant ja (per evitar reset en loops posteriors) + // [NOU] Iniciar música al entrar en LEVEL_START (después de INIT_HUD) + // Solo si no está sonant ya (per evitar reset en loops posteriors) if (Audio::get()->getMusicState() != Audio::MusicState::PLAYING) { Audio::get()->playMusic("game.ogg"); } } - std::cout << "[StageManager] Canvi d'state: "; + std::cout << "[StageManager] Canvi de state: "; switch (nou_estat) { case EstatStage::INIT_HUD: std::cout << "INIT_HUD"; @@ -127,12 +127,12 @@ void StageManager::processar_level_start(float delta_time) { } } -void StageManager::processar_playing(float delta_time, bool pausar_spawn) { - // Update spawn controller (pauses when pausar_spawn = true) +void StageManager::processar_playing(float delta_time, bool pause_spawn) { + // Update spawn controller (pauses when pause_spawn = true) // Note: The actual enemy array update happens in GameScene::update() // This is just for internal timekeeping (void)delta_time; // Spawn controller is updated externally - (void)pausar_spawn; // Passed to spawn_controller_.update() by GameScene + (void)pause_spawn; // Passed to spawn_controller_.update() by GameScene } void StageManager::processar_level_completed(float delta_time) { @@ -145,7 +145,7 @@ void StageManager::processar_level_completed(float delta_time) { // Loop back to stage 1 after final stage if (stage_actual_ > config_->metadata.total_stages) { stage_actual_ = 1; - std::cout << "[StageManager] Totes les stages completades! Tornant a stage 1" + std::cout << "[StageManager] Todas las stages completades! Tornant a stage 1" << '\n'; } @@ -164,11 +164,11 @@ void StageManager::carregar_stage(uint8_t stage_id) { } // Configure spawn controller - spawn_controller_.configurar(stage_config); - spawn_controller_.iniciar(); + spawn_controller_.configure(stage_config); + spawn_controller_.start(); std::cout << "[StageManager] Carregat stage " << static_cast(stage_id) << ": " - << static_cast(stage_config->total_enemics) << " enemics" << '\n'; + << static_cast(stage_config->total_enemies) << " enemigos" << '\n'; } } // namespace StageSystem diff --git a/source/game/stage_system/stage_manager.hpp b/source/game/stage_system/stage_manager.hpp index eb0f3f6..128a6e7 100644 --- a/source/game/stage_system/stage_manager.hpp +++ b/source/game/stage_system/stage_manager.hpp @@ -1,4 +1,4 @@ -// stage_manager.hpp - Gestor d'state i progressió d'stages +// stage_manager.hpp - Gestor de state i progressió de stages // © 2025 Orni Attack #pragma once @@ -13,7 +13,7 @@ namespace StageSystem { // Estats del stage system enum class EstatStage { - INIT_HUD, // Animació inicial del HUD (3s) + INIT_HUD, // Animación inicial del HUD (3s) LEVEL_START, // Pantalla "ENEMY INCOMING" (3s) PLAYING, // Gameplay normal LEVEL_COMPLETED // Pantalla "GOOD JOB COMMANDER!" (3s) @@ -25,7 +25,7 @@ class StageManager { // Lifecycle void init(); // Reset to stage 1 - void update(float delta_time, bool pausar_spawn = false); + void update(float delta_time, bool pause_spawn = false); // Stage progression void stage_completat(); // Call when all enemies destroyed @@ -39,8 +39,8 @@ class StageManager { [[nodiscard]] const std::string& get_missatge_level_start() const { return missatge_level_start_actual_; } // Spawn control (delegate to SpawnController) - SpawnController& get_spawn_controller() { return spawn_controller_; } - [[nodiscard]] const SpawnController& get_spawn_controller() const { return spawn_controller_; } + SpawnController& getSpawnController() { return spawn_controller_; } + [[nodiscard]] const SpawnController& getSpawnController() const { return spawn_controller_; } private: const StageSystemConfig* config_; // Non-owning pointer @@ -55,7 +55,7 @@ class StageManager { void canviar_estat(EstatStage nou_estat); void processar_init_hud(float delta_time); void processar_level_start(float delta_time); - void processar_playing(float delta_time, bool pausar_spawn); + void processar_playing(float delta_time, bool pause_spawn); void processar_level_completed(float delta_time); void carregar_stage(uint8_t stage_id); }; diff --git a/source/game/title/ship_animator.cpp b/source/game/title/ship_animator.cpp index ed1909e..4ad4cb2 100644 --- a/source/game/title/ship_animator.cpp +++ b/source/game/title/ship_animator.cpp @@ -1,5 +1,5 @@ -// ship_animator.cpp - Implementació del sistema d'animació de naus -// © 2025 Port a C++20 amb SDL3 +// ship_animator.cpp - Implementació del sistema de animación de naves +// © 2025 Port a C++20 con SDL3 #include "ship_animator.hpp" @@ -18,9 +18,9 @@ ShipAnimator::ShipAnimator(SDL_Renderer* renderer) } void ShipAnimator::init() { - // Carregar formes de naus amb perspectiva pre-calculada - auto forma_p1 = Graphics::ShapeLoader::load("ship_perspective.shp"); // Perspectiva esquerra - auto forma_p2 = Graphics::ShapeLoader::load("ship2_perspective.shp"); // Perspectiva dreta + // Carregar formes de naves con perspectiva pre-calculada + auto forma_p1 = Graphics::ShapeLoader::load("ship_perspective.shp"); // Perspectiva izquierda + auto forma_p2 = Graphics::ShapeLoader::load("ship2_perspective.shp"); // Perspectiva derecha // Configurar ship P1 ships_[0].player_id = 1; @@ -60,14 +60,14 @@ void ShipAnimator::draw() const { continue; } - // Renderitzar ship (perspectiva ja incorporada a la shape) + // Renderizar ship (perspectiva ya incorporada a la shape) Rendering::render_shape( renderer_, ship.shape, ship.current_position, - 0.0F, // angle (rotació 2D no utilitzada) + 0.0F, // angle (rotación 2D no utilitzada) ship.current_scale, - 1.0F, // progress (sempre visible) + 1.0F, // progress (siempre visible) 1.0F // brightness (brightness màxima) ); } @@ -76,14 +76,14 @@ void ShipAnimator::draw() const { void ShipAnimator::start_entry_animation() { using namespace Defaults::Title::Ships; - // Configurar ship P1 per a l'animació d'entrada + // Configurar ship P1 para l'animación de entrada ships_[0].state = ShipState::ENTERING; ships_[0].state_time = 0.0F; ships_[0].initial_position = calcular_posicio_fora_pantalla(CLOCK_8_ANGLE); ships_[0].current_position = ships_[0].initial_position; ships_[0].current_scale = ships_[0].initial_scale; - // Configurar ship P2 per a l'animació d'entrada + // Configurar ship P2 para l'animación de entrada ships_[1].state = ShipState::ENTERING; ships_[1].state_time = 0.0F; ships_[1].initial_position = calcular_posicio_fora_pantalla(CLOCK_4_ANGLE); @@ -92,38 +92,38 @@ void ShipAnimator::start_entry_animation() { } void ShipAnimator::trigger_exit_animation() { - // Configurar ambdues naus per a l'animació de sortida + // Configurar ambdues naves para l'animación de salida for (auto& ship : ships_) { // Canviar state a EXITING ship.state = ShipState::EXITING; ship.state_time = 0.0F; - // Preservar posició actual (pot estar a mig camí si START es prem durant ENTERING) + // Preservar posición actual (pot estar a mig camí si START es prem durante ENTERING) ship.initial_position = ship.current_position; - // La scale objectiu es preserva per a calcular la interpolació - // (current_scale pot ser diferent si està en ENTERING) + // La scale objetivo es preserva para calcular la interpolació + // (current_scale pot ser diferent si está en ENTERING) } } void ShipAnimator::skip_to_floating_state() { - // Posar ambdues naus directament en state FLOATING + // Posar ambdues naves directament en state FLOATING for (auto& ship : ships_) { ship.state = ShipState::FLOATING; ship.state_time = 0.0F; ship.oscillation_phase = 0.0F; - // Posar en posició objectiu (sense animació) + // Posar en posición objetivo (sin animación) ship.current_position = ship.target_position; ship.current_scale = ship.target_scale; - // NO establir visibilitat aquí - ja ho fa el caller - // (evita fer visibles ambdues naus quan només una ha premut START) + // NO establir visibilitat aquí - ya ho hace el caller + // (evita fer visibles ambdues naves cuando solo una ha premut START) } } bool ShipAnimator::is_visible() const { - // Retorna true si almenys una ship és visible + // Retorna true si almenys una ship es visible for (const auto& ship : ships_) { if (ship.visible) { return true; @@ -136,16 +136,16 @@ void ShipAnimator::trigger_exit_animation_for_player(int player_id) { // Trobar la ship del player especificat for (auto& ship : ships_) { if (ship.player_id == player_id) { - // Canviar state a EXITING només per aquesta ship + // Canviar state a EXITING solo per esta ship ship.state = ShipState::EXITING; ship.state_time = 0.0F; - // Preservar posició actual (pot estar a mig camí si START es prem durant ENTERING) + // Preservar posición actual (pot estar a mig camí si START es prem durante ENTERING) ship.initial_position = ship.current_position; - // La scale objectiu es preserva per a calcular la interpolació - // (current_scale pot ser diferent si està en ENTERING) - break; // Només una ship per player + // La scale objetivo es preserva para calcular la interpolació + // (current_scale pot ser diferent si está en ENTERING) + break; // Solo una ship per player } } } @@ -157,67 +157,67 @@ void ShipAnimator::set_visible(bool visible) { } bool ShipAnimator::is_animation_complete() const { - // Comprovar si totes les naus són invisibles (han completat l'animació de sortida) + // Comprovar si todas las naves són invisibles (han completat l'animación de salida) for (const auto& ship : ships_) { if (ship.visible) { - return false; // Encara hi ha alguna ship visible + return false; // Aún hay alguna ship visible } } - return true; // Totes les naus són invisibles + return true; // Todas las naves són invisibles } -// Mètodes d'animació (stubs) +// Métodos de animación (stubs) void ShipAnimator::actualitzar_entering(TitleShip& ship, float delta_time) { using namespace Defaults::Title::Ships; ship.state_time += delta_time; - // Esperar al delay abans de començar l'animació + // Esperar al delay antes de començar l'animación if (ship.state_time < ship.entry_delay) { - // Encara en delay: la ship es queda fora de pantalla (posició inicial) + // Aún en delay: la ship es queda fuera de pantalla (posición inicial) ship.current_position = ship.initial_position; ship.current_scale = ship.initial_scale; return; } - // Càlcul del progrés (restant el delay) + // Cálculo del progrés (restant el delay) float elapsed = ship.state_time - ship.entry_delay; float progress = std::min(1.0F, elapsed / ENTRY_DURATION); // Aplicar easing (ease_out_quad per arribada suau) float eased_progress = Easing::ease_out_quad(progress); - // Lerp posició (inicial → objectiu) + // Lerp posición (inicial → objetivo) ship.current_position.x = Easing::lerp(ship.initial_position.x, ship.target_position.x, eased_progress); ship.current_position.y = Easing::lerp(ship.initial_position.y, ship.target_position.y, eased_progress); - // Lerp scale (gran → normal) + // Lerp scale (grande → normal) ship.current_scale = Easing::lerp(ship.initial_scale, ship.target_scale, eased_progress); - // Transicionar a FLOATING quan completi + // Transicionar a FLOATING cuando completi if (elapsed >= ENTRY_DURATION) { ship.state = ShipState::FLOATING; ship.state_time = 0.0F; - ship.oscillation_phase = 0.0F; // Reiniciar fase d'oscil·lació + ship.oscillation_phase = 0.0F; // Reiniciar fase de oscil·lació } } void ShipAnimator::actualitzar_floating(TitleShip& ship, float delta_time) { using namespace Defaults::Title::Ships; - // Actualitzar time i fase d'oscil·lació + // Actualitzar time i fase de oscil·lació ship.state_time += delta_time; ship.oscillation_phase += delta_time; - // Oscil·lació sinusoïdal X/Y (paràmetres específics per ship) + // Oscil·lació sinusoïdal X/Y (parámetros específics per ship) float offset_x = ship.amplitude_x * std::sin(2.0F * Defaults::Math::PI * ship.frequency_x * ship.oscillation_phase); float offset_y = ship.amplitude_y * std::sin((2.0F * Defaults::Math::PI * ship.frequency_y * ship.oscillation_phase) + FLOAT_PHASE_OFFSET); - // Aplicar oscil·lació a la posició objectiu + // Aplicar oscil·lació a la posición objetivo ship.current_position.x = ship.target_position.x + offset_x; ship.current_position.y = ship.target_position.y + offset_y; - // Escala constant (sense "breathing" per ara) + // Escala constant (sin "breathing" per ara) ship.current_scale = ship.target_scale; } @@ -229,27 +229,27 @@ void ShipAnimator::actualitzar_exiting(TitleShip& ship, float delta_time) { // Calcular progrés (0.0 → 1.0) float progress = std::min(1.0F, ship.state_time / EXIT_DURATION); - // Aplicar easing (ease_in_quad per acceleració cap al point de fuga) + // Aplicar easing (ease_in_quad per aceleración hacia el point de fuga) float eased_progress = Easing::ease_in_quad(progress); - // Vec2 de fuga (centre del starfield) + // Vec2 de fuga (centro del starfield) constexpr Vec2 punt_fuga{.x = VANISHING_POINT_X, .y = VANISHING_POINT_Y}; - // Lerp posició cap al point de fuga (preservar posició inicial actual) - // Nota: initial_position conté la posició on estava quan es va activar EXITING + // Lerp posición hacia el point de fuga (preservar posición inicial actual) + // Nota: initial_position conté la posición on estava cuando es va activar EXITING ship.current_position.x = Easing::lerp(ship.initial_position.x, punt_fuga.x, eased_progress); ship.current_position.y = Easing::lerp(ship.initial_position.y, punt_fuga.y, eased_progress); // Escala redueix a 0 (simula Z → infinit) ship.current_scale = ship.target_scale * (1.0F - eased_progress); - // Marcar invisible quan l'animació completi + // Marcar invisible cuando l'animación completi if (progress >= 1.0F) { ship.visible = false; } } -// Configuració +// Configuración void ShipAnimator::configurar_nau_p1(TitleShip& ship) { using namespace Defaults::Title::Ships; @@ -260,9 +260,9 @@ void ShipAnimator::configurar_nau_p1(TitleShip& ship) { // Posicions (clock 8, bottom-left) ship.target_position = {.x = P1_TARGET_X(), .y = P1_TARGET_Y()}; - // Calcular posició inicial (fora de pantalla) + // Calcular posición inicial (fuera de pantalla) ship.initial_position = calcular_posicio_fora_pantalla(CLOCK_8_ANGLE); - ship.current_position = ship.initial_position; // Començar fora de pantalla + ship.current_position = ship.initial_position; // Començar fuera de pantalla // Escales ship.target_scale = FLOATING_SCALE; @@ -272,10 +272,10 @@ void ShipAnimator::configurar_nau_p1(TitleShip& ship) { // Flotació ship.oscillation_phase = 0.0F; - // Paràmetres d'entrada + // Parámetros de entrada ship.entry_delay = P1_ENTRY_DELAY; - // Paràmetres d'oscil·lació específics P1 + // Parámetros de oscil·lació específics P1 ship.amplitude_x = FLOAT_AMPLITUDE_X; ship.amplitude_y = FLOAT_AMPLITUDE_Y; ship.frequency_x = FLOAT_FREQUENCY_X_BASE * P1_FREQUENCY_MULTIPLIER; @@ -295,9 +295,9 @@ void ShipAnimator::configurar_nau_p2(TitleShip& ship) { // Posicions (clock 4, bottom-right) ship.target_position = {.x = P2_TARGET_X(), .y = P2_TARGET_Y()}; - // Calcular posició inicial (fora de pantalla) + // Calcular posición inicial (fuera de pantalla) ship.initial_position = calcular_posicio_fora_pantalla(CLOCK_4_ANGLE); - ship.current_position = ship.initial_position; // Començar fora de pantalla + ship.current_position = ship.initial_position; // Començar fuera de pantalla // Escales ship.target_scale = FLOATING_SCALE; @@ -307,10 +307,10 @@ void ShipAnimator::configurar_nau_p2(TitleShip& ship) { // Flotació ship.oscillation_phase = 0.0F; - // Paràmetres d'entrada + // Parámetros de entrada ship.entry_delay = P2_ENTRY_DELAY; - // Paràmetres d'oscil·lació específics P2 + // Parámetros de oscil·lació específics P2 ship.amplitude_x = FLOAT_AMPLITUDE_X; ship.amplitude_y = FLOAT_AMPLITUDE_Y; ship.frequency_x = FLOAT_FREQUENCY_X_BASE * P2_FREQUENCY_MULTIPLIER; @@ -324,7 +324,7 @@ Vec2 ShipAnimator::calcular_posicio_fora_pantalla(float angle_rellotge) const { using namespace Defaults::Title::Ships; // Convertir angle del rellotge a radians (per exemple: 240° per clock 8) - // Calcular posició en direcció radial des del centre, però més lluny + // Calcular posición en direcció radial des del centro, pero més lluny // ENTRY_OFFSET es calcula automàticament: (SHIP_MAX_RADIUS * ENTRY_SCALE_START) + ENTRY_OFFSET_MARGIN float extended_radius = CLOCK_RADIUS + ENTRY_OFFSET; diff --git a/source/game/title/ship_animator.hpp b/source/game/title/ship_animator.hpp index d0c6b72..47c5f8c 100644 --- a/source/game/title/ship_animator.hpp +++ b/source/game/title/ship_animator.hpp @@ -1,5 +1,5 @@ -// ship_animator.hpp - Sistema d'animació de naus per a l'escena de títol -// © 2025 Port a C++20 amb SDL3 +// ship_animator.hpp - Sistema de animación de naves para l'escena de título +// © 2025 Port a C++20 con SDL3 #pragma once @@ -13,14 +13,14 @@ namespace Title { -// Estats de l'animació de la ship +// Estats de l'animación de la ship enum class ShipState { - ENTERING, // Entrant des de fora de pantalla - FLOATING, // Flotant en posició estàtica - EXITING // Volant cap al point de fuga + ENTERING, // Entrant desde fuera de pantalla + FLOATING, // Flotante en posición estàtica + EXITING // Volant hacia el point de fuga }; -// Dades d'una ship individual al títol +// Dades de una ship individual al título struct TitleShip { // Identificació int player_id; // 1 o 2 @@ -30,22 +30,22 @@ struct TitleShip { float state_time; // Temps acumulat en l'state actual // Posicions - Vec2 initial_position; // Posició d'inici (fora de pantalla per ENTERING) - Vec2 target_position; // Posició objectiu (rellotge 8 o 4) - Vec2 current_position; // Posició interpolada actual + Vec2 initial_position; // Posición de start (fuera de pantalla per ENTERING) + Vec2 target_position; // Posición objetivo (rellotge 8 o 4) + Vec2 current_position; // Posición interpolada actual // Escales (simulació eix Z) - float initial_scale; // Escala d'inici (més gran = més a prop) - float target_scale; // Escala objectiu (mida flotació) + float initial_scale; // Escala de start (més grande = més a prop) + float target_scale; // Escala objetivo (mida flotació) float current_scale; // Escala interpolada actual // Flotació - float oscillation_phase; // Acumulador de fase per moviment sinusoïdal + float oscillation_phase; // Acumulador de fase per movement sinusoïdal - // Paràmetres d'entrada - float entry_delay; // Delay abans d'entrar (0.0 per P1, 0.5 per P2) + // Parámetros de entrada + float entry_delay; // Delay antes de entrar (0.0 per P1, 0.5 per P2) - // Paràmetres d'oscil·lació per ship + // Parámetros de oscil·lació per ship float amplitude_x; float amplitude_y; float frequency_x; @@ -58,7 +58,7 @@ struct TitleShip { bool visible; }; -// Gestor d'animació de naus per a l'escena de títol +// Gestor de animación de naves para l'escena de título class ShipAnimator { public: explicit ShipAnimator(SDL_Renderer* renderer); @@ -68,27 +68,27 @@ class ShipAnimator { void update(float delta_time); void draw() const; - // Control d'state (cridat per TitleScene) + // Control de state (cridat per TitleScene) void start_entry_animation(); - void trigger_exit_animation(); // Anima totes les naus - void trigger_exit_animation_for_player(int player_id); // Anima només una ship (P1=1, P2=2) - void skip_to_floating_state(); // Salta directament a FLOATING sense animació + void trigger_exit_animation(); // Anima todas las naves + void trigger_exit_animation_for_player(int player_id); // Anima solo una ship (P1=1, P2=2) + void skip_to_floating_state(); // Salta directament a FLOATING sin animación // Control de visibilitat void set_visible(bool visible); [[nodiscard]] bool is_animation_complete() const; - [[nodiscard]] bool is_visible() const; // Comprova si alguna ship és visible + [[nodiscard]] bool is_visible() const; // Comprova si alguna ship es visible private: SDL_Renderer* renderer_; - std::array ships_; // Naus P1 i P2 + std::array ships_; // Naves P1 i P2 - // Mètodes d'animació + // Métodos de animación void actualitzar_entering(TitleShip& ship, float delta_time); void actualitzar_floating(TitleShip& ship, float delta_time); void actualitzar_exiting(TitleShip& ship, float delta_time); - // Configuració + // Configuración void configurar_nau_p1(TitleShip& ship); void configurar_nau_p2(TitleShip& ship); [[nodiscard]] Vec2 calcular_posicio_fora_pantalla(float angle_rellotge) const; diff --git a/source/main.cpp b/source/main.cpp index 76ae868..9dedad5 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,6 +1,6 @@ -// main.cpp - Vec2 d'entrada del joc Asteroides -// © 1999 Visente i Sergi (versió Pascal) -// © 2025 Port a C++20 amb SDL3 +// main.cpp - Vec2 de entrada del juego Asteroides +// © 1999 Visente i Sergi (versión Pascal) +// © 2025 Port a C++20 con SDL3 #include #include @@ -11,9 +11,9 @@ int main(int argc, char* argv[]) { // Convertir arguments a std::vector std::vector args(argv, argv + argc); - // Crear director (inicialitza sistema, opcions, configuració) + // Crear director (inicialitza sistema, opciones, configuración) Director director(args); - // Executar bucle principal del joc + // Executar bucle principal del juego return director.run(); } From 56533caff04892a6db7af9d7afdf82b62c8ea83c Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 19 May 2026 12:19:24 +0200 Subject: [PATCH 07/27] Fix: clave YAML 'quadrat' renombrada a 'cuadrado' tras Fase 1e MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit El sweep de comentarios de la Fase 1e cambió por error el string literal yaml["quadrat"] a yaml["cuadrado"] dentro de stage_loader.cpp:172 (sed sin distinción comentario vs string). El archivo data/stages/stages.yaml seguía teniendo la clave 'quadrat:', lo que provocaba: [StageLoader] Error: enemy_distribution incompleta [GameScene] Error: no s'ha pogut load stages.yaml [StageManager] Error: config es null -> Violación de segmento al pasar de TITLE a GAME Solución coherente con la política "código en inglés/castellano, strings de UI en valenciano": el YAML es archivo de configuración, no UI, así que se alinea con el código. Cambios: - data/stages/stages.yaml: quadrat -> cuadrado en las 10 stages - build/resources.pack regenerado con `make pack` Audit completo: verificado que ninguna otra clave YAML ni string literal de filename (.shp, .wav) fue tocada por el sweep. Co-Authored-By: Claude Opus 4.7 (1M context) --- data/stages/stages.yaml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/data/stages/stages.yaml b/data/stages/stages.yaml index e6a24ac..b1bb66c 100644 --- a/data/stages/stages.yaml +++ b/data/stages/stages.yaml @@ -16,7 +16,7 @@ stages: spawn_interval: 3.0 enemy_distribution: pentagon: 100 - quadrat: 0 + cuadrado: 0 molinillo: 0 difficulty_multipliers: speed_multiplier: 0.7 @@ -32,7 +32,7 @@ stages: spawn_interval: 2.5 enemy_distribution: pentagon: 70 - quadrat: 30 + cuadrado: 30 molinillo: 0 difficulty_multipliers: speed_multiplier: 0.85 @@ -48,7 +48,7 @@ stages: spawn_interval: 2.0 enemy_distribution: pentagon: 50 - quadrat: 30 + cuadrado: 30 molinillo: 20 difficulty_multipliers: speed_multiplier: 1.0 @@ -64,7 +64,7 @@ stages: spawn_interval: 1.8 enemy_distribution: pentagon: 40 - quadrat: 35 + cuadrado: 35 molinillo: 25 difficulty_multipliers: speed_multiplier: 1.1 @@ -80,7 +80,7 @@ stages: spawn_interval: 1.5 enemy_distribution: pentagon: 35 - quadrat: 35 + cuadrado: 35 molinillo: 30 difficulty_multipliers: speed_multiplier: 1.2 @@ -96,7 +96,7 @@ stages: spawn_interval: 1.3 enemy_distribution: pentagon: 30 - quadrat: 30 + cuadrado: 30 molinillo: 40 difficulty_multipliers: speed_multiplier: 1.3 @@ -112,7 +112,7 @@ stages: spawn_interval: 1.0 enemy_distribution: pentagon: 25 - quadrat: 30 + cuadrado: 30 molinillo: 45 difficulty_multipliers: speed_multiplier: 1.4 @@ -128,7 +128,7 @@ stages: spawn_interval: 0.8 enemy_distribution: pentagon: 20 - quadrat: 30 + cuadrado: 30 molinillo: 50 difficulty_multipliers: speed_multiplier: 1.5 @@ -144,7 +144,7 @@ stages: spawn_interval: 0.6 enemy_distribution: pentagon: 15 - quadrat: 25 + cuadrado: 25 molinillo: 60 difficulty_multipliers: speed_multiplier: 1.6 @@ -160,7 +160,7 @@ stages: spawn_interval: 0.5 enemy_distribution: pentagon: 10 - quadrat: 20 + cuadrado: 20 molinillo: 70 difficulty_multipliers: speed_multiplier: 1.8 From a4f6a5514f00f991a33e20e567b59a5e6f965a84 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 19 May 2026 12:27:12 +0200 Subject: [PATCH 08/27] =?UTF-8?q?Fase=202:=20cambio=20de=20resoluci=C3=B3n?= =?UTF-8?q?=20l=C3=B3gica=20640x480=20a=201280x720=20(16:9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit El juego pasa de 4:3 a 16:9. Solo se tocan las constantes raíz: todo lo demás (PLAYAREA, SCOREBOARD, CENTER_X/Y, P1/P2_TARGET, VANISHING_POINT, etc.) se deriva de Game::WIDTH/HEIGHT y se recalcula automáticamente. Decisión del usuario: priorizar la base técnica sobre el feeling del juego. Las velocidades, masas, radios de colisión y tamaños de shape se mantienen sin cambios — la nave se verá más pequeña en relación al área de juego y habrá más espacio. El tuning jugable se hará tras completar la migración (post-Fase 7 GPU). Cambios: - Defaults::Window::WIDTH/HEIGHT: 640/480 -> 1280/720 - Defaults::Window::MIN_WIDTH/MIN_HEIGHT: 320/240 -> 640/360 (16:9) - Defaults::Game::WIDTH/HEIGHT: 640/480 -> 1280/720 - Options::Window defaults: width{640}/height{480} -> 1280/720 - logo_scene.cpp: PANTALLA_ANCHO/ALTO ya no hardcoded; deriva de Defaults::Game (era 640/480 magic numbers) - Comentarios obsoletos limpiados en defaults.hpp (// w = 640.0, // 320.0f, etc.) - Catalán residual traducido (marges->márgenes, percentatges->porcentajes, Àrea->Área, contenidor->contenedor, automàtic->automático) Verificado: el ShipAnimator del título usa CENTER_X / CENTER_Y / P1_TARGET_X/Y / VANISHING_POINT_X/Y, todos derivados de Game::WIDTH y Game::HEIGHT. Se reposicionan automáticamente. CLOCK_RADIUS=150 se mantiene (escala relativa al centro). PostFase: con 1280x720 el bug del HUD en ventana puede haber cambiado de síntomas. Verificar visualmente cuando se haga la prueba. Co-Authored-By: Claude Opus 4.7 (1M context) --- source/core/defaults.hpp | 86 +++++++++++++++---------------- source/game/constants.hpp | 2 +- source/game/options.hpp | 4 +- source/game/scenes/logo_scene.cpp | 4 +- 4 files changed, 48 insertions(+), 48 deletions(-) diff --git a/source/core/defaults.hpp b/source/core/defaults.hpp index 64973ba..687bd08 100644 --- a/source/core/defaults.hpp +++ b/source/core/defaults.hpp @@ -8,38 +8,38 @@ namespace Defaults { // Configuración de ventana namespace Window { -constexpr int WIDTH = 640; -constexpr int HEIGHT = 480; -constexpr int MIN_WIDTH = 320; // Mínimo: mitad del original -constexpr int MIN_HEIGHT = 240; +constexpr int WIDTH = 1280; +constexpr int HEIGHT = 720; +constexpr int MIN_WIDTH = 640; // Mínimo: mitad del baseline (16:9) +constexpr int MIN_HEIGHT = 360; // Zoom system -constexpr float BASE_ZOOM = 1.0F; // 640x480 baseline -constexpr float MIN_ZOOM = 0.5F; // 320x240 minimum +constexpr float BASE_ZOOM = 1.0F; // 1280x720 baseline (16:9) +constexpr float MIN_ZOOM = 0.5F; // 640x360 minimum constexpr float ZOOM_INCREMENT = 0.1F; // 10% steps (F1/F2) -constexpr bool FULLSCREEN = true; // Pantalla completa activadapor defecto +constexpr bool FULLSCREEN = true; // Pantalla completa activada por defecto } // namespace Window -// Dimensions base del juego (coordenades lògiques) +// Dimensiones base del juego (coordenadas lógicas, 16:9) namespace Game { -constexpr int WIDTH = 640; -constexpr int HEIGHT = 480; +constexpr int WIDTH = 1280; +constexpr int HEIGHT = 720; } // namespace Game -// Zones del juego (SDL_FRect con cálculos automàtics basat en percentatges) +// Zones del juego (SDL_FRect con cálculos automáticos basat en porcentajes) namespace Zones { // --- CONFIGURACIÓ DE PORCENTATGES --- -// Todas las zones definides como a percentatges de Game::WIDTH (640) i Game::HEIGHT (480) +// Todas las zones definides como a porcentajes de Game::WIDTH (640) i Game::HEIGHT (480) // Percentatges de height (divisió vertical) constexpr float SCOREBOARD_TOP_HEIGHT_PERCENT = 0.02F; // 10% superior constexpr float MAIN_PLAYAREA_HEIGHT_PERCENT = 0.88F; // 80% central constexpr float SCOREBOARD_BOTTOM_HEIGHT_PERCENT = 0.10F; // 10% inferior -// Padding horizontal para PLAYAREA (dins de MAIN_PLAYAREA) +// Padding horizontal para PLAYAREA (dentro de MAIN_PLAYAREA) constexpr float PLAYAREA_PADDING_HORIZONTAL_PERCENT = 0.015F; // 5% a cada costat // --- CÀLCULS AUTOMÀTICS DE PÍXELS --- -// Cálculos automàtics a partir dels percentatges +// Cálculos automáticos a partir dels porcentajes // Alçades constexpr float SCOREBOARD_TOP_H = Game::HEIGHT * SCOREBOARD_TOP_HEIGHT_PERCENT; @@ -56,44 +56,44 @@ constexpr float PLAYAREA_PADDING_H = Game::WIDTH * PLAYAREA_PADDING_HORIZONTAL_P // --- ZONES FINALS (SDL_FRect) --- -// Marcador superior (reservat para futur ús) -// Ocupa: 10% superior (0-48px) +// Marcador superior (reservado para futuro uso) +// Ocupa el 2% superior constexpr SDL_FRect SCOREBOARD_TOP = { 0.0F, // x = 0.0 SCOREBOARD_TOP_Y, // y = 0.0 - static_cast(Game::WIDTH), // w = 640.0 - SCOREBOARD_TOP_H // h = 48.0 + static_cast(Game::WIDTH), // ancho completo + SCOREBOARD_TOP_H // alto }; -// Àrea de juego principal (contenidor del 80% central, sin padding) -// Ocupa: 10-90% (48-432px), ample complet +// Área de juego principal (contenedor del 80% central, sin padding) +// Ocupa el 88% central, ancho completo constexpr SDL_FRect MAIN_PLAYAREA = { 0.0F, // x = 0.0 - MAIN_PLAYAREA_Y, // y = 48.0 - static_cast(Game::WIDTH), // w = 640.0 - MAIN_PLAYAREA_H // h = 384.0 + MAIN_PLAYAREA_Y, // debajo del scoreboard superior + static_cast(Game::WIDTH), // ancho completo + MAIN_PLAYAREA_H // alto }; // Zona de juego real (con padding horizontal del 5%) -// Ocupa: dins de MAIN_PLAYAREA, con marges laterals -// S'utilitza para límits del juego, colisiones, spawn +// Ocupa: dentro de MAIN_PLAYAREA, con márgenes laterales +// Se utiliza para límites del juego, colisiones, spawn constexpr SDL_FRect PLAYAREA = { - PLAYAREA_PADDING_H, // x = 32.0 - MAIN_PLAYAREA_Y, // y = 48.0 (igual que MAIN_PLAYAREA) - Game::WIDTH - (2.0F * PLAYAREA_PADDING_H), // w = 576.0 - MAIN_PLAYAREA_H // h = 384.0 (igual que MAIN_PLAYAREA) + PLAYAREA_PADDING_H, // padding horizontal + MAIN_PLAYAREA_Y, // debajo del scoreboard superior (igual que MAIN_PLAYAREA) + Game::WIDTH - (2.0F * PLAYAREA_PADDING_H), // ancho con padding + MAIN_PLAYAREA_H // alto (igual que MAIN_PLAYAREA) }; // Marcador inferior (marcador actual) -// Ocupa: 10% inferior (432-480px) +// Ocupa el 10% inferior constexpr SDL_FRect SCOREBOARD = { 0.0F, // x = 0.0 - SCOREBOARD_BOTTOM_Y, // y = 432.0 - static_cast(Game::WIDTH), // w = 640.0 - SCOREBOARD_BOTTOM_H // h = 48.0 + SCOREBOARD_BOTTOM_Y, // fondo + static_cast(Game::WIDTH), // ancho completo + SCOREBOARD_BOTTOM_H // alto }; -// Padding horizontal del marcador (per alinear zones izquierda/derecha con PLAYAREA) +// Padding horizontal del marcador (para alinear zonas izquierda/derecha con PLAYAREA) constexpr float SCOREBOARD_PADDING_H = 0.0F; // Game::WIDTH * 0.015f; } // namespace Zones @@ -143,7 +143,7 @@ constexpr float LEVEL_COMPLETED_TYPING_RATIO = 0.0F; // 0.0 = sin typewriter (d constexpr float INIT_HUD_DURATION = 3.0F; // Duración total del estado // Ratios de animación (inicio y fin como porcentajes del tiempo total) -// RECT (rectángulo de marges) +// RECT (rectángulo de márgenes) constexpr float INIT_HUD_RECT_RATIO_INIT = 0.30F; constexpr float INIT_HUD_RECT_RATIO_END = 0.85F; @@ -422,7 +422,7 @@ constexpr float TARGET_Y_RATIO = 0.15625F; constexpr float CLOCK_RADIUS = 150.0F; // Distancia des del centro // 4. Ángulos de posición (clock positions en coordenadas polares) -// En coordenades de pantalla: 0° = derecha, 90° = baix, 180° = izquierda, 270° = dalt +// En coordenadas de pantalla: 0° = derecha, 90° = baix, 180° = izquierda, 270° = dalt constexpr float CLOCK_8_ANGLE = 150.0F * Math::PI / 180.0F; // 8 o'clock (bottom-left) constexpr float CLOCK_4_ANGLE = 30.0F * Math::PI / 180.0F; // 4 o'clock (bottom-right) @@ -433,12 +433,12 @@ constexpr float SHIP_MAX_RADIUS = 30.0F; // Radi del cercle circumscrit a ship_ constexpr float ENTRY_OFFSET_MARGIN = 227.5F; // Para offset total de ~340px (ajustado) // ============================================================ -// VALORS DERIVATS (calculats automàticament - NO modificar) +// VALORS DERIVATS (calculats automáticoament - NO modificar) // ============================================================ // Centro de la pantalla (point de referència) -constexpr float CENTER_X = Game::WIDTH / 2.0F; // 320.0f -constexpr float CENTER_Y = Game::HEIGHT / 2.0F; // 240.0f +constexpr float CENTER_X = Game::WIDTH / 2.0F; // auto-derivado de Game::WIDTH +constexpr float CENTER_Y = Game::HEIGHT / 2.0F; // auto-derivado de Game::HEIGHT // Posicions target (calculades dinàmicament des dels parámetros base) // Nota: std::cos/sin no són constexpr en C++20, pero funcionen en runtime @@ -460,13 +460,13 @@ inline float P2_TARGET_Y() { constexpr float ENTRY_SCALE_START = 1.5F * SHIP_BASE_SCALE; // Entrada: 50% més grande constexpr float FLOATING_SCALE = 1.0F * SHIP_BASE_SCALE; // Flotante: scale base -// Offset de entrada (ajustat automàticament a l'scale) -// Fórmula: (radi màxim de la ship * scale de entrada) + marge +// Offset de entrada (ajustat automáticoament a l'scale) +// Fórmula: (radi 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) -constexpr float VANISHING_POINT_X = CENTER_X; // 320.0f -constexpr float VANISHING_POINT_Y = CENTER_Y; // 240.0f +constexpr float VANISHING_POINT_X = CENTER_X; // auto-derivado de Game::WIDTH +constexpr float VANISHING_POINT_Y = CENTER_Y; // auto-derivado de Game::HEIGHT // ============================================================ // ANIMACIONS (durades, oscil·lacions, delays) diff --git a/source/game/constants.hpp b/source/game/constants.hpp index bb6aa2a..82bb20a 100644 --- a/source/game/constants.hpp +++ b/source/game/constants.hpp @@ -6,7 +6,7 @@ // Permet usar Constants::MARGIN_LEFT en lloc de Defaults::Game::MARGIN_LEFT namespace Constants { -// Marges de l'àrea de juego (derivats de Defaults::Zones::GAME) +// Márgenes de l'àrea de juego (derivats de Defaults::Zones::GAME) constexpr int MARGIN_LEFT = static_cast(Defaults::Zones::PLAYAREA.x); constexpr int MARGIN_RIGHT = static_cast(Defaults::Zones::PLAYAREA.x + Defaults::Zones::PLAYAREA.w); diff --git a/source/game/options.hpp b/source/game/options.hpp index 65af46e..4fccd64 100644 --- a/source/game/options.hpp +++ b/source/game/options.hpp @@ -9,8 +9,8 @@ namespace Options { // Estructures de configuración struct Window { - int width{640}; - int height{480}; + int width{1280}; + int height{720}; bool fullscreen{false}; float zoom_factor{1.0F}; // Zoom level (0.5x to max_zoom) }; diff --git a/source/game/scenes/logo_scene.cpp b/source/game/scenes/logo_scene.cpp index 4bc4f90..f0383aa 100644 --- a/source/game/scenes/logo_scene.cpp +++ b/source/game/scenes/logo_scene.cpp @@ -178,8 +178,8 @@ void LogoScene::inicialitzar_lletres() { ancho_total += ESPAI_ENTRE_LLETRES * (lletres_.size() - 1); // Pas 3: Calcular posición inicial (centrat horitzontal) - constexpr float PANTALLA_ANCHO = 640.0F; - constexpr float PANTALLA_ALTO = 480.0F; + constexpr auto PANTALLA_ANCHO = static_cast(Defaults::Game::WIDTH); + constexpr auto PANTALLA_ALTO = static_cast(Defaults::Game::HEIGHT); float x_inicial = (PANTALLA_ANCHO - ancho_total) / 2.0F; float y_centre = PANTALLA_ALTO / 2.0F; From ed98ef612e8d3782cdfa7250a6916afb84d09776 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 19 May 2026 12:43:01 +0200 Subject: [PATCH 09/27] Fase 3: import del subsistema de audio desde AEEA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reemplaza el audio antiguo de orni_attack (singleton con new/delete raw, sin efectos, sin crossfade) por el subsistema moderno de AEEA (unique_ptr, RAII, crossfade nativo, echo/reverb, pitch-shift, callbacks de fin de pista, getMusicDurationMs para timelines deterministas). Eliminados: - source/core/audio/audio_cache.{hpp,cpp} (1 cache por subsistema) - source/core/audio/jail_audio.hpp viejo (motor inline globals) - source/external/stb_vorbis.h (v1.20) Añadidos (copiados de AEEA, traducidos comentarios al castellano): - source/core/audio/audio.{hpp,cpp} — singleton con Audio::Config inyectada - source/core/audio/audio_adapter.{hpp,cpp} — adapter para getMusic/getSound - source/core/audio/audio_effects.{hpp,cpp} — Schroeder reverb + echo DSP - source/core/audio/jail_audio.{hpp,cpp} — Ja::Engine class-based, streaming - source/core/audio/sound_effects_config.{hpp,cpp} — presets YAML (opcional) - source/external/stb_vorbis.c (v1.22) — OGG decoder, versión más reciente - source/external/stb_vorbis_impl.cpp — TU aislada para evitar clang-tidy Adaptaciones: - audio_adapter.cpp implementado a medida para orni: usa Resource::Helper::loadFile (no Resource::Cache de AEEA que orni no tiene). Cache local con unique_ptr / unique_ptr. - Includes: utils/defaults.hpp -> core/defaults.hpp, utils/log.hpp reemplazado por iostream con std::cerr/std::cout. API breaking changes (callsites migrados): - Audio::init() -> Audio::init(Config); el Director construye la Config desde Defaults::Audio::* (ENABLED, VOLUME, MUSIC_*, SOUND_*). - Audio::get()->getMusicState() -> Audio::getMusicState() (ahora static). - AudioCache::getMusic/getSound -> AudioResource::getMusic/getSound. Defaults::Audio consolidado: ahora aglutina las constantes que antes estaban repartidas entre namespace Audio (VOLUME, ENABLED), namespace Music (VOLUME, ENABLED), namespace Sound (VOLUME, ENABLED). Las pistas y rutas de efectos siguen en Music::* / Sound::*. Añadidas FREQUENCY, FORMAT, CHANNELS, CROSSFADE_MS, VOLUME_STEP para el motor. Beneficios para fases siguientes: - Crossfade en transiciones de escena (uso: playMusic(name, -1, 1500)). - Pitch-shift para variaciones de SFX (Audio::playSound(name, group, 0.95)). - Echo/reverb DSP via playSoundWithEcho/Reverb (sounds.yaml presets). - Callbacks setOnMusicEnded para sincronizar eventos con el fin de pista. Compila y enlaza. Pendiente: test runtime del usuario. Co-Authored-By: Claude Opus 4.7 (1M context) --- source/core/audio/audio.cpp | 328 +++++--- source/core/audio/audio.hpp | 222 ++++-- source/core/audio/audio_adapter.cpp | 99 +++ source/core/audio/audio_adapter.hpp | 19 + source/core/audio/audio_cache.cpp | 142 ---- source/core/audio/audio_cache.hpp | 42 -- source/core/audio/audio_effects.cpp | 251 +++++++ source/core/audio/audio_effects.hpp | 38 + source/core/audio/jail_audio.cpp | 645 ++++++++++++++++ source/core/audio/jail_audio.hpp | 708 ++++++------------ source/core/audio/sound_effects_config.cpp | 80 ++ source/core/audio/sound_effects_config.hpp | 36 + source/core/defaults.hpp | 19 +- source/core/system/director.cpp | 26 +- .../external/{stb_vorbis.h => stb_vorbis.c} | 117 +-- source/external/stb_vorbis_impl.cpp | 13 + source/game/options.cpp | 20 +- source/game/scenes/title_scene.cpp | 2 +- source/game/stage_system/stage_manager.cpp | 2 +- 19 files changed, 1893 insertions(+), 916 deletions(-) create mode 100644 source/core/audio/audio_adapter.cpp create mode 100644 source/core/audio/audio_adapter.hpp delete mode 100644 source/core/audio/audio_cache.cpp delete mode 100644 source/core/audio/audio_cache.hpp create mode 100644 source/core/audio/audio_effects.cpp create mode 100644 source/core/audio/audio_effects.hpp create mode 100644 source/core/audio/jail_audio.cpp create mode 100644 source/core/audio/sound_effects_config.cpp create mode 100644 source/core/audio/sound_effects_config.hpp rename source/external/{stb_vorbis.h => stb_vorbis.c} (98%) create mode 100644 source/external/stb_vorbis_impl.cpp diff --git a/source/core/audio/audio.cpp b/source/core/audio/audio.cpp index 6adf336..8bb79d0 100644 --- a/source/core/audio/audio.cpp +++ b/source/core/audio/audio.cpp @@ -1,183 +1,291 @@ -#include "audio.hpp" +#include "core/audio/audio.hpp" -#include // Para SDL_LogInfo, SDL_LogCategory, SDL_G... +#include // Para SDL_GetError, SDL_Init #include // Para clamp -#include // Para std::cout +#include // Para std::fprintf -// Implementación de stb_vorbis (debe estar ANTES de incluir jail_audio.hpp) -// clang-format off -#undef STB_VORBIS_HEADER_ONLY -#include "external/stb_vorbis.h" -// clang-format on +#include "core/audio/audio_adapter.hpp" // Para AudioResource::getMusic/getSound +#include "core/audio/jail_audio.hpp" // Para Ja::* (motor jailgames) +#include "core/audio/sound_effects_config.hpp" // Para SoundEffectsConfig +#include "core/defaults.hpp" // Para Defaults::Audio::FREQUENCY -#include "core/audio/audio_cache.hpp" // Para AudioCache -#include "core/audio/jail_audio.hpp" // Para JA_FadeOutMusic, JA_Init, JA_PauseM... -#include "game/options.hpp" // Para AudioOptions, audio, MusicOptions +// Invariant compile-time: tots los valors d'Audio::Group han de cabre als slots +// de volum per grup que manté l'engine. Si s'afegeix una nueva entrada a Group +// y no s'incrementa Ja::MAX_GROUPS, este assert falla antes de compilar. +static_assert(static_cast(Audio::Group::INTERFACE) < Ja::MAX_GROUPS, + "Audio::Group té més entrades que slots té Ja::MAX_GROUPS"); // Singleton -Audio* Audio::instance = nullptr; +std::unique_ptr