// escena_joc.hpp - Lògica principal del joc // © 1999 Visente i Sergi (versió Pascal) // © 2025 Port a C++20 amb SDL3 #ifndef ESCENA_JOC_HPP #define ESCENA_JOC_HPP #include #include #include #include #include "core/graphics/vector_text.hpp" #include "core/rendering/sdl_manager.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 { NONE, // Normal gameplay CONTINUE, // Continue countdown screen (9→0) GAME_OVER // Final game over (returning to title) }; // Classe principal del joc (escena) class GameScene { public: explicit GameScene(SDLManager& sdl, SceneManager::SceneContext& context); ~GameScene() = default; void run(); // Bucle principal de l'escena void init(); void update(float delta_time); void draw(); private: SDLManager& sdl_; SceneManager::SceneContext& context_; GameConfig::MatchConfig match_config_; // Configuració de jugadors active // Efectes visuals Effects::DebrisManager debris_manager_; Effects::FloatingScoreManager floating_score_manager_; // Estat del joc 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 d'animació INIT_HUD bool init_hud_rect_sound_played_; // Flag para evitar repetir sonido del rectángulo // Funcions privades void tocado(uint8_t player_id); void detectar_col·lisions_bales_enemics(); // Col·lisions bullet-enemy void detectar_col·lisio_naus_enemics(); // Ship-enemy collision detection (plural) void detectar_col·lisions_bales_jugadors(); // Bullet-player collision detection (friendly fire) void dibuixar_marges() const; // Dibuixar vores de la zona de joc void dibuixar_marcador(); // Dibuixar marcador de puntuació 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 processar_input_continue(); // Handle input during continue screen void actualitzar_continue(float delta_time); // Update continue countdown void check_and_apply_continue_timeout(); // Check if continue timed out and transition to GAME_OVER void dibuixar_continue(); // Draw continue screen // [NEW] Stage system helpers void dibuixar_missatge_stage(const std::string& message); // [NEW] Funcions d'animació per INIT_HUD void dibuixar_marges_animat(float progress) const; // Rectangle amb creixement uniforme void dibuixar_marcador_animat(float progress); // Marcador que puja des de baix [[nodiscard]] Vec2 calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const; // Posició animada de la ship // [NEW] Función helper del sistema de animación INIT_HUD [[nodiscard]] float calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const; // [NEW] Funció helper del marcador [[nodiscard]] std::string buildScoreboard() const; }; #endif // ESCENA_JOC_HPP