This commit is contained in:
2026-04-17 22:20:37 +02:00
parent 513eacf356
commit 20b9a95619
38 changed files with 310 additions and 622 deletions

View File

@@ -4,6 +4,7 @@
#include <stdlib.h> // for rand
#include <algorithm> // for max, min
#include <numeric> // for accumulate
#include <fstream> // for basic_ifstream
#include <iostream> // for basic_ostream, char_traits, operator<<
@@ -30,7 +31,8 @@
struct JA_Sound_t;
// Constructor
Game::Game(int numPlayers, int currentStage, SDL_Renderer *renderer, bool demo, section_t *section) {
Game::Game(int numPlayers, int currentStage, SDL_Renderer *renderer, bool demo, section_t *section)
: lastStageReached(currentStage) {
// Copia los punteros
this->renderer = renderer;
this->section = section;
@@ -43,7 +45,6 @@ Game::Game(int numPlayers, int currentStage, SDL_Renderer *renderer, bool demo,
#else
this->currentStage = currentStage;
#endif
lastStageReached = currentStage;
if (numPlayers == 1) { // Si solo juega un jugador, permite jugar tanto con teclado como con mando
onePlayerControl = Options::inputs[0].deviceType;
Options::inputs[0].deviceType = INPUT_USE_ANY;
@@ -961,7 +962,6 @@ void Game::initEnemyFormations() {
// #24 - Treinta enemigos BALLOON1. Del centro hacia los extremos. Juntos. Simetricos
j = 24;
enemyFormation[j].numberOfEnemies = 30;
incX = 0;
incTime = 5;
for (int i = 0; i < enemyFormation[j].numberOfEnemies; i++) {
Uint8 half = enemyFormation[j].numberOfEnemies / 2;
@@ -981,7 +981,6 @@ void Game::initEnemyFormations() {
// #25 - Treinta enemigos BALLOON1. Del centro hacia adentro. Juntos. Simetricos
j = 25;
enemyFormation[j].numberOfEnemies = 30;
incX = BALLOON_WIDTH_1 + 1;
incTime = 5;
for (int i = 0; i < enemyFormation[j].numberOfEnemies; i++) {
Uint8 half = enemyFormation[j].numberOfEnemies / 2;
@@ -1486,12 +1485,12 @@ void Game::updateStage() {
// Actualiza el estado de muerte
void Game::updateDeath() {
// Comprueba si todos los jugadores estan muertos
bool allPlayersAreDead = true;
bool allDead = true;
for (auto player : players) {
allPlayersAreDead &= (!player->isAlive());
allDead &= (!player->isAlive());
}
if (allPlayersAreDead) {
if (allDead) {
if (deathCounter > 0) {
deathCounter--;
@@ -1608,30 +1607,6 @@ void Game::incBalloonSpeed() {
}
}
// Decrementa la velocidad de los globos
void Game::decBalloonSpeed() {
// La velocidad solo se decrementa en el modo normal
if (difficulty == DIFFICULTY_NORMAL) {
if (enemySpeed == BALLOON_SPEED_5) {
enemySpeed = BALLOON_SPEED_4;
}
else if (enemySpeed == BALLOON_SPEED_4) {
enemySpeed = BALLOON_SPEED_3;
}
else if (enemySpeed == BALLOON_SPEED_3) {
enemySpeed = BALLOON_SPEED_2;
}
else if (enemySpeed == BALLOON_SPEED_2) {
enemySpeed = BALLOON_SPEED_1;
}
setBalloonSpeed(enemySpeed);
}
}
// Actualiza la velocidad de los globos en funcion del poder acumulado de la fase
void Game::updateBalloonSpeed() {
const float percent = (float)stage[currentStage].currentPower / (float)stage[currentStage].powerToComplete;
@@ -1761,17 +1736,6 @@ void Game::destroyBalloon(Balloon *balloon) {
evaluateAndSetMenace();
}
// Explosiona todos los globos
void Game::popAllBalloons() {
for (auto balloon : balloons) {
if ((balloon->isEnabled()) && (!balloon->isPopping()) && (!balloon->isBeingCreated())) {
popBalloon(balloon);
}
}
JA_PlaySound(balloonSound);
}
// Destruye todos los globos
void Game::destroyAllBalloons() {
for (auto balloon : balloons) {
@@ -1808,21 +1772,6 @@ void Game::startAllBalloons() {
}
}
// Obtiene el numero de globos activos
Uint8 Game::countBalloons() {
Uint8 num = 0;
for (auto balloon : balloons) {
if (balloon->isEnabled()) {
if (!balloon->isPopping()) {
num++;
}
}
}
return num;
}
// Vacia el vector de globos
void Game::freeBalloons() {
if (balloons.empty() == false) {
@@ -2090,7 +2039,7 @@ void Game::freeItems() {
}
// Crea un objeto SmartSprite para mostrar la puntuación al coger un objeto
void Game::createItemScoreSprite(int x, int y, SmartSprite *sprite) {
void Game::createItemScoreSprite(int x, int y, const SmartSprite *sprite) {
SmartSprite *ss = new SmartSprite(nullptr, renderer);
smartSprites.push_back(ss);
@@ -2235,12 +2184,8 @@ void Game::updateDeathSequence() {
// Calcula y establece el valor de amenaza en funcion de los globos activos
void Game::evaluateAndSetMenace() {
menaceCurrent = 0;
for (auto balloon : balloons) {
if (balloon->isEnabled()) {
menaceCurrent += balloon->getMenace();
}
}
menaceCurrent = std::accumulate(balloons.begin(), balloons.end(), Uint8(0),
[](Uint8 acc, Balloon *b) { return b->isEnabled() ? acc + b->getMenace() : acc; });
}
// Obtiene el valor de la variable
@@ -2685,19 +2630,19 @@ void Game::renderMessages() {
// STAGE NUMBER
if (stageBitmapCounter < STAGE_COUNTER) {
const int stageNum = stage[currentStage].number;
std::string text;
std::string stageText;
if (stageNum == 10) { // Ultima fase
text = Lang::get()->getText(79);
stageText = Lang::get()->getText(79);
} else { // X fases restantes
text = std::to_string(11 - stage[currentStage].number) + Lang::get()->getText(38);
stageText = std::to_string(11 - stage[currentStage].number) + Lang::get()->getText(38);
}
if (!gameCompleted) { // Escribe el numero de fases restantes
textNokiaBig2->writeDX(TXT_CENTER, PLAY_AREA_CENTER_X, stageBitmapPath[stageBitmapCounter], text, -2, noColor, 2, shdwTxtColor);
textNokiaBig2->writeDX(TXT_CENTER, PLAY_AREA_CENTER_X, stageBitmapPath[stageBitmapCounter], stageText, -2, noColor, 2, shdwTxtColor);
} else { // Escribe el texto de juego completado
text = Lang::get()->getText(50);
textNokiaBig2->writeDX(TXT_CENTER, PLAY_AREA_CENTER_X, stageBitmapPath[stageBitmapCounter], text, -2, noColor, 1, shdwTxtColor);
stageText = Lang::get()->getText(50);
textNokiaBig2->writeDX(TXT_CENTER, PLAY_AREA_CENTER_X, stageBitmapPath[stageBitmapCounter], stageText, -2, noColor, 1, shdwTxtColor);
textNokia2->writeDX(TXT_CENTER, PLAY_AREA_CENTER_X, stageBitmapPath[stageBitmapCounter] + textNokiaBig2->getCharacterSize() + 2, Lang::get()->getText(76), -1, noColor, 1, shdwTxtColor);
}
}
@@ -2813,7 +2758,7 @@ bool Game::hasFinished() const {
}
// Procesa un evento individual
void Game::handleEvent(SDL_Event *event) {
void Game::handleEvent(const SDL_Event *event) {
// SDL_EVENT_QUIT ya lo maneja Director
if (event->type == SDL_EVENT_WINDOW_FOCUS_LOST) {
@@ -3025,23 +2970,6 @@ void Game::updateGameOverScreen() {
}
}
// Comprueba los eventos de la pantalla de game over
void Game::checkGameOverEvents() {
while (SDL_PollEvent(eventHandler) != 0) {
// Evento de salida de la aplicación
if (eventHandler->type == SDL_EVENT_QUIT) {
section->name = SECTION_PROG_QUIT;
break;
} else if (eventHandler->type == SDL_EVENT_KEY_DOWN && eventHandler->key.repeat == 0) {
if (gameCompleted) {
gameOverPostFade = 1;
fade->activateFade();
JA_PlaySound(itemPickUpSound);
}
}
}
}
// Dibuja los elementos de la pantalla de game over
void Game::renderGameOverScreen() {
// Prepara para empezar a dibujar en la textura de juego
@@ -3120,15 +3048,8 @@ bool Game::canPowerBallBeCreated() {
// Calcula el poder actual de los globos en pantalla
int Game::calculateScreenPower() {
int power = 0;
for (auto balloon : balloons) {
if (balloon->isEnabled()) {
power += balloon->getPower();
}
}
return power;
return std::accumulate(balloons.begin(), balloons.end(), 0,
[](int acc, Balloon *b) { return b->isEnabled() ? acc + b->getPower() : acc; });
}
// Inicializa las variables que contienen puntos de ruta para mover objetos
@@ -3234,28 +3155,6 @@ bool Game::allPlayersAreDead() {
return success;
}
// Comprueba los eventos que hay en cola
void Game::checkEvents() {
while (SDL_PollEvent(eventHandler) != 0) {
// Evento de salida de la aplicación
if (eventHandler->type == SDL_EVENT_QUIT) {
section->name = SECTION_PROG_QUIT;
break;
}
else if (eventHandler->type == SDL_EVENT_WINDOW_FOCUS_LOST) {
section->subsection = SUBSECTION_GAME_PAUSE;
}
#ifdef PAUSE
else if (eventHandler->type == SDL_EVENT_KEY_DOWN) {
if (eventHandler->key.scancode == SDL_SCANCODE_P) {
pause = !pause;
}
}
#endif
}
}
// Elimina todos los objetos contenidos en vectores
void Game::deleteAllVectorObjects() {
for (auto player : players) {
@@ -3284,33 +3183,6 @@ void Game::deleteAllVectorObjects() {
smartSprites.clear();
}
// Recarga las texturas
void Game::reloadTextures() {
for (auto texture : itemTextures) {
texture->reLoad();
}
for (auto texture : balloonTextures) {
texture->reLoad();
}
for (auto texture : player1Textures) {
texture->reLoad();
}
for (auto texture : player2Textures) {
texture->reLoad();
}
bulletTexture->reLoad();
gameBuildingsTexture->reLoad();
gameCloudsTexture->reLoad();
gameGrassTexture->reLoad();
gamePowerMeterTexture->reLoad();
gameSkyColorsTexture->reLoad();
gameTextTexture->reLoad();
}
// Establece la máxima puntuación desde fichero o desde las puntuaciones online
void Game::setHiScore() {
// Carga el fichero de puntos