corregit: bug en Audio::fadeOutMusic quan la musica no es reproduia en bucle
This commit is contained in:
58
TODO.md
58
TODO.md
@@ -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"
|
||||||
@@ -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_) {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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_; }
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user