diff --git a/config/assets.txt b/config/assets.txt index b9510c1..f276589 100644 --- a/config/assets.txt +++ b/config/assets.txt @@ -22,6 +22,7 @@ DEMODATA|${PREFIX}/data/demo/demo1.bin DEMODATA|${PREFIX}/data/demo/demo2.bin # Música +MUSIC|${PREFIX}/data/music/congratulations.ogg MUSIC|${PREFIX}/data/music/credits.ogg MUSIC|${PREFIX}/data/music/intro.ogg MUSIC|${PREFIX}/data/music/playing.ogg diff --git a/data/gfx/player/player.ani b/data/gfx/player/player.ani index 5a2fda4..ca44c10 100644 --- a/data/gfx/player/player.ani +++ b/data/gfx/player/player.ani @@ -109,7 +109,7 @@ frames=38,39,40,41 [animation] name=celebration speed=0.167 -loop=-1 +loop=0 frames=42,42,42,42,42,42,43,44,45,46,46,46,46,46,46,45,45,45,46,46,46,45,45,45,44,43,42,42,42 [/animation] diff --git a/data/music/congratulations.ogg b/data/music/congratulations.ogg new file mode 100644 index 0000000..035107b Binary files /dev/null and b/data/music/congratulations.ogg differ diff --git a/source/manage_hiscore_table.cpp b/source/manage_hiscore_table.cpp index c569f0b..6ecdced 100644 --- a/source/manage_hiscore_table.cpp +++ b/source/manage_hiscore_table.cpp @@ -13,7 +13,6 @@ void ManageHiScoreTable::clear() { table_.clear(); // Añade 10 entradas predefinidas - /* table_.emplace_back("BRY", 1000000); table_.emplace_back("USUFO", 500000); table_.emplace_back("GLUCA", 100000); @@ -24,8 +23,8 @@ void ManageHiScoreTable::clear() { table_.emplace_back("SAM", 500); table_.emplace_back("PACMQ", 200); table_.emplace_back("PELEC", 100); - */ + /* table_.emplace_back("BRY", 1000); table_.emplace_back("USUFO", 500); table_.emplace_back("GLUCA", 100); @@ -36,6 +35,20 @@ void ManageHiScoreTable::clear() { table_.emplace_back("SAM", 3); table_.emplace_back("PACMQ", 2); table_.emplace_back("PELEC", 1); + */ + + /* + table_.emplace_back("BRY", 5000000); + table_.emplace_back("USUFO", 5000000); + table_.emplace_back("GLUCA", 5000000); + table_.emplace_back("PARRA", 5000000); + table_.emplace_back("CAGAM", 5000000); + table_.emplace_back("PEPE", 5000000); + table_.emplace_back("ROSIT", 5000000); + table_.emplace_back("SAM", 5000000); + table_.emplace_back("PACMQ", 5000000); + table_.emplace_back("PELEC", 5000000); + */ sort(); } diff --git a/source/player.cpp b/source/player.cpp index 681d6df..a060490 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -149,20 +149,20 @@ void Player::setInputEnteringName(Input::Action action) { name_entry_idle_time_accumulator_ = 0.0f; } -// Fase 1: Sistema de movimiento time-based +// Sistema de movimiento void Player::move(float deltaTime) { switch (playing_state_) { case State::PLAYING: handlePlayingMovement(deltaTime); break; case State::ROLLING: - handleRollingMovement(); + handleRollingMovement(); break; case State::TITLE_ANIMATION: handleTitleAnimation(deltaTime); break; case State::CONTINUE_TIME_OUT: - handleContinueTimeOut(); + handleContinueTimeOut(); break; case State::LEAVING_SCREEN: updateStepCounter(deltaTime); @@ -173,13 +173,13 @@ void Player::move(float deltaTime) { handleEnteringScreen(deltaTime); break; case State::CREDITS: - handleCreditsMovement(deltaTime); + handleCreditsMovement(deltaTime); break; case State::WAITING: - handleWaitingMovement(deltaTime); + handleWaitingMovement(deltaTime); break; case State::RECOVER: - handleRecoverMovement(); + handleRecoverMovement(); break; default: break; @@ -356,7 +356,7 @@ void Player::handleCreditsLeftMovement() { // Controla la animación del jugador saludando (time-based) void Player::handleWaitingMovement(float deltaTime) { waiting_time_accumulator_ += deltaTime; - const float WAITING_DURATION_S = static_cast(WAITING_COUNTER) / 60.0f; // Convert frames to seconds + const float WAITING_DURATION_S = static_cast(WAITING_COUNTER) / 60.0f; // Convert frames to seconds if (waiting_time_accumulator_ >= WAITING_DURATION_S) { waiting_time_accumulator_ = 0.0f; player_sprite_->resetAnimation(); @@ -387,7 +387,7 @@ void Player::setInputBasedOnPlayerId() { // Incrementa o ajusta el contador de pasos (time-based) void Player::updateStepCounter(float deltaTime) { step_time_accumulator_ += deltaTime; - const float STEP_INTERVAL_S = 10.0f / 60.0f; // 10 frames converted to seconds + const float STEP_INTERVAL_S = 10.0f / 60.0f; // 10 frames converted to seconds if (step_time_accumulator_ >= STEP_INTERVAL_S) { step_time_accumulator_ = 0.0f; playSound("walk.wav"); @@ -398,16 +398,16 @@ void Player::updateStepCounter(float deltaTime) { void Player::render() { if (power_up_ && isPlaying()) { // Convertir lógica de parpadeo a deltaTime en segundos - const float TOTAL_POWERUP_TIME_S = static_cast(POWERUP_COUNTER) / 60.0f; // Total time in seconds - const float QUARTER_TIME_S = TOTAL_POWERUP_TIME_S / 4.0f; // 25% del tiempo total + const float TOTAL_POWERUP_TIME_S = static_cast(POWERUP_COUNTER) / 60.0f; // Total time in seconds + const float QUARTER_TIME_S = TOTAL_POWERUP_TIME_S / 4.0f; // 25% del tiempo total if (power_up_time_accumulator_ > QUARTER_TIME_S) { // En los primeros 75% del tiempo, siempre visible power_sprite_->render(); } else { // En el último 25%, parpadea cada 20 frames (≈0.333s) - constexpr float BLINK_PERIOD_S = 20.0f / 60.0f; // 20 frames in seconds - constexpr float VISIBLE_PROPORTION = 4.0f / 20.0f; // 4 frames visible de 20 total + constexpr float BLINK_PERIOD_S = 20.0f / 60.0f; // 20 frames in seconds + constexpr float VISIBLE_PROPORTION = 4.0f / 20.0f; // 4 frames visible de 20 total float cycle_position = fmod(power_up_time_accumulator_, BLINK_PERIOD_S) / BLINK_PERIOD_S; if (cycle_position >= VISIBLE_PROPORTION) { @@ -475,11 +475,10 @@ auto Player::computeAnimation() const -> std::pair { return {anim_name, flip_mode}; } -// Fase 1: Establece la animación correspondiente al estado (time-based) +// Establece la animación correspondiente al estado void Player::setAnimation(float deltaTime) { switch (playing_state_) { case State::PLAYING: - case State::ENTERING_NAME_GAME_COMPLETED: case State::ENTERING_SCREEN: case State::LEAVING_SCREEN: case State::TITLE_ANIMATION: @@ -505,6 +504,7 @@ void Player::setAnimation(float deltaTime) { case State::CONTINUE: player_sprite_->setCurrentAnimation("dizzy"); break; + case State::ENTERING_NAME_GAME_COMPLETED: case State::CELEBRATING: player_sprite_->setCurrentAnimation("celebration"); break; @@ -519,16 +519,16 @@ void Player::setAnimation(float deltaTime) { // Actualiza al jugador con deltaTime (time-based) void Player::update(float deltaTime) { - move(deltaTime); // Sistema de movimiento time-based - setAnimation(deltaTime); // Animaciones time-based - shiftColliders(); // Sin cambios (posicional) - updateFireSystem(deltaTime); // Sistema de disparo de dos líneas - updatePowerUp(deltaTime); // Sistema de power-up time-based - updateInvulnerable(deltaTime); // Sistema de invulnerabilidad time-based - updateScoreboard(); // Sin cambios (no temporal) - updateContinueCounter(deltaTime); // Sistema de continue time-based - updateEnterNameCounter(deltaTime); // Sistema de name entry time-based - updateShowingName(deltaTime); // Sistema de showing name time-based + move(deltaTime); // Sistema de movimiento time-based + setAnimation(deltaTime); // Animaciones time-based + shiftColliders(); // Sin cambios (posicional) + updateFireSystem(deltaTime); // Sistema de disparo de dos líneas + updatePowerUp(deltaTime); // Sistema de power-up time-based + updateInvulnerable(deltaTime); // Sistema de invulnerabilidad time-based + updateScoreboard(); // Sin cambios (no temporal) + updateContinueCounter(deltaTime); // Sistema de continue time-based + updateEnterNameCounter(deltaTime); // Sistema de name entry time-based + updateShowingName(deltaTime); // Sistema de showing name time-based } void Player::passShowingName() { @@ -599,7 +599,7 @@ void Player::setPlayingState(State state) { case State::CONTINUE: { // Inicializa el contador de continuar continue_counter_ = 9; - continue_time_accumulator_ = 0.0f; // Initialize time accumulator + continue_time_accumulator_ = 0.0f; // Initialize time accumulator playSound("continue_clock.wav"); setScoreboardMode(Scoreboard::Mode::CONTINUE); break; @@ -618,7 +618,7 @@ void Player::setPlayingState(State state) { } pos_y_ = default_pos_y_; waiting_counter_ = 0; - waiting_time_accumulator_ = 0.0f; // Initialize time accumulator + waiting_time_accumulator_ = 0.0f; // Initialize time accumulator shiftSprite(); player_sprite_->setCurrentAnimation("hello"); player_sprite_->animtionPause(); @@ -639,10 +639,10 @@ void Player::setPlayingState(State state) { case State::ROLLING: { // Activa la animación de rodar dando botes player_sprite_->setCurrentAnimation("rolling"); - player_sprite_->setAnimationSpeed(4.0f / 60.0f); // 4 frames convertido a segundos - player_sprite_->setVelY(-396.0F); // Velocidad inicial (6.6 * 60 = 396 pixels/s) - player_sprite_->setAccelY(720.0F); // Gravedad (0.2 * 60² = 720 pixels/s²) - player_sprite_->setPosY(pos_y_ - 2); // Para "sacarlo" del suelo, ya que está hundido un pixel para ocultar el outline de los pies + player_sprite_->setAnimationSpeed(4.0f / 60.0f); // 4 frames convertido a segundos + player_sprite_->setVelY(-396.0F); // Velocidad inicial (6.6 * 60 = 396 pixels/s) + player_sprite_->setAccelY(720.0F); // Gravedad (0.2 * 60² = 720 pixels/s²) + player_sprite_->setPosY(pos_y_ - 2); // Para "sacarlo" del suelo, ya que está hundido un pixel para ocultar el outline de los pies (rand() % 2 == 0) ? player_sprite_->setVelX(198.0F) : player_sprite_->setVelX(-198.0F); // 3.3 * 60 = 198 pixels/s break; } @@ -659,8 +659,8 @@ void Player::setPlayingState(State state) { } case State::CONTINUE_TIME_OUT: { // Activa la animación de sacar al jugador de la zona de juego - player_sprite_->setAccelY(720.0F); // 0.2 * 60² = 720 pixels/s² - player_sprite_->setVelY(-240.0F); // -4.0 * 60 = -240 pixels/s + player_sprite_->setAccelY(720.0F); // 0.2 * 60² = 720 pixels/s² + player_sprite_->setVelY(-240.0F); // -4.0 * 60 = -240 pixels/s player_sprite_->setVelX(0.0F); player_sprite_->setCurrentAnimation("rolling"); player_sprite_->setAnimationSpeed(5.0f / 60.0f); // 5 frames convertido a segundos @@ -679,21 +679,21 @@ void Player::setPlayingState(State state) { break; } case State::ENTERING_NAME_GAME_COMPLETED: { - setWalkingState(State::WALKING_STOP); - setFiringState(State::FIRING_NONE); + // setWalkingState(State::WALKING_STOP); + // setFiringState(State::FIRING_NONE); setScoreboardMode(Scoreboard::Mode::ENTER_NAME); break; } case State::LEAVING_SCREEN: { step_counter_ = 0; - step_time_accumulator_ = 0.0f; // Initialize time accumulator + step_time_accumulator_ = 0.0f; // Initialize time accumulator setScoreboardMode(Scoreboard::Mode::GAME_COMPLETED); break; } case State::ENTERING_SCREEN: { init(); step_counter_ = 0; - step_time_accumulator_ = 0.0f; // Initialize time accumulator + step_time_accumulator_ = 0.0f; // Initialize time accumulator setScoreboardMode(Scoreboard::Mode::SCORE); switch (id_) { case Id::PLAYER1: @@ -734,7 +734,7 @@ void Player::decScoreMultiplier() { void Player::setInvulnerable(bool value) { invulnerable_ = value; invulnerable_counter_ = invulnerable_ ? INVULNERABLE_COUNTER : 0; - invulnerable_time_accumulator_ = invulnerable_ ? static_cast(INVULNERABLE_COUNTER) / 60.0f : 0.0f; // Convert frames to seconds + invulnerable_time_accumulator_ = invulnerable_ ? static_cast(INVULNERABLE_COUNTER) / 60.0f : 0.0f; // Convert frames to seconds } // Monitoriza el estado (time-based) @@ -744,12 +744,12 @@ void Player::updateInvulnerable(float deltaTime) { invulnerable_time_accumulator_ -= deltaTime; // Frecuencia fija de parpadeo adaptada a deltaTime (en segundos) - constexpr float BLINK_PERIOD_S = 8.0f / 60.0f; // 8 frames convertidos a segundos + constexpr float BLINK_PERIOD_S = 8.0f / 60.0f; // 8 frames convertidos a segundos // Calcula proporción decreciente basada en tiempo restante const float TOTAL_INVULNERABLE_TIME_S = static_cast(INVULNERABLE_COUNTER) / 60.0f; float progress = 1.0f - (invulnerable_time_accumulator_ / TOTAL_INVULNERABLE_TIME_S); - float white_proportion = 0.5f - progress * 0.2f; // Menos blanco hacia el final + float white_proportion = 0.5f - progress * 0.2f; // Menos blanco hacia el final // Calcula si debe mostrar textura de invulnerabilidad basado en el ciclo temporal float cycle_position = fmod(invulnerable_time_accumulator_, BLINK_PERIOD_S) / BLINK_PERIOD_S; @@ -773,7 +773,7 @@ void Player::updateInvulnerable(float deltaTime) { void Player::setPowerUp() { power_up_ = true; power_up_counter_ = POWERUP_COUNTER; - power_up_time_accumulator_ = static_cast(POWERUP_COUNTER) / 60.0f; // Convert frames to seconds + power_up_time_accumulator_ = static_cast(POWERUP_COUNTER) / 60.0f; // Convert frames to seconds } // Actualiza el valor de la variable (time-based) @@ -825,7 +825,7 @@ void Player::setPlayerTextures(const std::vector> &text void Player::updateContinueCounter(float deltaTime) { if (playing_state_ == State::CONTINUE) { continue_time_accumulator_ += deltaTime; - constexpr float CONTINUE_INTERVAL_S = 1.0f; // 1 segundo + constexpr float CONTINUE_INTERVAL_S = 1.0f; // 1 segundo if (continue_time_accumulator_ >= CONTINUE_INTERVAL_S) { continue_time_accumulator_ -= CONTINUE_INTERVAL_S; decContinueCounter(); @@ -837,7 +837,7 @@ void Player::updateContinueCounter(float deltaTime) { void Player::updateEnterNameCounter(float deltaTime) { if (playing_state_ == State::ENTERING_NAME || playing_state_ == State::ENTERING_NAME_GAME_COMPLETED) { name_entry_time_accumulator_ += deltaTime; - constexpr float NAME_ENTRY_INTERVAL_S = 1.0f; // 1 segundo + constexpr float NAME_ENTRY_INTERVAL_S = 1.0f; // 1 segundo if (name_entry_time_accumulator_ >= NAME_ENTRY_INTERVAL_S) { name_entry_time_accumulator_ -= NAME_ENTRY_INTERVAL_S; decNameEntryCounter(); @@ -849,7 +849,7 @@ void Player::updateEnterNameCounter(float deltaTime) { void Player::updateShowingName(float deltaTime) { if (playing_state_ == State::SHOWING_NAME) { showing_name_time_accumulator_ += deltaTime; - constexpr float SHOWING_NAME_DURATION_S = 5.0f; // 5 segundos + constexpr float SHOWING_NAME_DURATION_S = 5.0f; // 5 segundos if (showing_name_time_accumulator_ >= SHOWING_NAME_DURATION_S) { game_completed_ ? setPlayingState(State::LEAVING_SCREEN) : setPlayingState(State::CONTINUE); } @@ -858,7 +858,7 @@ void Player::updateShowingName(float deltaTime) { // Decrementa el contador de continuar void Player::decContinueCounter() { - continue_time_accumulator_ = 0.0f; // Reset time accumulator + continue_time_accumulator_ = 0.0f; // Reset time accumulator --continue_counter_; if (continue_counter_ < 0) { setPlayingState(State::CONTINUE_TIME_OUT); @@ -869,7 +869,7 @@ void Player::decContinueCounter() { // Decrementa el contador de entrar nombre void Player::decNameEntryCounter() { - name_entry_time_accumulator_ = 0.0f; // Reset time accumulator + name_entry_time_accumulator_ = 0.0f; // Reset time accumulator // Incrementa acumuladores de tiempo (1 segundo) name_entry_idle_time_accumulator_ += 1.0f; @@ -1007,7 +1007,7 @@ void Player::startFiringSystem(int cooldown_frames) { visual_fire_state_ = VisualFireState::AIMING; visual_state_timer_ = aiming_duration_; - updateFiringStateFromVisual(); // Sincroniza firing_state_ para animaciones + updateFiringStateFromVisual(); // Sincroniza firing_state_ para animaciones } // Sincroniza firing_state_ con visual_fire_state_ @@ -1034,19 +1034,35 @@ void Player::updateFiringStateFromVisual() { case VisualFireState::RECOILING: switch (base_state) { - case State::FIRING_LEFT: firing_state_ = State::RECOILING_LEFT; break; - case State::FIRING_RIGHT: firing_state_ = State::RECOILING_RIGHT; break; - case State::FIRING_UP: firing_state_ = State::RECOILING_UP; break; - default: firing_state_ = State::RECOILING_UP; break; + case State::FIRING_LEFT: + firing_state_ = State::RECOILING_LEFT; + break; + case State::FIRING_RIGHT: + firing_state_ = State::RECOILING_RIGHT; + break; + case State::FIRING_UP: + firing_state_ = State::RECOILING_UP; + break; + default: + firing_state_ = State::RECOILING_UP; + break; } break; case VisualFireState::THREAT_POSE: switch (base_state) { - case State::FIRING_LEFT: firing_state_ = State::COOLING_LEFT; break; - case State::FIRING_RIGHT: firing_state_ = State::COOLING_RIGHT; break; - case State::FIRING_UP: firing_state_ = State::COOLING_UP; break; - default: firing_state_ = State::COOLING_UP; break; + case State::FIRING_LEFT: + firing_state_ = State::COOLING_LEFT; + break; + case State::FIRING_RIGHT: + firing_state_ = State::COOLING_RIGHT; + break; + case State::FIRING_UP: + firing_state_ = State::COOLING_UP; + break; + default: + firing_state_ = State::COOLING_UP; + break; } break; } @@ -1064,8 +1080,8 @@ void Player::transitionToThreatPose() { // Calcular threat_pose_duration ajustada: // Duración original (833ms) menos el tiempo extra que ahora dura recoiling - float original_recoiling_duration = fire_cooldown_timer_; // Era 100% del cooldown - float new_recoiling_duration = aiming_duration_ * RECOILING_DURATION_MULTIPLIER; // Ahora es más del cooldown + float original_recoiling_duration = fire_cooldown_timer_; // Era 100% del cooldown + float new_recoiling_duration = aiming_duration_ * RECOILING_DURATION_MULTIPLIER; // Ahora es más del cooldown float extra_recoiling_time = new_recoiling_duration - original_recoiling_duration; float adjusted_threat_duration = THREAT_POSE_DURATION - extra_recoiling_time; diff --git a/source/sections/game.cpp b/source/sections/game.cpp index dd0bc34..1c7421e 100644 --- a/source/sections/game.cpp +++ b/source/sections/game.cpp @@ -204,8 +204,8 @@ void Game::updateHiScore() { // Si se supera la máxima puntuación if (!hi_score_achieved_) { hi_score_achieved_ = true; - playSound("hi_score_achieved.wav"); // Emite un sonido - createMessage({paths_.at(8), paths_.at(9)}, Resource::get()->getTexture("game_text_new_record")); // CRea un mensaje + playSound("hi_score_achieved.wav"); // Emite un sonido + createMessage({paths_.at(8), paths_.at(9)}, Resource::get()->getTexture("game_text_new_record")); // CRea un mensaje } } } @@ -1037,7 +1037,7 @@ void Game::initPaths() { const int X1 = param.game.play_area.center_x - (W / 2); const int X2 = param.game.play_area.rect.w; const int Y = param.game.play_area.center_y; - paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 0.5f); + paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 0.5f); paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0); } @@ -1049,7 +1049,7 @@ void Game::initPaths() { const int Y1 = param.game.play_area.center_y - (H / 2); const int Y2 = -H; const int X = param.game.play_area.center_x; - paths_.emplace_back(createPath(Y0, Y1, PathType::VERTICAL, X, 80, easeOutQuint), 0.5f); + paths_.emplace_back(createPath(Y0, Y1, PathType::VERTICAL, X, 80, easeOutQuint), 0.5f); paths_.emplace_back(createPath(Y1, Y2, PathType::VERTICAL, X, 80, easeInQuint), 0); } @@ -1061,8 +1061,8 @@ void Game::initPaths() { const int X0 = -W; const int X1 = param.game.play_area.center_x - (W / 2); const int X2 = param.game.play_area.rect.w; - const int Y = param.game.play_area.center_y - (H / 2) - 20; - paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 7.0F); + const int Y = param.game.play_area.center_y - (H / 2); + paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 7.0F); paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0); } @@ -1074,7 +1074,7 @@ void Game::initPaths() { const int X0 = param.game.play_area.rect.w; const int X1 = param.game.play_area.center_x - (W / 2); const int X2 = -W; - const int Y = param.game.play_area.center_y + (H / 2) - 20; + const int Y = param.game.play_area.center_y + (H / 2); paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 7.0F); paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0); } @@ -1083,11 +1083,12 @@ void Game::initPaths() { { const auto &texture = Resource::get()->getTexture("game_text_new_record"); const auto W = texture->getWidth(); + const auto H = texture->getHeight(); const int X0 = -W; const int X1 = param.game.play_area.center_x - (W / 2); const int X2 = param.game.play_area.rect.w; - const int Y = param.game.play_area.first_quarter_y; - paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 1.0f); + const int Y = param.game.play_area.center_y - (H / 2) - (H * 2); + paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 1.0f); paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0); } } @@ -1658,8 +1659,8 @@ void Game::initPlayers(Player::Id player_id) { } // Hace sonar la música -void Game::playMusic() { - Audio::get()->playMusic("playing.ogg"); +void Game::playMusic(const std::string &music_file, int loop) { + Audio::get()->playMusic(music_file, loop); } // Pausa la música @@ -1770,7 +1771,7 @@ void Game::updateGameStateShowingGetReadyMessage(float deltaTime) { if (!music_started) { music_timer += deltaTime; if (music_timer >= 1.67f) { - playMusic(); + playMusic("playing.ogg"); music_started = true; setState(State::PLAYING); } @@ -1781,7 +1782,7 @@ void Game::updateGameStateShowingGetReadyMessage(float deltaTime) { void Game::updateGameStatePlaying(float deltaTime) { #ifdef _DEBUG if (auto_pop_balloons_) { - stage_manager_->addPower(1); + stage_manager_->addPower(2); } #endif updatePlayers(deltaTime); @@ -1935,8 +1936,8 @@ void Game::onPauseStateChanged(bool is_paused) { // Maneja eventos del juego completado usando flags para triggers únicos void Game::handleGameCompletedEvents() { - constexpr float START_CELEBRATIONS_S = 6.667f; // 400 frames a 60fps → segundos - constexpr float END_CELEBRATIONS_S = 11.667f; // 700 frames a 60fps → segundos + constexpr float START_CELEBRATIONS_S = 6.0f; + constexpr float END_CELEBRATIONS_S = 14.0f; // Inicio de celebraciones static bool start_celebrations_triggered = false; @@ -1954,6 +1955,7 @@ void Game::handleGameCompletedEvents() { } updateHiScore(); + playMusic("congratulations.ogg", 1); start_celebrations_triggered = true; } diff --git a/source/sections/game.h b/source/sections/game.h index a6d42ad..f17b0a0 100644 --- a/source/sections/game.h +++ b/source/sections/game.h @@ -75,11 +75,11 @@ class Game { // --- Constantes de tiempo (en segundos) --- static constexpr float HELP_COUNTER_S = 16.667f; // Contador de ayuda (1000 frames a 60fps → segundos) - static constexpr float GAME_COMPLETED_START_FADE_S = 8.333f; // Inicio del fade al completar (500 frames → segundos) - static constexpr float GAME_COMPLETED_END_S = 11.667f; // Fin del juego completado (700 frames → segundos) - static constexpr float GAME_OVER_DURATION_S = 5.833f; // Duración game over (350 frames → segundos) - static constexpr float TIME_STOPPED_DURATION_S = 6.0f; // Duración del tiempo detenido (360 frames → segundos) - static constexpr float DEMO_FADE_PRE_DURATION_S = 0.5f; // Pre-duración del fade en modo demo + static constexpr float GAME_COMPLETED_START_FADE_S = 8.333f; // Inicio del fade al completar (500 frames → segundos) + static constexpr float GAME_COMPLETED_END_S = 11.667f; // Fin del juego completado (700 frames → segundos) + static constexpr float GAME_OVER_DURATION_S = 5.833f; // Duración game over (350 frames → segundos) + static constexpr float TIME_STOPPED_DURATION_S = 6.0f; // Duración del tiempo detenido (360 frames → segundos) + static constexpr float DEMO_FADE_PRE_DURATION_S = 0.5f; // Pre-duración del fade en modo demo static constexpr int ITEM_POINTS_1_DISK_ODDS = 10; static constexpr int ITEM_POINTS_2_GAVINA_ODDS = 6; static constexpr int ITEM_POINTS_3_PACMAR_ODDS = 3; @@ -226,7 +226,7 @@ class Game { void demoHandlePlayerInput(const std::shared_ptr &player, int index); // Procesa entrada de jugador en demo // --- Sistema de balas y proyectiles --- - void updateBullets(float deltaTime); // Actualiza posición y estado de todas las balas (time-based) + void updateBullets(float deltaTime); // Actualiza posición y estado de todas las balas (time-based) void renderBullets(); // Renderiza todas las balas activas void createBullet(int x, int y, BulletType kind, bool powered_up, Player::Id owner); // Crea una nueva bala void checkBulletCollision(); // Verifica colisiones de todas las balas @@ -238,7 +238,7 @@ class Game { void processBalloonHit(const std::shared_ptr &bullet, const std::shared_ptr &balloon); // Procesa impacto en globo // --- Sistema de ítems y power-ups --- - void updateItems(float deltaTime); // Actualiza posición y estado de todos los ítems + void updateItems(float deltaTime); // Actualiza posición y estado de todos los ítems void renderItems(); // Renderiza todos los ítems activos auto dropItem() -> ItemType; // Determina aleatoriamente qué ítem soltar void createItem(ItemType type, float x, float y); // Crea un nuevo ítem en posición específica @@ -258,14 +258,14 @@ class Game { // --- Sprites inteligentes (smartsprites) --- void updateSmartSprites(float deltaTime); // Actualiza todos los sprites con lógica propia (time-based) - void renderSmartSprites(); // Renderiza todos los sprites inteligentes - void freeSmartSprites(); // Libera memoria de sprites inteligentes + void renderSmartSprites(); // Renderiza todos los sprites inteligentes + void freeSmartSprites(); // Libera memoria de sprites inteligentes // --- Sprites por ruta (pathsprites) --- void updatePathSprites(float deltaTime); // Actualiza sprites que siguen rutas predefinidas - void renderPathSprites(); // Renderiza sprites animados por ruta - void freePathSprites(); // Libera memoria de sprites por ruta - void initPaths(); // Inicializa rutas predefinidas para animaciones + void renderPathSprites(); // Renderiza sprites animados por ruta + void freePathSprites(); // Libera memoria de sprites por ruta + void initPaths(); // Inicializa rutas predefinidas para animaciones // --- Creación de sprites especiales --- void createItemText(int x, const std::shared_ptr &texture); // Crea texto animado para ítems @@ -295,17 +295,17 @@ class Game { void updateDemo(); // Actualiza lógica específica del modo demo // --- Recursos y renderizado --- - void setResources(); // Asigna texturas y animaciones a los objetos + void setResources(); // Asigna texturas y animaciones a los objetos void updateBackground(float deltaTime); // Actualiza elementos del fondo (time-based) - void fillCanvas(); // Renderiza elementos del área de juego en su textura - void updateHelper(); // Actualiza variables auxiliares de renderizado + void fillCanvas(); // Renderiza elementos del área de juego en su textura + void updateHelper(); // Actualiza variables auxiliares de renderizado // --- Sistema de audio --- - static void playMusic(); // Reproduce la música de fondo - void stopMusic() const; // Detiene la reproducción de música - static void pauseMusic(); // Pausa la música - static void resumeMusic(); // Retoma la música que eestaba pausada - void playSound(const std::string &name) const; // Reproduce un efecto de sonido específico + static void playMusic(const std::string &music_file, int loop = -1); // Reproduce la música de fondo + void stopMusic() const; // Detiene la reproducción de música + static void pauseMusic(); // Pausa la música + static void resumeMusic(); // Retoma la música que eestaba pausada + void playSound(const std::string &name) const; // Reproduce un efecto de sonido específico void sendPlayerToTheBack(const std::shared_ptr &player); // Mueve el jugador para pintarlo al fondo de la lista de jugadores void sendPlayerToTheFront(const std::shared_ptr &player); // Mueve el jugador para pintarlo el primero de la lista de jugadores