diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f2be20..f8b2d53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,9 @@ project(orni VERSION 0.6.0) # Info del proyecto set(PROJECT_LONG_NAME "Orni Attack") -set(PROJECT_COPYRIGHT "© 1999 Visente i Sergi, 2025 Port") +set(PROJECT_COPYRIGHT_ORIGINAL "© 1999 Visente i Sergi") +set(PROJECT_COPYRIGHT_PORT "© 2025 JailDesigner") +set(PROJECT_COPYRIGHT "${PROJECT_COPYRIGHT_ORIGINAL}, ${PROJECT_COPYRIGHT_PORT}") # Establecer estándar de C++ set(CMAKE_CXX_STANDARD 20) diff --git a/source/core/audio/audio_cache.cpp b/source/core/audio/audio_cache.cpp index 45f9020..f3b671e 100644 --- a/source/core/audio/audio_cache.cpp +++ b/source/core/audio/audio_cache.cpp @@ -3,10 +3,10 @@ #include "core/audio/audio_cache.hpp" -#include "core/resources/resource_helper.hpp" - #include +#include "core/resources/resource_helper.hpp" + // Inicialització de variables estàtiques std::unordered_map AudioCache::sounds_; std::unordered_map AudioCache::musics_; diff --git a/source/core/defaults.hpp b/source/core/defaults.hpp index d74af67..e39b904 100644 --- a/source/core/defaults.hpp +++ b/source/core/defaults.hpp @@ -28,12 +28,12 @@ namespace Zones { // Totes les zones definides com a percentatges de Game::WIDTH (640) i Game::HEIGHT (480) // Percentatges d'alçada (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 +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) -constexpr float PLAYAREA_PADDING_HORIZONTAL_PERCENT = 0.015f; // 5% a cada costat +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 @@ -56,42 +56,42 @@ constexpr float PLAYAREA_PADDING_H = Game::WIDTH * PLAYAREA_PADDING_HORIZONTAL_P // Marcador superior (reservat per a futur ús) // Ocupa: 10% superior (0-48px) 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 + 0.0f, // x = 0.0 + SCOREBOARD_TOP_Y, // y = 0.0 + static_cast(Game::WIDTH), // w = 640.0 + SCOREBOARD_TOP_H // h = 48.0 }; // Àrea de joc principal (contenidor del 80% central, sense padding) // Ocupa: 10-90% (48-432px), ample complet 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 + 0.0f, // x = 0.0 + MAIN_PLAYAREA_Y, // y = 48.0 + static_cast(Game::WIDTH), // w = 640.0 + 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 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, // 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) }; // Marcador inferior (marcador actual) // Ocupa: 10% inferior (432-480px) 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 + 0.0f, // x = 0.0 + SCOREBOARD_BOTTOM_Y, // y = 432.0 + static_cast(Game::WIDTH), // w = 640.0 + SCOREBOARD_BOTTOM_H // h = 48.0 }; // Padding horizontal del marcador (per alinear zones esquerra/dreta amb PLAYAREA) -constexpr float SCOREBOARD_PADDING_H = 0.0f;//Game::WIDTH * 0.015f; +constexpr float SCOREBOARD_PADDING_H = 0.0f; // Game::WIDTH * 0.015f; } // namespace Zones // Objetos del juego @@ -361,55 +361,112 @@ constexpr int MOLINILLO_SCORE = 200; // Molinillo (agressiu, 50 px/s) // Title scene ship animations (naus 3D flotants a l'escena de títol) namespace Title { namespace Ships { -// Posicions clock (coordenades polars des del centre 320, 240) +// ============================================================ +// PARÀMETRES BASE (ajustar aquí per experimentar) +// ============================================================ + +// 1. Escala global de les naus +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 + +// 4. Ángulos de posición (clock positions en coordenadas polares) // En coordenades de pantalla: 0° = dreta, 90° = baix, 180° = esquerra, 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 -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) -// P1 (8 o'clock, bottom-left) -// 150° → cos(150°)=-0.866, sin(150°)=0.5 → X = 320 - 130 = 190, Y = 240 + 75 = 315 -constexpr float P1_TARGET_X = 190.0f; -constexpr float P1_TARGET_Y = 315.0f; +// 5. Radio máximo de la forma de la nave (para calcular offset automáticamente) +constexpr float SHIP_MAX_RADIUS = 30.0f; // Radi del cercle circumscrit a ship_p1.shp -// P2 (4 o'clock, bottom-right) -// 30° → cos(30°)=0.866, sin(30°)=0.5 → X = 320 + 130 = 450, Y = 240 + 75 = 315 -constexpr float P2_TARGET_X = 450.0f; -constexpr float P2_TARGET_Y = 315.0f; +// 6. Margen de seguridad para offset de entrada +constexpr float ENTRY_OFFSET_MARGIN = 227.5f; // Para offset total de ~340px (ajustado) -// Escala base de les naus (ajusta aquí per fer-les més grans o petites) -constexpr float SHIP_BASE_SCALE = 2.5f; // Multiplicador global (1.0 = mida original) +// ============================================================ +// VALORS DERIVATS (calculats automàticament - NO modificar) +// ============================================================ -// Escales d'animació (perspectiva ja incorporada a les formes .shp) -constexpr float ENTRY_SCALE_START = 1.5f * SHIP_BASE_SCALE; // Més gran per veure millor -constexpr float FLOATING_SCALE = 1.0f * SHIP_BASE_SCALE; // Mida normal (més grans) +// Centre de la pantalla (punt de referència) +constexpr float CENTER_X = Game::WIDTH / 2.0f; // 320.0f +constexpr float CENTER_Y = Game::HEIGHT / 2.0f; // 240.0f -// Animacions -constexpr float ENTRY_DURATION = 2.0f; // Entrada -constexpr float ENTRY_OFFSET = 340.0f; // Offset fora de pantalla (considera radi màxim 30px * escala 3.75 + marge) -constexpr float EXIT_DURATION = 1.0f; // Sortida (configurable) +// 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) +inline float P1_TARGET_X() { + return CENTER_X + CLOCK_RADIUS * std::cos(CLOCK_8_ANGLE); +} +inline float P1_TARGET_Y() { + return CENTER_Y + (Game::HEIGHT / 2.0f) * TARGET_Y_RATIO; +} +inline float P2_TARGET_X() { + return CENTER_X + CLOCK_RADIUS * std::cos(CLOCK_4_ANGLE); +} +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: escala base + +// Offset d'entrada (ajustat automàticament a l'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) +constexpr float VANISHING_POINT_X = CENTER_X; // 320.0f +constexpr float VANISHING_POINT_Y = CENTER_Y; // 240.0f + +// ============================================================ +// ANIMACIONS (durades, oscil·lacions, delays) +// ============================================================ + +// Durades d'animació +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) -constexpr float FLOAT_AMPLITUDE_X = 4.0f; // Era 6.0f -constexpr float FLOAT_AMPLITUDE_Y = 2.5f; // Era 4.0f +constexpr float FLOAT_AMPLITUDE_X = 4.0f; // Amplitud X (píxels) +constexpr float FLOAT_AMPLITUDE_Y = 2.5f; // Amplitud Y (píxels) // Freqüències base -constexpr float FLOAT_FREQUENCY_X_BASE = 0.5f; -constexpr float FLOAT_FREQUENCY_Y_BASE = 0.7f; -constexpr float FLOAT_PHASE_OFFSET = 1.57f; // π/2 (90°) +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 -constexpr float P1_ENTRY_DELAY = 0.0f; // P1 entra immediatament -constexpr float P2_ENTRY_DELAY = 0.5f; // P2 entra 0.5s després +// Delays d'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 // Multiplicadors de freqüència per a cada nau (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 -// Punt de fuga -constexpr float VANISHING_POINT_X = Game::WIDTH / 2.0f; // 320.0f -constexpr float VANISHING_POINT_Y = Game::HEIGHT / 2.0f; // 240.0f } // namespace Ships + +namespace Layout { +// 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.73f; // "PRESS START TO PLAY" +constexpr float COPYRIGHT1_POS = 0.87f; // Primera línia copyright + +// Separacions relatives (proporció respecte Game::HEIGHT = 480px) +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 +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) +constexpr float TEXT_SPACING = 2.0f; +} // namespace Layout } // namespace Title // Floating score numbers (números flotants de puntuació) diff --git a/source/core/graphics/shape_loader.cpp b/source/core/graphics/shape_loader.cpp index 60d7637..52edb09 100644 --- a/source/core/graphics/shape_loader.cpp +++ b/source/core/graphics/shape_loader.cpp @@ -3,10 +3,10 @@ #include "core/graphics/shape_loader.hpp" -#include "core/resources/resource_helper.hpp" - #include +#include "core/resources/resource_helper.hpp" + namespace Graphics { // Inicialització de variables estàtiques diff --git a/source/core/graphics/starfield.cpp b/source/core/graphics/starfield.cpp index 0b51cb2..1ace8fa 100644 --- a/source/core/graphics/starfield.cpp +++ b/source/core/graphics/starfield.cpp @@ -106,7 +106,7 @@ float Starfield::calcular_brightness(const Estrella& estrella) const { // distancia_centre: 0.0 (centre, llunyanes) → 1.0 (vora, properes) float brightness_base = Defaults::Brightness::STARFIELD_MIN + (Defaults::Brightness::STARFIELD_MAX - Defaults::Brightness::STARFIELD_MIN) * - estrella.distancia_centre; + estrella.distancia_centre; // Aplicar multiplicador i limitar a 1.0 return std::min(1.0f, brightness_base * multiplicador_brightness_); diff --git a/source/core/graphics/starfield.hpp b/source/core/graphics/starfield.hpp index 2fa3557..788e69a 100644 --- a/source/core/graphics/starfield.hpp +++ b/source/core/graphics/starfield.hpp @@ -72,10 +72,10 @@ class Starfield { SDL_Renderer* renderer_; // Configuració - Punt punt_fuga_; // Punt 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 + Punt punt_fuga_; // Punt 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 float multiplicador_brightness_{1.0f}; // Multiplicador de brillantor (1.0 = default) }; diff --git a/source/core/input/input.hpp b/source/core/input/input.hpp index 726e033..3a41e36 100644 --- a/source/core/input/input.hpp +++ b/source/core/input/input.hpp @@ -129,8 +129,8 @@ class Input { private: // --- Constantes --- - static constexpr Sint16 AXIS_THRESHOLD = 30000; // Umbral para ejes analógicos - static constexpr Sint16 TRIGGER_THRESHOLD = 16384; // Umbral para triggers (50% del rango) + static constexpr Sint16 AXIS_THRESHOLD = 30000; // Umbral para ejes analógicos + static constexpr Sint16 TRIGGER_THRESHOLD = 16384; // Umbral para triggers (50% del rango) static constexpr std::array BUTTON_INPUTS = {Action::SHOOT}; // Inputs que usan botones // --- Métodos --- diff --git a/source/core/input/input_types.cpp b/source/core/input/input_types.cpp index d047e33..b6c4897 100644 --- a/source/core/input/input_types.cpp +++ b/source/core/input/input_types.cpp @@ -4,57 +4,57 @@ // Definición de los mapas const std::unordered_map ACTION_TO_STRING = { - {InputAction::LEFT, "LEFT"}, - {InputAction::RIGHT, "RIGHT"}, - {InputAction::THRUST, "THRUST"}, - {InputAction::SHOOT, "SHOOT"}, - {InputAction::WINDOW_INC_ZOOM, "WINDOW_INC_ZOOM"}, - {InputAction::WINDOW_DEC_ZOOM, "WINDOW_DEC_ZOOM"}, - {InputAction::TOGGLE_FULLSCREEN, "TOGGLE_FULLSCREEN"}, - {InputAction::TOGGLE_VSYNC, "TOGGLE_VSYNC"}, - {InputAction::EXIT, "EXIT"}, - {InputAction::NONE, "NONE"}}; + {InputAction::LEFT, "LEFT"}, + {InputAction::RIGHT, "RIGHT"}, + {InputAction::THRUST, "THRUST"}, + {InputAction::SHOOT, "SHOOT"}, + {InputAction::WINDOW_INC_ZOOM, "WINDOW_INC_ZOOM"}, + {InputAction::WINDOW_DEC_ZOOM, "WINDOW_DEC_ZOOM"}, + {InputAction::TOGGLE_FULLSCREEN, "TOGGLE_FULLSCREEN"}, + {InputAction::TOGGLE_VSYNC, "TOGGLE_VSYNC"}, + {InputAction::EXIT, "EXIT"}, + {InputAction::NONE, "NONE"}}; const std::unordered_map STRING_TO_ACTION = { - {"LEFT", InputAction::LEFT}, - {"RIGHT", InputAction::RIGHT}, - {"THRUST", InputAction::THRUST}, - {"SHOOT", InputAction::SHOOT}, - {"WINDOW_INC_ZOOM", InputAction::WINDOW_INC_ZOOM}, - {"WINDOW_DEC_ZOOM", InputAction::WINDOW_DEC_ZOOM}, - {"TOGGLE_FULLSCREEN", InputAction::TOGGLE_FULLSCREEN}, - {"TOGGLE_VSYNC", InputAction::TOGGLE_VSYNC}, - {"EXIT", InputAction::EXIT}, - {"NONE", InputAction::NONE}}; + {"LEFT", InputAction::LEFT}, + {"RIGHT", InputAction::RIGHT}, + {"THRUST", InputAction::THRUST}, + {"SHOOT", InputAction::SHOOT}, + {"WINDOW_INC_ZOOM", InputAction::WINDOW_INC_ZOOM}, + {"WINDOW_DEC_ZOOM", InputAction::WINDOW_DEC_ZOOM}, + {"TOGGLE_FULLSCREEN", InputAction::TOGGLE_FULLSCREEN}, + {"TOGGLE_VSYNC", InputAction::TOGGLE_VSYNC}, + {"EXIT", InputAction::EXIT}, + {"NONE", InputAction::NONE}}; const std::unordered_map BUTTON_TO_STRING = { - {SDL_GAMEPAD_BUTTON_WEST, "WEST"}, - {SDL_GAMEPAD_BUTTON_NORTH, "NORTH"}, - {SDL_GAMEPAD_BUTTON_EAST, "EAST"}, - {SDL_GAMEPAD_BUTTON_SOUTH, "SOUTH"}, - {SDL_GAMEPAD_BUTTON_START, "START"}, - {SDL_GAMEPAD_BUTTON_BACK, "BACK"}, - {SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, "LEFT_SHOULDER"}, - {SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, "RIGHT_SHOULDER"}, - {SDL_GAMEPAD_BUTTON_DPAD_UP, "DPAD_UP"}, - {SDL_GAMEPAD_BUTTON_DPAD_DOWN, "DPAD_DOWN"}, - {SDL_GAMEPAD_BUTTON_DPAD_LEFT, "DPAD_LEFT"}, - {SDL_GAMEPAD_BUTTON_DPAD_RIGHT, "DPAD_RIGHT"}, - {static_cast(100), "L2_AS_BUTTON"}, - {static_cast(101), "R2_AS_BUTTON"}}; + {SDL_GAMEPAD_BUTTON_WEST, "WEST"}, + {SDL_GAMEPAD_BUTTON_NORTH, "NORTH"}, + {SDL_GAMEPAD_BUTTON_EAST, "EAST"}, + {SDL_GAMEPAD_BUTTON_SOUTH, "SOUTH"}, + {SDL_GAMEPAD_BUTTON_START, "START"}, + {SDL_GAMEPAD_BUTTON_BACK, "BACK"}, + {SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, "LEFT_SHOULDER"}, + {SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, "RIGHT_SHOULDER"}, + {SDL_GAMEPAD_BUTTON_DPAD_UP, "DPAD_UP"}, + {SDL_GAMEPAD_BUTTON_DPAD_DOWN, "DPAD_DOWN"}, + {SDL_GAMEPAD_BUTTON_DPAD_LEFT, "DPAD_LEFT"}, + {SDL_GAMEPAD_BUTTON_DPAD_RIGHT, "DPAD_RIGHT"}, + {static_cast(100), "L2_AS_BUTTON"}, + {static_cast(101), "R2_AS_BUTTON"}}; const std::unordered_map STRING_TO_BUTTON = { - {"WEST", SDL_GAMEPAD_BUTTON_WEST}, - {"NORTH", SDL_GAMEPAD_BUTTON_NORTH}, - {"EAST", SDL_GAMEPAD_BUTTON_EAST}, - {"SOUTH", SDL_GAMEPAD_BUTTON_SOUTH}, - {"START", SDL_GAMEPAD_BUTTON_START}, - {"BACK", SDL_GAMEPAD_BUTTON_BACK}, - {"LEFT_SHOULDER", SDL_GAMEPAD_BUTTON_LEFT_SHOULDER}, - {"RIGHT_SHOULDER", SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER}, - {"DPAD_UP", SDL_GAMEPAD_BUTTON_DPAD_UP}, - {"DPAD_DOWN", SDL_GAMEPAD_BUTTON_DPAD_DOWN}, - {"DPAD_LEFT", SDL_GAMEPAD_BUTTON_DPAD_LEFT}, - {"DPAD_RIGHT", SDL_GAMEPAD_BUTTON_DPAD_RIGHT}, - {"L2_AS_BUTTON", static_cast(100)}, - {"R2_AS_BUTTON", static_cast(101)}}; + {"WEST", SDL_GAMEPAD_BUTTON_WEST}, + {"NORTH", SDL_GAMEPAD_BUTTON_NORTH}, + {"EAST", SDL_GAMEPAD_BUTTON_EAST}, + {"SOUTH", SDL_GAMEPAD_BUTTON_SOUTH}, + {"START", SDL_GAMEPAD_BUTTON_START}, + {"BACK", SDL_GAMEPAD_BUTTON_BACK}, + {"LEFT_SHOULDER", SDL_GAMEPAD_BUTTON_LEFT_SHOULDER}, + {"RIGHT_SHOULDER", SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER}, + {"DPAD_UP", SDL_GAMEPAD_BUTTON_DPAD_UP}, + {"DPAD_DOWN", SDL_GAMEPAD_BUTTON_DPAD_DOWN}, + {"DPAD_LEFT", SDL_GAMEPAD_BUTTON_DPAD_LEFT}, + {"DPAD_RIGHT", SDL_GAMEPAD_BUTTON_DPAD_RIGHT}, + {"L2_AS_BUTTON", static_cast(100)}, + {"R2_AS_BUTTON", static_cast(101)}}; diff --git a/source/core/input/input_types.hpp b/source/core/input/input_types.hpp index 4d958b0..603de00 100644 --- a/source/core/input/input_types.hpp +++ b/source/core/input/input_types.hpp @@ -8,23 +8,23 @@ // --- Enums --- enum class InputAction : int { // Acciones de entrada posibles en el juego - // Inputs de juego (movimiento y acción) - LEFT, // Rotar izquierda - RIGHT, // Rotar derecha - THRUST, // Acelerar - SHOOT, // Disparar - START, // Empezar partida + // Inputs de juego (movimiento y acción) + LEFT, // Rotar izquierda + RIGHT, // Rotar derecha + THRUST, // Acelerar + SHOOT, // Disparar + START, // Empezar partida - // Inputs de sistema (globales) - WINDOW_INC_ZOOM, // F2 - WINDOW_DEC_ZOOM, // F1 - TOGGLE_FULLSCREEN, // F3 - TOGGLE_VSYNC, // F4 - EXIT, // ESC + // Inputs de sistema (globales) + WINDOW_INC_ZOOM, // F2 + WINDOW_DEC_ZOOM, // F1 + TOGGLE_FULLSCREEN, // F3 + TOGGLE_VSYNC, // F4 + EXIT, // ESC - // Input obligatorio - NONE, - SIZE, + // Input obligatorio + NONE, + SIZE, }; // --- Variables --- @@ -36,7 +36,6 @@ extern const std::unordered_map STRING_TO_BUTTON // --- Constantes --- // Physical arcade buttons (excludes directional controls LEFT/RIGHT) static constexpr std::array ARCADE_BUTTONS = { - InputAction::SHOOT, - InputAction::THRUST, - InputAction::START -}; + InputAction::SHOOT, + InputAction::THRUST, + InputAction::START}; diff --git a/source/core/rendering/sdl_manager.hpp b/source/core/rendering/sdl_manager.hpp index 1ebec68..ecb5f7e 100644 --- a/source/core/rendering/sdl_manager.hpp +++ b/source/core/rendering/sdl_manager.hpp @@ -13,8 +13,8 @@ class SDLManager { public: - SDLManager(); // Constructor per defecte (usa Defaults::) - SDLManager(int width, int height, bool fullscreen); // Constructor amb configuració + SDLManager(); // Constructor per defecte (usa Defaults::) + SDLManager(int width, int height, bool fullscreen); // Constructor amb configuració ~SDLManager(); // No permetre còpia ni assignació @@ -22,11 +22,11 @@ class SDLManager { SDLManager& operator=(const SDLManager&) = delete; // [NUEVO] Gestió de finestra dinàmica - void increaseWindowSize(); // F2: +100px - void decreaseWindowSize(); // F1: -100px - void toggleFullscreen(); // F3 - void toggleVSync(); // F4 - bool handleWindowEvent(const SDL_Event& event); // Per a SDL_EVENT_WINDOW_RESIZED + void increaseWindowSize(); // F2: +100px + void decreaseWindowSize(); // F1: -100px + void toggleFullscreen(); // F3 + 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); diff --git a/source/core/rendering/shape_renderer.hpp b/source/core/rendering/shape_renderer.hpp index e404aea..44b8174 100644 --- a/source/core/rendering/shape_renderer.hpp +++ b/source/core/rendering/shape_renderer.hpp @@ -14,16 +14,22 @@ 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ó eix X (cabeceo arriba/baix) + float yaw; // Rotació eix Y (guiñada esquerra/dreta) + float roll; // Rotació eix Z (alabeo lateral) - Rotation3D() : pitch(0.0f), yaw(0.0f), roll(0.0f) {} - Rotation3D(float p, float y, float r) : pitch(p), yaw(y), roll(r) {} + Rotation3D() + : pitch(0.0f), + yaw(0.0f), + roll(0.0f) {} + Rotation3D(float p, float y, float r) + : pitch(p), + yaw(y), + roll(r) {} - bool has_rotation() const { - return pitch != 0.0f || yaw != 0.0f || roll != 0.0f; - } + bool has_rotation() const { + return pitch != 0.0f || yaw != 0.0f || roll != 0.0f; + } }; // Renderitzar forma amb transformacions diff --git a/source/core/resources/resource_helper.cpp b/source/core/resources/resource_helper.cpp index c552299..b9176e2 100644 --- a/source/core/resources/resource_helper.cpp +++ b/source/core/resources/resource_helper.cpp @@ -3,11 +3,11 @@ #include "resource_helper.hpp" -#include "resource_loader.hpp" - #include #include +#include "resource_loader.hpp" + namespace Resource { namespace Helper { diff --git a/source/core/resources/resource_loader.hpp b/source/core/resources/resource_loader.hpp index 5e5797e..e84c861 100644 --- a/source/core/resources/resource_loader.hpp +++ b/source/core/resources/resource_loader.hpp @@ -4,50 +4,50 @@ #pragma once -#include "resource_pack.hpp" - #include #include #include +#include "resource_pack.hpp" + namespace Resource { // Singleton per gestionar la càrrega de recursos class Loader { -public: - // Singleton - static Loader& get(); + public: + // Singleton + static Loader& get(); - // Inicialització - bool initialize(const std::string& pack_file, bool enable_fallback); + // Inicialització + bool initialize(const std::string& pack_file, bool enable_fallback); - // Càrrega de recursos - std::vector loadResource(const std::string& filename); - bool resourceExists(const std::string& filename); + // Càrrega de recursos + std::vector loadResource(const std::string& filename); + bool resourceExists(const std::string& filename); - // Validació - bool validatePack(); - bool isPackLoaded() const; + // Validació + bool validatePack(); + bool isPackLoaded() const; - // Estat - void setBasePath(const std::string& path); - std::string getBasePath() const; + // Estat + void setBasePath(const std::string& path); + std::string getBasePath() const; -private: - Loader() = default; - ~Loader() = default; + private: + Loader() = default; + ~Loader() = default; - // No es pot copiar ni moure - Loader(const Loader&) = delete; - Loader& operator=(const Loader&) = delete; + // No es pot copiar ni moure + Loader(const Loader&) = delete; + Loader& operator=(const Loader&) = delete; - // Dades - std::unique_ptr pack_; - bool fallback_enabled_ = false; - std::string base_path_; + // Dades + std::unique_ptr pack_; + bool fallback_enabled_ = false; + std::string base_path_; - // Funcions auxiliars - std::vector loadFromFilesystem(const std::string& filename); + // Funcions auxiliars + std::vector loadFromFilesystem(const std::string& filename); }; } // namespace Resource diff --git a/source/core/resources/resource_pack.hpp b/source/core/resources/resource_pack.hpp index 1ed6e5f..9a0112e 100644 --- a/source/core/resources/resource_pack.hpp +++ b/source/core/resources/resource_pack.hpp @@ -13,55 +13,55 @@ namespace Resource { // Capçalera del fitxer de paquet struct PackHeader { - char magic[4]; // "ORNI" - uint32_t version; // Versió del format (1) + char magic[4]; // "ORNI" + uint32_t version; // Versió 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 - uint64_t size; // Mida en bytes - uint32_t checksum; // Checksum CRC32 per verificació + std::string filename; // Nom del recurs (amb barres normals) + uint64_t offset; // Posició 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 class Pack { -public: - Pack() = default; - ~Pack() = default; + public: + Pack() = default; + ~Pack() = default; - // Afegir fitxers 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 = ""); + // Afegir fitxers 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 = ""); - // Guardar i carregar paquets - bool savePack(const std::string& pack_file); - bool loadPack(const std::string& pack_file); + // Guardar i carregar paquets + bool savePack(const std::string& pack_file); + bool loadPack(const std::string& pack_file); - // Accés a recursos - std::vector getResource(const std::string& filename); - bool hasResource(const std::string& filename) const; - std::vector getResourceList() const; + // Accés a recursos + std::vector getResource(const std::string& filename); + bool hasResource(const std::string& filename) const; + std::vector getResourceList() const; - // Validació - bool validatePack() const; + // Validació + bool validatePack() const; -private: - // Constants - static constexpr const char* MAGIC_HEADER = "ORNI"; - static constexpr uint32_t VERSION = 1; - static constexpr const char* DEFAULT_ENCRYPT_KEY = "ORNI_RESOURCES_2025"; + private: + // Constants + static constexpr const char* MAGIC_HEADER = "ORNI"; + static constexpr uint32_t VERSION = 1; + static constexpr const char* DEFAULT_ENCRYPT_KEY = "ORNI_RESOURCES_2025"; - // Dades del paquet - std::unordered_map resources_; - std::vector data_; + // Dades del paquet + std::unordered_map resources_; + std::vector data_; - // Funcions auxiliars - std::vector readFile(const std::string& filepath); - uint32_t calculateChecksum(const std::vector& data) const; - void encryptData(std::vector& data, const std::string& key); - void decryptData(std::vector& data, const std::string& key); + // Funcions auxiliars + std::vector readFile(const std::string& filepath); + uint32_t calculateChecksum(const std::vector& data) const; + void encryptData(std::vector& data, const std::string& key); + void decryptData(std::vector& data, const std::string& key); }; } // namespace Resource diff --git a/source/core/system/context_escenes.hpp b/source/core/system/context_escenes.hpp index 8a6db74..f632bbd 100644 --- a/source/core/system/context_escenes.hpp +++ b/source/core/system/context_escenes.hpp @@ -10,70 +10,70 @@ 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 - }; + 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) - }; + // 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() - : escena_desti_(Escena::LOGO), - opcio_(Opcio::NONE) {} + // Constructor inicial amb escena LOGO i sense opcions + ContextEscenes() + : escena_desti_(Escena::LOGO), + opcio_(Opcio::NONE) {} - // Canviar escena amb opció específica - void canviar_escena(Escena nova_escena, Opcio opcio = Opcio::NONE) { - escena_desti_ = nova_escena; - opcio_ = opcio; - } + // 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 escena destinació + [[nodiscard]] auto escena_desti() const -> Escena { + return escena_desti_; + } - // Consultar opció actual - [[nodiscard]] auto opcio() const -> Opcio { - return opcio_; - } + // 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; - } + // 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; - } + // 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; - } + // 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_; - } + // Obtenir configuració de partida (consumit per EscenaJoc) + [[nodiscard]] const GameConfig::ConfigPartida& get_config_partida() const { + return config_partida_; + } -private: - Escena escena_desti_; // Escena a la qual transicionar - Opcio opcio_; // Opció específica per l'escena - GameConfig::ConfigPartida config_partida_; // Configuració de partida (jugadors actius, mode) + private: + Escena escena_desti_; // Escena a la qual transicionar + Opcio opcio_; // 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) diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 17c815f..5f3eda0 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -7,6 +7,7 @@ #include #include +#include "context_escenes.hpp" #include "core/audio/audio.hpp" #include "core/audio/audio_cache.hpp" #include "core/defaults.hpp" @@ -20,7 +21,6 @@ #include "game/escenes/escena_logo.hpp" #include "game/escenes/escena_titol.hpp" #include "game/options.hpp" -#include "context_escenes.hpp" #include "project.h" #ifndef _WIN32 @@ -240,7 +240,7 @@ auto Director::run() -> int { // Crear context d'escenes ContextEscenes context; #ifdef _DEBUG - context.canviar_escena(Escena::JOC); + context.canviar_escena(Escena::TITOL); #else context.canviar_escena(Escena::LOGO); #endif diff --git a/source/core/system/game_config.hpp b/source/core/system/game_config.hpp index 8326584..c9c6fa4 100644 --- a/source/core/system/game_config.hpp +++ b/source/core/system/game_config.hpp @@ -12,40 +12,40 @@ enum class Mode { // Configuració d'una partida struct ConfigPartida { - 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 + 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 - // Mètodes auxiliars + // Mètodes auxiliars - // Retorna true si només hi ha un jugador actiu - [[nodiscard]] bool es_un_jugador() const { - return (jugador1_actiu && !jugador2_actiu) || - (!jugador1_actiu && jugador2_actiu); - } + // Retorna true si només hi ha un jugador actiu + [[nodiscard]] bool es_un_jugador() const { + return (jugador1_actiu && !jugador2_actiu) || + (!jugador1_actiu && jugador2_actiu); + } - // Retorna true si hi ha dos jugadors actius - [[nodiscard]] bool son_dos_jugadors() const { - return jugador1_actiu && jugador2_actiu; - } + // Retorna true si hi ha dos jugadors actius + [[nodiscard]] bool son_dos_jugadors() const { + return jugador1_actiu && jugador2_actiu; + } - // Retorna true si no hi ha cap jugador actiu - [[nodiscard]] bool cap_jugador() const { - return !jugador1_actiu && !jugador2_actiu; - } + // Retorna true si no hi ha cap jugador actiu + [[nodiscard]] bool cap_jugador() const { + return !jugador1_actiu && !jugador2_actiu; + } - // Compte de jugadors actius (0, 1 o 2) - [[nodiscard]] uint8_t compte_jugadors() const { - return (jugador1_actiu ? 1 : 0) + (jugador2_actiu ? 1 : 0); - } + // Compte de jugadors actius (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) - // Només vàlid si es_un_jugador() retorna true - [[nodiscard]] uint8_t id_unic_jugador() const { - if (jugador1_actiu && !jugador2_actiu) return 0; - if (!jugador1_actiu && jugador2_actiu) return 1; - return 0; // Fallback (cal comprovar es_un_jugador() primer) - } + // Retorna l'ID de l'únic jugador actiu (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) return 0; + if (!jugador1_actiu && jugador2_actiu) return 1; + return 0; // Fallback (cal comprovar es_un_jugador() primer) + } }; } // namespace GameConfig diff --git a/source/core/system/global_events.cpp b/source/core/system/global_events.cpp index 1c39f88..9c340c7 100644 --- a/source/core/system/global_events.cpp +++ b/source/core/system/global_events.cpp @@ -5,10 +5,10 @@ #include +#include "context_escenes.hpp" #include "core/input/input.hpp" #include "core/input/mouse.hpp" #include "core/rendering/sdl_manager.hpp" -#include "context_escenes.hpp" // Using declarations per simplificar el codi using GestorEscenes::ContextEscenes; diff --git a/source/core/system/global_events.hpp b/source/core/system/global_events.hpp index 70b1e24..a11241d 100644 --- a/source/core/system/global_events.hpp +++ b/source/core/system/global_events.hpp @@ -8,7 +8,9 @@ // Forward declarations class SDLManager; -namespace GestorEscenes { class ContextEscenes; } +namespace GestorEscenes { +class ContextEscenes; +} namespace GlobalEvents { // Processa events globals (F1/F2/F3/ESC/QUIT) diff --git a/source/game/effects/debris.hpp b/source/game/effects/debris.hpp index d31ef30..0b2a0ec 100644 --- a/source/game/effects/debris.hpp +++ b/source/game/effects/debris.hpp @@ -18,9 +18,9 @@ struct Debris { float acceleracio; // Acceleració 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) + 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) // Estat de vida float temps_vida; // Temps transcorregut (segons) diff --git a/source/game/effects/gestor_puntuacio_flotant.cpp b/source/game/effects/gestor_puntuacio_flotant.cpp index efbbb52..90d7b0b 100644 --- a/source/game/effects/gestor_puntuacio_flotant.cpp +++ b/source/game/effects/gestor_puntuacio_flotant.cpp @@ -8,7 +8,8 @@ namespace Effects { GestorPuntuacioFlotant::GestorPuntuacioFlotant(SDL_Renderer* renderer) - : renderer_(renderer), text_(renderer) { + : renderer_(renderer), + text_(renderer) { // Inicialitzar tots els slots com inactius for (auto& pf : pool_) { pf.actiu = false; @@ -25,7 +26,7 @@ void GestorPuntuacioFlotant::crear(int punts, const Punt& posicio) { pf->text = std::to_string(punts); pf->posicio = posicio; pf->velocitat = {Defaults::FloatingScore::VELOCITY_X, - Defaults::FloatingScore::VELOCITY_Y}; + Defaults::FloatingScore::VELOCITY_Y}; pf->temps_vida = 0.0f; pf->temps_max = Defaults::FloatingScore::LIFETIME; pf->brightness = 1.0f; diff --git a/source/game/effects/gestor_puntuacio_flotant.hpp b/source/game/effects/gestor_puntuacio_flotant.hpp index 6c5243d..3ce5c60 100644 --- a/source/game/effects/gestor_puntuacio_flotant.hpp +++ b/source/game/effects/gestor_puntuacio_flotant.hpp @@ -17,38 +17,38 @@ namespace Effects { // Gestor de números de puntuació flotants // Manté un pool de PuntuacioFlotant i gestiona el seu cicle de vida class GestorPuntuacioFlotant { - public: - explicit GestorPuntuacioFlotant(SDL_Renderer* renderer); + public: + explicit GestorPuntuacioFlotant(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 Punt& posicio); + // 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); - // Actualitzar tots els números actius - void actualitzar(float delta_time); + // Actualitzar tots els números actius + void actualitzar(float delta_time); - // Dibuixar tots els números actius - void dibuixar(); + // Dibuixar tots els números actius + void dibuixar(); - // Reiniciar tots (neteja) - void reiniciar(); + // Reiniciar tots (neteja) + void reiniciar(); - // Obtenir número actius (debug) - int get_num_actius() const; + // Obtenir número actius (debug) + int get_num_actius() const; - private: - SDL_Renderer* renderer_; - Graphics::VectorText text_; // Sistema de text vectorial + private: + SDL_Renderer* renderer_; + 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 - static constexpr int MAX_PUNTUACIONS = - Defaults::FloatingScore::MAX_CONCURRENT; - std::array pool_; + // Pool de números flotants (màxim concurrent) + // Màxim 15 enemics simultanis = màxim 15 números + static constexpr int MAX_PUNTUACIONS = + Defaults::FloatingScore::MAX_CONCURRENT; + std::array pool_; - // Trobar primer slot inactiu - PuntuacioFlotant* trobar_slot_lliure(); + // Trobar primer slot inactiu + PuntuacioFlotant* trobar_slot_lliure(); }; } // namespace Effects diff --git a/source/game/effects/puntuacio_flotant.hpp b/source/game/effects/puntuacio_flotant.hpp index 2063c41..340e2a4 100644 --- a/source/game/effects/puntuacio_flotant.hpp +++ b/source/game/effects/puntuacio_flotant.hpp @@ -12,22 +12,22 @@ 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 { - // Text a mostrar (e.g., "100", "150", "200") - std::string text; + // Text a mostrar (e.g., "100", "150", "200") + std::string text; - // Posició actual (coordenades mundials) - Punt posicio; + // Posició actual (coordenades mundials) + Punt posicio; - // Animació de moviment - Punt velocitat; // px/s (normalment cap amunt: {0.0f, -30.0f}) + // Animació de moviment + Punt velocitat; // px/s (normalment cap amunt: {0.0f, -30.0f}) - // Animació 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) + // Animació 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) - // Estat - bool actiu; + // Estat + bool actiu; }; } // namespace Effects diff --git a/source/game/entities/enemic.cpp b/source/game/entities/enemic.cpp index c29f68b..d9ab819 100644 --- a/source/game/entities/enemic.cpp +++ b/source/game/entities/enemic.cpp @@ -25,7 +25,7 @@ Enemic::Enemic(SDL_Renderer* renderer) tipus_(TipusEnemic::PENTAGON), tracking_timer_(0.0f), ship_position_(nullptr), - tracking_strength_(0.5f), // Default tracking strength + tracking_strength_(0.5f), // Default tracking strength timer_invulnerabilitat_(0.0f) { // Start vulnerable // [NUEVO] Forma es carrega a inicialitzar() segons el tipus // Constructor no carrega forma per permetre tipus diferents @@ -126,7 +126,7 @@ void Enemic::inicialitzar(TipusEnemic tipus, const Punt* ship_pos) { // [NEW] Inicialitzar invulnerabilitat timer_invulnerabilitat_ = Defaults::Enemies::Spawn::INVULNERABILITY_DURATION; // 3.0s - brightness_ = Defaults::Enemies::Spawn::INVULNERABILITY_BRIGHTNESS_START; // 0.3f + brightness_ = Defaults::Enemies::Spawn::INVULNERABILITY_BRIGHTNESS_START; // 0.3f // Activar esta_ = true; @@ -144,7 +144,7 @@ void Enemic::actualitzar(float delta_time) { // [NEW] Update brightness with LERP during invulnerability float t_inv = timer_invulnerabilitat_ / Defaults::Enemies::Spawn::INVULNERABILITY_DURATION; - float t = 1.0f - t_inv; // 0.0 → 1.0 + float t = 1.0f - t_inv; // 0.0 → 1.0 float smooth_t = t * t * (3.0f - 2.0f * t); // smoothstep constexpr float START = Defaults::Enemies::Spawn::INVULNERABILITY_BRIGHTNESS_START; diff --git a/source/game/entities/enemic.hpp b/source/game/entities/enemic.hpp index 37ad790..f31b274 100644 --- a/source/game/entities/enemic.hpp +++ b/source/game/entities/enemic.hpp @@ -54,8 +54,7 @@ class Enemic { Punt get_velocitat_vector() const { return { velocitat_ * std::cos(angle_ - Constants::PI / 2.0f), - velocitat_ * std::sin(angle_ - Constants::PI / 2.0f) - }; + velocitat_ * std::sin(angle_ - Constants::PI / 2.0f)}; } // Set ship position reference for tracking behavior @@ -68,7 +67,10 @@ class Enemic { // [NEW] Setters for difficulty multipliers (stage system) void set_velocity(float vel) { velocitat_ = vel; } - void set_rotation(float rot) { drotacio_ = rot; animacio_.drotacio_base = rot; } + void set_rotation(float rot) { + drotacio_ = rot; + animacio_.drotacio_base = rot; + } void set_tracking_strength(float strength); // [NEW] Invulnerability queries diff --git a/source/game/entities/nau.cpp b/source/game/entities/nau.cpp index fdff25e..1fba668 100644 --- a/source/game/entities/nau.cpp +++ b/source/game/entities/nau.cpp @@ -140,7 +140,7 @@ void Nau::dibuixar() const { if (es_invulnerable()) { // Calcular ciclo de parpadeo float blink_cycle = Defaults::Ship::BLINK_VISIBLE_TIME + - Defaults::Ship::BLINK_INVISIBLE_TIME; + Defaults::Ship::BLINK_INVISIBLE_TIME; float time_in_cycle = std::fmod(invulnerable_timer_, blink_cycle); // Si estamos en fase invisible, no dibujar diff --git a/source/game/entities/nau.hpp b/source/game/entities/nau.hpp index bf76097..3ca9a17 100644 --- a/source/game/entities/nau.hpp +++ b/source/game/entities/nau.hpp @@ -33,8 +33,7 @@ class Nau { Punt get_velocitat_vector() const { return { velocitat_ * std::cos(angle_ - Constants::PI / 2.0f), - velocitat_ * std::sin(angle_ - Constants::PI / 2.0f) - }; + velocitat_ * std::sin(angle_ - Constants::PI / 2.0f)}; } // Setters @@ -55,7 +54,7 @@ class Nau { float angle_; // Angle d'orientació float velocitat_; // Velocitat (px/s) bool esta_tocada_; - float brightness_; // Factor de brillantor (0.0-1.0) + float brightness_; // Factor de brillantor (0.0-1.0) float invulnerable_timer_; // 0.0f = vulnerable, >0.0f = invulnerable void aplicar_fisica(float delta_time); diff --git a/source/game/escenes/escena_joc.cpp b/source/game/escenes/escena_joc.cpp index bba1a40..ca959b7 100644 --- a/source/game/escenes/escena_joc.cpp +++ b/source/game/escenes/escena_joc.cpp @@ -323,22 +323,19 @@ void EscenaJoc::actualitzar(float delta_time) { } // Calcular global progress (0.0 al inicio → 1.0 al final) - float global_progress = 1.0f - (stage_manager_->get_timer_transicio() / - Defaults::Game::INIT_HUD_DURATION); + float global_progress = 1.0f - (stage_manager_->get_timer_transicio() / Defaults::Game::INIT_HUD_DURATION); global_progress = std::min(1.0f, global_progress); // [NEW] Calcular progress independiente para cada nave float ship1_progress = calcular_progress_rango( global_progress, Defaults::Game::INIT_HUD_SHIP1_RATIO_INIT, - Defaults::Game::INIT_HUD_SHIP1_RATIO_END - ); + Defaults::Game::INIT_HUD_SHIP1_RATIO_END); float ship2_progress = calcular_progress_rango( global_progress, Defaults::Game::INIT_HUD_SHIP2_RATIO_INIT, - Defaults::Game::INIT_HUD_SHIP2_RATIO_END - ); + Defaults::Game::INIT_HUD_SHIP2_RATIO_END); // [MODIFICAT] Animar AMBAS naus con sus progress respectivos if (config_partida_.jugador1_actiu && ship1_progress < 1.0f) { @@ -501,26 +498,22 @@ void EscenaJoc::dibuixar() { float rect_progress = calcular_progress_rango( global_progress, Defaults::Game::INIT_HUD_RECT_RATIO_INIT, - Defaults::Game::INIT_HUD_RECT_RATIO_END - ); + Defaults::Game::INIT_HUD_RECT_RATIO_END); float score_progress = calcular_progress_rango( global_progress, Defaults::Game::INIT_HUD_SCORE_RATIO_INIT, - Defaults::Game::INIT_HUD_SCORE_RATIO_END - ); + Defaults::Game::INIT_HUD_SCORE_RATIO_END); float ship1_progress = calcular_progress_rango( global_progress, Defaults::Game::INIT_HUD_SHIP1_RATIO_INIT, - Defaults::Game::INIT_HUD_SHIP1_RATIO_END - ); + Defaults::Game::INIT_HUD_SHIP1_RATIO_END); float ship2_progress = calcular_progress_rango( global_progress, Defaults::Game::INIT_HUD_SHIP2_RATIO_INIT, - Defaults::Game::INIT_HUD_SHIP2_RATIO_END - ); + Defaults::Game::INIT_HUD_SHIP2_RATIO_END); // Dibuixar elements animats if (rect_progress > 0.0f) { @@ -643,15 +636,15 @@ void EscenaJoc::tocado(uint8_t player_id) { Punt vel_nau_80 = {vel_nau.x * 0.8f, vel_nau.y * 0.8f}; debris_manager_.explotar( - naus_[player_id].get_forma(), // 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 - vel_nau_80, // Heredar 80% velocitat - 0.0f, // Nave: trayectorias rectas (sin drotacio) - 0.0f // Sin herencia visual (rotación aleatoria) + naus_[player_id].get_forma(), // 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 + vel_nau_80, // Heredar 80% velocitat + 0.0f, // Nave: trayectorias rectas (sin drotacio) + 0.0f // Sin herencia visual (rotación aleatoria) ); Audio::get()->playSound(Defaults::Sound::EXPLOSION, Audio::Group::GAME); @@ -863,7 +856,7 @@ std::string EscenaJoc::construir_marcador() const { // Nivell (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); + : std::to_string(stage_num); // Puntuació P2 (6 dígits) - mostrar zeros si inactiu std::string score_p2; @@ -946,15 +939,15 @@ void EscenaJoc::detectar_col·lisions_bales_enemics() { // 2. Crear explosió de fragments Punt vel_enemic = enemic.get_velocitat_vector(); debris_manager_.explotar( - enemic.get_forma(), // 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 - vel_enemic, // Heredar velocitat - enemic.get_drotacio(), // Heredar velocitat angular (trayectorias curvas) - 0.0f // Sin herencia visual (rotación aleatoria) + enemic.get_forma(), // 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 + vel_enemic, // Heredar velocitat + enemic.get_drotacio(), // Heredar velocitat angular (trayectorias curvas) + 0.0f // Sin herencia visual (rotación aleatoria) ); // 3. Desactivar bala @@ -1063,8 +1056,8 @@ void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) { // Auto-scale if text exceeds max width float escala = (text_width_at_base <= max_width) - ? escala_base - : max_width / text_width_at_base; + ? 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); @@ -1099,8 +1092,7 @@ Punt EscenaJoc::obtenir_punt_spawn(uint8_t player_id) const { return { zona.x + zona.w * x_ratio, - zona.y + zona.h * Defaults::Game::SPAWN_Y_RATIO - }; + zona.y + zona.h * Defaults::Game::SPAWN_Y_RATIO}; } void EscenaJoc::disparar_bala(uint8_t player_id) { diff --git a/source/game/escenes/escena_joc.hpp b/source/game/escenes/escena_joc.hpp index 046cb7c..db93d6b 100644 --- a/source/game/escenes/escena_joc.hpp +++ b/source/game/escenes/escena_joc.hpp @@ -9,6 +9,7 @@ #include #include +#include #include "../constants.hpp" #include "../effects/debris_manager.hpp" @@ -23,8 +24,6 @@ #include "core/system/game_config.hpp" #include "core/types.hpp" -#include - // Classe principal del joc (escena) class EscenaJoc { public: @@ -57,7 +56,7 @@ class EscenaJoc { bool game_over_; // Game over state flag float game_over_timer_; // Countdown timer for auto-return (seconds) // 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, legacy) std::array puntuacio_per_jugador_; // [0]=P1, [1]=P2 // Text vectorial @@ -72,20 +71,20 @@ class EscenaJoc { // Funcions privades void tocado(uint8_t player_id); - void detectar_col·lisions_bales_enemics(); // Col·lisions bala-enemic - void detectar_col·lisio_naus_enemics(); // Ship-enemy collision detection (plural) - 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 + void detectar_col·lisions_bales_enemics(); // Col·lisions bala-enemic + void detectar_col·lisio_naus_enemics(); // Ship-enemy collision detection (plural) + 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 Punt obtenir_punt_spawn(uint8_t player_id) const; // Get spawn position for player // [NEW] Stage system helpers void dibuixar_missatge_stage(const std::string& missatge); // [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 - Punt calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const; // Posició animada de la nau + void dibuixar_marges_animat(float progress) const; // Rectangle amb creixement uniforme + void dibuixar_marcador_animat(float progress); // Marcador que puja des de baix + Punt 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 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 82d9525..0a9dc0e 100644 --- a/source/game/escenes/escena_logo.cpp +++ b/source/game/escenes/escena_logo.cpp @@ -220,10 +220,8 @@ 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) - { - Audio::get()->playMusic("title.ogg"); + } else if (nou_estat == EstatAnimacio::POST_EXPLOSION) { + Audio::get()->playMusic("title.ogg"); } std::cout << "[EscenaLogo] Canvi a estat: " << static_cast(nou_estat) @@ -246,13 +244,13 @@ void EscenaLogo::actualitzar_explosions(float delta_time) { const auto& lletra = lletres_[index_actual]; debris_manager_->explotar( - lletra.forma, // Forma a explotar - lletra.posicio, // Posició - 0.0f, // Angle (sense rotació) - ESCALA_FINAL, // Escala (lletres a escala final) - VELOCITAT_EXPLOSIO, // Velocitat base - 1.0f, // Brightness màxim (per defecte) - {0.0f, 0.0f} // Sense velocitat (per defecte) + lletra.forma, // Forma a explotar + lletra.posicio, // Posició + 0.0f, // Angle (sense rotació) + ESCALA_FINAL, // Escala (lletres a escala final) + VELOCITAT_EXPLOSIO, // Velocitat base + 1.0f, // Brightness màxim (per defecte) + {0.0f, 0.0f} // Sense velocitat (per defecte) ); std::cout << "[EscenaLogo] Explota lletra " << lletra_explosio_index_ << "\n"; diff --git a/source/game/escenes/escena_logo.hpp b/source/game/escenes/escena_logo.hpp index 18488b5..0b2ed47 100644 --- a/source/game/escenes/escena_logo.hpp +++ b/source/game/escenes/escena_logo.hpp @@ -10,18 +10,18 @@ #include #include -#include "game/effects/debris_manager.hpp" #include "core/defaults.hpp" #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/types.hpp" +#include "game/effects/debris_manager.hpp" class EscenaLogo { public: explicit EscenaLogo(SDLManager& sdl, GestorEscenes::ContextEscenes& context); - ~EscenaLogo(); // Destructor per aturar sons + ~EscenaLogo(); // Destructor per aturar sons void executar(); // Bucle principal de l'escena private: diff --git a/source/game/escenes/escena_titol.cpp b/source/game/escenes/escena_titol.cpp index 5fd92b4..b7f42ef 100644 --- a/source/game/escenes/escena_titol.cpp +++ b/source/game/escenes/escena_titol.cpp @@ -140,10 +140,10 @@ void EscenaTitol::inicialitzar_titol() { float ancho_sin_escalar = max_x - min_x; float altura_sin_escalar = max_y - min_y; - // Escalar ancho, altura i offset amb ESCALA_TITULO - float ancho = ancho_sin_escalar * ESCALA_TITULO; - float altura = altura_sin_escalar * ESCALA_TITULO; - float offset_centre = (forma->get_centre().x - min_x) * ESCALA_TITULO; + // 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; lletres_orni_.push_back({forma, {0.0f, 0.0f}, ancho, altura, offset_centre}); @@ -159,7 +159,7 @@ void EscenaTitol::inicialitzar_titol() { for (auto& lletra : lletres_orni_) { lletra.posicio.x = x_actual + lletra.offset_centre; - lletra.posicio.y = Y_ORNI; + lletra.posicio.y = Defaults::Game::HEIGHT * Defaults::Title::Layout::LOGO_POS; x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES; } @@ -169,7 +169,9 @@ void EscenaTitol::inicialitzar_titol() { // === Calcular posició Y dinàmica per "ATTACK!" === // Totes les lletres ORNI tenen la mateixa altura, utilitzem la primera float altura_orni = lletres_orni_.empty() ? 50.0f : lletres_orni_[0].altura; - y_attack_dinamica_ = Y_ORNI + altura_orni + SEPARACION_LINEAS; + float y_orni = Defaults::Game::HEIGHT * Defaults::Title::Layout::LOGO_POS; + 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 << " px, Y_ATTACK dinàmica: " << y_attack_dinamica_ << " px\n"; @@ -212,10 +214,10 @@ void EscenaTitol::inicialitzar_titol() { float ancho_sin_escalar = max_x - min_x; float altura_sin_escalar = max_y - min_y; - // Escalar ancho, altura i offset amb ESCALA_TITULO - float ancho = ancho_sin_escalar * ESCALA_TITULO; - float altura = altura_sin_escalar * ESCALA_TITULO; - float offset_centre = (forma->get_centre().x - min_x) * ESCALA_TITULO; + // 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; lletres_attack_.push_back({forma, {0.0f, 0.0f}, ancho, altura, offset_centre}); @@ -326,9 +328,9 @@ void EscenaTitol::actualitzar(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_ == EstatTitol::STARFIELD || + estat_actual_ == EstatTitol::MAIN || + estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE)) { ship_animator_->actualitzar(delta_time); } @@ -346,7 +348,7 @@ void EscenaTitol::actualitzar(float delta_time) { // Transició a STARFIELD quan el fade es completa if (temps_acumulat_ >= DURACIO_FADE_IN) { estat_actual_ = EstatTitol::STARFIELD; - temps_acumulat_ = 0.0f; // Reset timer per al següent estat + temps_acumulat_ = 0.0f; // Reset timer per al següent estat starfield_->set_brightness(BRIGHTNESS_STARFIELD); // Assegurar valor final } break; @@ -538,9 +540,9 @@ void EscenaTitol::dibuixar() { // 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_ == EstatTitol::STARFIELD || + estat_actual_ == EstatTitol::MAIN || + estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE)) { ship_animator_->dibuixar(); } @@ -580,7 +582,7 @@ void EscenaTitol::dibuixar() { lletres_orni_[i].forma, pos_shadow, 0.0f, - ESCALA_TITULO, + Defaults::Title::Layout::LOGO_SCALE, true, 1.0f, // progress = 1.0 (totalment visible) SHADOW_BRIGHTNESS // brightness = 0.4 (brillantor reduïda) @@ -598,7 +600,7 @@ void EscenaTitol::dibuixar() { lletres_attack_[i].forma, pos_shadow, 0.0f, - ESCALA_TITULO, + Defaults::Title::Layout::LOGO_SCALE, true, 1.0f, // progress = 1.0 (totalment visible) SHADOW_BRIGHTNESS); @@ -614,7 +616,7 @@ void EscenaTitol::dibuixar() { lletra.forma, lletra.posicio, 0.0f, - ESCALA_TITULO, + Defaults::Title::Layout::LOGO_SCALE, true, 1.0f // Brillantor completa ); @@ -627,7 +629,7 @@ void EscenaTitol::dibuixar() { lletra.forma, lletra.posicio, 0.0f, - ESCALA_TITULO, + Defaults::Title::Layout::LOGO_SCALE, true, 1.0f // Brillantor completa ); @@ -637,7 +639,7 @@ void EscenaTitol::dibuixar() { // En estat MAIN: sempre visible // En estat TRANSITION: parpellejant (blink amb sinusoide) - const float spacing = 2.0f; // Espai entre caràcters (usat també per copyright) + const float spacing = Defaults::Title::Layout::TEXT_SPACING; bool mostrar_text = true; if (estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE) { @@ -648,34 +650,46 @@ void EscenaTitol::dibuixar() { if (mostrar_text) { const std::string main_text = "PRESS START TO PLAY"; - const float escala_main = 1.0f; + const float escala_main = Defaults::Title::Layout::PRESS_START_SCALE; float text_width = text_.get_text_width(main_text, escala_main, spacing); float x_center = (Defaults::Game::WIDTH - text_width) / 2.0f; - float altura_attack = lletres_attack_.empty() ? 50.0f : lletres_attack_[0].altura; - float y_center = y_attack_dinamica_ + altura_attack + 70.0f; + float y_center = Defaults::Game::HEIGHT * Defaults::Title::Layout::PRESS_START_POS; text_.render(main_text, Punt{x_center, y_center}, escala_main, spacing); } - // === Copyright a la part inferior (centrat horitzontalment) === - // Convert to uppercase since VectorText only supports A-Z - std::string copyright = Project::COPYRIGHT; - for (char& c : copyright) { - if (c >= 'a' && c <= 'z') { - c = c - 32; // Convert to uppercase - } + // === Copyright a la part inferior (centrat horitzontalment, dues línies) === + const float escala_copy = Defaults::Title::Layout::COPYRIGHT_SCALE; + const float copy_height = text_.get_text_height(escala_copy); + const float line_spacing = Defaults::Game::HEIGHT * Defaults::Title::Layout::COPYRIGHT_LINE_SPACING; + + // Línea 1: Original (© 1999 Visente i Sergi) + std::string copyright_original = Project::COPYRIGHT_ORIGINAL; + for (char& c : copyright_original) { + if (c >= 'a' && c <= 'z') c = c - 32; // Uppercase } - const float escala_copy = 0.6f; - float copy_width = text_.get_text_width(copyright, escala_copy, spacing); - float copy_height = text_.get_text_height(escala_copy); + // Línea 2: Port (© 2025 jaildesigner) + std::string copyright_port = Project::COPYRIGHT_PORT; + for (char& c : copyright_port) { + if (c >= 'a' && c <= 'z') c = c - 32; // Uppercase + } - float x_copy = (Defaults::Game::WIDTH - copy_width) / 2.0f; - float y_copy = Defaults::Game::HEIGHT - copy_height - 20.0f; // 20px des del fons + // Calcular posicions (anclatge des del top + separació) + 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 - text_.render(copyright, Punt{x_copy, y_copy}, escala_copy, spacing); + // Renderitzar línea 1 (original) + float width_line1 = text_.get_text_width(copyright_original, escala_copy, spacing); + float x_line1 = (Defaults::Game::WIDTH - width_line1) / 2.0f; + text_.render(copyright_original, Punt{x_line1, y_line1}, escala_copy, spacing); + + // Renderitzar línea 2 (port) + float width_line2 = text_.get_text_width(copyright_port, escala_copy, spacing); + float x_line2 = (Defaults::Game::WIDTH - width_line2) / 2.0f; + text_.render(copyright_port, Punt{x_line2, y_line2}, escala_copy, spacing); } } diff --git a/source/game/escenes/escena_titol.hpp b/source/game/escenes/escena_titol.hpp index f55b146..3d2c6b5 100644 --- a/source/game/escenes/escena_titol.hpp +++ b/source/game/escenes/escena_titol.hpp @@ -23,8 +23,7 @@ // Botones para INICIAR PARTIDA desde MAIN (solo START) static constexpr std::array START_GAME_BUTTONS = { - InputAction::START -}; + InputAction::START}; class EscenaTitol { public: @@ -53,12 +52,12 @@ class EscenaTitol { SDLManager& sdl_; GestorEscenes::ContextEscenes& context_; - GameConfig::ConfigPartida config_partida_; // Configuració de jugadors actius + GameConfig::ConfigPartida config_partida_; // Configuració de jugadors actius Graphics::VectorText text_; // Sistema de text vectorial - std::unique_ptr starfield_; // Camp d'estrelles de fons + 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 - float temps_acumulat_; // Temps acumulat per l'estat INIT + EstatTitol estat_actual_; // Estat actual de la màquina + float temps_acumulat_; // Temps acumulat per l'estat INIT // Lletres del títol "ORNI ATTACK!" std::vector lletres_orni_; // Lletres de "ORNI" (línia 1) @@ -80,10 +79,7 @@ class EscenaTitol { 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_TRANSITION = 2.5f; // Duració de la transició (1.5 segons) - static constexpr float ESCALA_TITULO = 0.6f; // Escala per les lletres del títol (50%) static constexpr float ESPAI_ENTRE_LLETRES = 10.0f; // Espai entre lletres - static constexpr float Y_ORNI = 150.0f; // Posició Y de "ORNI" - static constexpr float SEPARACION_LINEAS = 10.0f; // Separació entre "ORNI" i "ATTACK!" (0.0f = pegades) 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 diff --git a/source/game/options.cpp b/source/game/options.cpp index bb2b199..40b0127 100644 --- a/source/game/options.cpp +++ b/source/game/options.cpp @@ -15,107 +15,169 @@ namespace Options { // Mapa de SDL_Scancode a string static const std::unordered_map SCANCODE_TO_STRING = { - {SDL_SCANCODE_A, "A"}, {SDL_SCANCODE_B, "B"}, {SDL_SCANCODE_C, "C"}, {SDL_SCANCODE_D, "D"}, - {SDL_SCANCODE_E, "E"}, {SDL_SCANCODE_F, "F"}, {SDL_SCANCODE_G, "G"}, {SDL_SCANCODE_H, "H"}, - {SDL_SCANCODE_I, "I"}, {SDL_SCANCODE_J, "J"}, {SDL_SCANCODE_K, "K"}, {SDL_SCANCODE_L, "L"}, - {SDL_SCANCODE_M, "M"}, {SDL_SCANCODE_N, "N"}, {SDL_SCANCODE_O, "O"}, {SDL_SCANCODE_P, "P"}, - {SDL_SCANCODE_Q, "Q"}, {SDL_SCANCODE_R, "R"}, {SDL_SCANCODE_S, "S"}, {SDL_SCANCODE_T, "T"}, - {SDL_SCANCODE_U, "U"}, {SDL_SCANCODE_V, "V"}, {SDL_SCANCODE_W, "W"}, {SDL_SCANCODE_X, "X"}, - {SDL_SCANCODE_Y, "Y"}, {SDL_SCANCODE_Z, "Z"}, - {SDL_SCANCODE_1, "1"}, {SDL_SCANCODE_2, "2"}, {SDL_SCANCODE_3, "3"}, {SDL_SCANCODE_4, "4"}, - {SDL_SCANCODE_5, "5"}, {SDL_SCANCODE_6, "6"}, {SDL_SCANCODE_7, "7"}, {SDL_SCANCODE_8, "8"}, - {SDL_SCANCODE_9, "9"}, {SDL_SCANCODE_0, "0"}, - {SDL_SCANCODE_RETURN, "RETURN"}, {SDL_SCANCODE_ESCAPE, "ESCAPE"}, - {SDL_SCANCODE_BACKSPACE, "BACKSPACE"}, {SDL_SCANCODE_TAB, "TAB"}, - {SDL_SCANCODE_SPACE, "SPACE"}, - {SDL_SCANCODE_UP, "UP"}, {SDL_SCANCODE_DOWN, "DOWN"}, - {SDL_SCANCODE_LEFT, "LEFT"}, {SDL_SCANCODE_RIGHT, "RIGHT"}, - {SDL_SCANCODE_LSHIFT, "LSHIFT"}, {SDL_SCANCODE_RSHIFT, "RSHIFT"}, - {SDL_SCANCODE_LCTRL, "LCTRL"}, {SDL_SCANCODE_RCTRL, "RCTRL"}, - {SDL_SCANCODE_LALT, "LALT"}, {SDL_SCANCODE_RALT, "RALT"} -}; + {SDL_SCANCODE_A, "A"}, + {SDL_SCANCODE_B, "B"}, + {SDL_SCANCODE_C, "C"}, + {SDL_SCANCODE_D, "D"}, + {SDL_SCANCODE_E, "E"}, + {SDL_SCANCODE_F, "F"}, + {SDL_SCANCODE_G, "G"}, + {SDL_SCANCODE_H, "H"}, + {SDL_SCANCODE_I, "I"}, + {SDL_SCANCODE_J, "J"}, + {SDL_SCANCODE_K, "K"}, + {SDL_SCANCODE_L, "L"}, + {SDL_SCANCODE_M, "M"}, + {SDL_SCANCODE_N, "N"}, + {SDL_SCANCODE_O, "O"}, + {SDL_SCANCODE_P, "P"}, + {SDL_SCANCODE_Q, "Q"}, + {SDL_SCANCODE_R, "R"}, + {SDL_SCANCODE_S, "S"}, + {SDL_SCANCODE_T, "T"}, + {SDL_SCANCODE_U, "U"}, + {SDL_SCANCODE_V, "V"}, + {SDL_SCANCODE_W, "W"}, + {SDL_SCANCODE_X, "X"}, + {SDL_SCANCODE_Y, "Y"}, + {SDL_SCANCODE_Z, "Z"}, + {SDL_SCANCODE_1, "1"}, + {SDL_SCANCODE_2, "2"}, + {SDL_SCANCODE_3, "3"}, + {SDL_SCANCODE_4, "4"}, + {SDL_SCANCODE_5, "5"}, + {SDL_SCANCODE_6, "6"}, + {SDL_SCANCODE_7, "7"}, + {SDL_SCANCODE_8, "8"}, + {SDL_SCANCODE_9, "9"}, + {SDL_SCANCODE_0, "0"}, + {SDL_SCANCODE_RETURN, "RETURN"}, + {SDL_SCANCODE_ESCAPE, "ESCAPE"}, + {SDL_SCANCODE_BACKSPACE, "BACKSPACE"}, + {SDL_SCANCODE_TAB, "TAB"}, + {SDL_SCANCODE_SPACE, "SPACE"}, + {SDL_SCANCODE_UP, "UP"}, + {SDL_SCANCODE_DOWN, "DOWN"}, + {SDL_SCANCODE_LEFT, "LEFT"}, + {SDL_SCANCODE_RIGHT, "RIGHT"}, + {SDL_SCANCODE_LSHIFT, "LSHIFT"}, + {SDL_SCANCODE_RSHIFT, "RSHIFT"}, + {SDL_SCANCODE_LCTRL, "LCTRL"}, + {SDL_SCANCODE_RCTRL, "RCTRL"}, + {SDL_SCANCODE_LALT, "LALT"}, + {SDL_SCANCODE_RALT, "RALT"}}; // Mapa invers: string a SDL_Scancode static const std::unordered_map STRING_TO_SCANCODE = { - {"A", SDL_SCANCODE_A}, {"B", SDL_SCANCODE_B}, {"C", SDL_SCANCODE_C}, {"D", SDL_SCANCODE_D}, - {"E", SDL_SCANCODE_E}, {"F", SDL_SCANCODE_F}, {"G", SDL_SCANCODE_G}, {"H", SDL_SCANCODE_H}, - {"I", SDL_SCANCODE_I}, {"J", SDL_SCANCODE_J}, {"K", SDL_SCANCODE_K}, {"L", SDL_SCANCODE_L}, - {"M", SDL_SCANCODE_M}, {"N", SDL_SCANCODE_N}, {"O", SDL_SCANCODE_O}, {"P", SDL_SCANCODE_P}, - {"Q", SDL_SCANCODE_Q}, {"R", SDL_SCANCODE_R}, {"S", SDL_SCANCODE_S}, {"T", SDL_SCANCODE_T}, - {"U", SDL_SCANCODE_U}, {"V", SDL_SCANCODE_V}, {"W", SDL_SCANCODE_W}, {"X", SDL_SCANCODE_X}, - {"Y", SDL_SCANCODE_Y}, {"Z", SDL_SCANCODE_Z}, - {"1", SDL_SCANCODE_1}, {"2", SDL_SCANCODE_2}, {"3", SDL_SCANCODE_3}, {"4", SDL_SCANCODE_4}, - {"5", SDL_SCANCODE_5}, {"6", SDL_SCANCODE_6}, {"7", SDL_SCANCODE_7}, {"8", SDL_SCANCODE_8}, - {"9", SDL_SCANCODE_9}, {"0", SDL_SCANCODE_0}, - {"RETURN", SDL_SCANCODE_RETURN}, {"ESCAPE", SDL_SCANCODE_ESCAPE}, - {"BACKSPACE", SDL_SCANCODE_BACKSPACE}, {"TAB", SDL_SCANCODE_TAB}, - {"SPACE", SDL_SCANCODE_SPACE}, - {"UP", SDL_SCANCODE_UP}, {"DOWN", SDL_SCANCODE_DOWN}, - {"LEFT", SDL_SCANCODE_LEFT}, {"RIGHT", SDL_SCANCODE_RIGHT}, - {"LSHIFT", SDL_SCANCODE_LSHIFT}, {"RSHIFT", SDL_SCANCODE_RSHIFT}, - {"LCTRL", SDL_SCANCODE_LCTRL}, {"RCTRL", SDL_SCANCODE_RCTRL}, - {"LALT", SDL_SCANCODE_LALT}, {"RALT", SDL_SCANCODE_RALT} -}; + {"A", SDL_SCANCODE_A}, + {"B", SDL_SCANCODE_B}, + {"C", SDL_SCANCODE_C}, + {"D", SDL_SCANCODE_D}, + {"E", SDL_SCANCODE_E}, + {"F", SDL_SCANCODE_F}, + {"G", SDL_SCANCODE_G}, + {"H", SDL_SCANCODE_H}, + {"I", SDL_SCANCODE_I}, + {"J", SDL_SCANCODE_J}, + {"K", SDL_SCANCODE_K}, + {"L", SDL_SCANCODE_L}, + {"M", SDL_SCANCODE_M}, + {"N", SDL_SCANCODE_N}, + {"O", SDL_SCANCODE_O}, + {"P", SDL_SCANCODE_P}, + {"Q", SDL_SCANCODE_Q}, + {"R", SDL_SCANCODE_R}, + {"S", SDL_SCANCODE_S}, + {"T", SDL_SCANCODE_T}, + {"U", SDL_SCANCODE_U}, + {"V", SDL_SCANCODE_V}, + {"W", SDL_SCANCODE_W}, + {"X", SDL_SCANCODE_X}, + {"Y", SDL_SCANCODE_Y}, + {"Z", SDL_SCANCODE_Z}, + {"1", SDL_SCANCODE_1}, + {"2", SDL_SCANCODE_2}, + {"3", SDL_SCANCODE_3}, + {"4", SDL_SCANCODE_4}, + {"5", SDL_SCANCODE_5}, + {"6", SDL_SCANCODE_6}, + {"7", SDL_SCANCODE_7}, + {"8", SDL_SCANCODE_8}, + {"9", SDL_SCANCODE_9}, + {"0", SDL_SCANCODE_0}, + {"RETURN", SDL_SCANCODE_RETURN}, + {"ESCAPE", SDL_SCANCODE_ESCAPE}, + {"BACKSPACE", SDL_SCANCODE_BACKSPACE}, + {"TAB", SDL_SCANCODE_TAB}, + {"SPACE", SDL_SCANCODE_SPACE}, + {"UP", SDL_SCANCODE_UP}, + {"DOWN", SDL_SCANCODE_DOWN}, + {"LEFT", SDL_SCANCODE_LEFT}, + {"RIGHT", SDL_SCANCODE_RIGHT}, + {"LSHIFT", SDL_SCANCODE_LSHIFT}, + {"RSHIFT", SDL_SCANCODE_RSHIFT}, + {"LCTRL", SDL_SCANCODE_LCTRL}, + {"RCTRL", SDL_SCANCODE_RCTRL}, + {"LALT", SDL_SCANCODE_LALT}, + {"RALT", SDL_SCANCODE_RALT}}; // Mapa de botó de gamepad (int) a string static const std::unordered_map BUTTON_TO_STRING = { - {SDL_GAMEPAD_BUTTON_SOUTH, "SOUTH"}, // A (Xbox), Cross (PS) - {SDL_GAMEPAD_BUTTON_EAST, "EAST"}, // B (Xbox), Circle (PS) - {SDL_GAMEPAD_BUTTON_WEST, "WEST"}, // X (Xbox), Square (PS) - {SDL_GAMEPAD_BUTTON_NORTH, "NORTH"}, // Y (Xbox), Triangle (PS) - {SDL_GAMEPAD_BUTTON_BACK, "BACK"}, - {SDL_GAMEPAD_BUTTON_START, "START"}, - {SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, "LEFT_SHOULDER"}, - {SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, "RIGHT_SHOULDER"}, - {SDL_GAMEPAD_BUTTON_DPAD_UP, "DPAD_UP"}, - {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 + {SDL_GAMEPAD_BUTTON_SOUTH, "SOUTH"}, // A (Xbox), Cross (PS) + {SDL_GAMEPAD_BUTTON_EAST, "EAST"}, // B (Xbox), Circle (PS) + {SDL_GAMEPAD_BUTTON_WEST, "WEST"}, // X (Xbox), Square (PS) + {SDL_GAMEPAD_BUTTON_NORTH, "NORTH"}, // Y (Xbox), Triangle (PS) + {SDL_GAMEPAD_BUTTON_BACK, "BACK"}, + {SDL_GAMEPAD_BUTTON_START, "START"}, + {SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, "LEFT_SHOULDER"}, + {SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, "RIGHT_SHOULDER"}, + {SDL_GAMEPAD_BUTTON_DPAD_UP, "DPAD_UP"}, + {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 }; // Mapa invers: string a botó de gamepad static const std::unordered_map STRING_TO_BUTTON = { - {"SOUTH", SDL_GAMEPAD_BUTTON_SOUTH}, - {"EAST", SDL_GAMEPAD_BUTTON_EAST}, - {"WEST", SDL_GAMEPAD_BUTTON_WEST}, - {"NORTH", SDL_GAMEPAD_BUTTON_NORTH}, - {"BACK", SDL_GAMEPAD_BUTTON_BACK}, - {"START", SDL_GAMEPAD_BUTTON_START}, - {"LEFT_SHOULDER", SDL_GAMEPAD_BUTTON_LEFT_SHOULDER}, - {"RIGHT_SHOULDER", SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER}, - {"DPAD_UP", SDL_GAMEPAD_BUTTON_DPAD_UP}, - {"DPAD_DOWN", SDL_GAMEPAD_BUTTON_DPAD_DOWN}, - {"DPAD_LEFT", SDL_GAMEPAD_BUTTON_DPAD_LEFT}, - {"DPAD_RIGHT", SDL_GAMEPAD_BUTTON_DPAD_RIGHT}, - {"L2_AS_BUTTON", 100}, - {"R2_AS_BUTTON", 101} -}; + {"SOUTH", SDL_GAMEPAD_BUTTON_SOUTH}, + {"EAST", SDL_GAMEPAD_BUTTON_EAST}, + {"WEST", SDL_GAMEPAD_BUTTON_WEST}, + {"NORTH", SDL_GAMEPAD_BUTTON_NORTH}, + {"BACK", SDL_GAMEPAD_BUTTON_BACK}, + {"START", SDL_GAMEPAD_BUTTON_START}, + {"LEFT_SHOULDER", SDL_GAMEPAD_BUTTON_LEFT_SHOULDER}, + {"RIGHT_SHOULDER", SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER}, + {"DPAD_UP", SDL_GAMEPAD_BUTTON_DPAD_UP}, + {"DPAD_DOWN", SDL_GAMEPAD_BUTTON_DPAD_DOWN}, + {"DPAD_LEFT", SDL_GAMEPAD_BUTTON_DPAD_LEFT}, + {"DPAD_RIGHT", SDL_GAMEPAD_BUTTON_DPAD_RIGHT}, + {"L2_AS_BUTTON", 100}, + {"R2_AS_BUTTON", 101}}; static auto scancodeToString(SDL_Scancode code) -> std::string { - auto it = SCANCODE_TO_STRING.find(code); - return (it != SCANCODE_TO_STRING.end()) ? it->second : "UNKNOWN"; + auto it = SCANCODE_TO_STRING.find(code); + return (it != SCANCODE_TO_STRING.end()) ? it->second : "UNKNOWN"; } static auto stringToScancode(const std::string& str) -> SDL_Scancode { - auto it = STRING_TO_SCANCODE.find(str); - return (it != STRING_TO_SCANCODE.end()) ? it->second : SDL_SCANCODE_UNKNOWN; + auto it = STRING_TO_SCANCODE.find(str); + return (it != STRING_TO_SCANCODE.end()) ? it->second : SDL_SCANCODE_UNKNOWN; } static auto buttonToString(int button) -> std::string { - auto it = BUTTON_TO_STRING.find(button); - return (it != BUTTON_TO_STRING.end()) ? it->second : "UNKNOWN"; + auto it = BUTTON_TO_STRING.find(button); + return (it != BUTTON_TO_STRING.end()) ? it->second : "UNKNOWN"; } static auto stringToButton(const std::string& str) -> int { - auto it = STRING_TO_BUTTON.find(str); - return (it != STRING_TO_BUTTON.end()) ? it->second : SDL_GAMEPAD_BUTTON_INVALID; + auto it = STRING_TO_BUTTON.find(str); + return (it != STRING_TO_BUTTON.end()) ? it->second : SDL_GAMEPAD_BUTTON_INVALID; } // ========== FI FUNCIONS AUXILIARS ========== - // Inicialitzar opcions amb valors per defecte de Defaults:: void init() { #ifdef _DEBUG diff --git a/source/game/options.hpp b/source/game/options.hpp index a21d2c1..3d74cd7 100644 --- a/source/game/options.hpp +++ b/source/game/options.hpp @@ -63,8 +63,8 @@ struct KeyboardControls { struct GamepadControls { int button_left{SDL_GAMEPAD_BUTTON_DPAD_LEFT}; int button_right{SDL_GAMEPAD_BUTTON_DPAD_RIGHT}; - int button_thrust{SDL_GAMEPAD_BUTTON_WEST}; // X button - int button_shoot{SDL_GAMEPAD_BUTTON_SOUTH}; // A button + int button_thrust{SDL_GAMEPAD_BUTTON_WEST}; // X button + int button_shoot{SDL_GAMEPAD_BUTTON_SOUTH}; // A button }; struct PlayerControls { @@ -85,23 +85,23 @@ inline Audio audio{}; // Controles per jugador inline PlayerControls player1{ - .keyboard = - {.key_left = SDL_SCANCODE_LEFT, - .key_right = SDL_SCANCODE_RIGHT, - .key_thrust = SDL_SCANCODE_UP, - .key_shoot = SDL_SCANCODE_SPACE, - .key_start = SDL_SCANCODE_1}, - .gamepad_name = "" // Primer gamepad disponible + .keyboard = + {.key_left = SDL_SCANCODE_LEFT, + .key_right = SDL_SCANCODE_RIGHT, + .key_thrust = SDL_SCANCODE_UP, + .key_shoot = SDL_SCANCODE_SPACE, + .key_start = SDL_SCANCODE_1}, + .gamepad_name = "" // Primer gamepad disponible }; inline PlayerControls player2{ - .keyboard = - {.key_left = SDL_SCANCODE_A, - .key_right = SDL_SCANCODE_D, - .key_thrust = SDL_SCANCODE_W, - .key_shoot = SDL_SCANCODE_LSHIFT, - .key_start = SDL_SCANCODE_2}, - .gamepad_name = "" // Segon gamepad disponible + .keyboard = + {.key_left = SDL_SCANCODE_A, + .key_right = SDL_SCANCODE_D, + .key_thrust = SDL_SCANCODE_W, + .key_shoot = SDL_SCANCODE_LSHIFT, + .key_start = SDL_SCANCODE_2}, + .gamepad_name = "" // Segon gamepad disponible }; // Per compatibilitat amb pollo (no utilitzat en orni, però necessari per Input) diff --git a/source/game/stage_system/spawn_controller.cpp b/source/game/stage_system/spawn_controller.cpp index cce8ede..dcacd53 100644 --- a/source/game/stage_system/spawn_controller.cpp +++ b/source/game/stage_system/spawn_controller.cpp @@ -9,7 +9,10 @@ namespace StageSystem { SpawnController::SpawnController() - : config_(nullptr), temps_transcorregut_(0.0f), index_spawn_actual_(0), ship_position_(nullptr) {} + : config_(nullptr), + temps_transcorregut_(0.0f), + index_spawn_actual_(0), + ship_position_(nullptr) {} void SpawnController::configurar(const ConfigStage* config) { config_ = config; @@ -114,7 +117,7 @@ void SpawnController::generar_spawn_events() { for (uint8_t i = 0; i < config_->total_enemics; i++) { float spawn_time = config_->config_spawn.delay_inicial + - (i * config_->config_spawn.interval_spawn); + (i * config_->config_spawn.interval_spawn); TipusEnemic tipus = seleccionar_tipus_aleatori(); diff --git a/source/game/stage_system/spawn_controller.hpp b/source/game/stage_system/spawn_controller.hpp index 055d5be..da4e3f1 100644 --- a/source/game/stage_system/spawn_controller.hpp +++ b/source/game/stage_system/spawn_controller.hpp @@ -15,44 +15,44 @@ namespace StageSystem { // Informació de spawn planificat struct SpawnEvent { - float temps_spawn; // Temps absolut (segons) per spawnejar - TipusEnemic tipus; // Tipus d'enemic - bool spawnejat; // Ja s'ha processat? + float temps_spawn; // Temps absolut (segons) per spawnejar + TipusEnemic tipus; // Tipus d'enemic + bool spawnejat; // Ja s'ha processat? }; class SpawnController { - public: - SpawnController(); + public: + SpawnController(); - // Configuration - void configurar(const ConfigStage* config); // Set stage config - void iniciar(); // Generate spawn schedule - void reset(); // Clear all pending spawns + // Configuration + void configurar(const ConfigStage* config); // Set stage config + void iniciar(); // Generate spawn schedule + void reset(); // Clear all pending spawns - // Update - void actualitzar(float delta_time, std::array& orni_array, bool pausar = false); + // Update + void actualitzar(float delta_time, std::array& orni_array, bool pausar = false); - // Status queries - bool tots_enemics_spawnejats() const; - bool tots_enemics_destruits(const std::array& orni_array) const; - uint8_t get_enemics_vius(const std::array& orni_array) const; - uint8_t get_enemics_spawnejats() const; + // Status queries + bool tots_enemics_spawnejats() const; + bool tots_enemics_destruits(const std::array& orni_array) const; + uint8_t get_enemics_vius(const std::array& orni_array) const; + 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; } + // [NEW] Set ship position reference for safe spawn + void set_ship_position(const Punt* ship_pos) { ship_position_ = ship_pos; } - private: - const ConfigStage* 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 + private: + const ConfigStage* 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 - // Spawn generation - void generar_spawn_events(); - TipusEnemic seleccionar_tipus_aleatori() const; - void spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Punt* ship_pos = nullptr); - void aplicar_multiplicadors(Enemic& enemic) const; - const Punt* ship_position_; // [NEW] Non-owning pointer to ship position + // Spawn generation + void generar_spawn_events(); + TipusEnemic seleccionar_tipus_aleatori() const; + void spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Punt* ship_pos = nullptr); + void aplicar_multiplicadors(Enemic& enemic) const; + const Punt* ship_position_; // [NEW] Non-owning pointer to ship position }; } // namespace StageSystem diff --git a/source/game/stage_system/stage_config.hpp b/source/game/stage_system/stage_config.hpp index 3b514ae..f8bd760 100644 --- a/source/game/stage_system/stage_config.hpp +++ b/source/game/stage_system/stage_config.hpp @@ -19,82 +19,81 @@ enum class ModeSpawn { // Configuració de spawn struct ConfigSpawn { - ModeSpawn mode; - float delay_inicial; // Segons abans del primer spawn - float interval_spawn; // Segons entre spawns consecutius + ModeSpawn mode; + float delay_inicial; // Segons abans del primer spawn + float interval_spawn; // Segons entre spawns consecutius }; // Distribució de tipus d'enemics (percentatges) struct DistribucioEnemics { - uint8_t pentagon; // 0-100 - uint8_t quadrat; // 0-100 - uint8_t molinillo; // 0-100 - // Suma ha de ser 100, validat en StageLoader + uint8_t pentagon; // 0-100 + uint8_t quadrat; // 0-100 + uint8_t molinillo; // 0-100 + // Suma ha de ser 100, validat en StageLoader }; // Multiplicadors de dificultat struct MultiplicadorsDificultat { - float velocitat; // 0.5-2.0 típic - float rotacio; // 0.5-2.0 típic - float tracking_strength; // 0.0-1.5 (aplicat a Quadrat) + float velocitat; // 0.5-2.0 típic + float rotacio; // 0.5-2.0 típic + float tracking_strength; // 0.0-1.5 (aplicat a Quadrat) }; // Metadades del fitxer YAML struct MetadataStages { - std::string version; - uint8_t total_stages; - std::string descripcio; + std::string version; + uint8_t total_stages; + std::string descripcio; }; // Configuració completa d'un stage struct ConfigStage { - uint8_t stage_id; // 1-10 - uint8_t total_enemics; // 5-15 - ConfigSpawn config_spawn; - DistribucioEnemics distribucio; - MultiplicadorsDificultat multiplicadors; + uint8_t stage_id; // 1-10 + uint8_t total_enemics; // 5-15 + ConfigSpawn config_spawn; + DistribucioEnemics distribucio; + MultiplicadorsDificultat multiplicadors; - // Validació - bool es_valid() const { - return stage_id >= 1 && stage_id <= 255 && - total_enemics > 0 && total_enemics <= 15 && - distribucio.pentagon + distribucio.quadrat + distribucio.molinillo == 100; - } + // Validació + bool es_valid() const { + return stage_id >= 1 && stage_id <= 255 && + total_enemics > 0 && total_enemics <= 15 && + distribucio.pentagon + distribucio.quadrat + distribucio.molinillo == 100; + } }; // Configuració completa del sistema (carregada des de YAML) struct ConfigSistemaStages { - MetadataStages metadata; - std::vector stages; // Índex [0] = stage 1 + MetadataStages metadata; + std::vector stages; // Índex [0] = stage 1 - // Obtenir configuració d'un stage específic - const ConfigStage* obte_stage(uint8_t stage_id) const { - if (stage_id < 1 || stage_id > stages.size()) { - return nullptr; + // Obtenir configuració d'un stage específic + const ConfigStage* obte_stage(uint8_t stage_id) const { + if (stage_id < 1 || stage_id > stages.size()) { + return nullptr; + } + return &stages[stage_id - 1]; } - return &stages[stage_id - 1]; - } }; // Constants per missatges de transició namespace Constants { - // Pool de missatges per inici de level (selecció aleatòria) - inline constexpr std::array MISSATGES_LEVEL_START = { - "ORNI ALERT!", - "INCOMING ORNIS!", - "ROLLING THREAT!", - "ENEMY WAVE!", - "WAVE OF ORNIS DETECTED!", - "NEXT SWARM APPROACHING!", - "BRACE FOR THE NEXT WAVE!", - "ANOTHER ATTACK INCOMING!", - "SENSORS DETECT HOSTILE ORNIS...", - "UNIDENTIFIED ROLLING OBJECTS INBOUND!", - "ENEMY FORCES MOBILIZING!", - "PREPARE FOR IMPACT!" - }; +// Pool de missatges per inici de level (selecció aleatòria) +inline constexpr std::array MISSATGES_LEVEL_START = { + "ORNI ALERT!", + "INCOMING ORNIS!", + "ROLLING THREAT!", + "ENEMY WAVE!", + "WAVE OF ORNIS DETECTED!", + "NEXT SWARM APPROACHING!", + "BRACE FOR THE NEXT WAVE!", + "ANOTHER ATTACK INCOMING!", + "SENSORS DETECT HOSTILE ORNIS...", + "UNIDENTIFIED ROLLING OBJECTS INBOUND!", + "ENEMY FORCES MOBILIZING!", + "PREPARE FOR IMPACT!"}; - constexpr const char* MISSATGE_LEVEL_COMPLETED = "GOOD JOB COMMANDER!"; -} +constexpr const char* MISSATGE_LEVEL_COMPLETED = "GOOD JOB COMMANDER!"; +} // namespace Constants } // namespace StageSystem diff --git a/source/game/stage_system/stage_loader.cpp b/source/game/stage_system/stage_loader.cpp index f83b466..99f6dbe 100644 --- a/source/game/stage_system/stage_loader.cpp +++ b/source/game/stage_system/stage_loader.cpp @@ -3,13 +3,13 @@ #include "stage_loader.hpp" -#include "core/resources/resource_helper.hpp" -#include "external/fkyaml_node.hpp" - #include #include #include +#include "core/resources/resource_helper.hpp" +#include "external/fkyaml_node.hpp" + namespace StageSystem { std::unique_ptr StageLoader::carregar(const std::string& path) { @@ -88,8 +88,8 @@ bool StageLoader::parse_metadata(const fkyaml::node& yaml, MetadataStages& meta) meta.version = yaml["version"].get_value(); meta.total_stages = yaml["total_stages"].get_value(); meta.descripcio = yaml.contains("description") - ? yaml["description"].get_value() - : ""; + ? yaml["description"].get_value() + : ""; return true; } catch (const std::exception& e) { diff --git a/source/game/stage_system/stage_loader.hpp b/source/game/stage_system/stage_loader.hpp index 0b725af..61238a3 100644 --- a/source/game/stage_system/stage_loader.hpp +++ b/source/game/stage_system/stage_loader.hpp @@ -5,28 +5,29 @@ #include #include + #include "external/fkyaml_node.hpp" #include "stage_config.hpp" namespace StageSystem { class StageLoader { -public: - // Carregar configuració des de fitxer YAML - // Retorna nullptr si hi ha errors - static std::unique_ptr carregar(const std::string& path); + public: + // Carregar configuració des de fitxer YAML + // Retorna nullptr si hi ha errors + static std::unique_ptr carregar(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_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); + 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_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); + // Validació + static bool validar_config(const ConfigSistemaStages& config); }; } // namespace StageSystem diff --git a/source/game/stage_system/stage_manager.cpp b/source/game/stage_system/stage_manager.cpp index 800f744..aa4be38 100644 --- a/source/game/stage_system/stage_manager.cpp +++ b/source/game/stage_system/stage_manager.cpp @@ -57,8 +57,8 @@ void StageManager::stage_completat() { bool StageManager::tot_completat() const { return stage_actual_ >= config_->metadata.total_stages && - estat_ == EstatStage::LEVEL_COMPLETED && - timer_transicio_ <= 0.0f; + estat_ == EstatStage::LEVEL_COMPLETED && + timer_transicio_ <= 0.0f; } const ConfigStage* StageManager::get_config_actual() const { @@ -127,8 +127,8 @@ 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() // 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)delta_time; // Spawn controller is updated externally + (void)pausar_spawn; // Passed to spawn_controller_.actualitzar() 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 c1b76e3..05ffde8 100644 --- a/source/game/stage_system/stage_manager.hpp +++ b/source/game/stage_system/stage_manager.hpp @@ -13,51 +13,51 @@ namespace StageSystem { // Estats del stage system enum class EstatStage { - INIT_HUD, // Animació inicial del HUD (3s) - LEVEL_START, // Pantalla "ENEMY INCOMING" (3s) - PLAYING, // Gameplay normal - LEVEL_COMPLETED // Pantalla "GOOD JOB COMMANDER!" (3s) + INIT_HUD, // Animació inicial del HUD (3s) + LEVEL_START, // Pantalla "ENEMY INCOMING" (3s) + PLAYING, // Gameplay normal + LEVEL_COMPLETED // Pantalla "GOOD JOB COMMANDER!" (3s) }; class StageManager { - public: - explicit StageManager(const ConfigSistemaStages* config); + public: + explicit StageManager(const ConfigSistemaStages* config); - // Lifecycle - void inicialitzar(); // Reset to stage 1 - void actualitzar(float delta_time, bool pausar_spawn = false); + // Lifecycle + void inicialitzar(); // Reset to stage 1 + void actualitzar(float delta_time, bool pausar_spawn = false); - // Stage progression - void stage_completat(); // Call when all enemies destroyed - bool tot_completat() const; // All 10 stages done? + // Stage progression + void stage_completat(); // Call when all enemies destroyed + bool tot_completat() const; // All 10 stages done? - // Current state queries - EstatStage get_estat() const { return estat_; } - uint8_t get_stage_actual() const { return stage_actual_; } - const ConfigStage* get_config_actual() const; - float get_timer_transicio() const { return timer_transicio_; } - const std::string& get_missatge_level_start() const { return missatge_level_start_actual_; } + // Current state queries + EstatStage get_estat() const { return estat_; } + uint8_t get_stage_actual() const { return stage_actual_; } + const ConfigStage* get_config_actual() const; + float get_timer_transicio() const { return timer_transicio_; } + 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_; } - const SpawnController& get_spawn_controller() const { return spawn_controller_; } + // Spawn control (delegate to SpawnController) + SpawnController& get_spawn_controller() { return spawn_controller_; } + const SpawnController& get_spawn_controller() const { return spawn_controller_; } - private: - const ConfigSistemaStages* config_; // Non-owning pointer - SpawnController spawn_controller_; + private: + const ConfigSistemaStages* config_; // Non-owning pointer + SpawnController spawn_controller_; - EstatStage estat_; - uint8_t stage_actual_; // 1-10 - float timer_transicio_; // Timer for LEVEL_START/LEVEL_COMPLETED (3.0s → 0.0s) - std::string missatge_level_start_actual_; // Missatge seleccionat per al level actual + EstatStage estat_; + uint8_t stage_actual_; // 1-10 + float timer_transicio_; // Timer for LEVEL_START/LEVEL_COMPLETED (3.0s → 0.0s) + std::string missatge_level_start_actual_; // Missatge seleccionat per al level actual - // State transitions - 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_level_completed(float delta_time); - void carregar_stage(uint8_t stage_id); + // State transitions + 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_level_completed(float delta_time); + void carregar_stage(uint8_t stage_id); }; } // namespace StageSystem diff --git a/source/game/title/ship_animator.cpp b/source/game/title/ship_animator.cpp index 3272cf3..e47d13d 100644 --- a/source/game/title/ship_animator.cpp +++ b/source/game/title/ship_animator.cpp @@ -17,8 +17,8 @@ ShipAnimator::ShipAnimator(SDL_Renderer* renderer) void ShipAnimator::inicialitzar() { // Carregar formes de naus amb perspectiva pre-calculada - auto forma_p1 = Graphics::ShapeLoader::load("ship_p1.shp"); // Perspectiva esquerra - auto forma_p2 = Graphics::ShapeLoader::load("ship2_p2.shp"); // Perspectiva dreta + auto forma_p1 = Graphics::ShapeLoader::load("ship_p1.shp"); // Perspectiva esquerra + auto forma_p2 = Graphics::ShapeLoader::load("ship2_p2.shp"); // Perspectiva dreta // Configurar nau P1 naus_[0].jugador_id = 1; @@ -59,11 +59,11 @@ void ShipAnimator::dibuixar() const { renderer_, nau.forma, nau.posicio_actual, - 0.0f, // angle (rotació 2D no utilitzada) + 0.0f, // angle (rotació 2D no utilitzada) nau.escala_actual, - true, // dibuixar - 1.0f, // progress (sempre visible) - 1.0f // brightness (brillantor màxima) + true, // dibuixar + 1.0f, // progress (sempre visible) + 1.0f // brightness (brillantor màxima) ); } } @@ -227,7 +227,7 @@ void ShipAnimator::configurar_nau_p1(NauTitol& nau) { nau.temps_estat = 0.0f; // Posicions (clock 8, bottom-left) - nau.posicio_objectiu = {P1_TARGET_X, P1_TARGET_Y}; + nau.posicio_objectiu = {P1_TARGET_X(), P1_TARGET_Y()}; // Calcular posició inicial (fora de pantalla) nau.posicio_inicial = calcular_posicio_fora_pantalla(CLOCK_8_ANGLE); @@ -262,7 +262,7 @@ void ShipAnimator::configurar_nau_p2(NauTitol& nau) { nau.temps_estat = 0.0f; // Posicions (clock 4, bottom-right) - nau.posicio_objectiu = {P2_TARGET_X, P2_TARGET_Y}; + nau.posicio_objectiu = {P2_TARGET_X(), P2_TARGET_Y()}; // Calcular posició inicial (fora de pantalla) nau.posicio_inicial = calcular_posicio_fora_pantalla(CLOCK_4_ANGLE); @@ -293,7 +293,8 @@ Punt 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 (+ ENTRY_OFFSET) + // Calcular posició en direcció radial des del centre, però 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; float x = Defaults::Game::WIDTH / 2.0f + extended_radius * std::cos(angle_rellotge); diff --git a/source/game/title/ship_animator.hpp b/source/game/title/ship_animator.hpp index c0652c2..b3fa5b7 100644 --- a/source/game/title/ship_animator.hpp +++ b/source/game/title/ship_animator.hpp @@ -23,74 +23,74 @@ enum class EstatNau { // Dades d'una nau individual al títol struct NauTitol { - // Identificació - int jugador_id; // 1 o 2 + // Identificació + int jugador_id; // 1 o 2 - // Estat - EstatNau estat; - float temps_estat; // Temps acumulat en l'estat actual + // Estat + EstatNau estat; + 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 + // 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 - // 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 + // 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 - // Flotació - float fase_oscilacio; // Acumulador de fase per moviment sinusoïdal + // Flotació + float fase_oscilacio; // 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'entrada + float entry_delay; // Delay abans d'entrar (0.0 per P1, 0.5 per P2) - // Paràmetres d'oscil·lació per nau - float amplitude_x; - float amplitude_y; - float frequency_x; - float frequency_y; + // Paràmetres d'oscil·lació per nau + float amplitude_x; + float amplitude_y; + float frequency_x; + float frequency_y; - // Forma - std::shared_ptr forma; + // Forma + std::shared_ptr forma; - // Visibilitat - bool visible; + // Visibilitat + bool visible; }; // Gestor d'animació de naus per a l'escena de títol class ShipAnimator { -public: - explicit ShipAnimator(SDL_Renderer* renderer); + public: + explicit ShipAnimator(SDL_Renderer* renderer); - // Cicle de vida - void inicialitzar(); - void actualitzar(float delta_time); - void dibuixar() const; + // Cicle de vida + void inicialitzar(); + void actualitzar(float delta_time); + void dibuixar() const; - // Control d'estat (cridat per EscenaTitol) - 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) + // Control d'estat (cridat per EscenaTitol) + 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) - // Control de visibilitat - void set_visible(bool visible); - bool is_animation_complete() const; + // Control de visibilitat + void set_visible(bool visible); + bool is_animation_complete() const; -private: - SDL_Renderer* renderer_; - std::array naus_; // Naus P1 i P2 + private: + SDL_Renderer* renderer_; + std::array naus_; // 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); + // 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); - // Configuració - void configurar_nau_p1(NauTitol& nau); - void configurar_nau_p2(NauTitol& nau); - Punt calcular_posicio_fora_pantalla(float angle_rellotge) const; + // Configuració + void configurar_nau_p1(NauTitol& nau); + void configurar_nau_p2(NauTitol& nau); + Punt calcular_posicio_fora_pantalla(float angle_rellotge) const; }; } // namespace Title diff --git a/source/project.h.in b/source/project.h.in index 34941db..a336301 100644 --- a/source/project.h.in +++ b/source/project.h.in @@ -5,5 +5,7 @@ constexpr const char* NAME = "@PROJECT_NAME@"; constexpr const char* LONG_NAME = "@PROJECT_LONG_NAME@"; constexpr const char* VERSION = "@PROJECT_VERSION@"; constexpr const char* COPYRIGHT = "@PROJECT_COPYRIGHT@"; +constexpr const char* COPYRIGHT_ORIGINAL = "@PROJECT_COPYRIGHT_ORIGINAL@"; +constexpr const char* COPYRIGHT_PORT = "@PROJECT_COPYRIGHT_PORT@"; constexpr const char* GIT_HASH = "@GIT_HASH@"; } // namespace Project