diff --git a/source/core/system/context_escenes.hpp b/source/core/system/context_escenes.hpp deleted file mode 100644 index 7ce2f90..0000000 --- a/source/core/system/context_escenes.hpp +++ /dev/null @@ -1,81 +0,0 @@ -// context_escenes.hpp - Sistema de gestió d'escenes i context de transicions -// © 2025 Port a C++20 - -#pragma once - -#include "core/system/game_config.hpp" - -namespace GestorEscenes { - -// Context de transició entre escenes -// Conté l'escena destinació i opcions específiques per aquella escena -class ContextEscenes { - public: - // Tipus d'escena del joc - enum class Escena { - LOGO, // Pantalla d'inici (logo JAILGAMES) - TITOL, // Pantalla de títol amb menú - JOC, // Joc principal (Asteroids) - EIXIR // Sortir del programa - }; - - // Opcions específiques per a cada escena - enum class Opcio { - NONE, // Sense opcions especials (comportament per defecte) - JUMP_TO_TITLE_MAIN, // TITOL: Saltar directament a MAIN (starfield instantani) - // MODE_DEMO, // JOC: Mode demostració amb IA (futur) - }; - - // Constructor inicial amb escena LOGO i sense opcions - ContextEscenes() = default; - - // Canviar escena amb opció específica - void canviar_escena(Escena nova_escena, Opcio opcio = Opcio::NONE) { - escena_desti_ = nova_escena; - opcio_ = opcio; - } - - // Consultar escena destinació - [[nodiscard]] auto escena_desti() const -> Escena { - return escena_desti_; - } - - // Consultar opció actual - [[nodiscard]] auto opcio() const -> Opcio { - return opcio_; - } - - // Consumir opció (retorna valor i reseteja a NONE) - // Utilitzar quan l'escena processa l'opció - [[nodiscard]] auto consumir_opcio() -> Opcio { - Opcio valor = opcio_; - opcio_ = Opcio::NONE; - return valor; - } - - // Reset opció a NONE (sense retornar valor) - void reset_opcio() { - opcio_ = Opcio::NONE; - } - - // Configurar partida abans de transicionar a JOC - void set_config_partida(const GameConfig::ConfigPartida& config) { - config_partida_ = config; - } - - // Obtenir configuració de partida (consumit per EscenaJoc) - [[nodiscard]] const GameConfig::ConfigPartida& get_config_partida() const { - return config_partida_; - } - - private: - Escena escena_desti_{Escena::LOGO}; // Escena a la qual transicionar - Opcio opcio_{Opcio::NONE}; // Opció específica per l'escena - GameConfig::ConfigPartida config_partida_; // Configuració de partida (jugadors actius, mode) -}; - -// Variable global inline per gestionar l'escena actual (backward compatibility) -// Sincronitzada amb context.escena_desti() pel Director -inline ContextEscenes::Escena actual = ContextEscenes::Escena::LOGO; - -} // namespace GestorEscenes diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 5f3eda0..e1603be 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -7,7 +7,7 @@ #include #include -#include "context_escenes.hpp" +#include "scene_context.hpp" #include "core/audio/audio.hpp" #include "core/audio/audio_cache.hpp" #include "core/defaults.hpp" @@ -17,9 +17,9 @@ #include "core/resources/resource_helper.hpp" #include "core/resources/resource_loader.hpp" #include "core/utils/path_utils.hpp" -#include "game/escenes/escena_joc.hpp" -#include "game/escenes/escena_logo.hpp" -#include "game/escenes/escena_titol.hpp" +#include "game/scenes/game_scene.hpp" +#include "game/scenes/logo_scene.hpp" +#include "game/scenes/title_scene.hpp" #include "game/options.hpp" #include "project.h" @@ -29,8 +29,8 @@ #endif // Using declarations per simplificar el codi -using GestorEscenes::ContextEscenes; -using Escena = ContextEscenes::Escena; +using SceneManager::SceneContext; +using SceneType = SceneContext::SceneType; // Constructor Director::Director(std::vector const& args) { @@ -238,35 +238,35 @@ auto Director::run() -> int { } // Crear context d'escenes - ContextEscenes context; + SceneContext context; #ifdef _DEBUG - context.canviar_escena(Escena::TITOL); + context.setNextScene(SceneType::TITLE); #else - context.canviar_escena(Escena::LOGO); + context.setNextScene(SceneType::LOGO); #endif // Bucle principal de gestió d'escenes - while (context.escena_desti() != Escena::EIXIR) { - // Sincronitzar GestorEscenes::actual amb context - // (altres sistemes encara poden llegir GestorEscenes::actual) - GestorEscenes::actual = context.escena_desti(); + while (context.nextScene() != SceneType::EXIT) { + // Sincronitzar SceneManager::actual amb context + // (altres sistemes encara poden llegir SceneManager::actual) + SceneManager::actual = context.nextScene(); - switch (context.escena_desti()) { - case Escena::LOGO: { - EscenaLogo logo(sdl, context); - logo.executar(); + switch (context.nextScene()) { + case SceneType::LOGO: { + LogoScene logo(sdl, context); + logo.run(); break; } - case Escena::TITOL: { - EscenaTitol titol(sdl, context); - titol.executar(); + case SceneType::TITLE: { + TitleScene titol(sdl, context); + titol.run(); break; } - case Escena::JOC: { - EscenaJoc joc(sdl, context); - joc.executar(); + case SceneType::GAME: { + GameScene joc(sdl, context); + joc.run(); break; } @@ -275,8 +275,8 @@ auto Director::run() -> int { } } - // Sincronitzar final amb GestorEscenes::actual - GestorEscenes::actual = Escena::EIXIR; + // Sincronitzar final amb SceneManager::actual + SceneManager::actual = SceneType::EXIT; return 0; } diff --git a/source/core/system/game_config.hpp b/source/core/system/game_config.hpp index ef0e907..e0707f1 100644 --- a/source/core/system/game_config.hpp +++ b/source/core/system/game_config.hpp @@ -11,7 +11,7 @@ enum class Mode { }; // Configuració d'una partida -struct ConfigPartida { +struct MatchConfig { bool jugador1_actiu{false}; // És actiu el jugador 1? bool jugador2_actiu{false}; // És actiu el jugador 2? Mode mode{Mode::NORMAL}; // Mode de joc diff --git a/source/core/system/global_events.cpp b/source/core/system/global_events.cpp index 0024ec2..2893bdf 100644 --- a/source/core/system/global_events.cpp +++ b/source/core/system/global_events.cpp @@ -5,18 +5,18 @@ #include -#include "context_escenes.hpp" +#include "scene_context.hpp" #include "core/input/input.hpp" #include "core/input/mouse.hpp" #include "core/rendering/sdl_manager.hpp" // Using declarations per simplificar el codi -using GestorEscenes::ContextEscenes; -using Escena = ContextEscenes::Escena; +using SceneManager::SceneContext; +using SceneType = SceneContext::SceneType; namespace GlobalEvents { -bool handle(const SDL_Event& event, SDLManager& sdl, ContextEscenes& context) { +bool handle(const SDL_Event& event, SDLManager& sdl, SceneContext& context) { // 1. Permitir que Input procese el evento (para hotplug de gamepads) auto event_msg = Input::get()->handleEvent(event); if (!event_msg.empty()) { @@ -25,8 +25,8 @@ bool handle(const SDL_Event& event, SDLManager& sdl, ContextEscenes& context) { // 2. Procesar SDL_EVENT_QUIT directamente (no es input de juego) if (event.type == SDL_EVENT_QUIT) { - context.canviar_escena(Escena::EIXIR); - GestorEscenes::actual = Escena::EIXIR; + context.setNextScene(SceneType::EXIT); + SceneManager::actual = SceneType::EXIT; return true; } @@ -54,8 +54,8 @@ bool handle(const SDL_Event& event, SDLManager& sdl, ContextEscenes& context) { return true; case SDL_SCANCODE_ESCAPE: - context.canviar_escena(Escena::EIXIR); - GestorEscenes::actual = Escena::EIXIR; + context.setNextScene(SceneType::EXIT); + SceneManager::actual = SceneType::EXIT; return true; default: diff --git a/source/core/system/global_events.hpp b/source/core/system/global_events.hpp index a11241d..b1edd60 100644 --- a/source/core/system/global_events.hpp +++ b/source/core/system/global_events.hpp @@ -8,12 +8,12 @@ // Forward declarations class SDLManager; -namespace GestorEscenes { -class ContextEscenes; +namespace SceneManager { +class SceneContext; } namespace GlobalEvents { // Processa events globals (F1/F2/F3/ESC/QUIT) // Retorna true si l'event ha estat processat i no cal seguir processant-lo -bool handle(const SDL_Event& event, SDLManager& sdl, GestorEscenes::ContextEscenes& context); +bool handle(const SDL_Event& event, SDLManager& sdl, SceneManager::SceneContext& context); } // namespace GlobalEvents diff --git a/source/core/system/scene_context.hpp b/source/core/system/scene_context.hpp new file mode 100644 index 0000000..83de5fe --- /dev/null +++ b/source/core/system/scene_context.hpp @@ -0,0 +1,81 @@ +// context_escenes.hpp - Sistema de gestió d'escenes i context de transicions +// © 2025 Port a C++20 + +#pragma once + +#include "core/system/game_config.hpp" + +namespace SceneManager { + +// Context de transició entre escenes +// Conté l'escena destinació i opcions específiques per aquella escena +class SceneContext { + public: + // Tipus d'escena del joc + enum class SceneType { + LOGO, // Pantalla d'inici (logo JAILGAMES) + TITLE, // Pantalla de títol amb menú + GAME, // Joc principal (Asteroids) + EXIT // Sortir del programa + }; + + // Opcions específiques per a cada escena + enum class Option { + NONE, // Sense opcions especials (comportament per defecte) + JUMP_TO_TITLE_MAIN, // TITLE: Saltar directament a MAIN (starfield instantani) + // MODE_DEMO, // GAME: Mode demostració amb IA (futur) + }; + + // Constructor inicial amb escena LOGO i sense opcions + SceneContext() = default; + + // Canviar escena amb opció específica + void setNextScene(SceneType next_scene, Option option = Option::NONE) { + next_scene_ = next_scene; + option_ = option; + } + + // Consultar escena destinació + [[nodiscard]] auto nextScene() const -> SceneType { + return next_scene_; + } + + // Consultar opció actual + [[nodiscard]] auto option() const -> Option { + return option_; + } + + // Consumir opció (retorna valor i reseteja a NONE) + // Utilitzar quan l'escena processa l'opció + [[nodiscard]] auto consumeOption() -> Option { + Option valor = option_; + option_ = Option::NONE; + return valor; + } + + // Reset opció a NONE (sense retornar valor) + void resetOption() { + option_ = Option::NONE; + } + + // Configurar partida abans de transicionar a GAME + void setMatchConfig(const GameConfig::MatchConfig& config) { + match_config_ = config; + } + + // Obtenir configuració de partida (consumit per GameScene) + [[nodiscard]] const GameConfig::MatchConfig& getMatchConfig() const { + return match_config_; + } + + private: + SceneType next_scene_{SceneType::LOGO}; // SceneType a la qual transicionar + Option option_{Option::NONE}; // Opció específica per l'escena + GameConfig::MatchConfig match_config_; // Configuració de partida (jugadors actius, mode) +}; + +// Variable global inline per gestionar l'escena actual (backward compatibility) +// Sincronitzada amb context.nextScene() pel Director +inline SceneContext::SceneType actual = SceneContext::SceneType::LOGO; + +} // namespace SceneManager diff --git a/source/game/escenes/escena_joc.cpp b/source/game/scenes/game_scene.cpp similarity index 90% rename from source/game/escenes/escena_joc.cpp rename to source/game/scenes/game_scene.cpp index 4c76348..2f54778 100644 --- a/source/game/escenes/escena_joc.cpp +++ b/source/game/scenes/game_scene.cpp @@ -2,7 +2,7 @@ // © 1999 Visente i Sergi (versió Pascal) // © 2025 Port a C++20 amb SDL3 -#include "escena_joc.hpp" +#include "game_scene.hpp" #include #include @@ -18,16 +18,16 @@ #include "core/math/easing.hpp" #include "core/physics/collision.hpp" #include "core/rendering/line_renderer.hpp" -#include "core/system/context_escenes.hpp" +#include "core/system/scene_context.hpp" #include "core/system/global_events.hpp" #include "game/stage_system/stage_loader.hpp" // Using declarations per simplificar el codi -using GestorEscenes::ContextEscenes; -using Escena = ContextEscenes::Escena; -using Opcio = ContextEscenes::Opcio; +using SceneManager::SceneContext; +using SceneType = SceneContext::SceneType; +using Option = SceneContext::Option; -EscenaJoc::EscenaJoc(SDLManager& sdl, ContextEscenes& context) +GameScene::GameScene(SDLManager& sdl, SceneContext& context) : sdl_(sdl), context_(context), debris_manager_(sdl.obte_renderer()), @@ -35,18 +35,18 @@ EscenaJoc::EscenaJoc(SDLManager& sdl, ContextEscenes& context) text_(sdl.obte_renderer()), init_hud_rect_sound_played_(false) { // Recuperar configuració de partida des del context - config_partida_ = context_.get_config_partida(); + match_config_ = context_.getMatchConfig(); // Debug output de la configuració - std::cout << "[EscenaJoc] Configuració de partida - P1: " - << (config_partida_.jugador1_actiu ? "ACTIU" : "INACTIU") + std::cout << "[GameScene] Configuració de partida - P1: " + << (match_config_.jugador1_actiu ? "ACTIU" : "INACTIU") << ", P2: " - << (config_partida_.jugador2_actiu ? "ACTIU" : "INACTIU") + << (match_config_.jugador2_actiu ? "ACTIU" : "INACTIU") << '\n'; // Consumir opcions (preparació per MODE_DEMO futur) - auto opcio = context_.consumir_opcio(); - (void)opcio; // Suprimir warning de variable no usada + auto option = context_.consumeOption(); + (void)option; // Suprimir warning de variable no usada // Inicialitzar naus amb renderer (P1=ship.shp, P2=ship2.shp) naus_[0] = Ship(sdl.obte_renderer(), "ship.shp"); // Jugador 1: nave estàndar @@ -63,8 +63,8 @@ EscenaJoc::EscenaJoc(SDLManager& sdl, ContextEscenes& context) } } -void EscenaJoc::executar() { - std::cout << "Escena Joc: Inicialitzant...\n"; +void GameScene::run() { + std::cout << "SceneType Joc: Inicialitzant...\n"; // Inicialitzar estat del joc init(); @@ -72,7 +72,7 @@ void EscenaJoc::executar() { SDL_Event event; Uint64 last_time = SDL_GetTicks(); - while (GestorEscenes::actual == Escena::JOC) { + while (SceneManager::actual == SceneType::GAME) { // Calcular delta_time real Uint64 current_time = SDL_GetTicks(); float delta_time = (current_time - last_time) / 1000.0F; @@ -123,10 +123,10 @@ void EscenaJoc::executar() { sdl_.presenta(); } - std::cout << "Escena Joc: Finalitzant...\n"; + std::cout << "SceneType Joc: Finalitzant...\n"; } -void EscenaJoc::init() { +void GameScene::init() { // Inicialitzar generador de números aleatoris // Basat en el codi Pascal original: line 376 std::srand(static_cast(std::time(nullptr))); @@ -135,7 +135,7 @@ void EscenaJoc::init() { if (!stage_config_) { stage_config_ = StageSystem::StageLoader::carregar("data/stages/stages.yaml"); if (!stage_config_) { - std::cerr << "[EscenaJoc] Error: no s'ha pogut carregar stages.yaml" << '\n'; + std::cerr << "[GameScene] Error: no s'ha pogut carregar stages.yaml" << '\n'; // Continue without stage system (will crash, but helps debugging) } } @@ -154,7 +154,7 @@ void EscenaJoc::init() { // Initialize lives and game over state (independent lives per player) vides_per_jugador_[0] = Defaults::Game::STARTING_LIVES; vides_per_jugador_[1] = Defaults::Game::STARTING_LIVES; - estat_game_over_ = EstatGameOver::NONE; + estat_game_over_ = GameOverState::NONE; continue_counter_ = 0; continue_tick_timer_ = 0.0F; continues_usados_ = 0; @@ -172,19 +172,19 @@ void EscenaJoc::init() { // Inicialitzar naus segons configuració (només jugadors actius) for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; + bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; if (jugador_actiu) { // Jugador actiu: init normalment Vec2 spawn_pos = obtenir_punt_spawn(i); naus_[i].init(&spawn_pos, false); // No invulnerability at start - std::cout << "[EscenaJoc] Jugador " << (i + 1) << " inicialitzat\n"; + std::cout << "[GameScene] Jugador " << (i + 1) << " inicialitzat\n"; } else { // Jugador inactiu: marcar com a mort permanent naus_[i].markHit(); itocado_per_jugador_[i] = 999.0F; // Valor sentinella (permanent inactiu) vides_per_jugador_[i] = 0; // Sense vides - std::cout << "[EscenaJoc] Jugador " << (i + 1) << " inactiu\n"; + std::cout << "[GameScene] Jugador " << (i + 1) << " inactiu\n"; } } @@ -208,20 +208,20 @@ void EscenaJoc::init() { init_hud_rect_sound_played_ = false; } -void EscenaJoc::update(float delta_time) { +void GameScene::update(float delta_time) { // Processar disparos (state-based, no event-based) - if (estat_game_over_ == EstatGameOver::NONE) { + if (estat_game_over_ == GameOverState::NONE) { auto* input = Input::get(); // Jugador 1 dispara (només si està actiu) - if (config_partida_.jugador1_actiu) { + if (match_config_.jugador1_actiu) { if (input->checkActionPlayer1(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) { disparar_bala(0); } } // Jugador 2 dispara (només si està actiu) - if (config_partida_.jugador2_actiu) { + if (match_config_.jugador2_actiu) { if (input->checkActionPlayer2(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) { disparar_bala(1); } @@ -232,17 +232,17 @@ void EscenaJoc::update(float delta_time) { if (stage_manager_->get_estat() == StageSystem::EstatStage::PLAYING) { // Check if at least one player is alive and playing (game in progress) bool algun_jugador_viu = false; - if (config_partida_.jugador1_actiu && itocado_per_jugador_[0] != 999.0F) { + if (match_config_.jugador1_actiu && itocado_per_jugador_[0] != 999.0F) { algun_jugador_viu = true; } - if (config_partida_.jugador2_actiu && itocado_per_jugador_[1] != 999.0F) { + if (match_config_.jugador2_actiu && itocado_per_jugador_[1] != 999.0F) { algun_jugador_viu = true; } // Only allow join if there's an active game if (algun_jugador_viu) { // P2 can join if not currently playing (never joined OR dead without lives) - bool p2_no_juga = !config_partida_.jugador2_actiu || // Never joined + bool p2_no_juga = !match_config_.jugador2_actiu || // Never joined itocado_per_jugador_[1] == 999.0F; // Dead without lives if (p2_no_juga) { @@ -252,7 +252,7 @@ void EscenaJoc::update(float delta_time) { } // P1 can join if not currently playing (never joined OR dead without lives) - bool p1_no_juga = !config_partida_.jugador1_actiu || // Never joined + bool p1_no_juga = !match_config_.jugador1_actiu || // Never joined itocado_per_jugador_[0] == 999.0F; // Dead without lives if (p1_no_juga) { @@ -265,7 +265,7 @@ void EscenaJoc::update(float delta_time) { } // Handle CONTINUE screen - if (estat_game_over_ == EstatGameOver::CONTINUE) { + if (estat_game_over_ == GameOverState::CONTINUE) { actualitzar_continue(delta_time); processar_input_continue(); @@ -282,7 +282,7 @@ void EscenaJoc::update(float delta_time) { } // Handle final GAME OVER state - if (estat_game_over_ == EstatGameOver::GAME_OVER) { + if (estat_game_over_ == GameOverState::GAME_OVER) { // Game over: only update timer, enemies, bullets, and debris game_over_timer_ -= delta_time; @@ -290,8 +290,8 @@ void EscenaJoc::update(float delta_time) { // Aturar música de joc abans de tornar al títol Audio::get()->stopMusic(); // Transició a pantalla de títol - context_.canviar_escena(Escena::TITOL); - GestorEscenes::actual = Escena::TITOL; + context_.setNextScene(SceneType::TITLE); + SceneManager::actual = SceneType::TITLE; return; } @@ -335,11 +335,11 @@ void EscenaJoc::update(float delta_time) { itocado_per_jugador_[i] = 999.0F; // Check if ALL ACTIVE players are dead (trigger continue screen) - bool p1_dead = !config_partida_.jugador1_actiu || vides_per_jugador_[0] <= 0; - bool p2_dead = !config_partida_.jugador2_actiu || vides_per_jugador_[1] <= 0; + bool p1_dead = !match_config_.jugador1_actiu || vides_per_jugador_[0] <= 0; + bool p2_dead = !match_config_.jugador2_actiu || vides_per_jugador_[1] <= 0; if (p1_dead && p2_dead) { - estat_game_over_ = EstatGameOver::CONTINUE; + estat_game_over_ = GameOverState::CONTINUE; continue_counter_ = Defaults::Game::CONTINUE_COUNT_START; continue_tick_timer_ = Defaults::Game::CONTINUE_TICK_DURATION; } @@ -396,12 +396,12 @@ void EscenaJoc::update(float delta_time) { Defaults::Game::INIT_HUD_SHIP2_RATIO_END); // [MODIFICAT] Animar AMBAS naus con sus progress respectivos - if (config_partida_.jugador1_actiu && ship1_progress < 1.0F) { + if (match_config_.jugador1_actiu && ship1_progress < 1.0F) { Vec2 pos_p1 = calcular_posicio_nau_init_hud(ship1_progress, 0); naus_[0].setCenter(pos_p1); } - if (config_partida_.jugador2_actiu && ship2_progress < 1.0F) { + if (match_config_.jugador2_actiu && ship2_progress < 1.0F) { Vec2 pos_p2 = calcular_posicio_nau_init_hud(ship2_progress, 1); naus_[1].setCenter(pos_p2); } @@ -425,7 +425,7 @@ void EscenaJoc::update(float delta_time) { // [NEW] Allow both ships movement and shooting during intro for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; + bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players naus_[i].processInput(delta_time, i); naus_[i].update(delta_time); @@ -460,7 +460,7 @@ void EscenaJoc::update(float delta_time) { // [EXISTING] Normal gameplay - update active players for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; + bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players naus_[i].processInput(delta_time, i); naus_[i].update(delta_time); @@ -489,7 +489,7 @@ void EscenaJoc::update(float delta_time) { // [NEW] Allow both ships movement and shooting during outro for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; + bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players naus_[i].processInput(delta_time, i); naus_[i].update(delta_time); @@ -508,9 +508,9 @@ void EscenaJoc::update(float delta_time) { } } -void EscenaJoc::draw() { +void GameScene::draw() { // Handle CONTINUE screen - if (estat_game_over_ == EstatGameOver::CONTINUE) { + if (estat_game_over_ == GameOverState::CONTINUE) { // Draw game background elements first dibuixar_marges(); @@ -532,7 +532,7 @@ void EscenaJoc::draw() { } // Handle final GAME OVER state - if (estat_game_over_ == EstatGameOver::GAME_OVER) { + if (estat_game_over_ == GameOverState::GAME_OVER) { // Game over: draw enemies, bullets, debris, and "GAME OVER" text dibuixar_marges(); @@ -610,11 +610,11 @@ void EscenaJoc::draw() { } // [MODIFICAT] Dibuixar naus amb progress independent - if (ship1_progress > 0.0F && config_partida_.jugador1_actiu && !naus_[0].isHit()) { + if (ship1_progress > 0.0F && match_config_.jugador1_actiu && !naus_[0].isHit()) { naus_[0].draw(); } - if (ship2_progress > 0.0F && config_partida_.jugador2_actiu && !naus_[1].isHit()) { + if (ship2_progress > 0.0F && match_config_.jugador2_actiu && !naus_[1].isHit()) { naus_[1].draw(); } @@ -625,7 +625,7 @@ void EscenaJoc::draw() { dibuixar_marges(); // [NEW] Draw both ships if active and alive for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; + bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { naus_[i].draw(); } @@ -650,7 +650,7 @@ void EscenaJoc::draw() { // [EXISTING] Normal rendering - active ships for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; + bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { naus_[i].draw(); } @@ -673,7 +673,7 @@ void EscenaJoc::draw() { dibuixar_marges(); // [NEW] Draw both ships if active and alive for (uint8_t i = 0; i < 2; i++) { - bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu; + bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu; if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { naus_[i].draw(); } @@ -695,7 +695,7 @@ void EscenaJoc::draw() { } } -void EscenaJoc::tocado(uint8_t player_id) { +void GameScene::tocado(uint8_t player_id) { // Death sequence: 3 phases // Phase 1: First call (itocado_per_jugador_[player_id] == 0) - trigger explosion // Phase 2: Animation (0 < itocado_ < 3.0s) - debris animation @@ -734,7 +734,7 @@ void EscenaJoc::tocado(uint8_t player_id) { // Phase 3 is handled in update() when itocado_per_jugador_ >= DEATH_DURATION } -void EscenaJoc::dibuixar_marges() const { +void GameScene::dibuixar_marges() const { // Dibuixar rectangle de la zona de joc const SDL_FRect& zona = Defaults::Zones::PLAYAREA; @@ -751,7 +751,7 @@ void EscenaJoc::dibuixar_marges() const { Rendering::linea(sdl_.obte_renderer(), x2, y1, x2, y2); // Right } -void EscenaJoc::dibuixar_marcador() { +void GameScene::dibuixar_marcador() { // Construir text del marcador std::string text = construir_marcador(); @@ -768,7 +768,7 @@ void EscenaJoc::dibuixar_marcador() { text_.render_centered(text, {.x = centre_x, .y = centre_y}, escala, spacing); } -void EscenaJoc::dibuixar_marges_animat(float progress) const { +void GameScene::dibuixar_marges_animat(float progress) const { // Animació seqüencial del rectangle amb efecte de "pinzell" // Dos pinzells comencen al centre superior i baixen pels laterals @@ -827,7 +827,7 @@ void EscenaJoc::dibuixar_marges_animat(float progress) const { } } -void EscenaJoc::dibuixar_marcador_animat(float progress) { +void GameScene::dibuixar_marcador_animat(float progress) { // Animació del marcador pujant des de baix amb easing // Calcular progrés amb easing @@ -855,7 +855,7 @@ void EscenaJoc::dibuixar_marcador_animat(float progress) { text_.render_centered(text, {.x = centre_x, .y = centre_y_animada}, escala, spacing); } -Vec2 EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const { +Vec2 GameScene::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const { // Animació de la nau pujant des de baix amb easing // [MODIFICAT] Ambas naves usan ease_out_quad (desfase temporal via INIT/END) @@ -879,7 +879,7 @@ Vec2 EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) return {.x = x_final, .y = y_animada}; } -float EscenaJoc::calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const { +float GameScene::calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const { // Convierte global_progress (0.0→1.0) a element_progress usando ventana [INIT, END] // // Casos: @@ -904,11 +904,11 @@ float EscenaJoc::calcular_progress_rango(float global_progress, float ratio_init return (global_progress - ratio_init) / (ratio_end - ratio_init); } -std::string EscenaJoc::construir_marcador() const { +std::string GameScene::construir_marcador() const { // Puntuació P1 (6 dígits) - mostrar zeros si inactiu std::string score_p1; std::string vides_p1; - if (config_partida_.jugador1_actiu) { + if (match_config_.jugador1_actiu) { score_p1 = std::to_string(puntuacio_per_jugador_[0]); score_p1 = std::string(6 - std::min(6, static_cast(score_p1.length())), '0') + score_p1; vides_p1 = (vides_per_jugador_[0] < 10) @@ -927,7 +927,7 @@ std::string EscenaJoc::construir_marcador() const { // Puntuació P2 (6 dígits) - mostrar zeros si inactiu std::string score_p2; std::string vides_p2; - if (config_partida_.jugador2_actiu) { + if (match_config_.jugador2_actiu) { score_p2 = std::to_string(puntuacio_per_jugador_[1]); score_p2 = std::string(6 - std::min(6, static_cast(score_p2.length())), '0') + score_p2; vides_p2 = (vides_per_jugador_[1] < 10) @@ -943,7 +943,7 @@ std::string EscenaJoc::construir_marcador() const { return score_p1 + " " + vides_p1 + " LEVEL " + stage_str + " " + score_p2 + " " + vides_p2; } -void EscenaJoc::detectar_col·lisions_bales_enemics() { +void GameScene::detectar_col·lisions_bales_enemics() { // Amplificador per hitbox més generós (115%) constexpr float AMPLIFIER = Defaults::Game::COLLISION_BULLET_ENEMY_AMPLIFIER; @@ -1007,7 +1007,7 @@ void EscenaJoc::detectar_col·lisions_bales_enemics() { } } -void EscenaJoc::detectar_col·lisio_naus_enemics() { +void GameScene::detectar_col·lisio_naus_enemics() { // Amplificador per hitbox generós (80%) constexpr float AMPLIFIER = Defaults::Game::COLLISION_SHIP_ENEMY_AMPLIFIER; @@ -1040,7 +1040,7 @@ void EscenaJoc::detectar_col·lisio_naus_enemics() { } } -void EscenaJoc::detectar_col·lisions_bales_jugadors() { +void GameScene::detectar_col·lisions_bales_jugadors() { // Skip if friendly fire disabled if (!Defaults::Game::FRIENDLY_FIRE_ENABLED) { return; @@ -1076,8 +1076,8 @@ void EscenaJoc::detectar_col·lisions_bales_jugadors() { } // Skip inactive players - bool jugador_actiu = (player_id == 0) ? config_partida_.jugador1_actiu - : config_partida_.jugador2_actiu; + bool jugador_actiu = (player_id == 0) ? match_config_.jugador1_actiu + : match_config_.jugador2_actiu; if (!jugador_actiu) { continue; } @@ -1113,7 +1113,7 @@ void EscenaJoc::detectar_col·lisions_bales_jugadors() { // [NEW] Stage system helper methods -void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) { +void GameScene::dibuixar_missatge_stage(const std::string& missatge) { constexpr float escala_base = 1.0F; constexpr float spacing = 2.0F; @@ -1182,11 +1182,11 @@ void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) { // Helper methods for 2-player support // ======================================== -Vec2 EscenaJoc::obtenir_punt_spawn(uint8_t player_id) const { +Vec2 GameScene::obtenir_punt_spawn(uint8_t player_id) const { const SDL_FRect& zona = Defaults::Zones::PLAYAREA; float x_ratio; - if (config_partida_.es_un_jugador()) { + if (match_config_.es_un_jugador()) { // Un sol jugador: spawn al centre (50%) x_ratio = 0.5F; } else { @@ -1201,7 +1201,7 @@ Vec2 EscenaJoc::obtenir_punt_spawn(uint8_t player_id) const { .y = zona.y + (zona.h * Defaults::Game::SPAWN_Y_RATIO)}; } -void EscenaJoc::disparar_bala(uint8_t player_id) { +void GameScene::disparar_bala(uint8_t player_id) { // Verificar que el jugador está vivo if (itocado_per_jugador_[player_id] > 0.0F) { return; @@ -1234,14 +1234,14 @@ void EscenaJoc::disparar_bala(uint8_t player_id) { // ==================== CONTINUE & JOIN SYSTEM ==================== -void EscenaJoc::check_and_apply_continue_timeout() { +void GameScene::check_and_apply_continue_timeout() { if (continue_counter_ < 0) { - estat_game_over_ = EstatGameOver::GAME_OVER; + estat_game_over_ = GameOverState::GAME_OVER; game_over_timer_ = Defaults::Game::GAME_OVER_DURATION; } } -void EscenaJoc::actualitzar_continue(float delta_time) { +void GameScene::actualitzar_continue(float delta_time) { continue_tick_timer_ -= delta_time; if (continue_tick_timer_ <= 0.0F) { @@ -1252,13 +1252,13 @@ void EscenaJoc::actualitzar_continue(float delta_time) { check_and_apply_continue_timeout(); // Play sound only if still in CONTINUE state (not transitioned to GAME_OVER) - if (estat_game_over_ == EstatGameOver::CONTINUE) { + if (estat_game_over_ == GameOverState::CONTINUE) { Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME); } } } -void EscenaJoc::processar_input_continue() { +void GameScene::processar_input_continue() { auto* input = Input::get(); // Check START for both players @@ -1269,7 +1269,7 @@ void EscenaJoc::processar_input_continue() { // Check continue limit (skip if infinite continues) if (!Defaults::Game::INFINITE_CONTINUES && continues_usados_ >= Defaults::Game::MAX_CONTINUES) { // Max continues reached → final game over - estat_game_over_ = EstatGameOver::GAME_OVER; + estat_game_over_ = GameOverState::GAME_OVER; game_over_timer_ = Defaults::Game::GAME_OVER_DURATION; return; } @@ -1289,9 +1289,9 @@ void EscenaJoc::processar_input_continue() { // Activate player if not already if (player_to_revive == 0) { - config_partida_.jugador1_actiu = true; + match_config_.jugador1_actiu = true; } else { - config_partida_.jugador2_actiu = true; + match_config_.jugador2_actiu = true; } // Spawn with invulnerability @@ -1304,13 +1304,13 @@ void EscenaJoc::processar_input_continue() { puntuacio_per_jugador_[other_player] = 0; vides_per_jugador_[other_player] = Defaults::Game::STARTING_LIVES; itocado_per_jugador_[other_player] = 0.0F; - config_partida_.jugador2_actiu = true; + match_config_.jugador2_actiu = true; Vec2 spawn_pos2 = obtenir_punt_spawn(other_player); naus_[other_player].init(&spawn_pos2, true); } // Resume game - estat_game_over_ = EstatGameOver::NONE; + estat_game_over_ = GameOverState::NONE; continue_counter_ = 0; continue_tick_timer_ = 0.0F; @@ -1333,7 +1333,7 @@ void EscenaJoc::processar_input_continue() { check_and_apply_continue_timeout(); // Play sound only if still in CONTINUE state - if (estat_game_over_ == EstatGameOver::CONTINUE) { + if (estat_game_over_ == GameOverState::CONTINUE) { Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME); } @@ -1342,7 +1342,7 @@ void EscenaJoc::processar_input_continue() { } } -void EscenaJoc::dibuixar_continue() { +void GameScene::dibuixar_continue() { const SDL_FRect& play_area = Defaults::Zones::PLAYAREA; constexpr float spacing = 4.0F; @@ -1377,12 +1377,12 @@ void EscenaJoc::dibuixar_continue() { } } -void EscenaJoc::unir_jugador(uint8_t player_id) { +void GameScene::unir_jugador(uint8_t player_id) { // Activate player if (player_id == 0) { - config_partida_.jugador1_actiu = true; + match_config_.jugador1_actiu = true; } else { - config_partida_.jugador2_actiu = true; + match_config_.jugador2_actiu = true; } // Reset stats @@ -1396,5 +1396,5 @@ void EscenaJoc::unir_jugador(uint8_t player_id) { // No visual message, just spawn (per user requirement) - std::cout << "[EscenaJoc] Jugador " << (int)(player_id + 1) << " s'ha unit a la partida!" << '\n'; + std::cout << "[GameScene] Jugador " << (int)(player_id + 1) << " s'ha unit a la partida!" << '\n'; } diff --git a/source/game/escenes/escena_joc.hpp b/source/game/scenes/game_scene.hpp similarity index 91% rename from source/game/escenes/escena_joc.hpp rename to source/game/scenes/game_scene.hpp index 25dad6d..b50e3f4 100644 --- a/source/game/escenes/escena_joc.hpp +++ b/source/game/scenes/game_scene.hpp @@ -12,7 +12,7 @@ #include "core/graphics/vector_text.hpp" #include "core/rendering/sdl_manager.hpp" -#include "core/system/context_escenes.hpp" +#include "core/system/scene_context.hpp" #include "core/system/game_config.hpp" #include "core/types.hpp" #include "game/constants.hpp" @@ -25,27 +25,27 @@ #include "game/stage_system/stage_manager.hpp" // Game over state machine -enum class EstatGameOver { +enum class GameOverState { NONE, // Normal gameplay CONTINUE, // Continue countdown screen (9→0) GAME_OVER // Final game over (returning to title) }; // Classe principal del joc (escena) -class EscenaJoc { +class GameScene { public: - explicit EscenaJoc(SDLManager& sdl, GestorEscenes::ContextEscenes& context); - ~EscenaJoc() = default; + explicit GameScene(SDLManager& sdl, SceneManager::SceneContext& context); + ~GameScene() = default; - void executar(); // Bucle principal de l'escena + void run(); // Bucle principal de l'escena void init(); void update(float delta_time); void draw(); private: SDLManager& sdl_; - GestorEscenes::ContextEscenes& context_; - GameConfig::ConfigPartida config_partida_; // Configuració de jugadors actius + SceneManager::SceneContext& context_; + GameConfig::MatchConfig match_config_; // Configuració de jugadors actius // Efectes visuals Effects::DebrisManager debris_manager_; @@ -59,7 +59,7 @@ class EscenaJoc { // Lives and game over system std::array vides_per_jugador_; // [0]=P1, [1]=P2 - EstatGameOver estat_game_over_; // Game over state machine (NONE, CONTINUE, GAME_OVER) + GameOverState estat_game_over_; // Game over state machine (NONE, CONTINUE, GAME_OVER) int continue_counter_; // Continue countdown (9→0) float continue_tick_timer_; // Timer for countdown tick (1.0s) int continues_usados_; // Continues used this game (0-3 max) diff --git a/source/game/escenes/escena_logo.cpp b/source/game/scenes/logo_scene.cpp similarity index 82% rename from source/game/escenes/escena_logo.cpp rename to source/game/scenes/logo_scene.cpp index 2d99c91..9b97979 100644 --- a/source/game/escenes/escena_logo.cpp +++ b/source/game/scenes/logo_scene.cpp @@ -1,7 +1,7 @@ // escena_logo.cpp - Implementació de l'escena logo // © 2025 Port a C++20 -#include "escena_logo.hpp" +#include "logo_scene.hpp" #include #include @@ -14,13 +14,13 @@ #include "core/input/input.hpp" #include "core/input/mouse.hpp" #include "core/rendering/shape_renderer.hpp" -#include "core/system/context_escenes.hpp" +#include "core/system/scene_context.hpp" #include "core/system/global_events.hpp" // Using declarations per simplificar el codi -using GestorEscenes::ContextEscenes; -using Escena = ContextEscenes::Escena; -using Opcio = ContextEscenes::Opcio; +using SceneManager::SceneContext; +using SceneType = SceneContext::SceneType; +using Option = SceneContext::Option; // Helper: calcular el progrés individual d'una lletra // en funció del progrés global (efecte seqüencial) @@ -45,35 +45,35 @@ static float calcular_progress_letra(size_t letra_index, size_t num_letras, floa return (global_progress - start) / (end - start); } -EscenaLogo::EscenaLogo(SDLManager& sdl, ContextEscenes& context) +LogoScene::LogoScene(SDLManager& sdl, SceneContext& context) : sdl_(sdl), context_(context), - estat_actual_(EstatAnimacio::PRE_ANIMATION), + estat_actual_(AnimationState::PRE_ANIMATION), temps_estat_actual_(0.0F), debris_manager_(std::make_unique(sdl.obte_renderer())), lletra_explosio_index_(0), temps_des_ultima_explosio_(0.0F) { - std::cout << "Escena Logo: Inicialitzant...\n"; + std::cout << "SceneType Logo: Inicialitzant...\n"; // Consumir opcions (LOGO no processa opcions actualment) - auto opcio = context_.consumir_opcio(); - (void)opcio; // Suprimir warning + auto option = context_.consumeOption(); + (void)option; // Suprimir warning so_reproduit_.fill(false); // Inicialitzar seguiment de sons inicialitzar_lletres(); } -EscenaLogo::~EscenaLogo() { +LogoScene::~LogoScene() { // Aturar tots els sons i la música Audio::get()->stopAllSounds(); - std::cout << "Escena Logo: Sons aturats\n"; + std::cout << "SceneType Logo: Sons aturats\n"; } -void EscenaLogo::executar() { +void LogoScene::run() { SDL_Event event; Uint64 last_time = SDL_GetTicks(); - while (GestorEscenes::actual == Escena::LOGO) { + while (SceneManager::actual == SceneType::LOGO) { // Calcular delta_time real Uint64 current_time = SDL_GetTicks(); float delta_time = (current_time - last_time) / 1000.0F; @@ -120,10 +120,10 @@ void EscenaLogo::executar() { draw(); } - std::cout << "Escena Logo: Finalitzant...\n"; + std::cout << "SceneType Logo: Finalitzant...\n"; } -void EscenaLogo::inicialitzar_lletres() { +void LogoScene::inicialitzar_lletres() { using namespace Graphics; // Llista de fitxers .shp (A repetida per a les dues A's) @@ -144,7 +144,7 @@ void EscenaLogo::inicialitzar_lletres() { for (const auto& fitxer : fitxers) { auto forma = ShapeLoader::load(fitxer); if (!forma || !forma->es_valida()) { - std::cerr << "[EscenaLogo] Error carregant " << fitxer << '\n'; + std::cerr << "[LogoScene] Error carregant " << fitxer << '\n'; continue; } @@ -198,16 +198,16 @@ void EscenaLogo::inicialitzar_lletres() { x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES; } - std::cout << "[EscenaLogo] " << lletres_.size() + std::cout << "[LogoScene] " << lletres_.size() << " lletres carregades, ancho total: " << ancho_total << " px\n"; } -void EscenaLogo::canviar_estat(EstatAnimacio nou_estat) { +void LogoScene::canviar_estat(AnimationState nou_estat) { estat_actual_ = nou_estat; temps_estat_actual_ = 0.0F; // Reset temps // Inicialitzar estat d'explosió - if (nou_estat == EstatAnimacio::EXPLOSION) { + if (nou_estat == AnimationState::EXPLOSION) { lletra_explosio_index_ = 0; temps_des_ultima_explosio_ = 0.0F; @@ -219,20 +219,20 @@ void EscenaLogo::canviar_estat(EstatAnimacio nou_estat) { std::random_device rd; std::mt19937 g(rd()); std::shuffle(ordre_explosio_.begin(), ordre_explosio_.end(), g); - } else if (nou_estat == EstatAnimacio::POST_EXPLOSION) { + } else if (nou_estat == AnimationState::POST_EXPLOSION) { Audio::get()->playMusic("title.ogg"); } - std::cout << "[EscenaLogo] Canvi a estat: " << static_cast(nou_estat) + std::cout << "[LogoScene] Canvi a estat: " << static_cast(nou_estat) << "\n"; } -bool EscenaLogo::totes_lletres_completes() const { +bool LogoScene::totes_lletres_completes() const { // Quan global_progress = 1.0, totes les lletres tenen letra_progress = 1.0 return temps_estat_actual_ >= DURACIO_ZOOM; } -void EscenaLogo::actualitzar_explosions(float delta_time) { +void LogoScene::actualitzar_explosions(float delta_time) { temps_des_ultima_explosio_ += delta_time; // Comprovar si és el moment d'explotar la següent lletra @@ -252,29 +252,29 @@ void EscenaLogo::actualitzar_explosions(float delta_time) { {.x = 0.0F, .y = 0.0F} // Sense velocitat (per defecte) ); - std::cout << "[EscenaLogo] Explota lletra " << lletra_explosio_index_ << "\n"; + std::cout << "[LogoScene] Explota lletra " << lletra_explosio_index_ << "\n"; // Passar a la següent lletra lletra_explosio_index_++; temps_des_ultima_explosio_ = 0.0F; } else { // Totes les lletres han explotat, transició a POST_EXPLOSION - canviar_estat(EstatAnimacio::POST_EXPLOSION); + canviar_estat(AnimationState::POST_EXPLOSION); } } } -void EscenaLogo::update(float delta_time) { +void LogoScene::update(float delta_time) { temps_estat_actual_ += delta_time; switch (estat_actual_) { - case EstatAnimacio::PRE_ANIMATION: + case AnimationState::PRE_ANIMATION: if (temps_estat_actual_ >= DURACIO_PRE) { - canviar_estat(EstatAnimacio::ANIMATION); + canviar_estat(AnimationState::ANIMATION); } break; - case EstatAnimacio::ANIMATION: { + case AnimationState::ANIMATION: { // Reproduir so per cada lletra quan comença a aparèixer float global_progress = std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0F); @@ -295,55 +295,55 @@ void EscenaLogo::update(float delta_time) { } if (totes_lletres_completes()) { - canviar_estat(EstatAnimacio::POST_ANIMATION); + canviar_estat(AnimationState::POST_ANIMATION); } break; } - case EstatAnimacio::POST_ANIMATION: + case AnimationState::POST_ANIMATION: if (temps_estat_actual_ >= DURACIO_POST_ANIMATION) { - canviar_estat(EstatAnimacio::EXPLOSION); + canviar_estat(AnimationState::EXPLOSION); } break; - case EstatAnimacio::EXPLOSION: + case AnimationState::EXPLOSION: actualitzar_explosions(delta_time); break; - case EstatAnimacio::POST_EXPLOSION: + case AnimationState::POST_EXPLOSION: if (temps_estat_actual_ >= DURACIO_POST_EXPLOSION) { // Transició a pantalla de títol - context_.canviar_escena(Escena::TITOL); - GestorEscenes::actual = Escena::TITOL; + context_.setNextScene(SceneType::TITLE); + SceneManager::actual = SceneType::TITLE; } break; } // Verificar botones de skip (SHOOT P1/P2) if (checkSkipButtonPressed()) { - context_.canviar_escena(Escena::TITOL, Opcio::JUMP_TO_TITLE_MAIN); - GestorEscenes::actual = Escena::TITOL; + context_.setNextScene(SceneType::TITLE, Option::JUMP_TO_TITLE_MAIN); + SceneManager::actual = SceneType::TITLE; } // Actualitzar animacions de debris debris_manager_->update(delta_time); } -void EscenaLogo::draw() { +void LogoScene::draw() { // Fons negre sdl_.neteja(0, 0, 0); // PRE_ANIMATION: Només pantalla negra - if (estat_actual_ == EstatAnimacio::PRE_ANIMATION) { + if (estat_actual_ == AnimationState::PRE_ANIMATION) { sdl_.presenta(); return; // No renderitzar lletres } // ANIMATION o POST_ANIMATION: Dibuixar lletres amb animació - if (estat_actual_ == EstatAnimacio::ANIMATION || - estat_actual_ == EstatAnimacio::POST_ANIMATION) { + if (estat_actual_ == AnimationState::ANIMATION || + estat_actual_ == AnimationState::POST_ANIMATION) { float global_progress = - (estat_actual_ == EstatAnimacio::ANIMATION) + (estat_actual_ == AnimationState::ANIMATION) ? std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0F) : 1.0F; // POST: mantenir al 100% @@ -384,7 +384,7 @@ void EscenaLogo::draw() { } // EXPLOSION: Dibuixar només lletres que encara no han explotat - if (estat_actual_ == EstatAnimacio::EXPLOSION) { + if (estat_actual_ == AnimationState::EXPLOSION) { // Crear conjunt de lletres ja explotades std::set explotades; for (size_t i = 0; i < lletra_explosio_index_; i++) { @@ -415,10 +415,10 @@ void EscenaLogo::draw() { sdl_.presenta(); } -auto EscenaLogo::checkSkipButtonPressed() -> bool { +auto LogoScene::checkSkipButtonPressed() -> bool { return Input::get()->checkAnyPlayerAction(ARCADE_BUTTONS); } -void EscenaLogo::processar_events(const SDL_Event& event) { +void LogoScene::processar_events(const SDL_Event& event) { // No procesar eventos genéricos aquí - la lógica se movió a update() } diff --git a/source/game/escenes/escena_logo.hpp b/source/game/scenes/logo_scene.hpp similarity index 88% rename from source/game/escenes/escena_logo.hpp rename to source/game/scenes/logo_scene.hpp index 9b685b7..9195753 100644 --- a/source/game/escenes/escena_logo.hpp +++ b/source/game/scenes/logo_scene.hpp @@ -14,19 +14,19 @@ #include "core/graphics/shape.hpp" #include "core/input/input_types.hpp" #include "core/rendering/sdl_manager.hpp" -#include "core/system/context_escenes.hpp" +#include "core/system/scene_context.hpp" #include "core/types.hpp" #include "game/effects/debris_manager.hpp" -class EscenaLogo { +class LogoScene { public: - explicit EscenaLogo(SDLManager& sdl, GestorEscenes::ContextEscenes& context); - ~EscenaLogo(); // Destructor per aturar sons - void executar(); // Bucle principal de l'escena + explicit LogoScene(SDLManager& sdl, SceneManager::SceneContext& context); + ~LogoScene(); // Destructor per aturar sons + void run(); // Bucle principal de l'escena private: // Màquina d'estats per l'animació - enum class EstatAnimacio { + enum class AnimationState { PRE_ANIMATION, // Pantalla negra inicial ANIMATION, // Animació de zoom de lletres POST_ANIMATION, // Logo complet visible @@ -35,8 +35,8 @@ class EscenaLogo { }; SDLManager& sdl_; - GestorEscenes::ContextEscenes& context_; - EstatAnimacio estat_actual_; // Estat actual de la màquina + SceneManager::SceneContext& context_; + AnimationState estat_actual_; // Estat actual de la màquina float temps_estat_actual_; // Temps en l'estat actual (reset en cada transició) @@ -86,6 +86,6 @@ class EscenaLogo { auto checkSkipButtonPressed() -> bool; // Mètodes de gestió d'estats - void canviar_estat(EstatAnimacio nou_estat); + void canviar_estat(AnimationState nou_estat); [[nodiscard]] bool totes_lletres_completes() const; }; diff --git a/source/game/escenes/escena_titol.cpp b/source/game/scenes/title_scene.cpp similarity index 81% rename from source/game/escenes/escena_titol.cpp rename to source/game/scenes/title_scene.cpp index e260b39..77b315f 100644 --- a/source/game/escenes/escena_titol.cpp +++ b/source/game/scenes/title_scene.cpp @@ -1,7 +1,7 @@ // escena_titol.cpp - Implementació de l'escena de títol // © 2025 Port a C++20 -#include "escena_titol.hpp" +#include "title_scene.hpp" #include #include @@ -15,38 +15,38 @@ #include "core/input/input.hpp" #include "core/input/mouse.hpp" #include "core/rendering/shape_renderer.hpp" -#include "core/system/context_escenes.hpp" +#include "core/system/scene_context.hpp" #include "core/system/global_events.hpp" #include "project.h" // Using declarations per simplificar el codi -using GestorEscenes::ContextEscenes; -using Escena = ContextEscenes::Escena; -using Opcio = ContextEscenes::Opcio; +using SceneManager::SceneContext; +using SceneType = SceneContext::SceneType; +using Option = SceneContext::Option; -EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context) +TitleScene::TitleScene(SDLManager& sdl, SceneContext& context) : sdl_(sdl), context_(context), text_(sdl.obte_renderer()), - estat_actual_(EstatTitol::STARFIELD_FADE_IN), + estat_actual_(TitleState::STARFIELD_FADE_IN), temps_acumulat_(0.0F), temps_animacio_(0.0F), temps_estat_main_(0.0F), animacio_activa_(false), factor_lerp_(0.0F) { - std::cout << "Escena Titol: Inicialitzant...\n"; + std::cout << "SceneType Titol: Inicialitzant...\n"; // Inicialitzar configuració de partida (cap jugador actiu per defecte) - config_partida_.jugador1_actiu = false; - config_partida_.jugador2_actiu = false; - config_partida_.mode = GameConfig::Mode::NORMAL; + match_config_.jugador1_actiu = false; + match_config_.jugador2_actiu = false; + match_config_.mode = GameConfig::Mode::NORMAL; // Processar opció del context - auto opcio = context_.consumir_opcio(); + auto option = context_.consumeOption(); - if (opcio == Opcio::JUMP_TO_TITLE_MAIN) { - std::cout << "Escena Titol: Opció JUMP_TO_TITLE_MAIN activada\n"; - estat_actual_ = EstatTitol::MAIN; + if (option == Option::JUMP_TO_TITLE_MAIN) { + std::cout << "SceneType Titol: Opció JUMP_TO_TITLE_MAIN activada\n"; + estat_actual_ = TitleState::MAIN; temps_estat_main_ = 0.0F; } @@ -69,7 +69,7 @@ EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context) ); // Brightness depèn de l'opció - if (estat_actual_ == EstatTitol::MAIN) { + if (estat_actual_ == TitleState::MAIN) { // Si saltem a MAIN, starfield instantàniament brillant starfield_->set_brightness(BRIGHTNESS_STARFIELD); } else { @@ -81,7 +81,7 @@ EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context) ship_animator_ = std::make_unique(sdl_.obte_renderer()); ship_animator_->init(); - if (estat_actual_ == EstatTitol::MAIN) { + if (estat_actual_ == TitleState::MAIN) { // Jump to MAIN: empezar entrada inmediatamente ship_animator_->set_visible(true); ship_animator_->start_entry_animation(); @@ -99,12 +99,12 @@ EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context) } } -EscenaTitol::~EscenaTitol() { +TitleScene::~TitleScene() { // Aturar música de títol quan es destrueix l'escena Audio::get()->stopMusic(); } -void EscenaTitol::inicialitzar_titol() { +void TitleScene::inicialitzar_titol() { using namespace Graphics; // === LÍNIA 1: "ORNI" === @@ -120,7 +120,7 @@ void EscenaTitol::inicialitzar_titol() { for (const auto& fitxer : fitxers_orni) { auto forma = ShapeLoader::load(fitxer); if (!forma || !forma->es_valida()) { - std::cerr << "[EscenaTitol] Error carregant " << fitxer << '\n'; + std::cerr << "[TitleScene] Error carregant " << fitxer << '\n'; continue; } @@ -165,7 +165,7 @@ void EscenaTitol::inicialitzar_titol() { x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES; } - std::cout << "[EscenaTitol] Línia 1 (ORNI): " << lletres_orni_.size() + std::cout << "[TitleScene] Línia 1 (ORNI): " << lletres_orni_.size() << " lletres, ancho total: " << ancho_total_orni << " px\n"; // === Calcular posició Y dinàmica per "ATTACK!" === @@ -175,7 +175,7 @@ void EscenaTitol::inicialitzar_titol() { float separacion_lineas = Defaults::Game::HEIGHT * Defaults::Title::Layout::LOGO_LINE_SPACING; y_attack_dinamica_ = y_orni + altura_orni + separacion_lineas; - std::cout << "[EscenaTitol] Altura ORNI: " << altura_orni + std::cout << "[TitleScene] Altura ORNI: " << altura_orni << " px, Y_ATTACK dinàmica: " << y_attack_dinamica_ << " px\n"; // === LÍNIA 2: "ATTACK!" === @@ -194,7 +194,7 @@ void EscenaTitol::inicialitzar_titol() { for (const auto& fitxer : fitxers_attack) { auto forma = ShapeLoader::load(fitxer); if (!forma || !forma->es_valida()) { - std::cerr << "[EscenaTitol] Error carregant " << fitxer << '\n'; + std::cerr << "[TitleScene] Error carregant " << fitxer << '\n'; continue; } @@ -239,7 +239,7 @@ void EscenaTitol::inicialitzar_titol() { x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES; } - std::cout << "[EscenaTitol] Línia 2 (ATTACK!): " << lletres_attack_.size() + std::cout << "[TitleScene] Línia 2 (ATTACK!): " << lletres_attack_.size() << " lletres, ancho total: " << ancho_total_attack << " px\n"; // Guardar posicions originals per l'animació orbital @@ -253,14 +253,14 @@ void EscenaTitol::inicialitzar_titol() { posicions_originals_attack_.push_back(lletra.posicio); } - std::cout << "[EscenaTitol] Animació: Posicions originals guardades\n"; + std::cout << "[TitleScene] Animació: Posicions originals guardades\n"; } -void EscenaTitol::executar() { +void TitleScene::run() { SDL_Event event; Uint64 last_time = SDL_GetTicks(); - while (GestorEscenes::actual == Escena::TITOL) { + while (SceneManager::actual == SceneType::TITLE) { // Calcular delta_time real Uint64 current_time = SDL_GetTicks(); float delta_time = (current_time - last_time) / 1000.0F; @@ -316,10 +316,10 @@ void EscenaTitol::executar() { sdl_.presenta(); } - std::cout << "Escena Titol: Finalitzant...\n"; + std::cout << "SceneType Titol: Finalitzant...\n"; } -void EscenaTitol::update(float delta_time) { +void TitleScene::update(float delta_time) { // Actualitzar starfield (sempre actiu) if (starfield_) { starfield_->update(delta_time); @@ -327,15 +327,15 @@ void EscenaTitol::update(float delta_time) { // Actualitzar naus (quan visibles) if (ship_animator_ && - (estat_actual_ == EstatTitol::STARFIELD_FADE_IN || - estat_actual_ == EstatTitol::STARFIELD || - estat_actual_ == EstatTitol::MAIN || - estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE)) { + (estat_actual_ == TitleState::STARFIELD_FADE_IN || + estat_actual_ == TitleState::STARFIELD || + estat_actual_ == TitleState::MAIN || + estat_actual_ == TitleState::PLAYER_JOIN_PHASE)) { ship_animator_->update(delta_time); } switch (estat_actual_) { - case EstatTitol::STARFIELD_FADE_IN: { + case TitleState::STARFIELD_FADE_IN: { temps_acumulat_ += delta_time; // Calcular progrés del fade (0.0 → 1.0) @@ -347,17 +347,17 @@ void EscenaTitol::update(float delta_time) { // Transició a STARFIELD quan el fade es completa if (temps_acumulat_ >= DURACIO_FADE_IN) { - estat_actual_ = EstatTitol::STARFIELD; + estat_actual_ = TitleState::STARFIELD; temps_acumulat_ = 0.0F; // Reset timer per al següent estat starfield_->set_brightness(BRIGHTNESS_STARFIELD); // Assegurar valor final } break; } - case EstatTitol::STARFIELD: + case TitleState::STARFIELD: temps_acumulat_ += delta_time; if (temps_acumulat_ >= DURACIO_INIT) { - estat_actual_ = EstatTitol::MAIN; + estat_actual_ = TitleState::MAIN; temps_estat_main_ = 0.0F; // Reset timer al entrar a MAIN animacio_activa_ = false; // Comença estàtic factor_lerp_ = 0.0F; // Sense animació encara @@ -366,7 +366,7 @@ void EscenaTitol::update(float delta_time) { } break; - case EstatTitol::MAIN: { + case TitleState::MAIN: { temps_estat_main_ += delta_time; // Iniciar animació d'entrada de naus després del delay @@ -399,7 +399,7 @@ void EscenaTitol::update(float delta_time) { break; } - case EstatTitol::PLAYER_JOIN_PHASE: + case TitleState::PLAYER_JOIN_PHASE: temps_acumulat_ += delta_time; // Continuar animació orbital durant la transició @@ -407,22 +407,22 @@ void EscenaTitol::update(float delta_time) { // [NOU] Continuar comprovant si l'altre jugador vol unir-se durant la transició ("late join") { - bool p1_actiu_abans = config_partida_.jugador1_actiu; - bool p2_actiu_abans = config_partida_.jugador2_actiu; + bool p1_actiu_abans = match_config_.jugador1_actiu; + bool p2_actiu_abans = match_config_.jugador2_actiu; if (checkStartGameButtonPressed()) { - // Updates config_partida_ if pressed, logs are in the method - context_.set_config_partida(config_partida_); + // Updates match_config_ if pressed, logs are in the method + context_.setMatchConfig(match_config_); // Trigger animació de sortida per la nau que acaba d'unir-se if (ship_animator_) { - if (config_partida_.jugador1_actiu && !p1_actiu_abans) { + if (match_config_.jugador1_actiu && !p1_actiu_abans) { ship_animator_->trigger_exit_animation_for_player(1); - std::cout << "[EscenaTitol] P1 late join - ship exiting\n"; + std::cout << "[TitleScene] P1 late join - ship exiting\n"; } - if (config_partida_.jugador2_actiu && !p2_actiu_abans) { + if (match_config_.jugador2_actiu && !p2_actiu_abans) { ship_animator_->trigger_exit_animation_for_player(2); - std::cout << "[EscenaTitol] P2 late join - ship exiting\n"; + std::cout << "[TitleScene] P2 late join - ship exiting\n"; } } @@ -432,35 +432,35 @@ void EscenaTitol::update(float delta_time) { // Reiniciar el timer per allargar el temps de transició temps_acumulat_ = 0.0F; - std::cout << "[EscenaTitol] Segon jugador s'ha unit - so i timer reiniciats\n"; + std::cout << "[TitleScene] Segon jugador s'ha unit - so i timer reiniciats\n"; } } if (temps_acumulat_ >= DURACIO_TRANSITION) { // Transició a pantalla negra - estat_actual_ = EstatTitol::BLACK_SCREEN; + estat_actual_ = TitleState::BLACK_SCREEN; temps_acumulat_ = 0.0F; - std::cout << "[EscenaTitol] Passant a BLACK_SCREEN\n"; + std::cout << "[TitleScene] Passant a BLACK_SCREEN\n"; } break; - case EstatTitol::BLACK_SCREEN: + case TitleState::BLACK_SCREEN: temps_acumulat_ += delta_time; // No animation, no input checking - just wait if (temps_acumulat_ >= DURACIO_BLACK_SCREEN) { - // Transició a escena JOC - GestorEscenes::actual = Escena::JOC; - std::cout << "[EscenaTitol] Canviant a escena JOC\n"; + // Transició a escena GAME + SceneManager::actual = SceneType::GAME; + std::cout << "[TitleScene] Canviant a escena GAME\n"; } break; } // Verificar botones de skip (FIRE/THRUST/START) para saltar escenas ANTES de MAIN - if (estat_actual_ == EstatTitol::STARFIELD_FADE_IN || estat_actual_ == EstatTitol::STARFIELD) { + if (estat_actual_ == TitleState::STARFIELD_FADE_IN || estat_actual_ == TitleState::STARFIELD) { if (checkSkipButtonPressed()) { // Saltar a MAIN - estat_actual_ = EstatTitol::MAIN; + estat_actual_ = TitleState::MAIN; starfield_->set_brightness(BRIGHTNESS_STARFIELD); temps_estat_main_ = 0.0F; @@ -469,10 +469,10 @@ void EscenaTitol::update(float delta_time) { } // Verificar boton START para iniciar partida desde MAIN - if (estat_actual_ == EstatTitol::MAIN) { + if (estat_actual_ == TitleState::MAIN) { // Guardar estat anterior per detectar qui ha premut START AQUEST frame - bool p1_actiu_abans = config_partida_.jugador1_actiu; - bool p2_actiu_abans = config_partida_.jugador2_actiu; + bool p1_actiu_abans = match_config_.jugador1_actiu; + bool p2_actiu_abans = match_config_.jugador2_actiu; if (checkStartGameButtonPressed()) { // Si START es prem durant el delay (naus encara invisibles), saltar-les a FLOATING @@ -482,26 +482,26 @@ void EscenaTitol::update(float delta_time) { } // Configurar partida abans de canviar d'escena - context_.set_config_partida(config_partida_); - std::cout << "[EscenaTitol] Configuració de partida - P1: " - << (config_partida_.jugador1_actiu ? "ACTIU" : "INACTIU") + context_.setMatchConfig(match_config_); + std::cout << "[TitleScene] Configuració de partida - P1: " + << (match_config_.jugador1_actiu ? "ACTIU" : "INACTIU") << ", P2: " - << (config_partida_.jugador2_actiu ? "ACTIU" : "INACTIU") + << (match_config_.jugador2_actiu ? "ACTIU" : "INACTIU") << '\n'; - context_.canviar_escena(Escena::JOC); - estat_actual_ = EstatTitol::PLAYER_JOIN_PHASE; + context_.setNextScene(SceneType::GAME); + estat_actual_ = TitleState::PLAYER_JOIN_PHASE; temps_acumulat_ = 0.0F; // Trigger animació de sortida NOMÉS per les naus que han premut START if (ship_animator_) { - if (config_partida_.jugador1_actiu && !p1_actiu_abans) { + if (match_config_.jugador1_actiu && !p1_actiu_abans) { ship_animator_->trigger_exit_animation_for_player(1); - std::cout << "[EscenaTitol] P1 ship exiting\n"; + std::cout << "[TitleScene] P1 ship exiting\n"; } - if (config_partida_.jugador2_actiu && !p2_actiu_abans) { + if (match_config_.jugador2_actiu && !p2_actiu_abans) { ship_animator_->trigger_exit_animation_for_player(2); - std::cout << "[EscenaTitol] P2 ship exiting\n"; + std::cout << "[TitleScene] P2 ship exiting\n"; } } @@ -511,7 +511,7 @@ void EscenaTitol::update(float delta_time) { } } -void EscenaTitol::actualitzar_animacio_logo(float delta_time) { +void TitleScene::actualitzar_animacio_logo(float delta_time) { // Només calcular i aplicar offsets si l'animació està activa if (animacio_activa_) { // Acumular temps escalat @@ -541,29 +541,29 @@ void EscenaTitol::actualitzar_animacio_logo(float delta_time) { } } -void EscenaTitol::draw() { +void TitleScene::draw() { // Dibuixar starfield de fons (en tots els estats excepte BLACK_SCREEN) - if (starfield_ && estat_actual_ != EstatTitol::BLACK_SCREEN) { + if (starfield_ && estat_actual_ != TitleState::BLACK_SCREEN) { starfield_->draw(); } // Dibuixar naus (després starfield, abans logo) if (ship_animator_ && - (estat_actual_ == EstatTitol::STARFIELD_FADE_IN || - estat_actual_ == EstatTitol::STARFIELD || - estat_actual_ == EstatTitol::MAIN || - estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE)) { + (estat_actual_ == TitleState::STARFIELD_FADE_IN || + estat_actual_ == TitleState::STARFIELD || + estat_actual_ == TitleState::MAIN || + estat_actual_ == TitleState::PLAYER_JOIN_PHASE)) { ship_animator_->draw(); } // En els estats STARFIELD_FADE_IN i STARFIELD, només mostrar starfield (sense text) - if (estat_actual_ == EstatTitol::STARFIELD_FADE_IN || estat_actual_ == EstatTitol::STARFIELD) { + if (estat_actual_ == TitleState::STARFIELD_FADE_IN || estat_actual_ == TitleState::STARFIELD) { return; } // Estat MAIN i PLAYER_JOIN_PHASE: Dibuixar títol i text (sobre el starfield) // BLACK_SCREEN: no draw res (fons negre ja està netejat) - if (estat_actual_ == EstatTitol::MAIN || estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE) { + if (estat_actual_ == TitleState::MAIN || estat_actual_ == TitleState::PLAYER_JOIN_PHASE) { // === Calcular i renderitzar ombra (només si animació activa) === if (animacio_activa_) { float temps_shadow = temps_animacio_ - SHADOW_DELAY; @@ -648,7 +648,7 @@ void EscenaTitol::draw() { const float spacing = Defaults::Title::Layout::TEXT_SPACING; bool mostrar_text = true; - if (estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE) { + if (estat_actual_ == TitleState::PLAYER_JOIN_PHASE) { // Parpelleig: sin oscil·la entre -1 i 1, volem ON quan > 0 float fase = temps_acumulat_ * BLINK_FREQUENCY * 2.0F * std::numbers::pi_v; // 2π × freq × temps mostrar_text = (std::sin(fase) > 0.0F); @@ -697,27 +697,27 @@ void EscenaTitol::draw() { } } -auto EscenaTitol::checkSkipButtonPressed() -> bool { +auto TitleScene::checkSkipButtonPressed() -> bool { return Input::get()->checkAnyPlayerAction(ARCADE_BUTTONS); } -auto EscenaTitol::checkStartGameButtonPressed() -> bool { +auto TitleScene::checkStartGameButtonPressed() -> bool { auto* input = Input::get(); bool any_pressed = false; for (auto action : START_GAME_BUTTONS) { if (input->checkActionPlayer1(action, Input::DO_NOT_ALLOW_REPEAT)) { - if (!config_partida_.jugador1_actiu) { - config_partida_.jugador1_actiu = true; + if (!match_config_.jugador1_actiu) { + match_config_.jugador1_actiu = true; any_pressed = true; - std::cout << "[EscenaTitol] P1 pressed START\n"; + std::cout << "[TitleScene] P1 pressed START\n"; } } if (input->checkActionPlayer2(action, Input::DO_NOT_ALLOW_REPEAT)) { - if (!config_partida_.jugador2_actiu) { - config_partida_.jugador2_actiu = true; + if (!match_config_.jugador2_actiu) { + match_config_.jugador2_actiu = true; any_pressed = true; - std::cout << "[EscenaTitol] P2 pressed START\n"; + std::cout << "[TitleScene] P2 pressed START\n"; } } } @@ -725,6 +725,6 @@ auto EscenaTitol::checkStartGameButtonPressed() -> bool { return any_pressed; } -void EscenaTitol::processar_events(const SDL_Event& event) { +void TitleScene::processar_events(const SDL_Event& event) { // No procesar eventos genéricos aquí - la lógica se movió a update() } diff --git a/source/game/escenes/escena_titol.hpp b/source/game/scenes/title_scene.hpp similarity index 91% rename from source/game/escenes/escena_titol.hpp rename to source/game/scenes/title_scene.hpp index 7f6ee0c..82c1271 100644 --- a/source/game/escenes/escena_titol.hpp +++ b/source/game/scenes/title_scene.hpp @@ -16,7 +16,7 @@ #include "core/graphics/vector_text.hpp" #include "core/input/input_types.hpp" #include "core/rendering/sdl_manager.hpp" -#include "core/system/context_escenes.hpp" +#include "core/system/scene_context.hpp" #include "core/system/game_config.hpp" #include "core/types.hpp" #include "game/title/ship_animator.hpp" @@ -25,15 +25,15 @@ static constexpr std::array START_GAME_BUTTONS = { InputAction::START}; -class EscenaTitol { +class TitleScene { public: - explicit EscenaTitol(SDLManager& sdl, GestorEscenes::ContextEscenes& context); - ~EscenaTitol(); // Destructor per aturar música - void executar(); // Bucle principal de l'escena + explicit TitleScene(SDLManager& sdl, SceneManager::SceneContext& context); + ~TitleScene(); // Destructor per aturar música + void run(); // Bucle principal de l'escena private: // Màquina d'estats per la pantalla de títol - enum class EstatTitol { + enum class TitleState { STARFIELD_FADE_IN, // Fade-in del starfield (3.0s) STARFIELD, // Pantalla amb camp d'estrelles (4.0s) MAIN, // Pantalla de títol amb text (indefinit, fins START) @@ -51,12 +51,12 @@ class EscenaTitol { }; SDLManager& sdl_; - GestorEscenes::ContextEscenes& context_; - GameConfig::ConfigPartida config_partida_; // Configuració de jugadors actius + SceneManager::SceneContext& context_; + GameConfig::MatchConfig match_config_; // Configuració de jugadors actius Graphics::VectorText text_; // Sistema de text vectorial std::unique_ptr starfield_; // Camp d'estrelles de fons std::unique_ptr ship_animator_; // Naus 3D flotants - EstatTitol estat_actual_; // Estat actual de la màquina + TitleState estat_actual_; // Estat actual de la màquina float temps_acumulat_; // Temps acumulat per l'estat INIT // Lletres del títol "ORNI ATTACK!" diff --git a/source/game/stage_system/stage_manager.cpp b/source/game/stage_system/stage_manager.cpp index 00fb32b..7b1bc31 100644 --- a/source/game/stage_system/stage_manager.cpp +++ b/source/game/stage_system/stage_manager.cpp @@ -129,10 +129,10 @@ void StageManager::processar_level_start(float delta_time) { void StageManager::processar_playing(float delta_time, bool pausar_spawn) { // Update spawn controller (pauses when pausar_spawn = true) - // Note: The actual enemy array update happens in EscenaJoc::update() + // Note: The actual enemy array update happens in GameScene::update() // This is just for internal timekeeping (void)delta_time; // Spawn controller is updated externally - (void)pausar_spawn; // Passed to spawn_controller_.update() by EscenaJoc + (void)pausar_spawn; // Passed to spawn_controller_.update() by GameScene } void StageManager::processar_level_completed(float delta_time) { diff --git a/source/game/title/ship_animator.hpp b/source/game/title/ship_animator.hpp index 4245ace..20f7641 100644 --- a/source/game/title/ship_animator.hpp +++ b/source/game/title/ship_animator.hpp @@ -68,7 +68,7 @@ class ShipAnimator { void update(float delta_time); void draw() const; - // Control d'estat (cridat per EscenaTitol) + // Control d'estat (cridat per TitleScene) void start_entry_animation(); void trigger_exit_animation(); // Anima totes les naus void trigger_exit_animation_for_player(int jugador_id); // Anima només una nau (P1=1, P2=2)