// game_scene.hpp - Lógica principal del juego // © 2026 JailDesigner #pragma once #include #include #include #include #include "core/graphics/vector_text.hpp" #include "core/physics/physics_world.hpp" #include "core/rendering/sdl_manager.hpp" #include "core/system/scene.hpp" #include "core/system/scene_context.hpp" #include "core/system/game_config.hpp" #include "core/types.hpp" #include "game/constants.hpp" #include "game/effects/debris_manager.hpp" #include "game/effects/floating_score_manager.hpp" #include "game/entities/bullet.hpp" #include "game/entities/enemy.hpp" #include "game/entities/ship.hpp" #include "game/stage_system/stage_config.hpp" #include "game/stage_system/stage_manager.hpp" // Game over state machine enum class GameOverState : uint8_t { NONE, // Normal gameplay CONTINUE, // Continue countdown screen (9→0) GAME_OVER // Final game over (returning to title) }; // Clase principal del juego (escena) class GameScene final : public Scene { public: explicit GameScene(SDLManager& sdl, SceneManager::SceneContext& context); ~GameScene() override = default; // Scene interface void handleEvent(const SDL_Event& event) override; void update(float delta_time) override; void draw() override; [[nodiscard]] auto isFinished() const -> bool override; // Inicialización del estado del juego (llamado por Director tras crear la escena). void init(); private: SDLManager& sdl_; SceneManager::SceneContext& context_; GameConfig::MatchConfig match_config_; // Configuración de jugadors active // Mundo físico (Fase 5) — integración cinemática + colisiones Physics::PhysicsWorld physics_world_; // Efectes visuals Effects::DebrisManager debris_manager_; Effects::FloatingScoreManager floating_score_manager_; // Estat del juego std::array ships_; // [0]=P1, [1]=P2 std::array enemies_; std::array bullets_; // 6 balas: P1=[0,1,2], P2=[3,4,5] std::array hit_timer_per_player_; // Death timers per player (seconds) // Lives and game over system std::array lives_per_player_; // [0]=P1, [1]=P2 GameOverState game_over_state_; // Game over state machine (NONE, CONTINUE, GAME_OVER) int continue_counter_; // Continue countdown (9→0) float continue_tick_timer_; // Timer for countdown tick (1.0s) int continues_used_; // Continues used this game (0-3 max) float game_over_timer_; // Final GAME OVER timer before title screen Vec2 death_position_; // Death position (for respawn) std::array score_per_player_; // [0]=P1, [1]=P2 // Text vectorial Graphics::VectorText text_; // [NEW] Stage system std::unique_ptr stage_config_; std::unique_ptr stage_manager_; // Control de sons de animación INIT_HUD bool init_hud_rect_sound_played_; // Flag para evitar repetir sonido del rectángulo // Funciones privades void tocado(uint8_t player_id); void dibuixar_marges() const; // Dibuixar vores de la zona de juego void dibuixar_marcador(); // Dibuixar marcador de puntuación void disparar_bala(uint8_t player_id); // Shoot bullet from player [[nodiscard]] Vec2 obtenir_punt_spawn(uint8_t player_id) const; // Get spawn position for player // [NEW] Continue & Join system void unir_jugador(uint8_t player_id); // Join inactive player mid-game void dibuixar_continue(); // Draw continue screen // [NEW] Stage system helpers void dibuixar_missatge_stage(const std::string& message); // [NEW] Función helper del marcador [[nodiscard]] std::string buildScoreboard() const; // Sub-pasos de update() (descompuestos en Fase 9d para reducir // complejidad cognitiva; cada uno es responsable de una sección). void stepPhysics(float delta_time); void stepShootingInput(); void stepMidGameJoin(); // Devuelven true si el frame debe salir tras esta sección. [[nodiscard]] auto stepContinueScreen(float delta_time) -> bool; [[nodiscard]] auto stepGameOver(float delta_time) -> bool; // Avanza el death timer / respawn / transición a CONTINUE. Si algún // jugador está en secuencia de muerte, también actualiza efectos // (enemigos, balas, debris) que siguen vivos en el escenario. void stepDeathSequence(float delta_time); void stepStageStateMachine(float delta_time); void runStageInitHud(float delta_time); void runStageLevelStart(float delta_time); void runStagePlaying(float delta_time); void runStageLevelCompleted(float delta_time); // Helper: ejecuta colisiones de gameplay con el Context preparado. void runCollisionDetections(); };