#pragma once #include #include // Para initializer_list #include // Para shared_ptr #include // Para string #include // Para unordered_map #include // Para vector #include "game/entities/player.hpp" // Para PlayerSpawn #include "game/gameplay/room.hpp" // Para Room, Room::Border #include "utils/delta_timer.hpp" // Para DeltaTimer class RoomTracker; // lines 13-13 class Scoreboard; // lines 14-14 class Surface; class Game { public: // --- Estructuras --- enum class Mode { DEMO, GAME }; enum class State { PLAYING, // Normal gameplay BLACK_SCREEN, // Black screen after death (0.30s) GAME_OVER, // Intermediate state before changing scene FADE_TO_ENDING, // Fade out transition POST_FADE_ENDING, // Black screen delay before ending }; // --- Constructor y Destructor --- explicit Game(Mode mode); ~Game(); // --- Frame (llamados desde Director::iterate) --- void update(); void render(); private: // --- Constantes de tiempo --- static constexpr float BLACK_SCREEN_DURATION = 0.30F; // Duración de la pantalla negra en segundos (20 frames a 66.67fps) static constexpr float GAME_OVER_THRESHOLD = 0.255F; // Tiempo antes del game over en segundos (17 frames a 66.67fps) static constexpr float DEMO_ROOM_DURATION = 6.0F; // Duración de cada habitación en modo demo en segundos (400 frames) static constexpr float FADE_STEP_INTERVAL = 0.05F; // Intervalo entre pasos de fade en segundos static constexpr float POST_FADE_DELAY = 2.0F; // Duración de la pantalla negra después del fade static constexpr float TRANSITION_DURATION = 0.5F; // Duración de la transición entre pantallas en segundos // --- Estructuras --- struct DemoData { float time_accumulator{0.0F}; // Acumulador de tiempo para el modo demo int room_index{0}; // Índice para el vector de habitaciones std::vector rooms; // Listado con los mapas de la demo }; // --- Métodos --- void handleEvents(); // Comprueba los eventos de la cola void transitionToState(State new_state); // Cambia al estado especificado y resetea los timers void updatePlaying(float delta_time); // Actualiza el juego en estado PLAYING void updateBlackScreen(float delta_time); // Actualiza el juego en estado BLACK_SCREEN void updateGameOver(float delta_time); // Actualiza el juego en estado GAME_OVER void updateFadeToEnding(float delta_time); // Actualiza el juego en estado FADE_TO_ENDING void updatePostFadeEnding(float delta_time); // Actualiza el juego en estado POST_FADE_ENDING void renderPlaying(); // Renderiza el juego en estado PLAYING (directo a pantalla) static void renderBlackScreen(); // Renderiza el juego en estado BLACK_SCREEN (pantalla negra) static void renderGameOver(); // Renderiza el juego en estado GAME_OVER (pantalla negra) void renderFadeToEnding(); // Renderiza el juego en estado FADE_TO_ENDING (via backbuffer) static void renderPostFadeEnding(); // Renderiza el juego en estado POST_FADE_ENDING (pantalla negra) auto changeRoom(const std::string& room_path) -> bool; // Cambia de habitación auto getOrCreateRoom(const std::string& room_path) -> std::shared_ptr; // Obtiene una habitación del caché o la crea void buildCollisionBorders(); // Rellena el tilemap extendido de la room actual con bordes adyacentes void updateAdjacentRooms(float delta_time); // Actualiza enemigos de las habitaciones adyacentes void handleInput(); // Comprueba el teclado void checkPlayerIsOnBorder(); // Comprueba si el jugador esta en el borde de la pantalla y actua auto checkPlayerAndEnemies() -> bool; // Comprueba las colisiones del jugador con los enemigos void checkPlayerAndPlatforms(); // Comprueba si el jugador está sobre una plataforma móvil void checkPlayerAndItems(); // Comprueba las colisiones del jugador con los objetos void checkIfPlayerIsAlive(); // Comprueba si el jugador esta vivo void killPlayer(); // Mata al jugador void togglePause(); // Pone el juego en pausa void initPlayer(const Player::SpawnData& spawn_point, std::shared_ptr room); // Inicializa al jugador void endTransition(); // Finaliza la transición entre pantallas void keepMusicPlaying(); // Hace sonar la música void demoInit(); // DEMO MODE: Inicializa las variables para el modo demo void demoCheckRoomChange(float delta_time); // DEMO MODE: Comprueba si se ha de cambiar de habitación #ifdef _DEBUG static void renderDebugInfo(); // Pone la información de debug en pantalla void handleDebugEvents(const SDL_Event& event); // Comprueba los eventos void handleDebugMouseDrag(float delta_time); // Maneja el arrastre del jugador con el ratón (debug) #endif // --- Variables miembro --- // Objetos y punteros a recursos std::shared_ptr scoreboard_data_; // Estructura con los datos del marcador std::shared_ptr scoreboard_; // Objeto encargado de gestionar el marcador std::shared_ptr room_tracker_; // Lleva el control de las habitaciones visitadas std::shared_ptr room_; // Objeto encargado de gestionar cada habitación del juego std::shared_ptr player_; // Objeto con el jugador std::shared_ptr game_backbuffer_surface_; // Backbuffer para efectos de fade // Variables de estado del juego Mode mode_; // Modo del juego State state_{State::PLAYING}; // Estado actual de la escena DeltaTimer delta_timer_; // Timer para calcular delta time std::string current_room_; // Fichero de la habitación actual Player::SpawnData spawn_data_; // Lugar de la habitación donde aparece el jugador bool paused_{false}; // Indica si el juego se encuentra en pausa float state_time_{0.0F}; // Tiempo acumulado en el estado actual float fade_accumulator_{0.0F}; // Acumulador de tiempo para el fade // Caché de habitaciones vivas (enemigos mantienen su posición) std::unordered_map> room_cache_; // Transición animada entre pantallas bool transitioning_{false}; // Indica si hay una transición en curso float transition_timer_{0.0F}; // Tiempo transcurrido en la transición std::shared_ptr transition_old_room_; // Habitación saliente (se mantiene viva durante la transición) Room::Border transition_direction_{Room::Border::NONE}; // Dirección de la transición bool transition_just_ended_{false}; // Cooldown de 1 frame tras finalizar transición // Variables de demo mode DemoData demo_; // Variables para el modo demo #ifdef _DEBUG // Variables de debug para arrastre con ratón bool debug_dragging_player_{false}; // Indica si estamos arrastrando al jugador con el ratón float debug_drag_speed_{0.0F}; // Velocidad actual del arrastre (ease-in) // Estado previo de invencibilidad antes de entrar en modo debug bool invincible_before_debug_{false}; #endif };