Posat ordre en el constructor de Game

This commit is contained in:
2024-10-24 22:08:53 +02:00
parent 43e7b83403
commit caf191672e
3 changed files with 252 additions and 258 deletions

View File

@@ -26,7 +26,6 @@
#include "lang.h" // para getText
#include "manage_hiscore_table.h" // para ManageHiScoreTable
#include "notifier.h" // para Notifier
#include "options.h" // para options
#include "param.h" // para param
#include "player.h" // para Player, PlayerStatus
#include "resource.h" // para Resource
@@ -42,39 +41,35 @@ struct JA_Sound_t; // lines 36-36
// Constructor
Game::Game(int player_id, int current_stage, bool demo)
: current_stage_(current_stage)
: renderer_(Screen::get()->getRenderer()),
screen_(Screen::get()),
asset_(Asset::get()),
input_(Input::get()),
background_(std::make_unique<Background>()),
explosions_(std::make_unique<Explosions>()),
balloon_formations_(std::make_unique<BalloonFormations>()),
canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.play_area.rect.w, param.game.play_area.rect.h)),
fade_(std::make_unique<Fade>()),
current_stage_(current_stage),
last_stage_reached_(current_stage)
{
// Copia los punteros
asset_ = Asset::get();
input_ = Input::get();
screen_ = Screen::get();
renderer_ = screen_->getRenderer();
// Pasa variables
demo_.enabled = demo;
last_stage_reached_ = current_stage_;
difficulty_ = options.game.difficulty;
// Crea los objetos
Scoreboard::init();
scoreboard_ = Scoreboard::get();
fade_ = std::make_unique<Fade>();
// Otras variables
section::name = section::Name::GAME;
section::options = section::Options::GAME_PLAY_1P;
background_ = std::make_unique<Background>();
explosions_ = std::make_unique<Explosions>();
balloon_formations_ = std::make_unique<BalloonFormations>();
// Asigna los recursos a variables privadas del objeto
// Asigna texturas y animaciones
setResources();
// Inicializa los vectores con los datos para la demo
if (demo_.enabled)
{ // Aleatoriza la asignación del fichero
const auto demo1 = rand() % 2;
const auto demo2 = (demo1 == 0) ? 1 : 0;
demo_.data.emplace_back(Resource::get()->getDemoData(demo1));
demo_.data.emplace_back(Resource::get()->getDemoData(demo2));
}
// Crea y configura los objetos
Scoreboard::init();
scoreboard_ = Scoreboard::get();
fade_->setColor(fade_color.r, fade_color.g, fade_color.b);
fade_->setPost(param.fade.post_duration);
fade_->setType(FadeType::VENETIAN);
background_->setPos(param.game.play_area.rect);
@@ -83,181 +78,16 @@ Game::Game(int player_id, int current_stage, bool demo)
explosions_->addTexture(3, explosions_textures_[2], explosions_animations_[2]);
explosions_->addTexture(4, explosions_textures_[3], explosions_animations_[3]);
canvas_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.play_area.rect.w, param.game.play_area.rect.h);
SDL_SetTextureBlendMode(canvas_, SDL_BLENDMODE_BLEND);
// Crea los dos jugadores
{
const int y = param.game.play_area.rect.h - 30;
players_.emplace_back(std::make_unique<Player>(1, param.game.play_area.first_quarter_x - 15, y, demo_.enabled, param.game.play_area.rect, player_textures_[0], player_animations_));
players_.back()->setScoreBoardPanel(SCOREBOARD_LEFT_PANEL);
players_.back()->setName(lang::getText(53));
players_.back()->setController(getController(players_.back()->getId()));
players_.emplace_back(std::make_unique<Player>(2, param.game.play_area.third_quarter_x - 15, y, demo_.enabled, param.game.play_area.rect, player_textures_[1], player_animations_));
players_.back()->setScoreBoardPanel(SCOREBOARD_RIGHT_PANEL);
players_.back()->setName(lang::getText(54));
players_.back()->setController(getController(players_.back()->getId()));
}
// Activa el jugador que coincide con el "player_id"
{
auto player = getPlayer(player_id);
player->setStatusPlaying(PlayerStatus::PLAYING);
player->setInvulnerable(false);
}
// Variables relacionadas con la dificultad
switch (difficulty_)
{
case GameDifficulty::EASY:
{
default_balloon_speed_ = BALLOON_SPEED_1;
difficulty_score_multiplier_ = 0.5f;
scoreboard_->setColor(scoreboard_easy_color);
break;
}
case GameDifficulty::NORMAL:
{
default_balloon_speed_ = BALLOON_SPEED_1;
difficulty_score_multiplier_ = 1.0f;
scoreboard_->setColor(scoreboard_normal_color);
break;
}
case GameDifficulty::HARD:
{
default_balloon_speed_ = BALLOON_SPEED_5;
difficulty_score_multiplier_ = 1.5f;
scoreboard_->setColor(scoreboard_hard_color);
break;
}
default:
break;
}
// Variables para el marcador
scoreboard_->setPos({param.scoreboard.x, param.scoreboard.y, param.scoreboard.w, param.scoreboard.h});
scoreboard_->setMode(SCOREBOARD_CENTER_PANEL, ScoreboardMode::STAGE_INFO);
for (const auto &player : players_)
{
scoreboard_->setName(player->getScoreBoardPanel(), player->getName());
if (player->isWaiting())
scoreboard_->setMode(player->getScoreBoardPanel(), ScoreboardMode::WAITING);
}
// Resto de variables
ticks_ = 0;
hi_score_.score = options.game.hi_score_table[0].score;
hi_score_.name = options.game.hi_score_table[0].name;
paused_ = false;
game_completed_ = false;
game_completed_counter_ = 0;
section::name = section::Name::GAME;
section::options = section::Options::GAME_PLAY_1P;
current_power_ = 0;
menace_current_ = 0;
menace_threshold_ = 0;
hi_score_achieved_ = false;
stage_bitmap_counter_ = STAGE_COUNTER_;
game_over_counter_ = GAME_OVER_COUNTER_;
time_stopped_ = false;
time_stopped_counter_ = 0;
counter_ = 0;
last_ballon_deploy_ = 0;
balloon_deploy_counter_ = 0;
balloon_speed_ = default_balloon_speed_;
helper_.need_coffee = false;
helper_.need_coffee_machine = false;
helper_.need_power_ball = false;
helper_.counter = HELP_COUNTER_;
helper_.item_disk_odds = ITEM_POINTS_1_DISK_ODDS_;
helper_.item_gavina_odds = ITEM_POINTS_2_GAVINA_ODDS_;
helper_.item_pacmar_odds = ITEM_POINTS_3_PACMAR_ODDS_;
helper_.item_clock_odds = ITEM_CLOCK_ODDS_;
helper_.item_coffee_odds = ITEM_COFFEE_ODDS_;
helper_.item_coffee_machine_odds = ITEM_COFFEE_MACHINE_ODDS_;
power_ball_enabled_ = false;
power_ball_counter_ = 0;
coffee_machine_enabled_ = false;
balloons_popped_ = 0;
#ifdef DEBUG
auto_pop_balloons_ = false;
#endif
// Inicializa las variables para el modo DEMO
if (demo_.enabled)
{
// Selecciona una pantalla al azar
{
constexpr auto demos = 3;
const auto demo = rand() % demos;
const int stages[demos] = {0, 3, 5};
current_stage_ = stages[demo];
}
// Actualiza el numero de globos explotados según la fase de la demo
for (int i = 0; i < current_stage_; ++i)
{
balloons_popped_ += balloon_formations_->getStage(i).power_to_complete;
}
// Activa o no al otro jugador
if (rand() % 2 == 0)
{
const auto other_player_id = player_id == 1 ? 2 : 1;
auto other_player = getPlayer(other_player_id);
other_player->setStatusPlaying(PlayerStatus::PLAYING);
}
for (auto &player : players_)
{
// Añade 0, 1 o 2 cafes al jugador
for (int i = 0; i < rand() % 3; ++i)
{
player->giveExtraHit();
}
// Empieza sin inmunidad
player->setInvulnerable(false);
}
// Deshabilita los sonidos
JA_EnableSound(false);
// Configura los marcadores
scoreboard_->setMode(SCOREBOARD_LEFT_PANEL, ScoreboardMode::DEMO);
scoreboard_->setMode(SCOREBOARD_RIGHT_PANEL, ScoreboardMode::DEMO);
}
// Inicializa el resto de variables
initPlayers(player_id);
initScoreboard();
initDifficultyVars();
initDemo(player_id);
initPaths();
total_power_to_complete_game_ = 0;
for (int i = 0; i < 10; ++i)
{
total_power_to_complete_game_ += balloon_formations_->getStage(i).power_to_complete;
}
// Modo grabar demo
#ifdef RECORDING
demo_.recording = true;
#else
demo_.recording = false;
#endif
demo_.counter = 0;
// Inicializa el objeto para el fundido
fade_->setColor(fade_color.r, fade_color.g, fade_color.b);
fade_->setPost(param.fade.post_duration);
fade_->setType(FadeType::VENETIAN);
// Con los globos creados, calcula el nivel de amenaza
setTotalPower();
evaluateAndSetMenace();
// Inicializa los sprites con los textos que aparecen al coger items
smart_sprites_.clear();
}
Game::~Game()
@@ -273,11 +103,10 @@ Game::~Game()
#endif
Scoreboard::destroy();
SDL_DestroyTexture(canvas_);
}
// Asigna los recursos a variables privadas del objeto
// Asigna texturas y animaciones
void Game::setResources()
{
// Texturas
@@ -404,12 +233,12 @@ void Game::deployBalloonFormation()
auto set = rand() % 10;
// Evita repetir la ultima formación enemiga desplegada
if (set == last_ballon_deploy_)
if (set == last_balloon_deploy_)
{
++set %= 10;
}
last_ballon_deploy_ = set;
last_balloon_deploy_ = set;
const Stage stage = balloon_formations_->getStage(current_stage_);
const auto numEnemies = stage.balloon_pool->set[set]->number_of_balloons;
@@ -2255,3 +2084,143 @@ void Game::handleNameInput(const std::shared_ptr<Player> &player)
player->setStatusPlaying(PlayerStatus::CONTINUE);
}
}
// Inicializa las variables para el modo DEMO
void Game::initDemo(int player_id)
{
if (demo_.enabled)
{
// Aleatoriza la asignación del fichero con los datos del modo demostracion
const auto demo1 = rand() % 2;
const auto demo2 = (demo1 == 0) ? 1 : 0;
demo_.data.emplace_back(Resource::get()->getDemoData(demo1));
demo_.data.emplace_back(Resource::get()->getDemoData(demo2));
// Selecciona una pantalla al azar
{
constexpr auto demos = 3;
const auto demo = rand() % demos;
const int stages[demos] = {0, 3, 5};
current_stage_ = stages[demo];
}
// Actualiza el numero de globos explotados según la fase del modo demostración
for (int i = 0; i < current_stage_; ++i)
{
balloons_popped_ += balloon_formations_->getStage(i).power_to_complete;
}
// Activa o no al otro jugador
if (rand() % 2 == 0)
{
const auto other_player_id = player_id == 1 ? 2 : 1;
auto other_player = getPlayer(other_player_id);
other_player->setStatusPlaying(PlayerStatus::PLAYING);
}
// Asigna cafes a los jugadores
for (auto &player : players_)
{
for (int i = 0; i < rand() % 3; ++i)
player->giveExtraHit();
player->setInvulnerable(false);
}
// Deshabilita los sonidos
JA_EnableSound(false);
// Configura los marcadores
scoreboard_->setMode(SCOREBOARD_LEFT_PANEL, ScoreboardMode::DEMO);
scoreboard_->setMode(SCOREBOARD_RIGHT_PANEL, ScoreboardMode::DEMO);
}
// Modo grabar demo
#ifdef RECORDING
demo_.recording = true;
#else
demo_.recording = false;
#endif
demo_.counter = 0;
}
// Calcula el poder total necesario para completar el juego
void Game::setTotalPower()
{
total_power_to_complete_game_ = 0;
for (int i = 0; i < 10; ++i)
{
total_power_to_complete_game_ += balloon_formations_->getStage(i).power_to_complete;
}
}
// Inicializa el marcador
void Game::initScoreboard()
{
scoreboard_->setPos({param.scoreboard.x, param.scoreboard.y, param.scoreboard.w, param.scoreboard.h});
scoreboard_->setMode(SCOREBOARD_CENTER_PANEL, ScoreboardMode::STAGE_INFO);
for (const auto &player : players_)
{
scoreboard_->setName(player->getScoreBoardPanel(), player->getName());
if (player->isWaiting())
scoreboard_->setMode(player->getScoreBoardPanel(), ScoreboardMode::WAITING);
}
}
// Inicializa las opciones relacionadas con la dificultad
void Game::initDifficultyVars()
{
// Variables relacionadas con la dificultad
switch (difficulty_)
{
case GameDifficulty::EASY:
{
default_balloon_speed_ = BALLOON_SPEED_1;
difficulty_score_multiplier_ = 0.5f;
scoreboard_->setColor(scoreboard_easy_color);
break;
}
case GameDifficulty::NORMAL:
{
default_balloon_speed_ = BALLOON_SPEED_1;
difficulty_score_multiplier_ = 1.0f;
scoreboard_->setColor(scoreboard_normal_color);
break;
}
case GameDifficulty::HARD:
{
default_balloon_speed_ = BALLOON_SPEED_5;
difficulty_score_multiplier_ = 1.5f;
scoreboard_->setColor(scoreboard_hard_color);
break;
}
default:
break;
}
balloon_speed_ = default_balloon_speed_;
}
// Inicializa los jugadores
void Game::initPlayers(int player_id)
{
// Crea los dos jugadores
const int y = param.game.play_area.rect.h - 30;
players_.emplace_back(std::make_unique<Player>(1, param.game.play_area.first_quarter_x - 15, y, demo_.enabled, param.game.play_area.rect, player_textures_[0], player_animations_));
players_.back()->setScoreBoardPanel(SCOREBOARD_LEFT_PANEL);
players_.back()->setName(lang::getText(53));
players_.back()->setController(getController(players_.back()->getId()));
players_.emplace_back(std::make_unique<Player>(2, param.game.play_area.third_quarter_x - 15, y, demo_.enabled, param.game.play_area.rect, player_textures_[1], player_animations_));
players_.back()->setScoreBoardPanel(SCOREBOARD_RIGHT_PANEL);
players_.back()->setName(lang::getText(54));
players_.back()->setController(getController(players_.back()->getId()));
// Activa el jugador que coincide con el "player_id"
auto player = getPlayer(player_id);
player->setStatusPlaying(PlayerStatus::PLAYING);
player->setInvulnerable(false);
}

View File

@@ -8,6 +8,7 @@
#include "balloon.h" // para Balloon
#include "player.h" // para Player
#include "utils.h" // para DemoKeys, Color, HiScoreEntry
#include "options.h" // para options
class Asset;
class Background;
class BalloonFormations;
@@ -63,27 +64,6 @@ constexpr int TOTAL_SCORE_DATA = 3;
class Game
{
private:
// 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
explicit Helper(bool nc = false, bool ncm = false, bool npb = false, int c = 0, int ido = 0, int igo = 0, int ipo = 0, int ico = 0, int icoffo = 0, int icmo = 0)
: need_coffee(nc), need_coffee_machine(ncm), need_power_ball(npb), counter(c),
item_disk_odds(ido), item_gavina_odds(igo), item_pacmar_odds(ipo), item_clock_odds(ico),
item_coffee_odds(icoffo), item_coffee_machine_odds(icmo) {}
};
// Constantes
// Contadores
@@ -103,6 +83,34 @@ private:
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
@@ -143,39 +151,42 @@ private:
std::unique_ptr<Fade> fade_; // Objeto para renderizar fades
// Variables
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
bool hi_score_achieved_; // Indica si se ha superado la puntuación máxima
HiScoreEntry hi_score_; // Máxima puntuación y nombre de quien la ostenta
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
int current_stage_; // Indica la fase actual
int stage_bitmap_counter_; // Contador para el tiempo visible del texto de Stage
float stage_bitmap_path_[STAGE_COUNTER_]; // Vector con los puntos Y por donde se desplaza el texto
float get_ready_bitmap_path_[STAGE_COUNTER_]; // Vector con los puntos X por donde se desplaza el texto
int game_over_counter_; // Contador para el estado de fin de partida
int menace_current_; // Nivel de amenaza actual
int menace_threshold_; // 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
bool time_stopped_; // Indica si el tiempo está detenido
int time_stopped_counter_; // Temporizador para llevar la cuenta del tiempo detenido
int counter_; // Contador para el juego
int balloons_popped_; // Lleva la cuenta de los globos explotados
int last_ballon_deploy_; // Guarda cual ha sido la última formación desplegada para no repetir;
int balloon_deploy_counter_; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero
float balloon_speed_; // Velocidad a la que se mueven los enemigos
float default_balloon_speed_; // Velocidad base de los enemigos, sin incrementar
Helper helper_; // Variable para gestionar las ayudas
bool power_ball_enabled_; // Indica si hay una powerball ya activa
int power_ball_counter_; // Contador de formaciones enemigas entre la aparicion de una PowerBall y otra
bool coffee_machine_enabled_; // Indica si hay una máquina de café en el terreno de juego
bool game_completed_; // Indica si se ha completado la partida, llegando al final de la ultima pantalla
int game_completed_counter_; // Contador para el tramo final, cuando se ha completado la partida y ya no aparecen más enemigos
GameDifficulty difficulty_; // Dificultad del juego
float difficulty_score_multiplier_; // Multiplicador de puntos en función de la dificultad
int last_stage_reached_; // Contiene el número de la última pantalla que se ha alcanzado
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 game_completed_ = false; // Indica si se ha completado la partida, llegando al final de la ultima pantalla
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)
bool power_ball_enabled_ = false; // Indica si hay una powerball ya activa
bool time_stopped_ = false; // Indica si el tiempo está detenido
float balloon_speed_; // Velocidad a la que se mueven los enemigos
float default_balloon_speed_; // Velocidad base de los enemigos, sin incrementar
float difficulty_score_multiplier_; // Multiplicador de puntos en función de la dificultad
float get_ready_bitmap_path_[STAGE_COUNTER_]; // Vector con los puntos X por donde se desplaza el texto
float stage_bitmap_path_[STAGE_COUNTER_]; // Vector con los puntos Y por donde se desplaza el texto
int balloon_deploy_counter_ = 0; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero
int balloons_popped_ = 0; // Lleva la cuenta de los globos explotados
int counter_ = 0; // Contador para el juego
int current_power_ = 0; // Poder actual almacenado para completar la fase
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 last_balloon_deploy_ = 0; // Guarda cual ha sido la última formación desplegada para no repetir;
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
int power_ball_counter_ = 0; // Contador de formaciones enemigas entre la aparicion de una PowerBall y otra
int stage_bitmap_counter_ = STAGE_COUNTER_; // Contador para el tiempo visible del texto de Stage
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
bool paused_; // Indica si el juego está pausado (no se deberia de poder utilizar en el modo arcade)
int current_power_; // Poder actual almacenado para completar la fase
#ifdef DEBUG
bool auto_pop_balloons_; // Si es true, incrementa automaticamente los globos explotados
bool auto_pop_balloons_ = false; // Si es true, incrementa automaticamente los globos explotados
#endif
// Actualiza el juego
@@ -187,7 +198,7 @@ private:
// Comprueba los eventos que hay en cola
void checkEvents();
// Asigna los recursos a variables privadas del objeto
// Asigna texturas y animaciones
void setResources();
// Crea una formación de enemigos
@@ -425,6 +436,21 @@ private:
// 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);
public:
// Constructor
Game(int playerID, int current_stage, bool demo);

View File

@@ -110,8 +110,7 @@ struct Demo
std::vector<DemoData> data; // Vector con diferentes sets de datos con los movimientos para la demo
// Constructor por defecto
Demo()
: enabled(false), recording(false), counter(0), keys(), data() {}
Demo() : enabled(false), recording(false), counter(0), keys(), data() {}
// Constructor con parámetros
Demo(bool e, bool r, int c, const DemoKeys &k, const std::vector<DemoData> &d)