diff --git a/source/sections/game.cpp b/source/sections/game.cpp index 4d33549..6192d37 100644 --- a/source/sections/game.cpp +++ b/source/sections/game.cpp @@ -495,64 +495,96 @@ void Game::checkPlayerItemCollision(std::shared_ptr &player) { // Comprueba y procesa la colisión de las balas void Game::checkBulletCollision() { for (auto &bullet : bullets_) { - // Comprueba la colisión con el Tabe - if (bullet->isEnabled() && tabe_->isEnabled()) { - if (checkCollision(bullet->getCollider(), tabe_->getCollider())) { - tabe_->setState(TabeState::HIT); - bullet->disable(); - auto pos = tabe_->getCollider(); - if (tabe_->tryToGetBonus()) { - createItem(ItemType::DEBIAN, pos.x, pos.y); - playSound("debian_drop.wav"); - } else { - if (rand() % 3 == 0) { - createItem(ItemType::COFFEE, pos.x, pos.y); - } - playSound("tabe_hit.wav"); - } - break; - } + if (!bullet->isEnabled()) continue; + + if (checkBulletTabeCollision(bullet)) { + break; // Exit early if bullet hit Tabe } - // Comprueba la colisión con los globos - for (auto &balloon : balloon_manager_->getBalloons()) { - if (balloon->isEnabled() && (!balloon->isInvulnerable()) && bullet->isEnabled()) { - if (checkCollision(balloon->getCollider(), bullet->getCollider())) { - // Obtiene al jugador que disparó la bala - auto player = getPlayer(bullet->getOwner()); - - // Suelta el item si se da el caso - const auto DROPPED_ITEM = dropItem(); - if (DROPPED_ITEM != ItemType::NONE && !demo_.recording) { - if (DROPPED_ITEM != ItemType::COFFEE_MACHINE) { - createItem(DROPPED_ITEM, balloon->getPosX(), balloon->getPosY()); - } else { - createItem(DROPPED_ITEM, player->getPosX(), param.game.game_area.rect.y - Item::COFFEE_MACHINE_HEIGHT); - coffee_machine_enabled_ = true; - } - } - - // Explota el globo - const auto SCORE = balloon_manager_->popBalloon(balloon); - evaluateAndSetMenace(); - - // Otorga los puntos al jugador que disparó la bala - if (player->isPlaying()) { - player->addScore(SCORE * player->getScoreMultiplier() * difficulty_score_multiplier_); - player->incScoreMultiplier(); - } - updateHiScore(); - - // Deshabilita la bala - bullet->disable(); - - break; - } - } + if (checkBulletBalloonCollision(bullet)) { + break; // Exit early if bullet hit balloon } } } +// Maneja la colisión entre bala y Tabe +bool Game::checkBulletTabeCollision(std::shared_ptr bullet) { + if (!tabe_->isEnabled()) return false; + + if (!checkCollision(bullet->getCollider(), tabe_->getCollider())) { + return false; + } + + tabe_->setState(TabeState::HIT); + bullet->disable(); + + handleTabeHitEffects(); + return true; +} + +// Maneja los efectos de golpear al Tabe +void Game::handleTabeHitEffects() { + auto pos = tabe_->getCollider(); + + if (tabe_->tryToGetBonus()) { + createItem(ItemType::DEBIAN, pos.x, pos.y); + playSound("debian_drop.wav"); + } else { + if (rand() % 3 == 0) { + createItem(ItemType::COFFEE, pos.x, pos.y); + } + playSound("tabe_hit.wav"); + } +} + +// Maneja la colisión entre bala y globos +bool Game::checkBulletBalloonCollision(std::shared_ptr bullet) { + for (auto &balloon : balloon_manager_->getBalloons()) { + if (!balloon->isEnabled() || balloon->isInvulnerable()) continue; + + if (!checkCollision(balloon->getCollider(), bullet->getCollider())) continue; + + processBalloonHit(bullet, balloon); + return true; + } + return false; +} + +// Procesa el impacto en un globo +void Game::processBalloonHit(std::shared_ptr bullet, std::shared_ptr balloon) { + auto player = getPlayer(bullet->getOwner()); + + handleItemDrop(balloon, player); + handleBalloonDestruction(balloon, player); + + bullet->disable(); +} + +// Maneja la caída de items cuando se destruye un globo +void Game::handleItemDrop(std::shared_ptr balloon, std::shared_ptr player) { + const auto DROPPED_ITEM = dropItem(); + if (DROPPED_ITEM == ItemType::NONE || demo_.recording) return; + + if (DROPPED_ITEM != ItemType::COFFEE_MACHINE) { + createItem(DROPPED_ITEM, balloon->getPosX(), balloon->getPosY()); + } else { + createItem(DROPPED_ITEM, player->getPosX(), param.game.game_area.rect.y - Item::COFFEE_MACHINE_HEIGHT); + coffee_machine_enabled_ = true; + } +} + +// Maneja la destrucción del globo y puntuación +void Game::handleBalloonDestruction(std::shared_ptr balloon, std::shared_ptr player) { + const auto SCORE = balloon_manager_->popBalloon(balloon); + evaluateAndSetMenace(); + + if (player->isPlaying()) { + player->addScore(SCORE * player->getScoreMultiplier() * difficulty_score_multiplier_); + player->incScoreMultiplier(); + } + updateHiScore(); +} + // Mueve las balas activas void Game::updateBullets() { for (auto &bullet : bullets_) { @@ -571,7 +603,7 @@ 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(x, y, kind, powered_up, owner)); + bullets_.emplace_back(std::make_shared(x, y, kind, powered_up, owner)); } // Vacia el vector de balas diff --git a/source/sections/game.h b/source/sections/game.h index f20da7e..24155a5 100644 --- a/source/sections/game.h +++ b/source/sections/game.h @@ -103,7 +103,7 @@ class Game { SDL_Texture *canvas_; // Textura para dibujar la zona de juego std::vector> players_; // Vector con los jugadores - std::vector> bullets_; // Vector con las balas + std::vector> bullets_; // Vector con las balas std::vector> items_; // Vector con los items std::vector> smart_sprites_; // Vector con los smartsprites std::vector> path_sprites_; // Vector con los pathsprites @@ -236,6 +236,12 @@ class Game { void setState(GameState state); // Cambia el estado del juego void movePlayersToFront(); // Organiza los jugadores para que los vivos se pinten sobre los muertos void checkServiceMenu(); // Comprueba si está activo el menu de servicio para poner el juego en pausa + bool checkBulletTabeCollision(std::shared_ptr bullet); + void handleTabeHitEffects(); + bool checkBulletBalloonCollision(std::shared_ptr bullet); + void processBalloonHit(std::shared_ptr bullet, std::shared_ptr balloon); + void handleItemDrop(std::shared_ptr balloon, std::shared_ptr player); + void handleBalloonDestruction(std::shared_ptr balloon, std::shared_ptr player); #ifdef RECORDING void updateRecording(); // Actualiza las variables durante el modo de grabación #endif