415 lines
14 KiB
C++
415 lines
14 KiB
C++
#pragma once
|
|
|
|
#include <SDL2/SDL_render.h> // Para SDL_Renderer, SDL_Texture
|
|
#include <SDL2/SDL_stdinc.h> // Para Uint32, 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 Options, OptionsGame, options
|
|
#include "player.h" // Para Player
|
|
#include "utils.h" // Para Demo
|
|
class Asset; // lines 13-13
|
|
class Background; // lines 14-14
|
|
class BalloonManager;
|
|
class Bullet; // lines 15-15
|
|
class Fade; // lines 16-16
|
|
class Input; // lines 17-17
|
|
class Item; // lines 18-18
|
|
class PathSprite; // lines 19-19
|
|
class Scoreboard; // lines 20-20
|
|
class Screen; // lines 21-21
|
|
class SmartSprite; // lines 22-22
|
|
class Texture; // lines 23-23
|
|
enum class BulletType : Uint8; // lines 24-24
|
|
enum class ItemType; // lines 25-25
|
|
struct Path; // lines 26-26
|
|
|
|
// 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;
|
|
|
|
/*
|
|
Esta clase gestiona un estado del programa. Se encarga de toda la parte en la
|
|
que se está jugando.
|
|
|
|
Tiene:
|
|
- Cacheadas todas las texturas y animaciones que usaran los diferentes objetos.
|
|
Mediante el método loadMedia() almacena en vectores todos los recursos
|
|
- Tiene vectores con objetos: jugadores, enemigos, balas, explosiones, objetos y otros (sprites con los puntos al coger objetos)
|
|
- Se encarga de comprobar las colisiones entre los diferentes objetos, los marca como deshabilitados si es el caso y
|
|
luego revisa los vectores para eliminar los objetos deshabilitados
|
|
|
|
Utiliza:
|
|
- Un objeto para dibujar el fondo animado
|
|
- Un objeto para dibujar el marcador
|
|
|
|
La clase comprueba el nivel de amenaza que hay en pantalla contando el número de enemigos y su peligrosidad y actua en consecuencia:
|
|
- Generando items
|
|
- Generando nuevas oleadas enemigas
|
|
|
|
Mientras haya un jugador activo siempre puede unirse un segundo jugador. Cada vez que un jugador muere
|
|
aparece una cuenta atras para permitirle continuar. Si la cuenta atras de ambos jugadores llega a cero,
|
|
el juego termina. Cuando ambos jugadores han finalizado, se permite introducir nombre para la tabla de records
|
|
adjuntando la máxima puntuación obtenida en la partida, solo en caso de que hayan conseguido superar la
|
|
puntuación mínima.
|
|
*/
|
|
|
|
// Clase Game
|
|
class Game
|
|
{
|
|
private:
|
|
// Enum
|
|
enum class GameState
|
|
{
|
|
PLAYING,
|
|
COMPLETED,
|
|
GAME_OVER,
|
|
};
|
|
|
|
// Contadores
|
|
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;
|
|
|
|
// Porcentaje de aparición de los objetos
|
|
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
|
|
|
|
// Constructor con valores predeterminados
|
|
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
|
|
Asset *asset_; // Objeto que gestiona todos los ficheros de recursos
|
|
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 smartsprites
|
|
|
|
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_; // Objeto para renderizar fades
|
|
std::unique_ptr<BalloonManager> balloon_manager_; // Objeto para gestionar los globos
|
|
std::vector<Path> paths_; // Vector con los recorridos precalculados almacenados
|
|
|
|
// Variables
|
|
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
|
|
Uint32 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::PLAYING; // Estado
|
|
#ifdef DEBUG
|
|
bool auto_pop_balloons_ = false; // Si es true, incrementa automaticamente los globos explotados
|
|
#endif
|
|
|
|
// Actualiza el juego
|
|
void update();
|
|
|
|
// Dibuja el juego
|
|
void render();
|
|
|
|
// Comprueba los eventos que hay en cola
|
|
void checkEvents();
|
|
|
|
// Asigna texturas y animaciones
|
|
void setResources();
|
|
|
|
// Actualiza el valor de HiScore en caso necesario
|
|
void updateHiScore();
|
|
|
|
// Actualiza las variables del jugador
|
|
void updatePlayers();
|
|
|
|
// Dibuja a los jugadores
|
|
void renderPlayers();
|
|
|
|
// Comprueba si hay cambio de fase y actualiza las variables
|
|
void updateStage();
|
|
|
|
// Actualiza el estado de fin de la partida
|
|
void updateGameOverState();
|
|
|
|
// Destruye todos los items
|
|
void destroyAllItems();
|
|
|
|
// Comprueba la colisión entre el jugador y los globos activos
|
|
bool checkPlayerBalloonCollision(std::shared_ptr<Player> &player);
|
|
|
|
// Comprueba la colisión entre el jugador y los items
|
|
void checkPlayerItemCollision(std::shared_ptr<Player> &player);
|
|
|
|
// Comprueba la colisión entre las balas y los globos
|
|
void checkBulletBalloonCollision();
|
|
|
|
// Mueve las balas activas
|
|
void moveBullets();
|
|
|
|
// Pinta las balas activas
|
|
void renderBullets();
|
|
|
|
// Crea un objeto bala
|
|
void createBullet(int x, int y, BulletType kind, bool powered_up, int owner);
|
|
|
|
// Vacia el vector de balas
|
|
void freeBullets();
|
|
|
|
// Actualiza los items
|
|
void updateItems();
|
|
|
|
// Pinta los items activos
|
|
void renderItems();
|
|
|
|
// Devuelve un item en función del azar
|
|
ItemType dropItem();
|
|
|
|
// Crea un objeto item
|
|
void createItem(ItemType type, float x, float y);
|
|
|
|
// Vacia el vector de items
|
|
void freeItems();
|
|
|
|
// Crea un objeto PathSprite
|
|
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);
|
|
|
|
// Vacia el vector de smartsprites
|
|
void freeSmartSprites();
|
|
|
|
// Vacia el vector de pathsprites
|
|
void freePathSprites();
|
|
|
|
// Crea un SpriteSmart para arrojar el item café al recibir un impacto
|
|
void throwCoffee(int x, int y);
|
|
|
|
// Actualiza los SpriteSmarts
|
|
void updateSmartSprites();
|
|
|
|
// Pinta los SpriteSmarts activos
|
|
void renderSmartSprites();
|
|
|
|
// Actualiza los PathSprites
|
|
void updatePathSprites();
|
|
|
|
// Pinta los PathSprites activos
|
|
void renderPathSprites();
|
|
|
|
// Acciones a realizar cuando el jugador muere
|
|
void killPlayer(std::shared_ptr<Player> &player);
|
|
|
|
// Actualiza y comprueba el valor de la variable
|
|
void updateTimeStopped();
|
|
|
|
// Actualiza el fondo
|
|
void updateBackground();
|
|
|
|
// Inicializa las variables que contienen puntos de ruta para mover objetos
|
|
void initPaths();
|
|
|
|
// Habilita el efecto del item de detener el tiempo
|
|
void enableTimeStopItem();
|
|
|
|
// Deshabilita el efecto del item de detener el tiempo
|
|
void disableTimeStopItem();
|
|
|
|
// Actualiza las variables de ayuda
|
|
void updateHelper();
|
|
|
|
// Comprueba si todos los jugadores han terminado de jugar
|
|
bool allPlayersAreWaitingOrGameOver();
|
|
|
|
// Comprueba si todos los jugadores han terminado de jugar
|
|
bool allPlayersAreGameOver();
|
|
|
|
// Comprueba si todos los jugadores han terminado de jugar
|
|
bool allPlayersAreNotPlaying();
|
|
|
|
// Recarga las texturas
|
|
void reloadTextures();
|
|
|
|
// Actualiza el marcador
|
|
void updateScoreboard();
|
|
|
|
// Dibuja los elementos de la zona de juego en su textura
|
|
void fillCanvas();
|
|
|
|
// Pausa el juego
|
|
void pause(bool value);
|
|
|
|
// Comprueba si la música ha de estar sonando
|
|
void checkMusicStatus();
|
|
|
|
// Añade una puntuación a la tabla de records
|
|
void addScoreToScoreBoard(const std::string &name, int score);
|
|
|
|
// Saca del estado de GAME OVER al jugador si el otro está activo
|
|
void checkAndUpdatePlayerStatus(int active_player_index, int inactive_player_index);
|
|
|
|
// Comprueba el estado de juego de los jugadores
|
|
void checkPlayersStatusPlaying();
|
|
|
|
// Obtiene un jugador a partir de su "id"
|
|
std::shared_ptr<Player> getPlayer(int id);
|
|
|
|
// Obtiene un controlador a partir del "id" del jugador
|
|
int getController(int playerId);
|
|
|
|
// Gestiona la entrada durante el juego
|
|
void checkInput();
|
|
|
|
// Verifica si alguno de los controladores ha solicitado una pausa y actualiza el estado de pausa del juego.
|
|
void checkPauseInput();
|
|
|
|
// Gestiona las entradas de los jugadores en el modo demo, incluyendo movimientos y disparos automáticos.
|
|
void handleDemoMode();
|
|
|
|
// Procesa las entradas para un jugador específico durante el modo demo.
|
|
void handleDemoPlayerInput(const std::shared_ptr<Player> &player, int index);
|
|
|
|
// Maneja el disparo de un jugador, incluyendo la creación de balas y la gestión del tiempo de espera entre disparos.
|
|
void handleFireInput(const std::shared_ptr<Player> &player, BulletType bulletType);
|
|
|
|
// Gestiona las entradas de todos los jugadores en el modo normal (fuera del modo demo).
|
|
void handlePlayersInput();
|
|
|
|
// Maneja las entradas de movimiento y disparo para un jugador en modo normal.
|
|
void handleNormalPlayerInput(const std::shared_ptr<Player> &player);
|
|
|
|
// Procesa las entradas de disparo del jugador, permitiendo disparos automáticos si está habilitado.
|
|
void handleFireInputs(const std::shared_ptr<Player> &player, bool autofire, int controllerIndex);
|
|
|
|
// Maneja la continuación del jugador cuando no está jugando, permitiendo que continúe si se pulsa el botón de inicio.
|
|
void handlePlayerContinue(const std::shared_ptr<Player> &player);
|
|
|
|
// Procesa las entradas para la introducción del nombre del jugador.
|
|
void handleNameInput(const std::shared_ptr<Player> &player);
|
|
|
|
// Inicializa las variables para el modo DEMO
|
|
void initDemo(int player_id);
|
|
|
|
// Calcula el poder total necesario para completar el juego
|
|
void setTotalPower();
|
|
|
|
// Inicializa el marcador
|
|
void initScoreboard();
|
|
|
|
// Inicializa las opciones relacionadas con la dificultad
|
|
void initDifficultyVars();
|
|
|
|
// Inicializa los jugadores
|
|
void initPlayers(int player_id);
|
|
|
|
// Pausa la música
|
|
void pauseMusic();
|
|
|
|
// Reanuda la música
|
|
void resumeMusic();
|
|
|
|
// Detiene la música
|
|
void stopMusic();
|
|
|
|
// Actualiza las variables durante el modo demo
|
|
void updateDemo();
|
|
#ifdef RECORDING
|
|
// Actualiza las variables durante el modo de grabación
|
|
void updateRecording();
|
|
#endif
|
|
// Actualiza las variables durante el transcurso normal del juego
|
|
void updateGame();
|
|
|
|
// Gestiona eventos para el estado del final del juego
|
|
void updateCompletedState();
|
|
|
|
// Comprueba el estado del juego
|
|
void checkState();
|
|
|
|
// Vacía los vectores de elementos deshabilitados
|
|
void cleanVectors();
|
|
|
|
// Gestiona el nivel de amenaza
|
|
void updateMenace();
|
|
|
|
// Calcula y establece el valor de amenaza en funcion de los globos activos
|
|
void evaluateAndSetMenace();
|
|
|
|
// Actualiza la velocidad de los globos en funcion del poder acumulado de la fase
|
|
void checkAndUpdateBalloonSpeed();
|
|
|
|
public:
|
|
// Constructor
|
|
Game(int playerID, int current_stage, bool demo);
|
|
|
|
// Destructor
|
|
~Game();
|
|
|
|
// Bucle para el juego
|
|
void run();
|
|
}; |