diff --git a/data/config/param_320x240.txt b/data/config/param_320x240.txt index b31e01d..645dd6a 100644 --- a/data/config/param_320x240.txt +++ b/data/config/param_320x240.txt @@ -54,10 +54,12 @@ balloon.settings[2].grav 0.10f # Gravedad aplicada al globo 3 balloon.settings[3].vel 5.45f # Velocidad inicial del globo 4 balloon.settings[3].grav 0.10f # Gravedad aplicada al globo 4 -balloon.color[0] blue # Color de creación del globo normal -balloon.color[1] orange # Color del globo normal -balloon.color[2] red # Color de creación del globo que rebota -balloon.color[3] green # Color del globo que rebota +balloon.color[0] blue # Color de creación del globo normal +balloon.color[1] orange # Color del globo normal +balloon.color[2] red # Color de creación del globo que rebota +balloon.color[3] green # Color del globo que rebota + +balloon.bouncing_sound false # Indica si los globos hacer sonido al rebotar ## --- NOTIFICATION --- notification.pos_v TOP # Posición vertical de la notificación (TOP/BOTTOM) diff --git a/data/config/param_320x256.txt b/data/config/param_320x256.txt index 21f24a5..c9f531f 100644 --- a/data/config/param_320x256.txt +++ b/data/config/param_320x256.txt @@ -54,10 +54,12 @@ balloon.settings[2].grav 0.10f # Gravedad aplicada al globo 3 balloon.settings[3].vel 5.45f # Velocidad inicial del globo 4 balloon.settings[3].grav 0.10f # Gravedad aplicada al globo 4 -balloon.color[0] blue # Color de creación del globo normal -balloon.color[1] orange # Color del globo normal -balloon.color[2] red # Color de creación del globo que rebota -balloon.color[3] green # Color del globo que rebota +balloon.color[0] blue # Color de creación del globo normal +balloon.color[1] orange # Color del globo normal +balloon.color[2] red # Color de creación del globo que rebota +balloon.color[3] green # Color del globo que rebota + +balloon.bouncing_sound false # Indica si los globos hacer sonido al rebotar ## --- NOTIFICATION --- notification.pos_v TOP # Posición vertical de la notificación (TOP/BOTTOM) diff --git a/data/sound/voice_thankyou.wav b/data/sound/voice_thankyou.wav index c45b73a..3b1c754 100644 Binary files a/data/sound/voice_thankyou.wav and b/data/sound/voice_thankyou.wav differ diff --git a/source/balloon.cpp b/source/balloon.cpp index 1691989..3474cd5 100644 --- a/source/balloon.cpp +++ b/source/balloon.cpp @@ -38,7 +38,8 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel power_ = BALLOON_POWER[index]; menace_ = BALLOON_MENACE[index]; score_ = BALLOON_SCORE[index]; - sound_ = BALLOON_SOUND[index]; + bouncing_sound_ = BALLOON_BOUNCING_SOUND[index]; + popping_sound_ = BALLOON_POPPING_SOUND[index]; break; } @@ -53,7 +54,8 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel power_ = BALLOON_POWER[index]; menace_ = BALLOON_MENACE[index]; score_ = BALLOON_SCORE[index]; - sound_ = BALLOON_SOUND[index]; + bouncing_sound_ = BALLOON_BOUNCING_SOUND[index]; + popping_sound_ = BALLOON_POPPING_SOUND[index]; break; } @@ -62,7 +64,7 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel { constexpr int index = 3; h_ = w_ = BALLOON_SIZE[4]; - sound_ = BALLOON_SOUND[3]; + bouncing_sound_ = BALLOON_BOUNCING_SOUND[3]; power_ = score_ = menace_ = 0; vy_ = 0; @@ -162,7 +164,8 @@ void Balloon::move() const float max_x = play_area_.x + play_area_.w - w_ + clip; if (x_ < min_x || x_ > max_x) { - playSound(); + if (bouncing_sound_enabled_) + playSound(bouncing_sound_); x_ = std::clamp(x_, min_x, max_x); vx_ = -vx_; // Activa el efecto de rebote o invierte la rotación @@ -185,7 +188,8 @@ void Balloon::move() const int min_y = play_area_.y; if (y_ < min_y) { - playSound(); + if (bouncing_sound_enabled_) + playSound(bouncing_sound_); y_ = min_y; vy_ = -vy_; enableBounce(); @@ -196,7 +200,8 @@ void Balloon::move() const int max_y = play_area_.y + play_area_.h - h_; if (y_ > max_y) { - playSound(); + if (bouncing_sound_enabled_) + playSound(bouncing_sound_); y_ = max_y; vy_ = -default_vy_; if (type_ != BalloonType::POWERBALL) @@ -409,11 +414,24 @@ void Balloon::useNormalColor() setAnimation(); } -// Reproduce el sonido al rebotar -void Balloon::playSound() +// Reproduce sonido +void Balloon::playSound(const std::string &name) { - if (sound_enabled_) + if (!sound_enabled_) + return; + + static auto audio = Audio::get(); + audio->playSound(name); +} + +// Explota el globo +void Balloon::pop(bool should_sound) +{ + if (should_sound) { - Audio::get()->playSound(sound_); + if (poping_sound_enabled_) + playSound(popping_sound_); } + + enabled_ = false; } \ No newline at end of file diff --git a/source/balloon.h b/source/balloon.h index fb274f1..a94e42a 100644 --- a/source/balloon.h +++ b/source/balloon.h @@ -17,7 +17,8 @@ constexpr int BALLOON_SCORE[] = {50, 100, 200, 400}; constexpr int BALLOON_POWER[] = {1, 3, 7, 15}; constexpr int BALLOON_MENACE[] = {1, 2, 4, 8}; constexpr int BALLOON_SIZE[] = {10, 16, 26, 48, 49}; -const std::string BALLOON_SOUND[] = {"bubble1.wav", "bubble2.wav", "bubble3.wav", "bubble4.wav"}; +const std::string BALLOON_BOUNCING_SOUND[] = {"bubble1.wav", "bubble2.wav", "bubble3.wav", "bubble4.wav"}; +const std::string BALLOON_POPPING_SOUND[] = {"balloon1.wav", "balloon2.wav", "balloon3.wav", "balloon4.wav"}; enum class BalloonSize : Uint8 { @@ -65,12 +66,13 @@ public: ~Balloon() = default; // --- Métodos principales --- - void alignTo(int x); // Centra el globo en la posición X - void render(); // Pinta el globo en la pantalla - void move(); // Actualiza la posición y estados del globo - void update(); // Actualiza el globo (posición, animación, contadores) - void stop(); // Detiene el globo - void start(); // Pone el globo en movimiento + void alignTo(int x); // Centra el globo en la posición X + void render(); // Pinta el globo en la pantalla + void move(); // Actualiza la posición y estados del globo + void update(); // Actualiza el globo (posición, animación, contadores) + void stop(); // Detiene el globo + void start(); // Pone el globo en movimiento + void pop(bool should_sound = false); // Explota el globo // --- Métodos de color --- void useReverseColor(); // Pone el color alternativo en el globo @@ -99,8 +101,9 @@ public: void setVelY(float vel_y) { vy_ = vel_y; } void setSpeed(float speed) { speed_ = speed; } void setInvulnerable(bool value) { invulnerable_ = value; } + void setBouncingSound(bool value) { bouncing_sound_enabled_ = value; } + void setPoppingSound(bool value) { poping_sound_enabled_ = value; } void setSound(bool value) { sound_enabled_ = value; } - void disable() { enabled_ = false; } private: // --- Estructura para el efecto de rebote --- @@ -132,43 +135,46 @@ private: std::unique_ptr sprite_; // Sprite del objeto globo // --- Variables de estado y físicas --- - float x_; // Posición X - float y_; // Posición Y - float w_; // Ancho - float h_; // Alto - float vx_; // Velocidad X - float vy_; // Velocidad Y - float gravity_; // Aceleración en Y - float default_vy_; // Velocidad inicial al rebotar - float max_vy_; // Máxima velocidad en Y - bool being_created_; // Si el globo se está creando - bool enabled_ = true; // Si el globo está activo - bool invulnerable_; // Si el globo es invulnerable - bool stopped_; // Si el globo está parado - bool use_reversed_colors_ = false; // Si se usa el color alternativo - Circle collider_; // Círculo de colisión - Uint16 creation_counter_; // Temporizador de creación - Uint16 creation_counter_ini_; // Valor inicial del temporizador de creación - Uint16 score_; // Puntos al destruir el globo - BalloonType type_; // Tipo de globo - BalloonSize size_; // Tamaño de globo - Uint8 menace_; // Amenaza que genera el globo - Uint32 counter_ = 0; // Contador interno - float travel_y_ = 1.0f; // Distancia a recorrer en Y antes de aplicar gravedad - float speed_; // Velocidad del globo - Uint8 power_; // Poder que alberga el globo - SDL_FRect play_area_; // Zona de movimiento del globo - std::string sound_; // Archivo de sonido al rebotar - bool sound_enabled_ = false; // Si debe sonar el globo al rebotar + float x_; // Posición X + float y_; // Posición Y + float w_; // Ancho + float h_; // Alto + float vx_; // Velocidad X + float vy_; // Velocidad Y + float gravity_; // Aceleración en Y + float default_vy_; // Velocidad inicial al rebotar + float max_vy_; // Máxima velocidad en Y + bool being_created_; // Si el globo se está creando + bool enabled_ = true; // Si el globo está activo + bool invulnerable_; // Si el globo es invulnerable + bool stopped_; // Si el globo está parado + bool use_reversed_colors_ = false; // Si se usa el color alternativo + Circle collider_; // Círculo de colisión + Uint16 creation_counter_; // Temporizador de creación + Uint16 creation_counter_ini_; // Valor inicial del temporizador de creación + Uint16 score_; // Puntos al destruir el globo + BalloonType type_; // Tipo de globo + BalloonSize size_; // Tamaño de globo + Uint8 menace_; // Amenaza que genera el globo + Uint32 counter_ = 0; // Contador interno + float travel_y_ = 1.0f; // Distancia a recorrer en Y antes de aplicar gravedad + float speed_; // Velocidad del globo + Uint8 power_; // Poder que alberga el globo + SDL_FRect play_area_; // Zona de movimiento del globo + std::string bouncing_sound_; // Archivo de sonido al rebotar + std::string popping_sound_; // Archivo de sonido al explotar + bool bouncing_sound_enabled_ = false; // Si debe sonar el globo al rebotar + bool poping_sound_enabled_ = true; // Si debe sonar el globo al explotar + bool sound_enabled_ = true; // Indica si los globos deben hacer algun sonido // --- Métodos internos --- - void shiftColliders(); // Alinea el círculo de colisión - void shiftSprite(); // Alinea el sprite - void zoomSprite(); // Establece el nivel de zoom del sprite - void enableBounce(); // Activa el efecto de rebote - void disableBounce(); // Detiene el efecto de rebote - void updateBounce(); // Aplica el efecto de rebote - void updateState(); // Actualiza los estados del globo - void setAnimation(); // Establece la animación correspondiente - void playSound(); // Reproduce el sonido al rebotar + void shiftColliders(); // Alinea el círculo de colisión + void shiftSprite(); // Alinea el sprite + void zoomSprite(); // Establece el nivel de zoom del sprite + void enableBounce(); // Activa el efecto de rebote + void disableBounce(); // Detiene el efecto de rebote + void updateBounce(); // Aplica el efecto de rebote + void updateState(); // Actualiza los estados del globo + void setAnimation(); // Establece la animación correspondiente + void playSound(const std::string &name); // Reproduce sonido }; \ No newline at end of file diff --git a/source/balloon_manager.cpp b/source/balloon_manager.cpp index 848d750..e9cf349 100644 --- a/source/balloon_manager.cpp +++ b/source/balloon_manager.cpp @@ -180,8 +180,11 @@ std::shared_ptr BalloonManager::createBalloon(float x, int y, BalloonTy { if (can_deploy_balloons_) { - const int index = static_cast(size); - balloons_.emplace_back(std::make_shared(x, y, type, size, velx, speed, creation_timer, play_area_, balloon_textures_.at(index), balloon_animations_.at(index))); + const int INDEX = static_cast(size); + balloons_.emplace_back(std::make_shared(x, y, type, size, velx, speed, creation_timer, play_area_, balloon_textures_.at(INDEX), balloon_animations_.at(INDEX))); + balloons_.back()->setSound(sound_enabled_); + balloons_.back()->setBouncingSound(bouncing_sound_enabled_); + balloons_.back()->setPoppingSound(poping_sound_enabled_); return balloons_.back(); } @@ -268,7 +271,7 @@ int BalloonManager::popBalloon(std::shared_ptr balloon) // Agrega la explosión y elimina el globo explosions_->add(balloon->getPosX(), balloon->getPosY(), static_cast(balloon->getSize())); - balloon->disable(); + balloon->pop(true); } return score; @@ -304,7 +307,7 @@ int BalloonManager::destroyBalloon(std::shared_ptr &balloon) // Destruye el globo explosions_->add(balloon->getPosX(), balloon->getPosY(), static_cast(balloon->getSize())); - balloon->disable(); + balloon->pop(); return score; } @@ -398,8 +401,28 @@ int BalloonManager::getMenace() // Establece el sonido de los globos void BalloonManager::setSounds(bool value) { + sound_enabled_ = value; for (auto &balloon : balloons_) { balloon->setSound(value); } +} + + // Activa o desactiva los sonidos de rebote los globos +void BalloonManager::setBouncingSounds(bool value) +{ + bouncing_sound_enabled_ = value; + for (auto &balloon : balloons_) + { + balloon->setBouncingSound(value); + } +} + // Activa o desactiva los sonidos de los globos al explotar +void BalloonManager::setPoppingSounds(bool value) +{ + poping_sound_enabled_ = value; + for (auto &balloon : balloons_) + { + balloon->setPoppingSound(value); + } } \ No newline at end of file diff --git a/source/balloon_manager.h b/source/balloon_manager.h index b7dd22c..8205371 100644 --- a/source/balloon_manager.h +++ b/source/balloon_manager.h @@ -61,6 +61,8 @@ public: // Configuración de sonido void setSounds(bool value); // Activa o desactiva los sonidos de los globos + void setBouncingSounds(bool value); // Activa o desactiva los sonidos de rebote los globos + void setPoppingSounds(bool value); // Activa o desactiva los sonidos de los globos al explotar // Configuración de juego void setPlayArea(SDL_FRect play_area) { play_area_ = play_area; }; // Define el área de juego @@ -94,7 +96,10 @@ private: SDL_FRect play_area_ = param.game.play_area.rect; bool creation_time_enabled_ = true; bool can_deploy_balloons_ = true; + bool bouncing_sound_enabled_ = false; // Si debe sonar el globo al rebotar + bool poping_sound_enabled_ = true; // Si debe sonar el globo al explotar + bool sound_enabled_ = true; // Indica si los globos deben hacer algun sonido - // Inicialización interna + // Metodos privados void init(); }; diff --git a/source/param.cpp b/source/param.cpp index 4930499..1bce33a 100644 --- a/source/param.cpp +++ b/source/param.cpp @@ -70,6 +70,8 @@ void initParam() param.balloon.color.at(2) = "red"; param.balloon.color.at(3) = "green"; + param.balloon.bouncing_sound = false; + // NOTIFICATION param.notification.pos_v = NotifyPosition::TOP; param.notification.pos_h = NotifyPosition::LEFT; @@ -373,6 +375,11 @@ bool setParams(const std::string &var, const std::string &value) param.balloon.color.at(3) = value; } + else if (var == "balloon.bouncing_sound") + { + param.balloon.bouncing_sound = stringToBool(value); + } + // NOTIFICACIONES else if (var == "notification.pos_h") { diff --git a/source/param.h b/source/param.h index b4dc18c..a005842 100644 --- a/source/param.h +++ b/source/param.h @@ -63,6 +63,7 @@ struct ParamBalloon std::array settings; std::array color; + bool bouncing_sound; // Indica si los globos hacer sonido al rebotar }; // --- Parámetros de las notificaciones --- diff --git a/source/sections/game.cpp b/source/sections/game.cpp index 27a5207..6ce25ac 100644 --- a/source/sections/game.cpp +++ b/source/sections/game.cpp @@ -78,6 +78,8 @@ Game::Game(int player_id, int current_stage, bool demo) background_->setPos(param.game.play_area.rect); + balloon_manager_->setBouncingSounds(param.balloon.bouncing_sound); + SDL_SetTextureBlendMode(canvas_, SDL_BLENDMODE_BLEND); // Inicializa el resto de variables @@ -320,7 +322,7 @@ void Game::updateGameStateGameOver() { createMessage({paths_.at(2), paths_.at(3)}, Resource::get()->getTexture("game_text_game_over")); Audio::get()->fadeOutMusic(1000); - balloon_manager_->setSounds(true); + balloon_manager_->setBouncingSounds(true); } game_over_counter_--; @@ -607,7 +609,6 @@ void Game::checkBulletCollision() if (dropped_item != ItemType::COFFEE_MACHINE) { createItem(dropped_item, balloon->getPosX(), balloon->getPosY()); - playSound("item_drop.wav"); } else { @@ -617,7 +618,6 @@ void Game::checkBulletCollision() } // Explota el globo - const auto SIZE = balloon->getSize(); const auto SCORE = balloon_manager_->popBalloon(balloon); evaluateAndSetMenace(); @@ -629,26 +629,6 @@ void Game::checkBulletCollision() } updateHiScore(); - // Sonido de explosión - switch (SIZE) - { - case BalloonSize::SIZE1: - playSound("balloon1.wav"); - break; - case BalloonSize::SIZE2: - playSound("balloon2.wav"); - break; - case BalloonSize::SIZE3: - playSound("balloon3.wav"); - break; - case BalloonSize::SIZE4: - playSound("balloon4.wav"); - break; - default: - playSound("balloon1.wav"); - break; - } - // Deshabilita la bala bullet->disable(); @@ -789,6 +769,7 @@ ItemType Game::dropItem() void Game::createItem(ItemType type, float x, float y) { items_.emplace_back(std::make_unique(type, x, y, param.game.play_area.rect, item_textures_[static_cast(type) - 1], item_animations_[static_cast(type) - 1])); + playSound("item_drop.wav"); } // Vacia el vector de items @@ -1069,13 +1050,13 @@ void Game::fillCanvas() // Dibuja los objetos background_->render(); - renderItems(); + renderPlayers(); renderSmartSprites(); + renderItems(); balloon_manager_->render(); tabe_->render(); renderBullets(); renderPathSprites(); - renderPlayers(); // Deja el renderizador apuntando donde estaba SDL_SetRenderTarget(renderer_, temp); @@ -1722,6 +1703,9 @@ void Game::initDemo(int player_id) // Configura los marcadores scoreboard_->setMode(SCOREBOARD_LEFT_PANEL, ScoreboardMode::DEMO); scoreboard_->setMode(SCOREBOARD_RIGHT_PANEL, ScoreboardMode::DEMO); + + // Silencia los globos + balloon_manager_->setSounds(false); } // Modo grabar demo