corregit: bug en Audio::fadeOutMusic quan la musica no es reproduia en bucle

This commit is contained in:
2025-09-25 21:21:39 +02:00
parent abeaf47f96
commit 35f4bf690c
6 changed files with 118 additions and 26 deletions

58
TODO.md
View File

@@ -2,4 +2,60 @@
## Tareas pendientes ## Tareas pendientes
- [ ] Revisar todas las variables static de los métodos para ver si se resetean correctamente - [ ] Revisar todas las variables static de los métodos para ver si se resetean correctamente
## Mejoras arquitecturales (refactoring)
### Eliminar variables static locales y usar patrones profesionales:
**Opción 1: Máquina de Estados**
```cpp
class GameCompletedState {
bool start_celebrations_done = false;
bool end_celebrations_done = false;
float timer = 0.0f;
public:
void reset() {
start_celebrations_done = false;
end_celebrations_done = false;
timer = 0.0f;
}
void update(float deltaTime) {
timer += deltaTime;
// lógica aquí
}
};
```
**Opción 2: Sistema de Eventos/Callbacks**
```cpp
// Al entrar en COMPLETED state
eventSystem.scheduleEvent(6.0f, []{ startCelebrations(); });
eventSystem.scheduleEvent(14.0f, []{ endCelebrations(); });
```
**Opción 3: Flags como miembros privados**
```cpp
class Game {
private:
struct GameOverState {
bool game_over_triggered = false;
bool start_celebrations_triggered = false;
bool end_celebrations_triggered = false;
void reset() {
game_over_triggered = false;
start_celebrations_triggered = false;
end_celebrations_triggered = false;
}
} game_over_state_;
};
```
**Ventajas:**
- Más fáciles de testear
- Más fáciles de debugear
- Más fáciles de entender y mantener
- No tienen "estado oculto"

View File

@@ -100,13 +100,33 @@ void Audio::stopAllSounds() const {
// Realiza un fundido de salida de la música // Realiza un fundido de salida de la música
void Audio::fadeOutMusic(int milliseconds) const { void Audio::fadeOutMusic(int milliseconds) const {
if (music_enabled_ && music_.state == MusicState::PLAYING) { if (music_enabled_ && getRealMusicState() == MusicState::PLAYING) {
#ifndef NO_AUDIO #ifndef NO_AUDIO
JA_FadeOutMusic(milliseconds); JA_FadeOutMusic(milliseconds);
#endif #endif
} }
} }
// Consulta directamente el estado real de la música en jailaudio
auto Audio::getRealMusicState() const -> MusicState {
#ifndef NO_AUDIO
JA_Music_state ja_state = JA_GetMusicState();
switch (ja_state) {
case JA_MUSIC_PLAYING:
return MusicState::PLAYING;
case JA_MUSIC_PAUSED:
return MusicState::PAUSED;
case JA_MUSIC_STOPPED:
case JA_MUSIC_INVALID:
case JA_MUSIC_DISABLED:
default:
return MusicState::STOPPED;
}
#else
return MusicState::STOPPED;
#endif
}
// Establece el volumen de los sonidos // Establece el volumen de los sonidos
void Audio::setSoundVolume(int sound_volume, Group group) const { void Audio::setSoundVolume(int sound_volume, Group group) const {
if (sound_enabled_) { if (sound_enabled_) {

View File

@@ -13,6 +13,12 @@ class Audio {
INTERFACE = 1 // Sonidos de la interfaz INTERFACE = 1 // Sonidos de la interfaz
}; };
enum class MusicState {
PLAYING, // Reproduciendo música
PAUSED, // Música pausada
STOPPED, // Música detenida
};
// --- Constantes --- // --- Constantes ---
static constexpr int MAX_VOLUME = 100; // Volumen máximo static constexpr int MAX_VOLUME = 100; // Volumen máximo
static constexpr int MIN_VOLUME = 0; // Volumen mínimo static constexpr int MIN_VOLUME = 0; // Volumen mínimo
@@ -60,14 +66,15 @@ class Audio {
void setSoundVolume(int volume, Group group = Group::ALL) const; // Ajustar volumen de efectos void setSoundVolume(int volume, Group group = Group::ALL) const; // Ajustar volumen de efectos
void setMusicVolume(int volume) const; // Ajustar volumen de música void setMusicVolume(int volume) const; // Ajustar volumen de música
private: // --- Getters para debug ---
// --- Enums privados --- bool isEnabled() const { return enabled_; }
enum class MusicState { bool isSoundEnabled() const { return sound_enabled_; }
PLAYING, // Reproduciendo música bool isMusicEnabled() const { return music_enabled_; }
PAUSED, // Música pausada MusicState getMusicState() const { return music_.state; }
STOPPED, // Música detenida MusicState getRealMusicState() const; // Consulta directamente a jailaudio
}; const std::string& getCurrentMusicName() const { return music_.name; }
private:
// --- Estructuras privadas --- // --- Estructuras privadas ---
struct Music { struct Music {
MusicState state; // Estado actual de la música (reproduciendo, detenido, en pausa) MusicState state; // Estado actual de la música (reproduciendo, detenido, en pausa)

View File

@@ -37,19 +37,19 @@ class Fade {
~Fade(); ~Fade();
// --- Métodos principales --- // --- Métodos principales ---
void reset(); // Resetea variables para reutilizar el fade void reset(); // Resetea variables para reutilizar el fade
void render(); // Dibuja la transición en pantalla void render(); // Dibuja la transición en pantalla
void update(); // Actualiza el estado interno (ya usa tiempo real) void update(); // Actualiza el estado interno (ya usa tiempo real)
void update(float delta_time); // Compatibilidad delta-time (ignora el parámetro) void update(float delta_time); // Compatibilidad delta-time (ignora el parámetro)
void activate(); // Activa el fade void activate(); // Activa el fade
// --- Configuración --- // --- Configuración ---
void setColor(Uint8 r, Uint8 g, Uint8 b); // Establece el color RGB del fade void setColor(Uint8 r, Uint8 g, Uint8 b); // Establece el color RGB del fade
void setColor(Color color); // Establece el color del fade void setColor(Color color); // Establece el color del fade
void setType(Type type) { type_ = type; } // Establece el tipo de fade void setType(Type type) { type_ = type; } // Establece el tipo de fade
void setMode(Mode mode) { mode_ = mode; } // Establece el modo de fade void setMode(Mode mode) { mode_ = mode; } // Establece el modo de fade
void setPostDuration(int value) { post_duration_ = value; } // Duración posterior al fade en milisegundos void setPostDuration(int milliseconds) { post_duration_ = milliseconds; } // Duración posterior al fade en milisegundos
void setPreDuration(int value) { pre_duration_ = value; } // Duración previa al fade en milisegundos void setPreDuration(int milliseconds) { pre_duration_ = milliseconds; } // Duración previa al fade en milisegundos
// --- Getters --- // --- Getters ---
[[nodiscard]] auto getValue() const -> int { return value_; } [[nodiscard]] auto getValue() const -> int { return value_; }

View File

@@ -49,13 +49,13 @@ Credits::Credits()
fade_in_->setColor(param.fade.color); fade_in_->setColor(param.fade.color);
fade_in_->setType(Fade::Type::FULLSCREEN); fade_in_->setType(Fade::Type::FULLSCREEN);
fade_in_->setPostDuration(static_cast<int>(50 * (1000.0f / 60.0f))); // 50 frames = ~833ms fade_in_->setPostDuration(800);
fade_in_->setMode(Fade::Mode::IN); fade_in_->setMode(Fade::Mode::IN);
fade_in_->activate(); fade_in_->activate();
fade_out_->setColor(0, 0, 0); fade_out_->setColor(0, 0, 0);
fade_out_->setType(Fade::Type::FULLSCREEN); fade_out_->setType(Fade::Type::FULLSCREEN);
fade_out_->setPostDuration(static_cast<int>(400 * (1000.0f / 60.0f))); // 400 frames = ~6667ms fade_out_->setPostDuration(7000);
updateRedRect(); updateRedRect();
tiled_bg_->setColor(Color(255, 96, 96)); tiled_bg_->setColor(Color(255, 96, 96));
@@ -487,12 +487,12 @@ void Credits::updateAllFades(float deltaTime) {
updateRedRect(); updateRedRect();
} }
fade_in_->update(); // Fade ya usa tiempo interno fade_in_->update();
if (fade_in_->hasEnded()) { if (fade_in_->hasEnded() && Audio::get()->getMusicState() != Audio::MusicState::PLAYING) {
Audio::get()->playMusic("credits.ogg"); Audio::get()->playMusic("credits.ogg");
} }
fade_out_->update(); // Fade ya usa tiempo interno fade_out_->update();
if (fade_out_->hasEnded()) { if (fade_out_->hasEnded()) {
Section::name = Section::Name::HI_SCORE_TABLE; Section::name = Section::Name::HI_SCORE_TABLE;
} }

View File

@@ -117,8 +117,11 @@ Game::~Game() {
auto manager = std::make_unique<ManageHiScoreTable>(Options::settings.hi_score_table); auto manager = std::make_unique<ManageHiScoreTable>(Options::settings.hi_score_table);
manager->saveToFile(Asset::get()->get("score.bin")); manager->saveToFile(Asset::get()->get("score.bin"));
Section::attract_mode = Section::AttractMode::TITLE_TO_DEMO; Section::attract_mode = Section::AttractMode::TITLE_TO_DEMO;
Audio::get()->stopMusic();
if (Options::audio.enabled) { if (Options::audio.enabled) {
// Musica
Audio::get()->stopMusic();
Audio::get()->setMusicVolume(Options::audio.music.volume);
// Sonidos
Audio::get()->stopAllSounds(); Audio::get()->stopAllSounds();
Audio::get()->setSoundVolume(Options::audio.sound.volume, Audio::Group::GAME); Audio::get()->setSoundVolume(Options::audio.sound.volume, Audio::Group::GAME);
} }
@@ -1977,6 +1980,12 @@ void Game::handleGameCompletedEvents() {
// Maneja eventos de game over usando flag para trigger único // Maneja eventos de game over usando flag para trigger único
void Game::handleGameOverEvents() { void Game::handleGameOverEvents() {
static bool game_over_triggered = false; static bool game_over_triggered = false;
// Resetear
if (game_over_timer_ == 0.0f) {
game_over_triggered = false;
}
if (!game_over_triggered && game_over_timer_ == 0.0f) { if (!game_over_triggered && game_over_timer_ == 0.0f) {
createMessage({paths_.at(2), paths_.at(3)}, Resource::get()->getTexture("game_text_game_over")); createMessage({paths_.at(2), paths_.at(3)}, Resource::get()->getTexture("game_text_game_over"));
Audio::get()->fadeOutMusic(1000); Audio::get()->fadeOutMusic(1000);