Treballant en el final del joc
This commit is contained in:
541
source/game.cpp
541
source/game.cpp
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user