Treballant en el final del joc

This commit is contained in:
2024-10-31 11:58:01 +01:00
parent 7e2691e33e
commit 30dfa4c545
7 changed files with 502 additions and 656 deletions

View File

@@ -1,15 +1,4 @@
#include "game.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event, SDL_KEYDOWN
#include <SDL2/SDL_keycode.h> // for SDLK_1, SDLK_2, SDLK_3, SDLK_4
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <SDL2/SDL_video.h> // for SDL_WINDOWEVENT_FOCUS_GAINED, SDL_...
#include <stdlib.h> // for rand, size_t
#include <algorithm> // for find_if, clamp, min, remove_if
#include <functional> // for function
#include <iterator> // for distance, size
#include <numeric> // for accumulate
#include "asset.h" // for Asset
#include "background.h" // for Background
#include "balloon.h" // for Balloon, BALLOON_SCORE, BALLOON_VE...
@@ -34,7 +23,19 @@
#include "smart_sprite.h" // for SmartSprite
#include "text.h" // for Text
#include "texture.h" // for Texture
struct JA_Sound_t; // lines 36-36
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event, SDL_KEYDOWN
#include <SDL2/SDL_keycode.h> // for SDLK_1, SDLK_2, SDLK_3, SDLK_4
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <SDL2/SDL_video.h> // for SDL_WINDOWEVENT_FOCUS_GAINED, SDL_...
#include <algorithm> // for find_if, clamp, min, remove_if
#include <functional> // for function
#include <iterator> // for distance, size
#include <numeric> // for accumulate
#include <stdlib.h> // for rand, size_t
struct JA_Sound_t; // lines 36-36
// Constructor
Game::Game(int player_id, int current_stage, bool demo)
@@ -84,7 +85,7 @@ Game::Game(int player_id, int current_stage, bool demo)
initPaths();
setTotalPower();
// Crea los primeros globos
// Crea los primeros globos y el mensaje de inicio
if (!demo_.enabled)
{
createTwoBigBalloons();
@@ -210,7 +211,6 @@ void Game::deployBalloonFormation()
// Solo despliega una formación enemiga si ha pasado cierto tiempo desde la última
if (balloon_deploy_counter_ == 0)
{
// En este punto se decide entre crear una powerball o una formación enemiga
if ((rand() % 100 < 15) && (canPowerBallBeCreated()))
{
@@ -250,10 +250,7 @@ void Game::deployBalloonFormation()
}
// Aumenta el poder de la fase
void Game::increaseStageCurrentPower(int power)
{
current_power_ += power;
}
void Game::increaseStageCurrentPower(int power) { current_power_ += power; }
// Actualiza el valor de hiScore en caso necesario
void Game::updateHiScore()
@@ -328,34 +325,40 @@ void Game::updateStage()
// Cambio de fase
++current_stage_;
current_power_ = 0;
// Ha llegado al final el juego
if (current_stage_ == 10)
{
game_completed_ = true; // Marca el juego como completado
current_stage_ = 9; // Deja el valor dentro de los limites
destroyAllBalloons(); // Destruye a todos los enemigos
current_power_ = 0; // Vuelve a dejar el poder a cero, por lo que hubiera podido subir al destruir todos lo globos
menace_current_ = 255; // Sube el nivel de amenaza para que no cree mas globos
// Añade un millon de puntos a los jugadores que queden vivos
for (auto &player : players_)
if (player->isPlaying())
player->addScore(1000000);
updateHiScore();
JA_StopMusic();
}
JA_PlaySound(Resource::get()->getSound("stage_change.wav"));
balloon_speed_ = default_balloon_speed_;
setBalloonSpeed(balloon_speed_);
screen_->flash(flash_color, 100);
screen_->shake();
// Escribe el texto por pantalla
const auto stage_number = balloon_formations_->getStage(current_stage_).number;
if (!game_completed_)
// Ha llegado al final el juego
if (status_ == GameStatus::PLAYING && current_stage_ == 10)
{
status_ = GameStatus::COMPLETED;
stopMusic();
current_stage_ = 9; // Deja el valor dentro de los limites
destroyAllBalloons(); // Destruye a todos los globos
destroyAllItems(); // Destruye todos los items
current_power_ = 0; // Vuelve a dejar el poder a cero, por lo que hubiera podido subir al destruir todos los globos
for (auto &player : players_)
if (player->isPlaying())
{
player->addScore(1000000);
player->setStatusPlaying(player->IsEligibleForHighScore() ? PlayerStatus::ENTERING_NAME_GAME_COMPLETED : PlayerStatus::GAME_COMPLETED);
}
else
{
player->setStatusPlaying(PlayerStatus::GAME_OVER);
}
updateHiScore();
}
// Escribe el texto por pantalla
if (status_ == GameStatus::PLAYING)
{
const auto stage_number = balloon_formations_->getStage(current_stage_).number;
std::vector<Path> paths = {paths_.at(2), paths_.at(3)};
if (stage_number == 10)
createMessage(paths, Resource::get()->getTexture("last_stage"));
@@ -377,8 +380,8 @@ void Game::updateStage()
// Actualiza el estado de fin de la partida
void Game::updateGameOver()
{
// Si todos estan en estado de Game Over
if (allPlayersAreGameOver())
// Si todos estan en estado de Game Over y no hay mensajes por pantalla
if (allPlayersAreGameOver() && path_sprites_.empty())
{
if (game_over_counter_ > 0)
{
@@ -391,11 +394,7 @@ void Game::updateGameOver()
{
// Hace sonar aleatoriamente uno de los 4 sonidos de burbujas
const auto index = rand() % 4;
JA_Sound_t *sound[4] = {
Resource::get()->getSound("bubble1.wav"),
Resource::get()->getSound("bubble2.wav"),
Resource::get()->getSound("bubble3.wav"),
Resource::get()->getSound("bubble4.wav")};
JA_Sound_t *sound[4] = {Resource::get()->getSound("bubble1.wav"), Resource::get()->getSound("bubble2.wav"), Resource::get()->getSound("bubble3.wav"), Resource::get()->getSound("bubble4.wav")};
JA_PlaySound(sound[index], 0);
}
@@ -416,18 +415,14 @@ void Game::updateGameOver()
void Game::updateBalloons()
{
for (auto balloon : balloons_)
{
balloon->update();
}
}
// Pinta en pantalla todos los globos activos
void Game::renderBalloons()
{
for (auto &balloon : balloons_)
{
balloon->render();
}
}
// Crea un globo nuevo en el vector de globos
@@ -477,29 +472,25 @@ void Game::createPowerBall()
void Game::setBalloonSpeed(float speed)
{
for (auto &balloon : balloons_)
{
if (balloon->isEnabled())
{
balloon->setSpeed(speed);
}
}
balloon->setSpeed(speed);
}
// Actualiza la velocidad de los globos en funcion del poder acumulado de la fase
void Game::updateBalloonSpeed()
void Game::checkAndUpdateBalloonSpeed()
{
if (difficulty_ != GameDifficulty::NORMAL)
return;
const float percent = static_cast<float>(current_power_) / balloon_formations_->getStage(current_stage_).power_to_complete;
const float thresholds[] = {0.2f, 0.4f, 0.6f, 0.8f};
for (size_t i = 0; i < std::size(thresholds); ++i)
{
if (balloon_speed_ == BALLOON_SPEED[i] && percent > thresholds[i])
{
balloon_speed_ = BALLOON_SPEED[i + 1];
setBalloonSpeed(balloon_speed_);
break; // Salir del bucle una vez actualizada la velocidad y aplicada
}
}
}
// Explosiona un globo. Lo destruye y crea otros dos si es el caso
@@ -575,8 +566,7 @@ void Game::destroyBalloon(std::shared_ptr<Balloon> &balloon)
void Game::destroyAllBalloons()
{
for (auto &balloon : balloons_)
if (balloon->canBeDestroyed())
destroyBalloon(balloon);
destroyBalloon(balloon);
balloon_deploy_counter_ = 300;
JA_PlaySound(Resource::get()->getSound("powerball.wav"));
@@ -584,6 +574,13 @@ void Game::destroyAllBalloons()
screen_->shake();
}
// Destruye todos los items
void Game::destroyAllItems()
{
for (auto &item : items_)
item->disable();
}
// Detiene todos los globos
void Game::stopAllBalloons()
{
@@ -617,8 +614,7 @@ void Game::normalColorsToAllBalloons()
// Vacia del vector de globos los globos que ya no sirven
void Game::freeBalloons()
{
auto it = std::remove_if(balloons_.begin(), balloons_.end(),
[](const auto &balloon)
auto it = std::remove_if(balloons_.begin(), balloons_.end(), [](const auto &balloon)
{ return !balloon->isEnabled(); });
balloons_.erase(it, balloons_.end());
}
@@ -627,7 +623,7 @@ void Game::freeBalloons()
bool Game::checkPlayerBalloonCollision(std::shared_ptr<Player> &player)
{
for (auto &balloon : balloons_)
if ((balloon->isEnabled()) && !(balloon->isStopped()) && !(balloon->isInvulnerable()))
if (!balloon->isStopped() && !balloon->isInvulnerable())
if (checkCollision(player->getCollider(), balloon->getCollider()))
return true;
@@ -651,28 +647,36 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player)
case ItemType::DISK:
{
player->addScore(1000);
const auto x = item->getPosX() + (item->getWidth() - game_text_textures_[0]->getWidth()) / 2;
const auto x =
item->getPosX() +
(item->getWidth() - game_text_textures_[0]->getWidth()) / 2;
createItemText(x, game_text_textures_[0]);
break;
}
case ItemType::GAVINA:
{
player->addScore(2500);
const auto x = item->getPosX() + (item->getWidth() - game_text_textures_[1]->getWidth()) / 2;
const auto x =
item->getPosX() +
(item->getWidth() - game_text_textures_[1]->getWidth()) / 2;
createItemText(x, game_text_textures_[1]);
break;
}
case ItemType::PACMAR:
{
player->addScore(5000);
const auto x = item->getPosX() + (item->getWidth() - game_text_textures_[2]->getWidth()) / 2;
const auto x =
item->getPosX() +
(item->getWidth() - game_text_textures_[2]->getWidth()) / 2;
createItemText(x, game_text_textures_[2]);
break;
}
case ItemType::CLOCK:
{
enableTimeStopItem();
const auto x = item->getPosX() + (item->getWidth() - game_text_textures_[5]->getWidth()) / 2;
const auto x =
item->getPosX() +
(item->getWidth() - game_text_textures_[5]->getWidth()) / 2;
createItemText(x, game_text_textures_[5]);
break;
}
@@ -681,13 +685,17 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player)
if (player->getCoffees() == 2)
{
player->addScore(5000);
const auto x = item->getPosX() + (item->getWidth() - game_text_textures_[2]->getWidth()) / 2;
const auto x =
item->getPosX() +
(item->getWidth() - game_text_textures_[2]->getWidth()) / 2;
createItemText(x, game_text_textures_[2]);
}
else
{
player->giveExtraHit();
const auto x = item->getPosX() + (item->getWidth() - game_text_textures_[4]->getWidth()) / 2;
const auto x =
item->getPosX() +
(item->getWidth() - game_text_textures_[4]->getWidth()) / 2;
createItemText(x, game_text_textures_[4]);
}
break;
@@ -696,7 +704,9 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player)
{
player->setPowerUp();
coffee_machine_enabled_ = false;
const auto x = item->getPosX() + (item->getWidth() - game_text_textures_[3]->getWidth()) / 2;
const auto x =
item->getPosX() +
(item->getWidth() - game_text_textures_[3]->getWidth()) / 2;
createItemText(x, game_text_textures_[3]);
break;
}
@@ -723,7 +733,7 @@ void Game::checkBulletBalloonCollision()
{
if (checkCollision(balloon->getCollider(), bullet->getCollider()))
{
// Otorga los puntos correspondientes al globo al jugador que disparó la bala
// Otorga los puntos al jugador que disparó la bala
auto player = getPlayer(bullet->getOwner());
if (!player)
{
@@ -783,7 +793,8 @@ void Game::renderBullets()
// Crea un objeto bala
void Game::createBullet(int x, int y, BulletType kind, bool powered_up, int owner)
{
bullets_.emplace_back(std::make_unique<Bullet>(x, y, kind, powered_up, owner, bullet_texture_));
bullets_.emplace_back(
std::make_unique<Bullet>(x, y, kind, powered_up, owner, bullet_texture_));
}
// Vacia el vector de balas
@@ -1033,8 +1044,9 @@ void Game::killPlayer(std::shared_ptr<Player> &player)
// Calcula y establece el valor de amenaza en funcion de los globos activos
void Game::evaluateAndSetMenace()
{
menace_current_ = std::accumulate(balloons_.begin(), balloons_.end(), 0, [](int sum, const auto &balloon)
{ return sum + (balloon->isEnabled() ? balloon->getMenace() : 0); });
menace_current_ = std::accumulate(
balloons_.begin(), balloons_.end(), 0, [](int sum, const auto &balloon)
{ return sum + (balloon->isEnabled() ? balloon->getMenace() : 0); });
}
// Actualiza y comprueba el valor de la variable
@@ -1076,131 +1088,19 @@ void Game::update()
if (SDL_GetTicks() - ticks_ > TICKS_SPEED)
{
// Actualiza el contador de ticks
ticks_ = SDL_GetTicks();
// Actualiza el contador de juego
counter_++;
if (demo_.enabled)
{
// Incrementa el contador de la demo
if (demo_.counter < TOTAL_DEMO_DATA)
demo_.counter++;
// Activa el fundido antes de acabar con los datos de la demo
if (demo_.counter == TOTAL_DEMO_DATA - 200)
{
fade_->setType(FadeType::RANDOM_SQUARE);
fade_->activate();
}
// Si ha terminado el fundido, cambia de sección
if (fade_->hasEnded())
{
section::name = section::Name::HI_SCORE_TABLE;
return;
}
}
updateDemo();
#ifdef RECORDING
// Solo mira y guarda el input en cada update
checkInput();
// Incrementa el contador de la demo
if (demo_.counter < TOTAL_DEMO_DATA)
demo_.counter++;
// Si se ha llenado el vector con datos, sale del programa
else
{
section::name = section::Name::QUIT;
return;
}
updateRecording();
#endif
#ifdef DEBUG
if (auto_pop_balloons_ && !game_completed_)
{
balloons_popped_++;
increaseStageCurrentPower(1);
}
#endif
if (!paused_)
{
// Actualiza el objeto fade
fade_->update();
updateNormalGame();
updateCompletedGame();
// Actualiza las variables del jugador
updatePlayers();
// Actualiza el marcador
checkPlayersStatusPlaying();
updateScoreboard();
// Actualiza el fondo
updateBackground();
// Mueve los globos
updateBalloons();
// Actualiza el objeto encargado de las explosiones
explosions_->update();
// Mueve las balas
moveBullets();
// Actualiza los items
updateItems();
// Comprueba si hay cambio de fase y actualiza las variables
updateStage();
// Actualiza el estado de muerte
updateGameOver();
// Actualiza los SpriteSmarts
updateSmartSprites();
// Actualiza los PathSmarts
updatePathSprites();
// Actualiza los contadores de estado y efectos
updateTimeStopped();
updateBalloonDeployCounter();
// Actualiza el ayudante
updateHelper();
// Comprueba las colisiones entre globos y balas
checkBulletBalloonCollision();
// Comprueba el nivel de amenaza para ver si se han de crear nuevos enemigos
updateMenace();
// Actualiza la velocidad de los enemigos
if (difficulty_ == GameDifficulty::NORMAL)
{
updateBalloonSpeed();
}
// Actualiza el tramo final de juego, una vez completado
updateGameCompleted();
// Vacia los vectores
freeBullets();
freeBalloons();
freeItems();
freeSmartSprites();
freePathSprites();
}
// Comprueba si la música ha de estar sonando
checkMusicStatus();
// Actualiza el objeto screen
screen_->update();
// Dibuja los graficos de la zona de juego en la textura
fillCanvas();
}
}
@@ -1209,7 +1109,7 @@ void Game::update()
void Game::updateBackground()
{
// Si el juego está completado, se reduce la velocidad de las nubes
if (game_completed_)
if (status_ == GameStatus::COMPLETED)
balloons_popped_ = (balloons_popped_ > 400) ? (balloons_popped_ - 25) : 200;
// Calcula la velocidad en función de los globos explotados y el total de globos a explotar para acabar el juego
@@ -1271,9 +1171,6 @@ void Game::render()
// Gestiona el nivel de amenaza
void Game::updateMenace()
{
if (game_completed_)
return;
const auto stage = balloon_formations_->getStage(current_stage_);
const float percent = current_power_ / stage.power_to_complete;
const int difference = stage.max_menace - stage.min_menace;
@@ -1312,9 +1209,10 @@ void Game::disableTimeStopItem()
void Game::checkMusicStatus()
{
// Si la música no está sonando
if (JA_GetMusicState() == JA_MUSIC_INVALID || JA_GetMusicState() == JA_MUSIC_STOPPED)
if (JA_GetMusicState() == JA_MUSIC_INVALID ||
JA_GetMusicState() == JA_MUSIC_STOPPED)
// Si se ha completado el juego o los jugadores han terminado, detiene la música
game_completed_ || allPlayersAreGameOver() ? JA_StopMusic() : JA_PlayMusic(Resource::get()->getMusic("playing.ogg"));
status_ == GameStatus::COMPLETED || allPlayersAreGameOver() ? JA_StopMusic() : JA_PlayMusic(Resource::get()->getMusic("playing.ogg"));
}
// Bucle para el juego
@@ -1335,10 +1233,7 @@ void Game::run()
}
// Indica si se puede crear una powerball
bool Game::canPowerBallBeCreated()
{
return (!power_ball_enabled_) && (calculateScreenPower() > POWERBALL_SCREENPOWER_MINIMUM) && (power_ball_counter_ == 0);
}
bool Game::canPowerBallBeCreated() { return (!power_ball_enabled_) && (calculateScreenPower() > POWERBALL_SCREENPOWER_MINIMUM) && (power_ball_counter_ == 0); }
// Calcula el poder actual de los globos en pantalla
int Game::calculateScreenPower()
@@ -1362,7 +1257,8 @@ void Game::initPaths()
paths_.emplace_back(Path(createPath(x1, x2, PathType::HORIZONTAL, y, 80, easeInQuint), 0));
}
// Recorrido para el texto de "Last Stage!" o de "X stages left" o "Game Over" (2,3)
// Recorrido para el texto de "Last Stage!" o de "X stages left" o "Game Over"
// (2,3)
{
const auto &texture = Resource::get()->getTexture("last_stage");
const auto h = texture->getHeight();
@@ -1401,19 +1297,6 @@ void Game::initPaths()
}
}
// Actualiza el tramo final de juego, una vez completado
void Game::updateGameCompleted()
{
if (game_completed_)
game_completed_counter_++;
if (game_completed_counter_ == GAME_COMPLETED_END_)
{
section::name = section::Name::TITLE;
section::options = section::Options::TITLE_1;
}
}
// Actualiza las variables de ayuda
void Game::updateHelper()
{
@@ -1547,6 +1430,10 @@ void Game::checkEvents()
screen_->flash(flash_color, 100);
break;
}
case SDLK_8:
{
players_.at(0)->setStatusPlaying(PlayerStatus::GAME_COMPLETED);
}
default:
break;
}
@@ -1613,9 +1500,7 @@ void Game::addScoreToScoreBoard(const std::string &name, int score)
// Saca del estado de GAME OVER al jugador si el otro está activo
void Game::checkAndUpdatePlayerStatus(int activePlayerIndex, int inactivePlayerIndex)
{
if (players_[activePlayerIndex]->isGameOver() &&
!players_[inactivePlayerIndex]->isGameOver() &&
!players_[inactivePlayerIndex]->isWaiting())
if (players_[activePlayerIndex]->isGameOver() && !players_[inactivePlayerIndex]->isGameOver() && !players_[inactivePlayerIndex]->isWaiting())
{
players_[activePlayerIndex]->setStatusPlaying(PlayerStatus::WAITING);
}
@@ -1660,11 +1545,8 @@ std::shared_ptr<Player> Game::getPlayer(int id)
// Obtiene un controlador a partir del "id" del jugador
int Game::getController(int player_id)
{
auto it = std::find_if(options.controller.begin(), options.controller.end(),
[player_id](const auto &controller)
{
return controller.player_id == player_id;
});
auto it = std::find_if(options.controller.begin(), options.controller.end(), [player_id](const auto &controller)
{ return controller.player_id == player_id; });
if (it != options.controller.end())
{
@@ -1680,9 +1562,13 @@ void Game::checkInput()
checkPauseInput(); // Verifica si se debe pausar el juego.
if (demo_.enabled)
handleDemoMode(); // Controla el comportamiento de los jugadores en modo demo.
{ // Controla el comportamiento de los jugadores en modo demo.
handleDemoMode();
}
else
handlePlayersInput(); // Gestiona el input normal de los jugadores.
{ // Gestiona el input normal de los jugadores.
handlePlayersInput();
}
screen_->checkInput(); // Verifica el input en la pantalla del juego.
globalInputs::check(); // Verifica los inputs globales.
@@ -1710,17 +1596,20 @@ void Game::checkPauseInput()
// Gestiona las entradas de los jugadores en el modo demo, incluyendo movimientos y disparos automáticos.
void Game::handleDemoMode()
{
int i = 0;
int index = 0;
for (const auto &player : players_)
{
if (player->isPlaying())
handleDemoPlayerInput(player, i); // Maneja el input específico del jugador en modo demo.
{ // Maneja el input específico del jugador en modo demo.
handleDemoPlayerInput(player, index);
}
if (input_->checkAnyButtonPressed())
{
section::name = section::Name::TITLE; // Salir del modo demo y regresar al menú principal.
return;
}
i++;
++index;
}
}
@@ -1730,18 +1619,30 @@ void Game::handleDemoPlayerInput(const std::shared_ptr<Player> &player, int inde
const auto &demoData = demo_.data[index][demo_.counter];
if (demoData.left == 1)
{
player->setInput(InputType::LEFT);
}
else if (demoData.right == 1)
{
player->setInput(InputType::RIGHT);
}
else if (demoData.no_input == 1)
{
player->setInput(InputType::NONE);
}
if (demoData.fire == 1)
{
handleFireInput(player, BulletType::UP);
}
else if (demoData.fire_left == 1)
{
handleFireInput(player, BulletType::LEFT);
}
else if (demoData.fire_right == 1)
{
handleFireInput(player, BulletType::RIGHT);
}
}
// Maneja el disparo de un jugador, incluyendo la creación de balas y la gestión del tiempo de espera entre disparos.
@@ -1753,7 +1654,8 @@ void Game::handleFireInput(const std::shared_ptr<Player> &player, BulletType bul
: InputType::FIRE_RIGHT);
createBullet(player->getPosX() + (player->getWidth() / 2) - 6, player->getPosY() + (player->getHeight() / 2), bulletType, player->isPowerUp(), player->getId());
JA_PlaySound(Resource::get()->getSound("bullet.wav"));
player->setFireCooldown(10); // Establece un tiempo de espera para el próximo disparo.
// Establece un tiempo de espera para el próximo disparo.
player->setFireCooldown(10);
}
}
@@ -1763,11 +1665,17 @@ void Game::handlePlayersInput()
for (const auto &player : players_)
{
if (player->isPlaying())
handleNormalPlayerInput(player); // Maneja el input de los jugadores en modo normal.
{ // Maneja el input de los jugadores en modo normal.
handleNormalPlayerInput(player);
}
else if (player->isContinue() || player->isWaiting())
handlePlayerContinue(player); // Gestiona la continuación del jugador.
else if (player->isEnteringName())
handleNameInput(player); // Gestiona la introducción del nombre del jugador.
{ // Gestiona la continuación del jugador.
handlePlayerContinue(player);
}
else if (player->isEnteringName() || player->isEnteringNameGameCompleted())
{ // Gestiona la introducción del nombre del jugador.
handleNameInput(player);
}
}
}
@@ -1802,24 +1710,32 @@ void Game::handleNormalPlayerInput(const std::shared_ptr<Player> &player)
handleFireInputs(player, autofire, controllerIndex); // Verifica y maneja todas las posibles entradas de disparo.
}
// Procesa las entradas de disparo del jugador, permitiendo disparos automáticos si está habilitado.
void Game::handleFireInputs(const std::shared_ptr<Player> &player, bool autofire, int controllerIndex)
// Procesa las entradas de disparo del jugador, permitiendo disparos automáticos
// si está habilitado.
void Game::handleFireInputs(const std::shared_ptr<Player> &player,
bool autofire, int controllerIndex)
{
if (input_->checkInput(InputType::FIRE_CENTER, autofire, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index))
if (input_->checkInput(InputType::FIRE_CENTER, autofire,
options.controller[controllerIndex].device_type,
options.controller[controllerIndex].index))
{
handleFireInput(player, BulletType::UP);
#ifdef RECORDING
demo_.keys.fire = 1;
#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);
#ifdef RECORDING
demo_.keys.fire_left = 1;
#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);
#ifdef RECORDING
@@ -1828,19 +1744,29 @@ void Game::handleFireInputs(const std::shared_ptr<Player> &player, bool autofire
}
}
// Maneja la continuación del jugador cuando no está jugando, permitiendo que continúe si se pulsa el botón de inicio.
// Maneja la continuación del jugador cuando no está jugando, permitiendo que
// continúe si se pulsa el botón de inicio.
void Game::handlePlayerContinue(const std::shared_ptr<Player> &player)
{
const auto controllerIndex = player->getController();
if (input_->checkInput(InputType::START, INPUT_DO_NOT_ALLOW_REPEAT, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index))
if (input_->checkInput(InputType::START, INPUT_DO_NOT_ALLOW_REPEAT,
options.controller[controllerIndex].device_type,
options.controller[controllerIndex].index))
{
player->setStatusPlaying(PlayerStatus::PLAYING);
}
// Disminuye el contador de continuación si se presiona cualquier botón de disparo.
if (input_->checkInput(InputType::FIRE_LEFT, INPUT_DO_NOT_ALLOW_REPEAT, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index) ||
input_->checkInput(InputType::FIRE_CENTER, INPUT_DO_NOT_ALLOW_REPEAT, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index) ||
input_->checkInput(InputType::FIRE_RIGHT, INPUT_DO_NOT_ALLOW_REPEAT, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index))
// Disminuye el contador de continuación si se presiona cualquier botón de
// disparo.
if (input_->checkInput(InputType::FIRE_LEFT, INPUT_DO_NOT_ALLOW_REPEAT,
options.controller[controllerIndex].device_type,
options.controller[controllerIndex].index) ||
input_->checkInput(InputType::FIRE_CENTER, INPUT_DO_NOT_ALLOW_REPEAT,
options.controller[controllerIndex].device_type,
options.controller[controllerIndex].index) ||
input_->checkInput(InputType::FIRE_RIGHT, INPUT_DO_NOT_ALLOW_REPEAT,
options.controller[controllerIndex].device_type,
options.controller[controllerIndex].index))
{
player->decContinueCounter();
}
@@ -1858,7 +1784,8 @@ void Game::handleNameInput(const std::shared_ptr<Player> &player)
{
player->setInput(InputType::START);
addScoreToScoreBoard(player->getRecordName(), player->getScore());
player->setStatusPlaying(PlayerStatus::CONTINUE);
const auto status = player->getStatusPlaying();
player->setStatusPlaying(status == PlayerStatus::ENTERING_NAME ? PlayerStatus::CONTINUE : PlayerStatus::GAME_COMPLETED);
}
else
{
@@ -1877,15 +1804,18 @@ void Game::handleNameInput(const std::shared_ptr<Player> &player)
{
player->setInput(InputType::LEFT);
}
/*
else if (input_->checkInput(InputType::RIGHT, INPUT_DO_NOT_ALLOW_REPEAT, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index))
{
player->setInput(InputType::RIGHT);
}
*/
else if (input_->checkInput(InputType::START, INPUT_DO_NOT_ALLOW_REPEAT, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index))
{
player->setInput(InputType::START);
addScoreToScoreBoard(player->getRecordName(), player->getScore());
player->setStatusPlaying(PlayerStatus::CONTINUE);
const auto status = player->getStatusPlaying();
player->setStatusPlaying(status == PlayerStatus::ENTERING_NAME ? PlayerStatus::CONTINUE : PlayerStatus::GAME_COMPLETED);
}
}
@@ -1908,7 +1838,8 @@ void Game::initDemo(int player_id)
current_stage_ = stages[demo];
}
// Actualiza el numero de globos explotados según la fase del modo demostración
// 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;
@@ -1954,7 +1885,8 @@ 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;
total_power_to_complete_game_ +=
balloon_formations_->getStage(i).power_to_complete;
}
}
@@ -2037,7 +1969,8 @@ void Game::createTwoBigBalloons()
for (int i = 0; i < numEnemies; ++i)
{
auto p = set.init[i];
createBalloon(p.x, p.y, p.type, p.size, p.vel_x, balloon_speed_, p.creation_counter);
createBalloon(p.x, p.y, p.type, p.size, p.vel_x, balloon_speed_,
p.creation_counter);
}
}
@@ -2060,4 +1993,114 @@ void Game::stopMusic()
{
if (!demo_.enabled)
JA_StopMusic();
}
// Actualiza las variables durante el modo demo
void Game::updateDemo()
{
if (demo_.enabled)
{
// Incrementa el contador de la demo
if (demo_.counter < TOTAL_DEMO_DATA)
demo_.counter++;
// Activa el fundido antes de acabar con los datos de la demo
if (demo_.counter == TOTAL_DEMO_DATA - 200)
{
fade_->setType(FadeType::RANDOM_SQUARE);
fade_->activate();
}
// Si ha terminado el fundido, cambia de sección
if (fade_->hasEnded())
{
section::name = section::Name::HI_SCORE_TABLE;
return;
}
}
}
#ifdef RECORDING
// Actualiza las variables durante el modo de grabación
void Game::updateRecording()
{
// Solo mira y guarda el input en cada update
checkInput();
// Incrementa el contador de la demo
if (demo_.counter < TOTAL_DEMO_DATA)
demo_.counter++;
// Si se ha llenado el vector con datos, sale del programa
else
{
section::name = section::Name::QUIT;
return;
}
}
#endif
// Actualiza las variables durante el transcurso normal del juego
void Game::updateNormalGame()
{
if (status_ == GameStatus::PLAYING && !paused_)
{
#ifdef DEBUG
if (auto_pop_balloons_)
{
balloons_popped_++;
increaseStageCurrentPower(1);
}
#endif
fade_->update();
updatePlayers();
checkPlayersStatusPlaying();
updateScoreboard();
updateBackground();
updateBalloons();
explosions_->update();
moveBullets();
updateItems();
updateStage();
updateGameOver();
updateSmartSprites();
updatePathSprites();
updateTimeStopped();
updateBalloonDeployCounter();
updateHelper();
checkBulletBalloonCollision();
updateMenace();
checkAndUpdateBalloonSpeed();
freeBullets();
freeBalloons();
freeItems();
freeSmartSprites();
freePathSprites();
}
}
// Actualiza las variables durante el transcurso normal del juego
void Game::updateCompletedGame()
{
if (status_ == GameStatus::COMPLETED && !paused_)
{
fade_->update();
updatePlayers();
checkPlayersStatusPlaying();
updateScoreboard();
updateBackground();
updateBalloons();
explosions_->update();
moveBullets();
updateItems();
updateGameOver();
updateSmartSprites();
updatePathSprites();
checkBulletBalloonCollision();
freeBullets();
freeBalloons();
freeItems();
freeSmartSprites();
freePathSprites();
}
}