From 2fb7e88e4b307ad7ccfaa39df265e15ff6c5d5b8 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Thu, 7 Nov 2024 20:56:56 +0100 Subject: [PATCH] Continue amb BalloonManager --- source/balloon_formations.cpp | 14 ++- source/balloon_formations.h | 4 + source/balloon_manager.cpp | 87 +++++++++--------- source/balloon_manager.h | 55 ++++++----- source/define_buttons.cpp | 1 - source/director.cpp | 5 +- source/game.cpp | 166 ++++++++++++++++++++-------------- source/game.h | 46 ++++------ source/resource.cpp | 9 +- source/stage.cpp | 8 ++ source/stage.h | 6 +- source/title.cpp | 3 +- 12 files changed, 226 insertions(+), 178 deletions(-) diff --git a/source/balloon_formations.cpp b/source/balloon_formations.cpp index b94bf09..c8383af 100644 --- a/source/balloon_formations.cpp +++ b/source/balloon_formations.cpp @@ -25,22 +25,20 @@ void BalloonFormations::initBalloonFormations() balloon_formation_.reserve(NUMBER_OF_BALLOON_FORMATIONS); constexpr int CREATION_TIME = 300; - int inc_x = 0; - int inc_time = 0; // #00 - Dos enemigos BALLOON4 uno a cada extremo { std::vector init_params = { - BalloonFormationParams(x4_0, y4, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME), - BalloonFormationParams(x4_100, y4, -BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME)}; + BalloonFormationParams(x4_0, y4, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME), + BalloonFormationParams(x4_100, y4, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME)}; balloon_formation_.emplace_back(2, init_params); } // #01 - Dos enemigos BALLOON4 uno a cada cuarto. Ambos van hacia el centro { std::vector init_params = { - BalloonFormationParams(param.game.play_area.first_quarter_x - (BALLOON_SIZE[3] / 2), y4, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME), - BalloonFormationParams(param.game.play_area.third_quarter_x - (BALLOON_SIZE[3] / 2), y4, -BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME)}; + BalloonFormationParams(param.game.play_area.first_quarter_x - (BALLOON_SIZE[3] / 2), y4, BALLOON_VELX_POSITIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME), + BalloonFormationParams(param.game.play_area.third_quarter_x - (BALLOON_SIZE[3] / 2), y4, BALLOON_VELX_NEGATIVE, BalloonType::BALLOON, BalloonSize::SIZE4, CREATION_TIME)}; balloon_formation_.emplace_back(2, init_params); } @@ -124,7 +122,7 @@ void BalloonFormations::initBalloonFormations() balloon_formation_.emplace_back(6, init_params); } - // #10 - Tres enemigos BALLOON4 seguidos desde la izquierda + // #10 - Tres enemigos BALLOON4 seguidos desde la izquierda. Hacia la derecha { std::vector init_params; for (int i = 0; i < 3; ++i) @@ -134,7 +132,7 @@ void BalloonFormations::initBalloonFormations() balloon_formation_.emplace_back(3, init_params); } - // #11 - Tres enemigos BALLOON4 seguidos desde la derecha + // #11 - Tres enemigos BALLOON4 seguidos desde la derecha. Hacia la izquierda { std::vector init_params; for (int i = 0; i < 3; ++i) diff --git a/source/balloon_formations.h b/source/balloon_formations.h index 415321f..09a7165 100644 --- a/source/balloon_formations.h +++ b/source/balloon_formations.h @@ -33,8 +33,12 @@ struct BalloonFormationUnit // Constructor BalloonFormationUnit(int num_balloons, const std::vector &init_params) : number_of_balloons(num_balloons), init(init_params) {} + + // Default constructor + BalloonFormationUnit() : number_of_balloons(0), init() {} }; + using BalloonFormationPool = std::vector; class BalloonFormations diff --git a/source/balloon_manager.cpp b/source/balloon_manager.cpp index 8855540..095b31f 100644 --- a/source/balloon_manager.cpp +++ b/source/balloon_manager.cpp @@ -1,14 +1,17 @@ #include "balloon_manager.h" -#include "stage.h" +#include // Para rand +#include // Para remove_if #include // Para accumulate -#include // Para find_if, clamp, min, remove_if -#include "balloon.h" // Para Balloon, BALLOON_SCORE, BALLOON_VE... -#include "balloon_formations.h" // Para BalloonFormations, BalloonFormatio... -#include "resource.h" -#include "game.h" -#include "screen.h" -#include "explosions.h" // Para Explosions -#include "jail_audio.h" +#include "balloon.h" // Para Balloon, BALLOON_SCORE, BALLOON_VELX... +#include "balloon_formations.h" // Para BalloonFormationParams, BalloonForma... +#include "explosions.h" // Para Explosions +#include "jail_audio.h" // Para JA_PlaySound +#include "param.h" // Para Param, ParamGame, param +#include "resource.h" // Para Resource +#include "screen.h" // Para Screen +#include "stage.h" // Para power +#include "texture.h" // Para Texture +#include "utils.h" // Para Zone, BLOCK, Color, flash_color // Constructor BalloonManager::BalloonManager() @@ -58,19 +61,22 @@ void BalloonManager::update() { balloon->update(); } + updateBalloonDeployCounter(); + explosions_->update(); } -// Renderiza los globos -void BalloonManager::renderBalloons() +// Renderiza los objetos +void BalloonManager::render() { for (auto &balloon : balloons_) { balloon->render(); } + explosions_->render(); } // Crea una formación de enemigos -void BalloonManager::deployBalloonFormation() +void BalloonManager::deployBalloonFormation(int stage) { // Solo despliega una formación enemiga si ha pasado cierto tiempo desde la última if (balloon_deploy_counter_ == 0) @@ -100,7 +106,7 @@ void BalloonManager::deployBalloonFormation() last_balloon_deploy_ = formation; - const auto set = balloon_formations_->getStage(game_.getCurrentStage()).balloon_pool.set[formation]; + const auto set = balloon_formations_->getSet(stage, formation); const auto numEnemies = set.number_of_balloons; for (int i = 0; i < numEnemies; ++i) { @@ -125,7 +131,9 @@ void BalloonManager::freeBalloons() void BalloonManager::updateBalloonDeployCounter() { if (balloon_deploy_counter_ > 0) + { --balloon_deploy_counter_; + } } // Indica si se puede crear una powerball @@ -184,33 +192,17 @@ void BalloonManager::createPowerBall() // Establece la velocidad de los globos void BalloonManager::setBalloonSpeed(float speed) { + balloon_speed_ = speed; for (auto &balloon : balloons_) + { balloon->setSpeed(speed); -} - -// Actualiza la velocidad de los globos en funcion del poder acumulado de la fase -void BalloonManager::checkAndUpdateBalloonSpeed() -{ - if (difficulty_ != GameDifficulty::NORMAL) - return; - - const float percent = static_cast(game_.getCurrentPower()) / balloon_formations_->getStage(game_.getCurrentStage()).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 void BalloonManager::popBalloon(std::shared_ptr balloon) { - game_.increaseStageCurrentPower(1); - balloons_popped_++; + ++Stage::power; if (balloon->getType() == BalloonType::POWERBALL) { @@ -230,13 +222,10 @@ void BalloonManager::popBalloon(std::shared_ptr balloon) explosions_->add(balloon->getPosX(), balloon->getPosY(), static_cast(balloon->getSize())); balloon->pop(); } - - // Recalcula el nivel de amenaza - evaluateAndSetMenace(); } // Explosiona un globo. Lo destruye = no crea otros globos -void BalloonManager::destroyBalloon(std::shared_ptr &balloon) +int BalloonManager::destroyBalloon(std::shared_ptr &balloon) { int score = 0; @@ -261,32 +250,41 @@ void BalloonManager::destroyBalloon(std::shared_ptr &balloon) } // Otorga los puntos correspondientes al globo + /* for (auto &player : players_) + { player->addScore(score * player->getScoreMultiplier() * difficulty_score_multiplier_); + } updateHiScore(); + */ // Aumenta el poder de la fase const auto power = balloon->getPower(); - game_.increaseStageCurrentPower(power); - balloons_popped_ += power; + Stage::power += power; + // balloons_popped_ += power; // Destruye el globo explosions_->add(balloon->getPosX(), balloon->getPosY(), static_cast(balloon->getSize())); balloon->pop(); + + return score; } // Destruye todos los globos -void BalloonManager::destroyAllBalloons() +int BalloonManager::destroyAllBalloons() { + int score = 0; for (auto &balloon : balloons_) { - destroyBalloon(balloon); + score += destroyBalloon(balloon); } balloon_deploy_counter_ = 300; JA_PlaySound(Resource::get()->getSound("powerball.wav")); Screen::get()->flash(flash_color, 100); Screen::get()->shake(); + + return score; } // Detiene todos los globos @@ -350,4 +348,11 @@ void BalloonManager::createTwoBigBalloons() auto p = set.init[i]; createBalloon(p.x, p.y, p.type, p.size, p.vel_x, balloon_speed_, p.creation_counter); } +} + +// Obtiene el nivel de ameza actual generado por los globos +int BalloonManager::getMenace() +{ + return std::accumulate(balloons_.begin(), balloons_.end(), 0, [](int sum, const auto &balloon) + { return sum + (balloon->isEnabled() ? balloon->getMenace() : 0); }); } \ No newline at end of file diff --git a/source/balloon_manager.h b/source/balloon_manager.h index 380154e..b2120fe 100644 --- a/source/balloon_manager.h +++ b/source/balloon_manager.h @@ -1,29 +1,34 @@ #pragma once -#include "balloon.h" -class BalloonFormations; // lines 16-16 -class Explosions; // lines 18-18 +#include // Para shared_ptr, unique_ptr +#include // Para string +#include // Para vector +#include "balloon.h" // Para BALLOON_SPEED, Balloon +#include "balloon_formations.h" // Para BalloonFormations +#include "explosions.h" // Para Explosions +class Texture; + +using Balloons = std::vector>; class BalloonManager { private: - std::vector> balloons_; // Vector con los globos + Balloons balloons_; // Vector con los globos std::unique_ptr explosions_; // Objeto para dibujar explosiones std::unique_ptr balloon_formations_; // Objeto para gestionar las oleadas enemigas std::vector> balloon_textures_; // Vector con las texturas de los globos std::vector> explosions_textures_; // Vector con las texturas de las explosiones - std::vector> balloon_animations_; // Vector con las animaciones de los globos - std::vector> explosions_animations_; // Vector con las animaciones de las explosiones + std::vector> balloon_animations_; // Vector con las animaciones de los globos + std::vector> explosions_animations_; // Vector con las animaciones de las explosiones - float balloon_speed_; // Velocidad a la que se mueven los enemigos - float default_balloon_speed_; // Velocidad base de los enemigos, sin incrementar - int balloon_deploy_counter_ = 0; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero - int balloons_popped_ = 0; // Lleva la cuenta de los globos explotados - bool power_ball_enabled_ = false; // Indica si hay una powerball ya activa - int power_ball_counter_ = 0; // Contador de formaciones enemigas entre la aparicion de una PowerBall y otra - int last_balloon_deploy_ = 0; // Guarda cual ha sido la última formación desplegada para no repetir; + float balloon_speed_ = BALLOON_SPEED[0]; // Velocidad a la que se mueven los enemigos + float default_balloon_speed_ = BALLOON_SPEED[0]; // Velocidad base de los enemigos, sin incrementar + int balloon_deploy_counter_ = 0; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero + bool power_ball_enabled_ = false; // Indica si hay una powerball ya activa + int power_ball_counter_ = 0; // Contador de formaciones enemigas entre la aparicion de una PowerBall y otra + int last_balloon_deploy_ = 0; // Guarda cual ha sido la última formación desplegada para no repetir; // Inicializa void init(); @@ -39,13 +44,13 @@ public: void update(); // Renderiza los globos - void renderBalloons(); + void render(); // Vacia del vector de globos los globos que ya no sirven void freeBalloons(); // Crea una formación de enemigos - void deployBalloonFormation(); + void deployBalloonFormation(int stage); // Actualiza la variable enemyDeployCounter void updateBalloonDeployCounter(); @@ -68,17 +73,14 @@ public: // Establece la velocidad de los globos void setBalloonSpeed(float speed); - // Actualiza la velocidad de los globos en funcion del poder acumulado de la fase - void checkAndUpdateBalloonSpeed(); - // Explosiona un globo. Lo destruye y crea otros dos si es el caso void popBalloon(std::shared_ptr balloon); // Explosiona un globo. Lo destruye = no crea otros globos - void destroyBalloon(std::shared_ptr &balloon); + int destroyBalloon(std::shared_ptr &balloon); // Destruye todos los globos - void destroyAllBalloons(); + int destroyAllBalloons(); // Detiene todos los globos void stopAllBalloons(); @@ -96,5 +98,16 @@ public: void reLoad(); // Crea dos globos gordos - void createTwoBigBalloons(); + void createTwoBigBalloons(); + + // Obtiene el nivel de ameza actual generado por los globos + int getMenace(); + + // Getters + float getBalloonSpeed() const { return balloon_speed_; } + Balloons &getBalloons() { return balloons_; } + + // Setters + void setDefaultBalloonSpeed(float speed) { default_balloon_speed_ = speed; } + void resetBalloonSpeed() { setBalloonSpeed(default_balloon_speed_); } }; \ No newline at end of file diff --git a/source/define_buttons.cpp b/source/define_buttons.cpp index f5d1f33..f6449d2 100644 --- a/source/define_buttons.cpp +++ b/source/define_buttons.cpp @@ -1,5 +1,4 @@ #include "define_buttons.h" -#include // Para move #include "input.h" // Para Input, InputType #include "lang.h" // Para getText #include "options.h" // Para OptionsController, Options, options diff --git a/source/director.cpp b/source/director.cpp index 901dd4d..998cf26 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -7,7 +7,7 @@ #include // Para SDL_SetHint, SDL_HINT_RENDER_DR... #include // Para SDL_SCANCODE_0, SDL_SCANCODE_DOWN #include // Para SDL_bool, Uint32 -#include // Para duration, system_clock +#include // Para duration, system_clock #include // Para errno, EEXIST, EACCES, ENAMETOO... #include // Para printf, perror #include // Para mkdir, stat, S_IRWXU @@ -15,7 +15,7 @@ #include // Para min #include // Para exit, EXIT_FAILURE, size_t, rand #include // Para basic_ostream, operator<<, basi... -#include // Para make_unique, unique_ptr, make_s... +#include // Para make_unique, unique_ptr #include // Para runtime_error #include // Para operator+, char_traits, allocator #include // Para vector @@ -38,7 +38,6 @@ #include "resource.h" // Para Resource #include "screen.h" // Para Screen #include "section.h" // Para Name, Options, name, options -#include "text.h" // Para Text #include "title.h" // Para Title #include "utils.h" // Para Overrides, overrides diff --git a/source/game.cpp b/source/game.cpp index a1a8f57..9b2cf43 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -1,9 +1,19 @@ #include "game.h" -#include "stage.h" -#include "asset.h" // Para Asset -#include "background.h" // Para Background -#include "bullet.h" // Para Bullet, BulletType, BulletMoveStatus -#include "balloon_manager.h" +#include // Para SDL_BLENDMODE_BLEND +#include // Para SDL_PollEvent, SDL_Event, SDL_KEYDOWN +#include // Para SDLK_1, SDLK_2, SDLK_3, SDLK_4 +#include // Para SDL_PIXELFORMAT_RGBA8888 +#include // Para SDL_GetTicks +#include // Para SDL_WINDOWEVENT_FOCUS_GAINED, SDL_... +#include // Para rand, size_t +#include // Para find_if, clamp, min +#include // Para function +#include // Para distance, size +#include "asset.h" // Para Asset +#include "background.h" // Para Background +#include "balloon.h" // Para Balloon, BALLOON_SPEED +#include "balloon_manager.h" // Para BalloonManager +#include "bullet.h" // Para Bullet, BulletType, BulletMoveStatus #include "fade.h" // Para Fade, FadeType #include "global_inputs.h" // Para check #include "input.h" // Para InputType, Input, INPUT_DO_NOT_ALL... @@ -14,27 +24,17 @@ #include "notifier.h" // Para Notifier #include "param.h" // Para Param, param, ParamGame, ParamFade #include "path_sprite.h" // Para Path, PathSprite, createPath, Path... -#include "player.h" // Para Player, PlayerStatus +#include "player.h" // Para Player, PlayerState #include "resource.h" // Para Resource #include "scoreboard.h" // Para Scoreboard, ScoreboardMode, SCOREB... #include "screen.h" // Para Screen #include "section.h" // Para Name, name, Options, options #include "smart_sprite.h" // Para SmartSprite +#include "stage.h" // Para get, number, Stage, power #include "text.h" // Para Text +#include "dbgtxt.h" // Para dbg_print #include "texture.h" // Para Texture -#include // Para SDL_BLENDMODE_BLEND -#include // Para SDL_PollEvent, SDL_Event, SDL_KEYDOWN -#include // Para SDLK_1, SDLK_2, SDLK_3, SDLK_4 -#include // Para SDL_PIXELFORMAT_RGBA8888 -#include // Para SDL_GetTicks -#include // Para SDL_WINDOWEVENT_FOCUS_GAINED, SDL_... -#include // Para find_if, clamp, min, remove_if -#include // Para function -#include // Para distance, size -#include // Para accumulate -#include // Para rand, size_t - -struct JA_Sound_t; // lines 36-36 +struct JA_Sound_t; // lines 37-37 // Constructor Game::Game(int player_id, int current_stage, bool demo) @@ -45,8 +45,7 @@ Game::Game(int player_id, int current_stage, bool demo) background_(std::make_unique()), canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.play_area.rect.w, param.game.play_area.rect.h)), fade_(std::make_unique()), - balloon_manager_(std::make_unique(*this)), - current_stage_(current_stage) + balloon_manager_(std::make_unique()) { // Pasa variables demo_.enabled = demo; @@ -54,6 +53,8 @@ Game::Game(int player_id, int current_stage, bool demo) // Otras variables section::name = section::Name::GAME; section::options = section::Options::GAME_PLAY_1P; + Stage::init(); + Stage::number = current_stage; // Asigna texturas y animaciones setResources(); @@ -81,16 +82,16 @@ Game::Game(int player_id, int current_stage, bool demo) #ifdef DEBUG // Si se empieza en una fase que no es la primera if (!demo_.enabled) - for (int i = 0; i < current_stage_; ++i) + for (int i = 0; i < Stage::number; ++i) { - balloons_popped_ += balloon_formations_->getStage(i).power_to_complete; + balloons_popped_ += Stage::get(i).power_to_complete; } #endif // Crea los primeros globos y el mensaje de inicio if (!demo_.enabled) { - createTwoBigBalloons(); + balloon_manager_->createTwoBigBalloons(); evaluateAndSetMenace(); createMessage({paths_.at(0), paths_.at(1)}, Resource::get()->getTexture("get_ready")); } @@ -243,28 +244,29 @@ void Game::updateStage() { if (state_ == GameState::PLAYING) { - if (current_power_ >= balloon_formations_->getStage(current_stage_).power_to_complete) + if (Stage::power >= Stage::get(Stage::number).power_to_complete) { // Cambio de fase - ++current_stage_; - current_power_ = 0; + ++Stage::number; + Stage::power = 0; JA_PlaySound(Resource::get()->getSound("stage_change.wav")); - balloon_speed_ = default_balloon_speed_; - setBalloonSpeed(balloon_speed_); + balloon_manager_->resetBalloonSpeed(); screen_->flash(flash_color, 100); screen_->shake(); // Escribe el texto por pantalla - if (current_stage_ < 10) + if (Stage::number < 10) { - const auto stage_number = balloon_formations_->getStage(current_stage_).number; + const auto stage_number = Stage::get(Stage::number).number; std::vector paths = {paths_.at(2), paths_.at(3)}; if (stage_number == 10) + { createMessage(paths, Resource::get()->getTexture("last_stage")); + } else { auto text = Resource::get()->getText("04b_25_2x"); - const std::string caption = std::to_string(10 - current_stage_) + lang::getText(38); + const std::string caption = std::to_string(10 - Stage::number) + lang::getText(38); createMessage(paths, text->writeToTexture(caption, 1, -4)); } } @@ -314,10 +316,10 @@ void Game::updateCompletedState() 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 + Stage::number = 9; // Deja el valor dentro de los limites + balloon_manager_->destroyAllBalloons(); // Destruye a todos los globos + destroyAllItems(); // Destruye todos los items + Stage::power = 0; // Vuelve a dejar el poder a cero, por lo que hubiera podido subir al destruir todos los globos } // Comienza las celebraciones @@ -359,7 +361,7 @@ void Game::updateCompletedState() // Comprueba el estado del juego void Game::checkState() { - if (state_ != GameState::COMPLETED && current_stage_ == 10) + if (state_ != GameState::COMPLETED && Stage::number == 10) { state_ = GameState::COMPLETED; } @@ -380,10 +382,16 @@ void Game::destroyAllItems() // Comprueba la colisión entre el jugador y los globos activos bool Game::checkPlayerBalloonCollision(std::shared_ptr &player) { - for (auto &balloon : balloons_) + for (auto &balloon : balloon_manager_->getBalloons()) + { if (!balloon->isStopped() && !balloon->isInvulnerable()) + { if (checkCollision(player->getCollider(), balloon->getCollider())) + { return true; + } + } + } return false; } @@ -485,7 +493,7 @@ void Game::checkBulletBalloonCollision() { for (auto &bullet : bullets_) { - for (auto &balloon : balloons_) + for (auto &balloon : balloon_manager_->getBalloons()) { if (balloon->isEnabled() && (!balloon->isInvulnerable()) && bullet->isEnabled()) { @@ -518,7 +526,9 @@ void Game::checkBulletBalloonCollision() } // Explota el globo - popBalloon(balloon); + balloon_manager_->popBalloon(balloon); + balloons_popped_++; + evaluateAndSetMenace(); // Sonido de explosión JA_PlaySound(Resource::get()->getSound("balloon.wav")); @@ -821,9 +831,9 @@ void Game::updateTimeStopped() if (time_stopped_counter_ % 15 == 0) JA_PlaySound(Resource::get()->getSound("clock.wav")); if (time_stopped_counter_ % 30 == 0) - normalColorsToAllBalloons(); + balloon_manager_->normalColorsToAllBalloons(); if (time_stopped_counter_ % 30 == 15) - reverseColorsToAllBalloons(); + balloon_manager_->reverseColorsToAllBalloons(); } } else @@ -858,7 +868,9 @@ void Game::updateBackground() { // Si el juego está completado, se reduce la velocidad de las nubes 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 constexpr float clouds_initial_speed = 0.05f; @@ -887,11 +899,12 @@ void Game::fillCanvas() background_->render(); renderItems(); renderSmartSprites(); - explosions_->render(); - balloon_manager_->renderBalloons(); + balloon_manager_->render(); renderBullets(); renderPathSprites(); renderPlayers(); + dbg_print(0, 40, std::to_string(menace_current_).c_str(), 255, 0 ,0); + dbg_print(0, 50, std::to_string(menace_threshold_).c_str(), 255, 0 ,0); // Deja el renderizador apuntando donde estaba SDL_SetRenderTarget(renderer_, temp); @@ -919,8 +932,8 @@ void Game::render() // Habilita el efecto del item de detener el tiempo void Game::enableTimeStopItem() { - stopAllBalloons(); - reverseColorsToAllBalloons(); + balloon_manager_->stopAllBalloons(); + balloon_manager_->reverseColorsToAllBalloons(); time_stopped_counter_ = TIME_STOPPED_COUNTER_; } @@ -928,8 +941,8 @@ void Game::enableTimeStopItem() void Game::disableTimeStopItem() { time_stopped_counter_ = 0; - startAllBalloons(); - normalColorsToAllBalloons(); + balloon_manager_->startAllBalloons(); + balloon_manager_->normalColorsToAllBalloons(); } // Comprueba si la música ha de estar sonando @@ -1118,7 +1131,7 @@ void Game::checkEvents() } case SDLK_2: // Crea dos globos gordos { - createTwoBigBalloons(); + balloon_manager_->createTwoBigBalloons(); } break; case SDLK_3: // Activa el modo para pasar el juego automaticamente @@ -1188,8 +1201,8 @@ void Game::updateScoreboard() } // Resto de marcador - scoreboard_->setStage(balloon_formations_->getStage(current_stage_).number); - scoreboard_->setPower((float)current_power_ / (float)balloon_formations_->getStage(current_stage_).power_to_complete); + scoreboard_->setStage(Stage::get(Stage::number).number); + scoreboard_->setPower((float)Stage::power / (float)Stage::get(Stage::number).power_to_complete); scoreboard_->setHiScore(hi_score_.score); scoreboard_->setHiScoreName(hi_score_.name); @@ -1200,8 +1213,8 @@ void Game::updateScoreboard() // Pausa el juego void Game::pause(bool value) { - paused_ = value; - screen_->attenuate(paused_); + //paused_ = value; + //screen_->attenuate(paused_); } // Añade una puntuación a la tabla de records @@ -1528,13 +1541,13 @@ void Game::initDemo(int player_id) constexpr auto demos = 3; const auto demo = rand() % demos; const int stages[demos] = {0, 3, 5}; - current_stage_ = stages[demo]; + Stage::number = stages[demo]; } // Actualiza el numero de globos explotados según la fase del modo demostración - for (int i = 0; i < current_stage_; ++i) + for (int i = 0; i < Stage::number; ++i) { - balloons_popped_ += balloon_formations_->getStage(i).power_to_complete; + balloons_popped_ += Stage::get(i).power_to_complete; } // Activa o no al otro jugador @@ -1604,7 +1617,7 @@ void Game::initDifficultyVars() { case GameDifficulty::EASY: { - default_balloon_speed_ = BALLOON_SPEED[0]; + balloon_manager_->setDefaultBalloonSpeed(BALLOON_SPEED[0]); difficulty_score_multiplier_ = 0.5f; scoreboard_->setColor(scoreboard_easy_color); break; @@ -1612,7 +1625,7 @@ void Game::initDifficultyVars() case GameDifficulty::NORMAL: { - default_balloon_speed_ = BALLOON_SPEED[0]; + balloon_manager_->setDefaultBalloonSpeed(BALLOON_SPEED[0]); difficulty_score_multiplier_ = 1.0f; scoreboard_->setColor(scoreboard_normal_color); break; @@ -1620,7 +1633,7 @@ void Game::initDifficultyVars() case GameDifficulty::HARD: { - default_balloon_speed_ = BALLOON_SPEED[4]; + balloon_manager_->setDefaultBalloonSpeed(BALLOON_SPEED[4]); difficulty_score_multiplier_ = 1.5f; scoreboard_->setColor(scoreboard_hard_color); break; @@ -1630,7 +1643,7 @@ void Game::initDifficultyVars() break; } - balloon_speed_ = default_balloon_speed_; + balloon_manager_->resetBalloonSpeed(); } // Inicializa los jugadores @@ -1729,7 +1742,7 @@ void Game::updateGame() if (auto_pop_balloons_ && state_ == GameState::PLAYING) { balloons_popped_ += 5; - increaseStageCurrentPower(5); + Stage::power += 5; } #endif fade_->update(); @@ -1738,7 +1751,6 @@ void Game::updateGame() updateScoreboard(); updateBackground(); balloon_manager_->update(); - explosions_->update(); moveBullets(); updateItems(); updateStage(); @@ -1747,7 +1759,6 @@ void Game::updateGame() updateSmartSprites(); updatePathSprites(); updateTimeStopped(); - updateBalloonDeployCounter(); updateHelper(); checkBulletBalloonCollision(); updateMenace(); @@ -1770,8 +1781,8 @@ void Game::cleanVectors() // Gestiona el nivel de amenaza void Game::updateMenace() { - const auto stage = balloon_formations_->getStage(current_stage_); - const float percent = current_power_ / stage.power_to_complete; + const auto stage = Stage::get(Stage::number); + const float percent = Stage::power / stage.power_to_complete; const int difference = stage.max_menace - stage.min_menace; // Aumenta el nivel de amenaza en función de la puntuación @@ -1781,7 +1792,7 @@ void Game::updateMenace() if (menace_current_ < menace_threshold_) { // Crea una formación de enemigos - balloon_manager_->deployBalloonFormation(); + balloon_manager_->deployBalloonFormation(Stage::number); // Recalcula el nivel de amenaza con el nuevo globo evaluateAndSetMenace(); @@ -1791,7 +1802,24 @@ void Game::updateMenace() // 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_ = balloon_manager_->getMenace(); +} + +// Actualiza la velocidad de los globos en funcion del poder acumulado de la fase +void Game::checkAndUpdateBalloonSpeed() +{ + if (difficulty_ != GameDifficulty::NORMAL) + return; + + const float percent = static_cast(Stage::power) / Stage::get(Stage::number).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_manager_->getBalloonSpeed() == BALLOON_SPEED[i] && percent > thresholds[i]) + { + balloon_manager_->setBalloonSpeed(BALLOON_SPEED[i + 1]); + break; // Salir del bucle una vez actualizada la velocidad y aplicada + } + } } \ No newline at end of file diff --git a/source/game.h b/source/game.h index bf32726..c9be52f 100644 --- a/source/game.h +++ b/source/game.h @@ -5,25 +5,25 @@ #include // Para shared_ptr, unique_ptr #include // Para string #include // Para vector -#include "balloon_manager.h" // Para BalloonManager #include "manage_hiscore_table.h" // Para HiScoreEntry #include "options.h" // Para Options, OptionsGame, options #include "player.h" // Para Player #include "utils.h" // Para Demo -class Asset; // lines 14-14 -class Background; // lines 15-15 -class Bullet; // lines 17-17 -class Fade; // lines 19-19 -class Input; // lines 20-20 -class Item; // lines 21-21 -class PathSprite; // lines 22-22 -class Scoreboard; // lines 23-23 -class Screen; // lines 24-24 -class SmartSprite; // lines 25-25 -class Texture; // lines 27-27 -enum class BulletType : Uint8; // lines 28-28 -enum class ItemType; // lines 29-29 -struct Path; +class Asset; // lines 13-13 +class Background; // lines 14-14 +class BalloonManager; +class Bullet; // lines 15-15 +class Fade; // lines 16-16 +class Input; // lines 17-17 +class Item; // lines 18-18 +class PathSprite; // lines 19-19 +class Scoreboard; // lines 20-20 +class Screen; // lines 21-21 +class SmartSprite; // lines 22-22 +class Texture; // lines 23-23 +enum class BulletType : Uint8; // lines 24-24 +enum class ItemType; // lines 25-25 +struct Path; // lines 26-26 // Modo demo constexpr bool GAME_MODE_DEMO_OFF = false; @@ -149,8 +149,6 @@ private: options.game.hi_score_table[0].name, options.game.hi_score_table[0].score); // Máxima puntuación y nombre de quien la ostenta - int current_stage_; // Indica la fase actual - int current_power_ = 0; // Poder actual almacenado para completar la fase Demo demo_; // Variable con todas las variables relacionadas con el modo demo GameDifficulty difficulty_ = options.game.difficulty; // Dificultad del juego Helper helper_; // Variable para gestionar las ayudas @@ -164,6 +162,7 @@ private: int game_over_counter_ = GAME_OVER_COUNTER_; // Contador para el estado de fin de partida int time_stopped_counter_ = 0; // Temporizador para llevar la cuenta del tiempo detenido int total_power_to_complete_game_; // La suma del poder necesario para completar todas las fases + int balloons_popped_ = 0; // Lleva la cuenta de los globos explotados int menace_current_ = 0; // Nivel de amenaza actual int menace_threshold_ = 0; // 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 GameState state_ = GameState::PLAYING; // Estado @@ -402,6 +401,9 @@ private: // Calcula y establece el valor de amenaza en funcion de los globos activos void evaluateAndSetMenace(); + // Actualiza la velocidad de los globos en funcion del poder acumulado de la fase + void checkAndUpdateBalloonSpeed(); + public: // Constructor Game(int playerID, int current_stage, bool demo); @@ -411,14 +413,4 @@ public: // Bucle para el juego void run(); - - // Aumenta el poder de la fase - void increaseStageCurrentPower(int power) { current_power_ += power; } - - // Getters y Setters - int getCurrentStage() const { return current_stage_; } - void setCurrentStage(int stage) { current_stage_ = stage; } - - int getCurrentPower() const { return current_power_; } - void setCurrentPower(int power) { current_power_ = power; } }; \ No newline at end of file diff --git a/source/resource.cpp b/source/resource.cpp index edd33e4..b4d9299 100644 --- a/source/resource.cpp +++ b/source/resource.cpp @@ -2,13 +2,14 @@ #include // Para find_if #include // Para basic_ostream, operator<<, endl, cout, cerr #include // Para runtime_error +#include // Para pair #include "asset.h" // Para Asset, AssetType -#include "lang.h" // Para lang #include "jail_audio.h" // Para JA_LoadMusic, JA_LoadSound +#include "lang.h" // Para getText #include "screen.h" // Para Screen -#include "text.h" // Para Text -struct JA_Music_t; -struct JA_Sound_t; +#include "text.h" // Para Text, loadTextFile +struct JA_Music_t; // lines 10-10 +struct JA_Sound_t; // lines 11-11 // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado Resource *Resource::resource_ = nullptr; diff --git a/source/stage.cpp b/source/stage.cpp index 5bcba6a..72db028 100644 --- a/source/stage.cpp +++ b/source/stage.cpp @@ -3,6 +3,14 @@ namespace Stage { + + std::vector stages; // Variable con los datos de cada pantalla + int power = 0; // Poder acumulado en la fase + int number = 0; // Fase actual + + // Devuelve una fase + Stage get(int index) { return stages.at(index); } + // Inicializa las fases del juego void init() { diff --git a/source/stage.h b/source/stage.h index 66dd2ce..f3ead96 100644 --- a/source/stage.h +++ b/source/stage.h @@ -16,10 +16,12 @@ namespace Stage : number(number), power_to_complete(power_to_complete), min_menace(min_menace), max_menace(max_menace) {} }; - std::vector stages; // Variable con los datos de cada pantalla + extern std::vector stages; // Variable con los datos de cada pantalla + extern int power; // Poder acumulado en la fase + extern int number; // Fase actual // Devuelve una fase - Stage get(int index) { return stages.at(index); } + Stage get(int index); // Inicializa las fases del juego void init(); diff --git a/source/title.cpp b/source/title.cpp index b8c1360..4cbd7c2 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -5,7 +5,6 @@ #include // Para SDL_GetTicks #include // Para size_t #include // Para char_traits, operator+, basic_string -#include // Para move #include // Para vector #include "define_buttons.h" // Para DefineButtons #include "fade.h" // Para Fade, FadeType @@ -21,7 +20,7 @@ #include "screen.h" // Para Screen #include "section.h" // Para Options, options, Name, name, AttractMode #include "sprite.h" // Para Sprite -#include "text.h" // Para Text, TEXT_CENTER, TEXT_SHADOW +#include "text.h" // Para TEXT_CENTER, TEXT_SHADOW, Text #include "texture.h" // Para Texture #include "tiled_bg.h" // Para TiledBG, TiledBGMode #include "utils.h" // Para Color, Zone, fade_color, no_color, BLOCK