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 "moving_sprite.h" // for MovingSprite
#include "param.h" // for param #include "param.h" // for param
#include "resource.h" // for Resource #include "resource.h" // for Resource
#include "sprite.h" // for Sprite #include "screen.h"
#include "texture.h" // for Texture #include "sprite.h" // for Sprite
#include "texture.h" // for Texture
// Constructor // Constructor
Background::Background(SDL_Renderer *renderer) Background::Background()
: renderer_(renderer), : renderer_(Screen::get()->getRenderer()),
buildings_texture_(Resource::get()->getTexture("game_buildings.png")), buildings_texture_(Resource::get()->getTexture("game_buildings.png")),
top_clouds_texture_(Resource::get()->getTexture("game_clouds1.png")), top_clouds_texture_(Resource::get()->getTexture("game_clouds1.png")),
bottom_clouds_texture_(Resource::get()->getTexture("game_clouds2.png")), bottom_clouds_texture_(Resource::get()->getTexture("game_clouds2.png")),
grass_texture_(Resource::get()->getTexture("game_grass.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 // 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_[0] = {0, 0, rect_.w, rect_.h};
gradient_rect_[1] = {rect_.w, 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}; 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 // 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); SDL_SetTextureBlendMode(canvas_, SDL_BLENDMODE_BLEND);
// Crea la textura para atenuar el fondo // 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); SDL_SetTextureBlendMode(color_texture_, SDL_BLENDMODE_BLEND);
setColor(color_); setColor(color_);
SDL_SetTextureAlphaMod(color_texture_, alpha_color_text_); SDL_SetTextureAlphaMod(color_texture_, alpha_color_text_);
@@ -120,7 +121,7 @@ void Background::update()
alpha_ = std::max((255 - (int)(255 * transition_)), 0); alpha_ = std::max((255 - (int)(255 * transition_)), 0);
// Incrementa el contador // Incrementa el contador
counter_++; ++counter_;
// Compone todos los elementos del fondo en la textura // Compone todos los elementos del fondo en la textura
fillCanvas(); fillCanvas();

View File

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

View File

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

View File

@@ -34,25 +34,6 @@ constexpr bool GAME_MODE_DEMO_ON = true;
constexpr int TOTAL_SCORE_DATA = 3; constexpr int TOTAL_SCORE_DATA = 3;
constexpr int TOTAL_DEMO_DATA = 2000; 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 Esta clase gestiona un estado del programa. Se encarga de toda la parte en la
que se está jugando. que se está jugando.
@@ -79,10 +60,22 @@ constexpr int TIME_STOPPED_COUNTER = 300;
puntuación mínima. 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 // Clase Game
class Game class Game
{ {
private: private:
// Estructuras
struct Helper struct Helper
{ {
bool need_coffee; // Indica si se necesitan cafes bool need_coffee; // Indica si se necesitan cafes
@@ -97,14 +90,25 @@ private:
int item_coffee_machine_odds; // Probabilidad de aparición del objeto int item_coffee_machine_odds; // Probabilidad de aparición del objeto
}; };
struct Demo // Constantes
{
bool enabled; // Indica si está activo el modo demo // Contadores
bool recording; // Indica si está activado el modo para grabar la demo static constexpr int STAGE_COUNTER_ = 200;
int counter; // Contador para el modo demo static constexpr int HELP_COUNTER_ = 1000;
DemoKeys keys; // Variable con las pulsaciones de teclas del modo demo static constexpr int GAME_COMPLETED_START_FADE_ = 500;
DemoKeys data_file[2][TOTAL_DEMO_DATA]; // Vector con diferentes sets de datos con los movimientos para la demo 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 // Objetos y punteros
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
@@ -146,39 +150,38 @@ private:
std::unique_ptr<Fade> fade_; // Objeto para renderizar fades std::unique_ptr<Fade> fade_; // Objeto para renderizar fades
// Variables // Variables
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa 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
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_; // Máxima puntuación y nombre de quien la ostenta int current_stage_; // Indica la fase actual
int current_stage_; // Indica la fase actual int stage_bitmap_counter_; // Contador para el tiempo visible del texto de Stage
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 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
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 game_over_counter_; // Contador para el estado de fin de partida int menace_current_; // Nivel de amenaza actual
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
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
bool time_stopped_; // Indica si el tiempo está detenido int time_stopped_counter_; // Temporizador para llevar la cuenta del tiempo detenido
int time_stopped_counter_; // Temporizador para llevar la cuenta del tiempo detenido int counter_; // Contador para el juego
int counter_; // Contador para el juego int balloons_popped_; // Lleva la cuenta de los globos explotados
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 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
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 balloon_speed_; // Velocidad a la que se mueven los enemigos float default_balloon_speed_; // Velocidad base de los enemigos, sin incrementar
float default_balloon_speed_; // Velocidad base de los enemigos, sin incrementar Helper helper_; // Variable para gestionar las ayudas
Helper helper_; // Variable para gestionar las ayudas bool power_ball_enabled_; // Indica si hay una powerball ya activa
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
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 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
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
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
GameDifficulty difficulty_; // Dificultad del juego float difficulty_score_multiplier_; // Multiplicador de puntos en función de la dificultad
float difficulty_score_multiplier_; // Multiplicador de puntos en función de la dificultad Color difficulty_color_; // Color asociado a 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
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
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
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)
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
int current_power_; // Poder actual almacenado para completar la fase
#ifdef DEBUG #ifdef DEBUG
bool auto_pop_balloons_; // Si es true, incrementa automaticamente los globos explotados bool auto_pop_balloons_; // Si es true, incrementa automaticamente los globos explotados
#endif #endif
@@ -202,7 +205,7 @@ private:
void unloadMedia(); void unloadMedia();
// Carga el fichero de datos para la demo // 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 #ifdef RECORDING
// Guarda el fichero de datos para la demo // Guarda el fichero de datos para la demo
bool saveDemoFile(const std::string &file_path); bool saveDemoFile(const std::string &file_path);

View File

@@ -23,29 +23,21 @@
// Constructor // Constructor
HiScoreTable::HiScoreTable() 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 // Inicializa el resto de variables
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
section::name = section::Name::HI_SCORE_TABLE; 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 // Inicializa objetos
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
background_->setPos(param.game.game_area.rect); background_->setPos(param.game.game_area.rect);
background_->setCloudsSpeed(-0.1f); background_->setCloudsSpeed(-0.1f);
background_->setGradientNumber(1); background_->setGradientNumber(1);
@@ -70,7 +62,7 @@ HiScoreTable::~HiScoreTable()
void HiScoreTable::update() void HiScoreTable::update()
{ {
// Actualiza las variables // Actualiza las variables
if (SDL_GetTicks() - ticks_ > ticks_speed_) if (SDL_GetTicks() - ticks_ > TICKS_SPEED_)
{ {
// Actualiza el contador de ticks // Actualiza el contador de ticks
ticks_ = SDL_GetTicks(); ticks_ = SDL_GetTicks();
@@ -99,7 +91,7 @@ void HiScoreTable::update()
background_->setAlpha(96); background_->setAlpha(96);
} }
if (counter_ == counter_end_) if (counter_ == COUNTER_END_)
{ {
fade_->activate(); fade_->activate();
} }

View File

@@ -24,6 +24,10 @@ enum class FadeMode : Uint8; // lines 11-11
class HiScoreTable class HiScoreTable
{ {
private: 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 // Objetos y punteros
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
SDL_Texture *backbuffer_; // Textura para usar como backbuffer SDL_Texture *backbuffer_; // Textura para usar como backbuffer
@@ -34,9 +38,7 @@ private:
// Variables // Variables
Uint16 counter_; // Contador Uint16 counter_; // Contador
Uint16 counter_end_; // Valor final para el contador
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa 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 SDL_Rect view_area_; // Parte de la textura que se muestra en pantalla
FadeMode fade_mode_; // Modo de fade a utilizar FadeMode fade_mode_; // Modo de fade a utilizar

View File

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

View File

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

View File

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

View File

@@ -58,7 +58,6 @@ struct HiScoreEntry
int score; // Puntuación int score; // Puntuación
}; };
// Estructura para mapear el teclado usado en la demo
struct DemoKeys struct DemoKeys
{ {
Uint8 left; Uint8 left;
@@ -67,6 +66,10 @@ struct DemoKeys
Uint8 fire; Uint8 fire;
Uint8 fire_left; Uint8 fire_left;
Uint8 fire_right; 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 // Estructura para las opciones de la ventana
@@ -215,7 +218,6 @@ struct Param
ParamNotification notification; // Opciones para las notificaciones ParamNotification notification; // Opciones para las notificaciones
}; };
// Calcula el cuadrado de la distancia entre dos puntos // Calcula el cuadrado de la distancia entre dos puntos
double distanceSquared(int x1, int y1, int x2, int y2); double distanceSquared(int x1, int y1, int x2, int y2);