Modificada la estructura on es guarden els datos de la demo

This commit is contained in:
2024-10-20 20:43:03 +02:00
parent 3bf61fc758
commit b263e0c4be
10 changed files with 183 additions and 208 deletions

View File

@@ -6,35 +6,36 @@
#include "moving_sprite.h" // for MovingSprite
#include "param.h" // for param
#include "resource.h" // for Resource
#include "sprite.h" // for Sprite
#include "texture.h" // for Texture
#include "screen.h"
#include "sprite.h" // for Sprite
#include "texture.h" // for Texture
// Constructor
Background::Background(SDL_Renderer *renderer)
: renderer_(renderer),
Background::Background()
: renderer_(Screen::get()->getRenderer()),
buildings_texture_(Resource::get()->getTexture("game_buildings.png")),
top_clouds_texture_(Resource::get()->getTexture("game_clouds1.png")),
bottom_clouds_texture_(Resource::get()->getTexture("game_clouds2.png")),
grass_texture_(Resource::get()->getTexture("game_grass.png")),
gradients_texture_(Resource::get()->getTexture("game_sky_colors.png"))
gradients_texture_(Resource::get()->getTexture("game_sky_colors.png")),
gradient_number_(0),
alpha_(0),
clouds_speed_(0),
transition_(0),
counter_(0),
rect_({0, 0, gradients_texture_->getWidth() / 2, gradients_texture_->getHeight() / 2}),
src_rect_({0, 0, 320, 240}),
dst_rect_({0, 0, 320, 240}),
base_(rect_.h),
color_({param.background.attenuate_color.r, param.background.attenuate_color.g, param.background.attenuate_color.b}),
alpha_color_text_(param.background.attenuate_alpha),
alpha_color_text_temp_(param.background.attenuate_alpha)
{
// Inicializa variables
{
gradient_number_ = 0;
alpha_ = 0;
clouds_speed_ = 0;
transition_ = 0;
counter_ = 0;
rect_ = {0, 0, gradients_texture_->getWidth() / 2, gradients_texture_->getHeight() / 2};
src_rect_ = {0, 0, 320, 240};
dst_rect_ = {0, 0, 320, 240};
base_ = rect_.h;
color_ = {param.background.attenuate_color.r, param.background.attenuate_color.g, param.background.attenuate_color.b};
alpha_color_text_ = alpha_color_text_temp_ = param.background.attenuate_alpha;
gradient_rect_[0] = {0, 0, rect_.w, rect_.h};
gradient_rect_[1] = {rect_.w, 0, rect_.w, rect_.h};
gradient_rect_[2] = {0, rect_.h, rect_.w, rect_.h};
@@ -87,11 +88,11 @@ Background::Background(SDL_Renderer *renderer)
}
// Crea la textura para componer el fondo
canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h);
canvas_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h);
SDL_SetTextureBlendMode(canvas_, SDL_BLENDMODE_BLEND);
// Crea la textura para atenuar el fondo
color_texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h);
color_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h);
SDL_SetTextureBlendMode(color_texture_, SDL_BLENDMODE_BLEND);
setColor(color_);
SDL_SetTextureAlphaMod(color_texture_, alpha_color_text_);
@@ -120,7 +121,7 @@ void Background::update()
alpha_ = std::max((255 - (int)(255 * transition_)), 0);
// Incrementa el contador
counter_++;
++counter_;
// Compone todos los elementos del fondo en la textura
fillCanvas();

View File

@@ -107,7 +107,7 @@ private:
public:
// Constructor
explicit Background(SDL_Renderer *renderer);
Background();
// Destructor
~Background();

View File

@@ -55,11 +55,11 @@ Game::Game(int player_id, int current_stage, bool demo)
difficulty_ = options.game.difficulty;
// Crea los objetos
Scoreboard::init(renderer_);
Scoreboard::init();
scoreboard_ = Scoreboard::get();
fade_ = std::make_unique<Fade>();
background_ = std::make_unique<Background>(renderer_);
background_ = std::make_unique<Background>();
explosions_ = std::make_unique<Explosions>();
balloon_formations_ = std::make_unique<BalloonFormations>();
@@ -69,10 +69,10 @@ Game::Game(int player_id, int current_stage, bool demo)
// Inicializa los vectores con los datos para la demo
if (demo_.enabled)
{ // Aleatoriza la asignación del fichero
const auto index1 = rand() % 2;
const auto index2 = (index1 + 1) % 2;
loadDemoFile(asset_->get("demo1.bin"), &this->demo_.data_file[index1]);
loadDemoFile(asset_->get("demo2.bin"), &this->demo_.data_file[index2]);
const std::string demo1 = rand() % 2 == 0 ? "demo1.bin" : "demo2.bin";
const std::string demo2 = (demo1 == "demo1.bin") ? "demo2.bin" : "demo1.bin";
demo_.data.emplace_back(loadDemoDataFromFile(asset_->get(demo1)));
demo_.data.emplace_back(loadDemoDataFromFile(asset_->get(demo2)));
}
background_->setPos(param.game.play_area.rect);
@@ -98,7 +98,7 @@ Game::~Game()
manager->saveToFile(asset_->get("score.bin"));
}
#ifdef RECORDING
saveDemoFile(asset->get("demo1.bin"));
saveDemoFile(Asset::get()->get("demo1.bin"));
#endif
// Elimina todos los objetos contenidos en vectores
@@ -115,9 +115,6 @@ Game::~Game()
// Inicializa las variables necesarias para la sección 'Game'
void Game::init(int player_id)
{
ticks_ = 0;
ticks_speed_ = 15;
// Elimina qualquier jugador que hubiese antes de crear los nuevos
players_.clear();
@@ -192,6 +189,7 @@ void Game::init(int player_id)
scoreboard_->setMode(SCOREBOARD_CENTER_PANEL, ScoreboardMode::STAGE_INFO);
// 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;
@@ -203,8 +201,8 @@ void Game::init(int player_id)
menace_current_ = 0;
menace_threshold_ = 0;
hi_score_achieved_ = false;
stage_bitmap_counter_ = STAGE_COUNTER;
game_over_counter_ = GAME_OVER_COUNTER;
stage_bitmap_counter_ = STAGE_COUNTER_;
game_over_counter_ = GAME_OVER_COUNTER_;
time_stopped_ = false;
time_stopped_counter_ = 0;
counter_ = 0;
@@ -214,13 +212,13 @@ void Game::init(int player_id)
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;
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;
@@ -282,7 +280,7 @@ void Game::init(int player_id)
// Modo grabar demo
#ifdef RECORDING
demo.recording = true;
demo_.recording = true;
#else
demo_.recording = false;
#endif
@@ -422,10 +420,11 @@ void Game::unloadMedia()
}
// Carga el fichero de datos para la demo
bool Game::loadDemoFile(const std::string &file_path, DemoKeys (*data_file)[TOTAL_DEMO_DATA])
DemoData Game::loadDemoDataFromFile(const std::string &file_path)
{
DemoData dd;
// Indicador de éxito en la carga
auto success = true;
const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1);
auto file = SDL_RWFromFile(file_path.c_str(), "r+b");
if (!file)
@@ -443,14 +442,8 @@ bool Game::loadDemoFile(const std::string &file_path, DemoKeys (*data_file)[TOTA
// Inicializas los datos y los guarda en el fichero
for (int i = 0; i < TOTAL_DEMO_DATA; ++i)
{
DemoKeys dk;
dk.left = 0;
dk.right = 0;
dk.no_input = 0;
dk.fire = 0;
dk.fire_left = 0;
dk.fire_right = 0;
(*data_file)[i] = dk;
DemoKeys dk = DemoKeys();
dd.push_back(dk);
SDL_RWwrite(file, &dk, sizeof(DemoKeys), 1);
}
@@ -460,7 +453,6 @@ bool Game::loadDemoFile(const std::string &file_path, DemoKeys (*data_file)[TOTA
else
{ // Si no puede crear el fichero
std::cout << "Error: Unable to create file " << file_name.c_str() << std::endl;
success = false;
}
}
// El fichero existe
@@ -472,16 +464,16 @@ bool Game::loadDemoFile(const std::string &file_path, DemoKeys (*data_file)[TOTA
// Lee todos los datos del fichero y los deja en el destino
for (int i = 0; i < TOTAL_DEMO_DATA; ++i)
{
DemoKeys tmp;
SDL_RWread(file, &tmp, sizeof(DemoKeys), 1);
(*data_file)[i] = tmp;
DemoKeys dk = DemoKeys();
SDL_RWread(file, &dk, sizeof(DemoKeys), 1);
dd.push_back(dk);
}
// Cierra el fichero
SDL_RWclose(file);
}
return success;
return dd;
}
#ifdef RECORDING
@@ -497,7 +489,7 @@ bool Game::saveDemoFile(const std::string &file_path)
// Guarda los datos
for (int i = 0; i < TOTAL_DEMO_DATA; ++i)
{
SDL_RWwrite(file, &demo.dataFile[0][i], sizeof(DemoKeys), 1);
SDL_RWwrite(file, &demo_.data[0][i], sizeof(DemoKeys), 1);
}
std::cout << "Writing file " << file_name.c_str() << std::endl;
@@ -669,7 +661,7 @@ void Game::updateStage()
}
// Incrementa el contador del bitmap que aparece mostrando el cambio de fase
if (stage_bitmap_counter_ < STAGE_COUNTER)
if (stage_bitmap_counter_ < STAGE_COUNTER_)
{
stage_bitmap_counter_++;
}
@@ -1195,8 +1187,6 @@ void Game::renderItems()
// Devuelve un item al azar y luego segun sus probabilidades
ItemType Game::dropItem()
{
return ItemType::COFFEE_MACHINE;
const auto lucky_number = rand() % 100;
const auto item = rand() % 6;
@@ -1233,7 +1223,7 @@ ItemType Game::dropItem()
case 4:
if (lucky_number < helper_.item_coffee_odds)
{
helper_.item_coffee_odds = ITEM_COFFEE_ODDS;
helper_.item_coffee_odds = ITEM_COFFEE_ODDS_;
return ItemType::COFFEE;
}
else
@@ -1248,7 +1238,7 @@ ItemType Game::dropItem()
case 5:
if (lucky_number < helper_.item_coffee_machine_odds)
{
helper_.item_coffee_machine_odds = ITEM_COFFEE_MACHINE_ODDS;
helper_.item_coffee_machine_odds = ITEM_COFFEE_MACHINE_ODDS_;
if (!coffee_machine_enabled_ && helper_.need_coffee_machine)
{
return ItemType::COFFEE_MACHINE;
@@ -1447,7 +1437,7 @@ void Game::updateTimeStoppedCounter()
if (time_stopped_counter_ > 0)
{
time_stopped_counter_--;
stopAllBalloons(TIME_STOPPED_COUNTER);
stopAllBalloons(TIME_STOPPED_COUNTER_);
}
else
{
@@ -1469,7 +1459,7 @@ void Game::updateBalloonDeployCounter()
void Game::update()
{
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks_ > ticks_speed_)
if (SDL_GetTicks() - ticks_ > TICKS_SPEED_)
{
// Actualiza el contador de ticks
ticks_ = SDL_GetTicks();
@@ -1505,9 +1495,9 @@ void Game::update()
checkInput();
// Incrementa el contador de la demo
if (demo.counter < TOTAL_DEMO_DATA)
if (demo_.counter < TOTAL_DEMO_DATA)
{
demo.counter++;
demo_.counter++;
}
// Si se ha llenado el vector con datos, sale del programa
@@ -1695,7 +1685,7 @@ void Game::updateMenace()
void Game::renderMessages()
{
// GetReady
if (counter_ < STAGE_COUNTER && !demo_.enabled)
if (counter_ < STAGE_COUNTER_ && !demo_.enabled)
{
text_nokia2_big_->write((int)get_ready_bitmap_path_[counter_], param.game.play_area.center_y - 8, lang::getText(75), -2);
}
@@ -1725,7 +1715,7 @@ void Game::renderMessages()
}
// STAGE NUMBER
if (stage_bitmap_counter_ < STAGE_COUNTER)
if (stage_bitmap_counter_ < STAGE_COUNTER_)
{
const auto stage_number = balloon_formations_->getStage(current_stage_).number;
std::string text;
@@ -1755,9 +1745,9 @@ void Game::renderMessages()
// Habilita el efecto del item de detener el tiempo
void Game::enableTimeStopItem()
{
stopAllBalloons(TIME_STOPPED_COUNTER);
stopAllBalloons(TIME_STOPPED_COUNTER_);
setTimeStopped(true);
incTimeStoppedCounter(TIME_STOPPED_COUNTER);
incTimeStoppedCounter(TIME_STOPPED_COUNTER_);
if (JA_GetMusicState() == JA_MUSIC_PLAYING && !demo_.enabled)
{
JA_PauseMusic();
@@ -1828,8 +1818,8 @@ void Game::initPaths()
}
// Letrero de STAGE #
constexpr auto first_part = STAGE_COUNTER / 4; // 50
constexpr auto second_part = first_part * 3; // 150
constexpr auto first_part = STAGE_COUNTER_ / 4; // 50
constexpr auto second_part = first_part * 3; // 150
const auto center_point = param.game.play_area.center_y - (BLOCK * 2);
const auto distance = (param.game.play_area.rect.h) - (param.game.play_area.center_y - 16);
@@ -1843,7 +1833,7 @@ void Game::initPaths()
stage_bitmap_path_[i] = (int)center_point;
}
for (int i = second_part; i < STAGE_COUNTER; ++i)
for (int i = second_part; i < STAGE_COUNTER_; ++i)
{
stage_bitmap_path_[i] = (sin[(int)(((i - 149) * 1.8f) + 90)] * (center_point + 17) - 17);
}
@@ -1870,7 +1860,7 @@ void Game::initPaths()
get_ready_bitmap_path_[i] = (int)finish1;
}
for (int i = second_part; i < STAGE_COUNTER; ++i)
for (int i = second_part; i < STAGE_COUNTER_; ++i)
{
get_ready_bitmap_path_[i] = sin[(int)((i - second_part) * 1.8f)];
get_ready_bitmap_path_[i] *= distance2;
@@ -1886,7 +1876,7 @@ void Game::updateGameCompleted()
game_completed_counter_++;
}
if (game_completed_counter_ == GAME_COMPLETED_END)
if (game_completed_counter_ == GAME_COMPLETED_END_)
{
section::name = section::Name::TITLE;
section::options = section::Options::TITLE_1;
@@ -2034,20 +2024,6 @@ void Game::checkEvents()
break;
}
// Ralentiza mucho la lógica
case SDLK_4:
{
ticks_speed_ *= 10;
break;
}
// Acelera mucho la lógica
case SDLK_5:
{
ticks_speed_ /= 10;
break;
}
default:
break;
}
@@ -2247,7 +2223,7 @@ void Game::handleDemoMode()
// Incluye movimientos (izquierda, derecha, sin movimiento) y disparos automáticos.
void Game::handleDemoPlayerInput(const std::shared_ptr<Player> &player, int index)
{
const auto &demoData = demo_.data_file[index][demo_.counter];
const auto &demoData = demo_.data[index][demo_.counter];
if (demoData.left == 1)
player->setInput(InputType::LEFT);
@@ -2307,21 +2283,21 @@ void Game::handleNormalPlayerInput(const std::shared_ptr<Player> &player)
{
player->setInput(InputType::LEFT);
#ifdef RECORDING
demo.keys.left = 1;
demo_.keys.left = 1;
#endif
}
else if (input_->checkInput(InputType::RIGHT, INPUT_ALLOW_REPEAT, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index))
{
player->setInput(InputType::RIGHT);
#ifdef RECORDING
demo.keys.right = 1;
demo_.keys.right = 1;
#endif
}
else
{
player->setInput(InputType::NONE);
#ifdef RECORDING
demo.keys.no_input = 1;
demo_.keys.no_input = 1;
#endif
}
@@ -2335,21 +2311,21 @@ void Game::handleFireInputs(const std::shared_ptr<Player> &player, bool autofire
{
handleFireInput(player, BulletType::UP);
#ifdef RECORDING
demo.keys.fire = 1;
demo_.keys.fire = 1;
#endif
}
else if (input_->checkInput(InputType::FIRE_LEFT, autofire, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index))
{
handleFireInput(player, BulletType::LEFT);
#ifdef RECORDING
demo.keys.fire_left = 1;
demo_.keys.fire_left = 1;
#endif
}
else if (input_->checkInput(InputType::FIRE_RIGHT, autofire, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index))
{
handleFireInput(player, BulletType::RIGHT);
#ifdef RECORDING
demo.keys.fire_right = 1;
demo_.keys.fire_right = 1;
#endif
}
}

View File

@@ -34,25 +34,6 @@ constexpr bool GAME_MODE_DEMO_ON = true;
constexpr int TOTAL_SCORE_DATA = 3;
constexpr int TOTAL_DEMO_DATA = 2000;
// Contadores
constexpr int STAGE_COUNTER = 200;
constexpr int HELP_COUNTER = 1000;
constexpr int GAME_COMPLETED_START_FADE = 500;
constexpr int GAME_COMPLETED_END = 700;
constexpr int GAME_OVER_COUNTER = 350;
// Porcentaje de aparición de los objetos
constexpr int ITEM_POINTS_1_DISK_ODDS = 10;
constexpr int ITEM_POINTS_2_GAVINA_ODDS = 6;
constexpr int ITEM_POINTS_3_PACMAR_ODDS = 3;
constexpr int ITEM_CLOCK_ODDS = 5;
constexpr int ITEM_COFFEE_ODDS = 5;
constexpr int ITEM_POWER_BALL_ODDS = 0;
constexpr int ITEM_COFFEE_MACHINE_ODDS = 4;
// Valores para las variables asociadas a los objetos
constexpr int TIME_STOPPED_COUNTER = 300;
/*
Esta clase gestiona un estado del programa. Se encarga de toda la parte en la
que se está jugando.
@@ -79,10 +60,22 @@ constexpr int TIME_STOPPED_COUNTER = 300;
puntuación mínima.
*/
using DemoData = std::vector<DemoKeys>;
struct Demo
{
bool enabled; // Indica si está activo el modo demo
bool recording; // Indica si está activado el modo para grabar la demo
int counter; // Contador para el modo demo
DemoKeys keys; // Variable con las pulsaciones de teclas del modo demo
std::vector<DemoData> data; // Vector con diferentes sets de datos con los movimientos para la demo
};
// Clase Game
class Game
{
private:
// Estructuras
struct Helper
{
bool need_coffee; // Indica si se necesitan cafes
@@ -97,14 +90,25 @@ private:
int item_coffee_machine_odds; // Probabilidad de aparición del objeto
};
struct Demo
{
bool enabled; // Indica si está activo el modo demo
bool recording; // Indica si está activado el modo para grabar la demo
int counter; // Contador para el modo demo
DemoKeys keys; // Variable con las pulsaciones de teclas del modo demo
DemoKeys data_file[2][TOTAL_DEMO_DATA]; // Vector con diferentes sets de datos con los movimientos para la demo
};
// Constantes
// Contadores
static constexpr int STAGE_COUNTER_ = 200;
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_ = 300;
static constexpr int TICKS_SPEED_ = 15;
// 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;
// Objetos y punteros
SDL_Renderer *renderer_; // El renderizador de la ventana
@@ -146,39 +150,38 @@ private:
std::unique_ptr<Fade> fade_; // Objeto para renderizar fades
// Variables
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticks_speed_; // Velocidad a la que se repiten los bucles 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
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
Color difficulty_color_; // Color asociado a 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
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
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
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
Color difficulty_color_; // Color asociado a 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
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
#endif
@@ -202,7 +205,7 @@ private:
void unloadMedia();
// Carga el fichero de datos para la demo
bool loadDemoFile(const std::string &file_path, DemoKeys (*data_file)[TOTAL_DEMO_DATA]);
DemoData loadDemoDataFromFile(const std::string &file_path);
#ifdef RECORDING
// Guarda el fichero de datos para la demo
bool saveDemoFile(const std::string &file_path);

View File

@@ -23,29 +23,21 @@
// Constructor
HiScoreTable::HiScoreTable()
: renderer_(Screen::get()->getRenderer()),
backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
fade_(std::make_unique<Fade>()),
background_(std::make_unique<Background>()),
text_(std::make_unique<Text>(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt"))),
counter_(0),
ticks_(0),
view_area_({0, 0, param.game.width, param.game.height}),
fade_mode_(FadeMode::IN)
{
// Copia punteros
renderer_ = Screen::get()->getRenderer();
// Objetos
fade_ = std::make_unique<Fade>();
background_ = std::make_unique<Background>(renderer_);
text_ = std::make_unique<Text>(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt"));
// Crea un backbuffer para el renderizador
backbuffer_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height);
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
// Inicializa variables
// Inicializa el resto de variables
section::name = section::Name::HI_SCORE_TABLE;
ticks_ = 0;
ticks_speed_ = 15;
counter_ = 0;
counter_end_ = 800;
view_area_ = {0, 0, param.game.width, param.game.height};
fade_mode_ = FadeMode::IN;
// Inicializa objetos
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
background_->setPos(param.game.game_area.rect);
background_->setCloudsSpeed(-0.1f);
background_->setGradientNumber(1);
@@ -70,7 +62,7 @@ HiScoreTable::~HiScoreTable()
void HiScoreTable::update()
{
// Actualiza las variables
if (SDL_GetTicks() - ticks_ > ticks_speed_)
if (SDL_GetTicks() - ticks_ > TICKS_SPEED_)
{
// Actualiza el contador de ticks
ticks_ = SDL_GetTicks();
@@ -99,7 +91,7 @@ void HiScoreTable::update()
background_->setAlpha(96);
}
if (counter_ == counter_end_)
if (counter_ == COUNTER_END_)
{
fade_->activate();
}

View File

@@ -24,6 +24,10 @@ enum class FadeMode : Uint8; // lines 11-11
class HiScoreTable
{
private:
// Constantes
static constexpr Uint16 COUNTER_END_ = 800; // Valor final para el contador
static constexpr Uint32 TICKS_SPEED_ = 15; // Velocidad a la que se repiten los bucles del programa
// Objetos y punteros
SDL_Renderer *renderer_; // El renderizador de la ventana
SDL_Texture *backbuffer_; // Textura para usar como backbuffer
@@ -34,9 +38,7 @@ private:
// Variables
Uint16 counter_; // Contador
Uint16 counter_end_; // Valor final para el contador
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticks_speed_; // Velocidad a la que se repiten los bucles del programa
SDL_Rect view_area_; // Parte de la textura que se muestra en pantalla
FadeMode fade_mode_; // Modo de fade a utilizar

View File

@@ -33,11 +33,9 @@ Resource::Resource()
loadTextures();
loadTextFiles();
loadAnimations();
addPalettes();
std::cout << "\n** RESOURCES LOADED" << std::endl;
std::cout << "\n** ADD PALETTES" << std::endl;
addPalettes();
std::cout << "\n** PALETTES ADDED" << std::endl;
}
// Destructor
@@ -229,18 +227,16 @@ void Resource::loadAnimations()
void Resource::addPalettes()
{
// Jugador 1
std::cout << "\n>> PLAYER1" << std::endl;
std::cout << "\n>> PALETTES" << std::endl;
getTexture("player1.gif")->addPaletteFromFile(Asset::get()->get("player1_one_coffee_palette.pal"));
getTexture("player1.gif")->addPaletteFromFile(Asset::get()->get("player1_two_coffee_palette.pal"));
getTexture("player1.gif")->addPaletteFromFile(Asset::get()->get("player1_all_white_palette.pal"));
// Jugador 2
std::cout << "\n>> PLAYER2" << std::endl;
getTexture("player2.gif")->addPaletteFromFile(Asset::get()->get("player2_one_coffee_palette.pal"));
getTexture("player2.gif")->addPaletteFromFile(Asset::get()->get("player2_two_coffee_palette.pal"));
getTexture("player2.gif")->addPaletteFromFile(Asset::get()->get("player2_all_white_palette.pal"));
// Fuentes
std::cout << "\n>> FONTS" << std::endl;
getTexture("smb2.gif")->addPaletteFromFile(Asset::get()->get("smb2_palette1.pal"));
}

View File

@@ -8,17 +8,18 @@
#include "asset.h" // for Asset
#include "lang.h" // for getText
#include "resource.h" // for Resource
#include "sprite.h" // for Sprite
#include "text.h" // for Text
#include "texture.h" // for Texture
#include "screen.h"
#include "sprite.h" // for Sprite
#include "text.h" // for Text
#include "texture.h" // for Texture
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
Scoreboard *Scoreboard::scoreboard_ = nullptr;
// [SINGLETON] Crearemos el objeto score_board con esta función estática
void Scoreboard::init(SDL_Renderer *renderer)
void Scoreboard::init()
{
Scoreboard::scoreboard_ = new Scoreboard(renderer);
Scoreboard::scoreboard_ = new Scoreboard();
}
// [SINGLETON] Destruiremos el objeto score_board con esta función estática
@@ -34,8 +35,8 @@ Scoreboard *Scoreboard::get()
}
// Constructor
Scoreboard::Scoreboard(SDL_Renderer *renderer)
: renderer_(renderer),
Scoreboard::Scoreboard()
: renderer_(Screen::get()->getRenderer()),
game_power_meter_texture_(Resource::get()->getTexture("game_power_meter.png")),
power_meter_sprite_(std::make_unique<Sprite>(game_power_meter_texture_)),
@@ -107,7 +108,7 @@ std::string Scoreboard::updateScoreText(int num)
// Actualiza el contador
void Scoreboard::updateCounter()
{
if (SDL_GetTicks() - ticks_ > SCOREBOARD_TICK_SPEED)
if (SDL_GetTicks() - ticks_ > SCOREBOARD_TICK_SPEED_)
{
ticks_ = SDL_GetTicks();
counter_++;

View File

@@ -1,12 +1,12 @@
#pragma once
#include <SDL2/SDL_rect.h> // for SDL_Point, SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for unique_ptr, shared_ptr
#include <string> // for string
#include <vector> // for vector
#include "utils.h" // for Color
#include <SDL2/SDL_rect.h> // for SDL_Point, SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for unique_ptr, shared_ptr
#include <string> // for string
#include <vector> // for vector
#include "utils.h" // for Color
class Sprite;
class Text;
class Texture;
@@ -16,7 +16,6 @@ constexpr int SCOREBOARD_LEFT_PANEL = 0;
constexpr int SCOREBOARD_CENTER_PANEL = 1;
constexpr int SCOREBOARD_RIGHT_PANEL = 2;
constexpr int SCOREBOARD_MAX_PANELS = 3;
constexpr int SCOREBOARD_TICK_SPEED = 100;
// Enums
enum class ScoreboardMode : int
@@ -42,6 +41,9 @@ struct Panel
class Scoreboard
{
private:
// Constantes
static constexpr int SCOREBOARD_TICK_SPEED_ = 100;
// [SINGLETON] Objeto scoreboard privado para Don Melitón
static Scoreboard *scoreboard_;
@@ -103,14 +105,14 @@ private:
// [SINGLETON] Ahora el constructor y el destructor son privados
// Constructor
explicit Scoreboard(SDL_Renderer *renderer);
Scoreboard();
// Destructor
~Scoreboard();
public:
// [SINGLETON] Crearemos el objeto scoreboard con esta función estática
static void init(SDL_Renderer *renderer);
static void init();
// [SINGLETON] Destruiremos el objeto scoreboard con esta función estática
static void destroy();

View File

@@ -58,7 +58,6 @@ struct HiScoreEntry
int score; // Puntuación
};
// Estructura para mapear el teclado usado en la demo
struct DemoKeys
{
Uint8 left;
@@ -67,6 +66,10 @@ struct DemoKeys
Uint8 fire;
Uint8 fire_left;
Uint8 fire_right;
// Constructor que inicializa todos los campos
DemoKeys(Uint8 l = 0, Uint8 r = 0, Uint8 ni = 0, Uint8 f = 0, Uint8 fl = 0, Uint8 fr = 0)
: left(l), right(r), no_input(ni), fire(f), fire_left(fl), fire_right(fr) {}
};
// Estructura para las opciones de la ventana
@@ -215,7 +218,6 @@ struct Param
ParamNotification notification; // Opciones para las notificaciones
};
// Calcula el cuadrado de la distancia entre dos puntos
double distanceSquared(int x1, int y1, int x2, int y2);