Implementat el final del joc

This commit is contained in:
2024-11-01 13:05:11 +01:00
parent 2e0d27a95c
commit f786cb7776
8 changed files with 349 additions and 443 deletions

View File

@@ -85,6 +85,14 @@ Game::Game(int player_id, int current_stage, bool demo)
initPaths();
setTotalPower();
#ifdef DEBUG
// Si se empieza en una fase que no es la primera
for (int i = 0; i < current_stage_; ++i)
{
balloons_popped_ += balloon_formations_->getStage(i).power_to_complete;
}
#endif
// Crea los primeros globos y el mensaje de inicio
if (!demo_.enabled)
{
@@ -320,68 +328,41 @@ void Game::renderPlayers()
// Comprueba si hay cambio de fase y actualiza las variables
void Game::updateStage()
{
if (current_power_ >= balloon_formations_->getStage(current_stage_).power_to_complete)
if (state_ == GameState::PLAYING)
{
// Cambio de fase
++current_stage_;
current_power_ = 0;
JA_PlaySound(Resource::get()->getSound("stage_change.wav"));
balloon_speed_ = default_balloon_speed_;
setBalloonSpeed(balloon_speed_);
screen_->flash(flash_color, 100);
screen_->shake();
// Ha llegado al final el juego
if (status_ == GameStatus::PLAYING && current_stage_ == 10)
if (current_power_ >= balloon_formations_->getStage(current_stage_).power_to_complete)
{
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
// Cambio de fase
++current_stage_;
current_power_ = 0;
JA_PlaySound(Resource::get()->getSound("stage_change.wav"));
balloon_speed_ = default_balloon_speed_;
setBalloonSpeed(balloon_speed_);
screen_->flash(flash_color, 100);
screen_->shake();
for (auto &player : players_)
if (player->isPlaying())
{
player->addScore(1000000);
player->setStatusPlaying(player->IsEligibleForHighScore() ? PlayerStatus::ENTERING_NAME_GAME_COMPLETED : PlayerStatus::GAME_COMPLETED);
}
// Escribe el texto por pantalla
if (current_stage_ < 10)
{
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"));
else
{
player->setStatusPlaying(PlayerStatus::GAME_OVER);
auto text = std::make_unique<Text>(Resource::get()->getTexture("04b_25.png"), Resource::get()->getTextFile("04b_25.txt"));
const std::string caption = std::to_string(10 - current_stage_) + lang::getText(38);
createMessage(paths, text->writeToTexture(caption, 2, -2));
}
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"));
else
{
auto text = std::make_unique<Text>(Resource::get()->getTexture("04b_25.png"), Resource::get()->getTextFile("04b_25.txt"));
const std::string caption = std::to_string(10 - current_stage_) + lang::getText(38);
createMessage(paths, text->writeToTexture(caption, 2, -2));
}
}
else
{
createMessage({paths_.at(4), paths_.at(5)}, Resource::get()->getTexture("congratulations"));
createMessage({paths_.at(6), paths_.at(7)}, Resource::get()->getTexture("1000000_points"));
}
}
}
// Actualiza el estado de fin de la partida
void Game::updateGameOver()
void Game::updateGameOverState()
{
// Si todos estan en estado de Game Over y no hay mensajes por pantalla
if (allPlayersAreGameOver() && path_sprites_.empty())
if (state_ == GameState::GAME_OVER)
{
if (game_over_counter_ > 0)
{
@@ -411,6 +392,71 @@ void Game::updateGameOver()
}
}
// Gestiona eventos para el estado del final del juego
void Game::updateCompletedState()
{
if (state_ == GameState::COMPLETED)
{
// Para la música y elimina todos los globos e items
if (game_completed_counter_ == 0)
{
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
}
// Comienza las celebraciones
// Muestra el mensaje de felicitación y da los puntos a los jugadores
if (game_completed_counter_ == 200)
{
createMessage({paths_.at(4), paths_.at(5)}, Resource::get()->getTexture("congratulations"));
createMessage({paths_.at(6), paths_.at(7)}, Resource::get()->getTexture("1000000_points"));
for (auto &player : players_)
if (player->isPlaying())
{
player->addScore(1000000);
player->setPlayingState(PlayerState::CELEBRATING);
}
else
{
player->setPlayingState(PlayerState::GAME_OVER);
}
updateHiScore();
}
// Termina las celebraciones
if (game_completed_counter_ == 500)
{
for (auto &player : players_)
if (player->isCelebrating())
{
player->setPlayingState(player->IsEligibleForHighScore() ? PlayerState::ENTERING_NAME_GAME_COMPLETED : PlayerState::GAME_COMPLETED);
}
}
// Incrementa el contador al final
++game_completed_counter_;
}
}
// Comprueba el estado del juego
void Game::checkState()
{
if (state_ != GameState::COMPLETED && current_stage_ == 10)
{
state_ = GameState::COMPLETED;
}
if (state_ != GameState::GAME_OVER && allPlayersAreGameOver())
{
state_ = GameState::GAME_OVER;
}
}
// Actualiza los globos
void Game::updateBalloons()
{
@@ -1036,7 +1082,7 @@ void Game::killPlayer(std::shared_ptr<Player> &player)
JA_PlaySound(Resource::get()->getSound("player_collision.wav"));
screen_->shake();
JA_PlaySound(Resource::get()->getSound("coffeeout.wav"));
player->setStatusPlaying(PlayerStatus::DYING);
player->setPlayingState(PlayerState::DYING);
allPlayersAreNotPlaying() ? stopMusic() : resumeMusic();
}
}
@@ -1096,8 +1142,7 @@ void Game::update()
#ifdef RECORDING
updateRecording();
#endif
updateNormalGame();
updateCompletedGame();
updateGame();
checkMusicStatus();
screen_->update();
@@ -1109,7 +1154,7 @@ void Game::update()
void Game::updateBackground()
{
// Si el juego está completado, se reduce la velocidad de las nubes
if (status_ == GameStatus::COMPLETED)
if (state_ == GameState::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
@@ -1212,7 +1257,7 @@ void Game::checkMusicStatus()
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
status_ == GameStatus::COMPLETED || allPlayersAreGameOver() ? JA_StopMusic() : JA_PlayMusic(Resource::get()->getMusic("playing.ogg"));
state_ == GameState::COMPLETED || allPlayersAreGameOver() ? JA_StopMusic() : JA_PlayMusic(Resource::get()->getMusic("playing.ogg"));
}
// Bucle para el juego
@@ -1432,7 +1477,7 @@ void Game::checkEvents()
}
case SDLK_8:
{
players_.at(0)->setStatusPlaying(PlayerStatus::GAME_COMPLETED);
players_.at(0)->setPlayingState(PlayerState::GAME_COMPLETED);
}
default:
break;
@@ -1502,7 +1547,7 @@ void Game::checkAndUpdatePlayerStatus(int activePlayerIndex, int inactivePlayerI
{
if (players_[activePlayerIndex]->isGameOver() && !players_[inactivePlayerIndex]->isGameOver() && !players_[inactivePlayerIndex]->isWaiting())
{
players_[activePlayerIndex]->setStatusPlaying(PlayerStatus::WAITING);
players_[activePlayerIndex]->setPlayingState(PlayerState::WAITING);
}
}
@@ -1520,7 +1565,7 @@ void Game::checkPlayersStatusPlaying()
// Entonces los pone en estado de Game Over
for (auto &player : players_)
{
player->setStatusPlaying(PlayerStatus::GAME_OVER);
player->setPlayingState(PlayerState::GAME_OVER);
}
}
@@ -1742,7 +1787,7 @@ 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))
{
player->setStatusPlaying(PlayerStatus::PLAYING);
player->setPlayingState(PlayerState::PLAYING);
}
// Disminuye el contador de continuación si se presiona cualquier botón de disparo.
@@ -1766,8 +1811,8 @@ void Game::handleNameInput(const std::shared_ptr<Player> &player)
{
player->setInput(InputType::START);
addScoreToScoreBoard(player->getRecordName(), player->getScore());
const auto status = player->getStatusPlaying();
player->setStatusPlaying(status == PlayerStatus::ENTERING_NAME ? PlayerStatus::CONTINUE : PlayerStatus::GAME_COMPLETED);
const auto status = player->getPlayingState();
player->setPlayingState(status == PlayerState::ENTERING_NAME ? PlayerState::CONTINUE : PlayerState::GAME_COMPLETED);
}
else
{
@@ -1796,8 +1841,8 @@ void Game::handleNameInput(const std::shared_ptr<Player> &player)
{
player->setInput(InputType::START);
addScoreToScoreBoard(player->getRecordName(), player->getScore());
const auto status = player->getStatusPlaying();
player->setStatusPlaying(status == PlayerStatus::ENTERING_NAME ? PlayerStatus::CONTINUE : PlayerStatus::GAME_COMPLETED);
const auto status = player->getPlayingState();
player->setPlayingState(status == PlayerState::ENTERING_NAME ? PlayerState::CONTINUE : PlayerState::GAME_COMPLETED);
}
}
@@ -1820,8 +1865,7 @@ 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;
@@ -1832,7 +1876,7 @@ void Game::initDemo(int player_id)
{
const auto other_player_id = player_id == 1 ? 2 : 1;
auto other_player = getPlayer(other_player_id);
other_player->setStatusPlaying(PlayerStatus::PLAYING);
other_player->setPlayingState(PlayerState::PLAYING);
}
// Asigna cafes a los jugadores
@@ -1939,7 +1983,7 @@ void Game::initPlayers(int player_id)
// Activa el jugador que coincide con el "player_id"
auto player = getPlayer(player_id);
player->setStatusPlaying(PlayerStatus::PLAYING);
player->setPlayingState(PlayerState::PLAYING);
player->setInvulnerable(false);
}
@@ -2023,15 +2067,15 @@ void Game::updateRecording()
#endif
// Actualiza las variables durante el transcurso normal del juego
void Game::updateNormalGame()
void Game::updateGame()
{
if (status_ == GameStatus::PLAYING && !paused_)
if (!paused_)
{
#ifdef DEBUG
if (auto_pop_balloons_)
if (auto_pop_balloons_ && state_ == GameState::PLAYING)
{
balloons_popped_++;
increaseStageCurrentPower(1);
balloons_popped_ += 5;
increaseStageCurrentPower(5);
}
#endif
fade_->update();
@@ -2044,7 +2088,8 @@ void Game::updateNormalGame()
moveBullets();
updateItems();
updateStage();
updateGameOver();
updateGameOverState();
updateCompletedState();
updateSmartSprites();
updatePathSprites();
updateTimeStopped();
@@ -2053,36 +2098,17 @@ void Game::updateNormalGame()
checkBulletBalloonCollision();
updateMenace();
checkAndUpdateBalloonSpeed();
freeBullets();
freeBalloons();
freeItems();
freeSmartSprites();
freePathSprites();
checkState();
cleanVectors();
}
}
// Actualiza las variables durante el transcurso normal del juego
void Game::updateCompletedGame()
// Vacía los vectores de elementos deshabilitados
void Game::cleanVectors()
{
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();
}
freeBullets();
freeBalloons();
freeItems();
freeSmartSprites();
freePathSprites();
}