Files
coffee_crisis_arcade_edition/source/game.h
2025-05-29 09:58:23 +02:00

248 lines
14 KiB
C++

#pragma once
#include <SDL3/SDL_events.h> // Para SDL_Event
#include <SDL3/SDL_render.h> // Para SDL_Renderer, SDL_Texture
#include <SDL3/SDL_stdinc.h> // Para Uint64, Uint8
#include <memory> // Para shared_ptr, unique_ptr
#include <string> // Para string
#include <vector> // Para vector
#include "manage_hiscore_table.h" // Para HiScoreEntry
#include "options.h" // Para GameOptions, Options, options
#include "player.h" // Para Player
#include "utils.h" // Para Demo
class Audio;
class Asset;
class Background;
class BalloonManager;
class Tabe;
class Bullet;
class Fade;
class Input;
class Item;
class PathSprite;
class Scoreboard;
class Screen;
class SmartSprite;
class Texture;
enum class BulletType : Uint8;
enum class ItemType;
struct Path;
// Modo demo
constexpr bool GAME_MODE_DEMO_OFF = false;
constexpr bool GAME_MODE_DEMO_ON = true;
// Cantidad de elementos a escribir en los ficheros de datos
constexpr int TOTAL_SCORE_DATA = 3;
// Clase Game
class Game
{
public:
// Constructor
Game(int playerID, int current_stage, bool demo);
// Destructor
~Game();
// Bucle principal del juego
void run();
private:
// --- Tipos internos ---
enum class GameState
{
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; // Indica si se necesitan cafes
bool need_coffee_machine; // Indica si se necesita PowerUp
bool need_power_ball; // 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()
: need_coffee(false),
need_coffee_machine(false),
need_power_ball(false),
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::unique_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::shared_ptr<Texture> bullet_texture_; // Textura para las balas
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<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.game.hi_score_table[0].name,
options.game.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
GameDifficulty difficulty_ = options.game.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
bool paused_ = false; // Indica si el juego está pausado (no se deberia de poder utilizar en el modo arcade)
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 enemigos
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
GameState state_ = GameState::FADE_IN; // Estado
#ifdef DEBUG
bool auto_pop_balloons_ = false; // Si es true, incrementa automaticamente los globos explotados
// Comprueba los eventos en el modo DEBUG
void checkDebugEvents(const SDL_Event &event);
#endif
// --- Métodos internos ---
void update(); // Actualiza el juego
void render(); // Dibuja el juego
void checkEvents(); // Comprueba los eventos que hay en cola
void setResources(); // Asigna texturas y animaciones
void updateHiScore(); // Actualiza el valor de HiScore en caso necesario
void updatePlayers(); // Actualiza las variables del jugador
void renderPlayers(); // Dibuja a los jugadores
void updateStage(); // Comprueba si hay cambio de fase y actualiza las variables
void updateGameStateGameOver(); // Actualiza el estado de fin de la partida
void destroyAllItems(); // Destruye todos los items
bool checkPlayerBalloonCollision(std::shared_ptr<Player> &player); // Comprueba la colisión entre el jugador y los globos activos
void checkPlayerItemCollision(std::shared_ptr<Player> &player); // Comprueba la colisión entre el jugador y los items
void checkBulletCollision(); // Comprueba y procesa la colisión de las balas
void updateBullets(); // Mueve las balas activas
void renderBullets(); // Pinta las balas activas
void createBullet(int x, int y, BulletType kind, bool powered_up, int owner); // Crea un objeto bala
void freeBullets(); // Vacia el vector de balas
void updateItems(); // Actualiza los items
void renderItems(); // Pinta los items activos
ItemType dropItem(); // Devuelve un item en función del azar
void createItem(ItemType type, float x, float y); // Crea un objeto item
void freeItems(); // Vacia el vector de items
void createItemText(int x, std::shared_ptr<Texture> texture); // Crea un objeto PathSprite
void createMessage(const std::vector<Path> &paths, std::shared_ptr<Texture> texture); // Crea un objeto PathSprite
void freeSmartSprites(); // Vacia el vector de smartsprites
void freePathSprites(); // Vacia el vector de pathsprites
void throwCoffee(int x, int y); // Crea un SpriteSmart para arrojar el item café al recibir un impacto
void updateSmartSprites(); // Actualiza los SpriteSmarts
void renderSmartSprites(); // Pinta los SpriteSmarts activos
void updatePathSprites(); // Actualiza los PathSprites
void renderPathSprites(); // Pinta los PathSprites activos
void killPlayer(std::shared_ptr<Player> &player); // Acciones a realizar cuando el jugador muere
void updateTimeStopped(); // Actualiza y comprueba el valor de la variable
void updateBackground(); // Actualiza el fondo
void initPaths(); // Inicializa las variables que contienen puntos de ruta para mover objetos
void enableTimeStopItem(); // Habilita el efecto del item de detener el tiempo
void disableTimeStopItem(); // Deshabilita el efecto del item de detener el tiempo
void updateHelper(); // Actualiza las variables de ayuda
bool allPlayersAreWaitingOrGameOver(); // Comprueba si todos los jugadores han terminado de jugar
bool allPlayersAreGameOver(); // Comprueba si todos los jugadores han terminado de jugar
bool allPlayersAreNotPlaying(); // Comprueba si todos los jugadores han terminado de jugar
void updateScoreboard(); // Actualiza el marcador
void fillCanvas(); // Dibuja los elementos de la zona de juego en su textura
void pause(bool value); // Pausa el juego
void addScoreToScoreBoard(const std::shared_ptr<Player> &player); // Añade una puntuación a la tabla de records
void checkAndUpdatePlayerStatus(int active_player_index, int inactive_player_index); // Saca del estado de GAME OVER al jugador si el otro está activo
void checkPlayersStatusPlaying(); // Comprueba el estado de juego de los jugadores
std::shared_ptr<Player> getPlayer(int id); // Obtiene un jugador a partir de su "id"
int getController(int playerId); // Obtiene un controlador a partir del "id" del jugador
void checkInput(); // Gestiona la entrada durante el juego
void checkPauseInput(); // Verifica si alguno de los controladores ha solicitado una pausa y actualiza el estado de pausa del juego.
void handleDemoMode(); // Gestiona las entradas de los jugadores en el modo demo, incluyendo movimientos y disparos automáticos.
void handleDemoPlayerInput(const std::shared_ptr<Player> &player, int index); // Procesa las entradas para un jugador específico durante el modo demo.
void handleFireInput(const std::shared_ptr<Player> &player, BulletType bulletType); // Maneja el disparo de un jugador, incluyendo la creación de balas y la gestión del tiempo de espera entre disparos.
void handlePlayersInput(); // Gestiona las entradas de todos los jugadores en el modo normal (fuera del modo demo).
void handleNormalPlayerInput(const std::shared_ptr<Player> &player); // Maneja las entradas de movimiento y disparo para un jugador en modo normal.
void handleFireInputs(const std::shared_ptr<Player> &player, bool autofire, int controllerIndex); // Procesa las entradas de disparo del jugador, permitiendo disparos automáticos si está habilitado.
void handlePlayerContinue(const std::shared_ptr<Player> &player); // Maneja la continuación del jugador cuando no está jugando, permitiendo que continúe si se pulsa el botón de inicio.
void handleNameInput(const std::shared_ptr<Player> &player); // Procesa las entradas para la introducción del nombre del jugador.
void initDemo(int player_id); // Inicializa las variables para el modo DEMO
void setTotalPower(); // Calcula el poder total necesario para completar el juego
void initScoreboard(); // Inicializa el marcador
void initDifficultyVars(); // Inicializa las opciones relacionadas con la dificultad
void initPlayers(int player_id); // Inicializa los jugadores
void playMusic(); // Hace sonar la música
void stopMusic(); // Detiene la música
void updateDemo(); // Actualiza las variables durante el modo demo
#ifdef RECORDING
void updateRecording(); // Actualiza las variables durante el modo de grabación
#endif
void updateGameStateFadeIn(); // Actualiza las variables durante dicho estado
void updateGameStateEnteringPlayer(); // Actualiza las variables durante dicho estado
void updateGameStateShowingGetReadyMessage(); // Actualiza las variables durante dicho estado
void updateGameStatePlaying(); // Actualiza las variables durante el transcurso normal del juego
void updateGameStateCompleted(); // Gestiona eventos para el estado del final del juego
void checkState(); // Comprueba el estado del juego
void cleanVectors(); // Vacía los vectores de elementos deshabilitados
void updateMenace(); // Gestiona el nivel de amenaza
void evaluateAndSetMenace(); // Calcula y establece el valor de amenaza en funcion de los globos activos
void checkAndUpdateBalloonSpeed(); // Actualiza la velocidad de los globos en funcion del poder acumulado de la fase
void setState(GameState state); // Cambia el estado del juego
};