308 lines
19 KiB
C++
308 lines
19 KiB
C++
#pragma once
|
|
|
|
#include <SDL3/SDL.h> // Para SDL_Event, SDL_Renderer, SDL_Texture, Uint64, Uint8
|
|
|
|
#include <memory> // Para shared_ptr, unique_ptr
|
|
#include <set> // Para Set
|
|
#include <string> // Para string
|
|
#include <vector> // Para vector
|
|
|
|
#include "hit.h" // Para Hit
|
|
#include "item.h" // Para Item, ItemType
|
|
#include "manage_hiscore_table.h" // Para HiScoreEntry
|
|
#include "options.h" // Para SettingsOptions, settings
|
|
#include "path_sprite.h" // Para PathSprite, Path
|
|
#include "pause_manager.h" // Para PauseManager
|
|
#include "player.h" // Para Player
|
|
#include "smart_sprite.h" // Para SmartSprite
|
|
#include "utils.h" // Para Demo
|
|
|
|
class Background;
|
|
class Balloon;
|
|
class BalloonManager;
|
|
class Bullet;
|
|
class Fade;
|
|
class Input;
|
|
class Scoreboard;
|
|
class Screen;
|
|
class Tabe;
|
|
class Texture;
|
|
enum class BulletType : Uint8;
|
|
namespace Difficulty {
|
|
enum class Code;
|
|
} // namespace Difficulty
|
|
|
|
// Clase Game
|
|
class Game {
|
|
public:
|
|
// --- Constantes ---
|
|
static constexpr bool DEMO_OFF = false;
|
|
static constexpr bool DEMO_ON = true;
|
|
|
|
// --- Constructor y destructor ---
|
|
Game(Player::Id player_id, int current_stage, bool demo);
|
|
~Game();
|
|
|
|
// --- Bucle principal ---
|
|
void run();
|
|
|
|
private:
|
|
// --- Tipos internos ---
|
|
enum class State {
|
|
FADE_IN,
|
|
ENTERING_PLAYER,
|
|
SHOWING_GET_READY_MESSAGE,
|
|
PLAYING,
|
|
COMPLETED,
|
|
GAME_OVER,
|
|
};
|
|
|
|
// --- Constantes internas ---
|
|
static constexpr int HELP_COUNTER = 1000;
|
|
static constexpr int GAME_COMPLETED_START_FADE = 500;
|
|
static constexpr int GAME_COMPLETED_END = 700;
|
|
static constexpr int GAME_OVER_COUNTER = 350;
|
|
static constexpr int TIME_STOPPED_COUNTER = 360;
|
|
static constexpr int ITEM_POINTS_1_DISK_ODDS = 10;
|
|
static constexpr int ITEM_POINTS_2_GAVINA_ODDS = 6;
|
|
static constexpr int ITEM_POINTS_3_PACMAR_ODDS = 3;
|
|
static constexpr int ITEM_CLOCK_ODDS = 5;
|
|
static constexpr int ITEM_COFFEE_ODDS = 5;
|
|
static constexpr int ITEM_POWER_BALL_ODDS = 0;
|
|
static constexpr int ITEM_COFFEE_MACHINE_ODDS = 4;
|
|
|
|
// --- Estructuras ---
|
|
struct Helper {
|
|
bool need_coffee{false}; // Indica si se necesitan cafes
|
|
bool need_coffee_machine{false}; // Indica si se necesita PowerUp
|
|
bool need_power_ball{false}; // Indica si se necesita una PowerBall
|
|
int counter; // Contador para no dar ayudas consecutivas
|
|
int item_disk_odds; // Probabilidad de aparición del objeto
|
|
int item_gavina_odds; // Probabilidad de aparición del objeto
|
|
int item_pacmar_odds; // Probabilidad de aparición del objeto
|
|
int item_clock_odds; // Probabilidad de aparición del objeto
|
|
int item_coffee_odds; // Probabilidad de aparición del objeto
|
|
int item_coffee_machine_odds; // Probabilidad de aparición del objeto
|
|
|
|
Helper()
|
|
: counter(HELP_COUNTER),
|
|
item_disk_odds(ITEM_POINTS_1_DISK_ODDS),
|
|
item_gavina_odds(ITEM_POINTS_2_GAVINA_ODDS),
|
|
item_pacmar_odds(ITEM_POINTS_3_PACMAR_ODDS),
|
|
item_clock_odds(ITEM_CLOCK_ODDS),
|
|
item_coffee_odds(ITEM_COFFEE_ODDS),
|
|
item_coffee_machine_odds(ITEM_COFFEE_MACHINE_ODDS) {}
|
|
};
|
|
|
|
// --- Objetos y punteros ---
|
|
SDL_Renderer *renderer_; // El renderizador de la ventana
|
|
Screen *screen_; // Objeto encargado de dibujar en pantalla
|
|
Input *input_; // Manejador de entrada
|
|
Scoreboard *scoreboard_; // Objeto para dibujar el marcador
|
|
|
|
std::unique_ptr<Background> background_; // Objeto para dibujar el fondo del juego
|
|
|
|
SDL_Texture *canvas_; // Textura para dibujar la zona de juego
|
|
|
|
std::vector<std::shared_ptr<Player>> players_; // Vector con los jugadores
|
|
std::vector<std::shared_ptr<Bullet>> bullets_; // Vector con las balas
|
|
std::vector<std::unique_ptr<Item>> items_; // Vector con los items
|
|
std::vector<std::unique_ptr<SmartSprite>> smart_sprites_; // Vector con los smartsprites
|
|
std::vector<std::unique_ptr<PathSprite>> path_sprites_; // Vector con los pathsprites
|
|
|
|
std::vector<std::shared_ptr<Texture>> item_textures_; // Vector con las texturas de los items
|
|
std::vector<std::vector<std::shared_ptr<Texture>>> player_textures_; // Vector con todas las texturas de los jugadores
|
|
|
|
std::vector<std::shared_ptr<Texture>> game_text_textures_; // Vector con las texturas para los sprites con textos
|
|
|
|
std::vector<std::vector<std::string>> item_animations_; // Vector con las animaciones de los items
|
|
std::vector<std::vector<std::string>> player_animations_; // Vector con las animaciones del jugador
|
|
|
|
std::unique_ptr<PauseManager> pause_manager_; // Objeto para gestionar la pausa
|
|
std::unique_ptr<Fade> fade_in_; // Objeto para renderizar fades
|
|
std::unique_ptr<Fade> fade_out_; // Objeto para renderizar fades
|
|
std::unique_ptr<BalloonManager> balloon_manager_; // Objeto para gestionar los globos
|
|
std::unique_ptr<Tabe> tabe_; // Objeto para gestionar el Tabe Volaor
|
|
std::vector<Path> paths_; // Vector con los recorridos precalculados almacenados
|
|
|
|
// --- Variables de estado ---
|
|
HiScoreEntry hi_score_ = HiScoreEntry(
|
|
Options::settings.hi_score_table[0].name,
|
|
Options::settings.hi_score_table[0].score); // Máxima puntuación y nombre de quien la ostenta
|
|
|
|
Demo demo_; // Variable con todas las variables relacionadas con el modo demo
|
|
Difficulty::Code difficulty_ = Options::settings.difficulty; // Dificultad del juego
|
|
Helper helper_; // Variable para gestionar las ayudas
|
|
Uint64 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
|
bool coffee_machine_enabled_ = false; // Indica si hay una máquina de café en el terreno de juego
|
|
bool hi_score_achieved_ = false; // Indica si se ha superado la puntuación máxima
|
|
float difficulty_score_multiplier_; // Multiplicador de puntos en función de la dificultad
|
|
int counter_ = 0; // Contador para el juego
|
|
int game_completed_counter_ = 0; // Contador para el tramo final, cuando se ha completado la partida y ya no aparecen más globos
|
|
int game_over_counter_ = GAME_OVER_COUNTER; // Contador para el estado de fin de partida
|
|
int time_stopped_counter_ = 0; // Temporizador para llevar la cuenta del tiempo detenido
|
|
int total_power_to_complete_game_; // La suma del poder necesario para completar todas las fases
|
|
int menace_current_ = 0; // Nivel de amenaza actual
|
|
int menace_threshold_ = 0; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el número de globos
|
|
State state_ = State::FADE_IN; // Estado
|
|
std::vector<std::shared_ptr<Player>> players_to_put_at_back_;
|
|
std::vector<std::shared_ptr<Player>> players_to_put_at_front_;
|
|
Hit hit_; // Para representar colisiones en pantalla
|
|
|
|
#ifdef _DEBUG
|
|
bool auto_pop_balloons_ = false; // Si es true, incrementa automaticamente los globos explotados
|
|
#endif
|
|
|
|
// --- Ciclo principal del juego ---
|
|
void update(); // Actualiza la lógica principal del juego
|
|
void render(); // Renderiza todos los elementos del juego
|
|
void checkEvents(); // Procesa los eventos del sistema en cola
|
|
void checkState(); // Verifica y actualiza el estado actual del juego
|
|
void setState(State state); // Cambia el estado del juego
|
|
void cleanVectors(); // Limpia vectores de elementos deshabilitados
|
|
|
|
// --- Gestión de estados del juego ---
|
|
void updateGameStates(); // Actualiza todos los estados del juego
|
|
void updateGameStateFadeIn(); // Gestiona el estado de transición de entrada
|
|
void updateGameStateEnteringPlayer(); // Gestiona el estado de entrada de jugador
|
|
void updateGameStateShowingGetReadyMessage(); // Gestiona el estado de mensaje "preparado"
|
|
void updateGameStatePlaying(); // Gestiona el estado de juego activo
|
|
void updateGameStateCompleted(); // Gestiona el estado de juego completado
|
|
void updateGameStateGameOver(); // Gestiona el estado de fin de partida
|
|
|
|
// --- Gestión de jugadores ---
|
|
void initPlayers(Player::Id player_id); // Inicializa los datos de los jugadores
|
|
void updatePlayers(); // Actualiza las variables y estados de los jugadores
|
|
void renderPlayers(); // Renderiza todos los jugadores en pantalla
|
|
void sortPlayersByZOrder(); // Reorganiza el orden de dibujado de jugadores
|
|
auto getPlayer(Player::Id id) -> std::shared_ptr<Player>; // Obtiene un jugador por su identificador
|
|
static auto getController(Player::Id player_id) -> int; // Obtiene el controlador asignado a un jugador
|
|
|
|
// --- Estado de jugadores ---
|
|
void checkAndUpdatePlayerStatus(int active_player_index, int inactive_player_index); // Actualiza estado entre jugadores
|
|
void checkPlayersStatusPlaying(); // Verifica el estado de juego de todos los jugadores
|
|
auto allPlayersAreWaitingOrGameOver() -> bool; // Verifica si todos esperan o han perdido
|
|
auto allPlayersAreGameOver() -> bool; // Verifica si todos los jugadores han perdido
|
|
auto allPlayersAreNotPlaying() -> bool; // Verifica si ningún jugador está activo
|
|
|
|
// --- Colisiones de jugadores ---
|
|
void handlePlayerCollision(std::shared_ptr<Player> &player, std::shared_ptr<Balloon> &balloon); // Procesa colisión de jugador con globo
|
|
auto checkPlayerBalloonCollision(std::shared_ptr<Player> &player) -> std::shared_ptr<Balloon>; // Detecta colisión jugador-globo
|
|
void checkPlayerItemCollision(std::shared_ptr<Player> &player); // Detecta colisión jugador-ítem
|
|
|
|
// --- Sistema de entrada (input) ---
|
|
void checkInput(); // Gestiona toda la entrada durante el juego
|
|
void checkPauseInput(); // Verifica solicitudes de pausa de controladores
|
|
|
|
// --- Entrada de jugadores normales ---
|
|
void handlePlayersInput(); // Gestiona entrada de todos los jugadores
|
|
void handleNormalPlayerInput(const std::shared_ptr<Player> &player); // Procesa entrada de un jugador específico
|
|
void handleFireInput(const std::shared_ptr<Player> &player, BulletType bullet_type); // Gestiona disparo de jugador
|
|
void handleFireInputs(const std::shared_ptr<Player> &player, bool autofire); // Procesa disparos automáticos
|
|
void handlePlayerContinueInput(const std::shared_ptr<Player> &player); // Permite continuar al jugador
|
|
void handlePlayerWaitingInput(const std::shared_ptr<Player> &player); // Permite (re)entrar al jugador
|
|
void handleNameInput(const std::shared_ptr<Player> &player); // Gestiona entrada de nombre del jugador
|
|
|
|
// --- Entrada en modo demo ---
|
|
void demoHandleInput(); // Gestiona entrada durante el modo demostración
|
|
void demoHandlePassInput(); // Permite saltar la demostración
|
|
void demoHandlePlayerInput(const std::shared_ptr<Player> &player, int index); // Procesa entrada de jugador en demo
|
|
|
|
// --- Sistema de balas y proyectiles ---
|
|
void updateBullets(); // Actualiza posición y estado de todas las balas
|
|
void renderBullets(); // Renderiza todas las balas activas
|
|
void createBullet(int x, int y, BulletType kind, bool powered_up, Player::Id owner); // Crea una nueva bala
|
|
void checkBulletCollision(); // Verifica colisiones de todas las balas
|
|
void freeBullets(); // Libera memoria del vector de balas
|
|
|
|
// --- Colisiones específicas de balas ---
|
|
auto checkBulletTabeCollision(std::shared_ptr<Bullet> bullet) -> bool; // Detecta colisión bala-Tabe
|
|
auto checkBulletBalloonCollision(std::shared_ptr<Bullet> bullet) -> bool; // Detecta colisión bala-globo
|
|
void processBalloonHit(std::shared_ptr<Bullet> bullet, std::shared_ptr<Balloon> balloon); // Procesa impacto en globo
|
|
|
|
// --- Sistema de ítems y power-ups ---
|
|
void updateItems(); // Actualiza posición y estado de todos los ítems
|
|
void renderItems(); // Renderiza todos los ítems activos
|
|
auto dropItem() -> ItemType; // Determina aleatoriamente qué ítem soltar
|
|
void createItem(ItemType type, float x, float y); // Crea un nuevo ítem en posición específica
|
|
void freeItems(); // Libera memoria del vector de ítems
|
|
void destroyAllItems(); // Elimina todos los ítems activos de la pantalla
|
|
|
|
// --- ítems especiales ---
|
|
void enableTimeStopItem(); // Activa el efecto de detener el tiempo
|
|
void disableTimeStopItem(); // Desactiva el efecto de detener el tiempo
|
|
void updateTimeStopped(); // Actualiza el estado del tiempo detenido
|
|
void throwCoffee(int x, int y); // Crea efecto de café arrojado al ser golpeado
|
|
|
|
// --- Gestión de caída de ítems ---
|
|
void handleItemDrop(std::shared_ptr<Balloon> balloon, std::shared_ptr<Player> player); // Gestiona caída de ítem desde globo
|
|
|
|
// --- Sprites inteligentes (smartsprites) ---
|
|
void updateSmartSprites(); // Actualiza todos los sprites con lógica propia
|
|
void renderSmartSprites(); // Renderiza todos los sprites inteligentes
|
|
void freeSmartSprites(); // Libera memoria de sprites inteligentes
|
|
|
|
// --- Sprites por ruta (pathsprites) ---
|
|
void updatePathSprites(); // Actualiza sprites que siguen rutas predefinidas
|
|
void renderPathSprites(); // Renderiza sprites animados por ruta
|
|
void freePathSprites(); // Libera memoria de sprites por ruta
|
|
void initPaths(); // Inicializa rutas predefinidas para animaciones
|
|
|
|
// --- Creación de sprites especiales ---
|
|
void createItemText(int x, std::shared_ptr<Texture> texture); // Crea texto animado para ítems
|
|
void createMessage(const std::vector<Path> &paths, std::shared_ptr<Texture> texture); // Crea mensaje con animación por ruta
|
|
|
|
// --- Sistema de globos y enemigos ---
|
|
void handleBalloonDestruction(std::shared_ptr<Balloon> balloon, std::shared_ptr<Player> player); // Procesa destrucción de globo
|
|
void handleTabeHitEffects(); // Gestiona efectos al golpear a Tabe
|
|
void checkAndUpdateBalloonSpeed(); // Ajusta velocidad de globos según progreso
|
|
|
|
// --- Gestión de fases y progresión ---
|
|
void updateStage(); // Verifica y actualiza cambio de fase
|
|
void setTotalPower(); // Calcula poder total necesario para completar el juego
|
|
void initDifficultyVars(); // Inicializa variables de dificultad
|
|
|
|
// --- Sistema de amenaza ---
|
|
void updateMenace(); // Gestiona el nivel de amenaza del juego
|
|
void evaluateAndSetMenace(); // Calcula y establece amenaza según globos activos
|
|
|
|
// --- Puntuación y marcador ---
|
|
void updateHiScore(); // Actualiza el récord máximo si es necesario
|
|
void updateScoreboard(); // Actualiza la visualización del marcador
|
|
void addScoreToScoreBoard(const std::shared_ptr<Player> &player); // Añade puntuación del jugador al marcador
|
|
void initScoreboard(); // Inicializa el sistema de puntuación
|
|
|
|
// --- Modo demostración ---
|
|
void initDemo(Player::Id player_id); // Inicializa variables para el modo demostración
|
|
void updateDemo(); // Actualiza lógica específica del modo demo
|
|
|
|
// --- Recursos y renderizado ---
|
|
void setResources(); // Asigna texturas y animaciones a los objetos
|
|
void updateBackground(); // Actualiza elementos del fondo
|
|
void fillCanvas(); // Renderiza elementos del área de juego en su textura
|
|
void updateHelper(); // Actualiza variables auxiliares de renderizado
|
|
|
|
// --- Sistema de audio ---
|
|
static void playMusic(); // Reproduce la música de fondo
|
|
void stopMusic() const; // Detiene la reproducción de música
|
|
static void pauseMusic(); // Pausa la música
|
|
static void resumeMusic(); // Retoma la música que eestaba pausada
|
|
void playSound(const std::string &name) const; // Reproduce un efecto de sonido específico
|
|
|
|
// --- Utilidades y servicios ---
|
|
void checkServiceMenu(); // Verifica si el menú de servicio está activo
|
|
|
|
void sendPlayerToTheBack(const std::shared_ptr<Player> &player); // Mueve el jugador para pintarlo al fondo de la lista de jugadores
|
|
void sendPlayerToTheFront(const std::shared_ptr<Player> &player); // Mueve el jugador para pintarlo el primero de la lista de jugadores
|
|
void onPauseStateChanged(bool isPaused);
|
|
|
|
// SISTEMA DE GRABACIÓN (CONDICIONAL)
|
|
#ifdef RECORDING
|
|
void updateRecording(); // Actualiza variables durante modo de grabación
|
|
#endif
|
|
|
|
// --- Depuración (solo en modo DEBUG) ---
|
|
#ifdef _DEBUG
|
|
void checkDebugEvents(const SDL_Event &event); // Comprueba los eventos en el modo DEBUG
|
|
#endif
|
|
}; |