diff --git a/TODO.md b/TODO.md index e5864ab..48c408a 100644 --- a/TODO.md +++ b/TODO.md @@ -2,4 +2,60 @@ ## Tareas pendientes -- [ ] Revisar todas las variables static de los métodos para ver si se resetean correctamente \ No newline at end of file +- [ ] 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" \ No newline at end of file diff --git a/source/audio.cpp b/source/audio.cpp index 3fde5f4..783e0a2 100644 --- a/source/audio.cpp +++ b/source/audio.cpp @@ -100,13 +100,33 @@ void Audio::stopAllSounds() const { // Realiza un fundido de salida de la música void Audio::fadeOutMusic(int milliseconds) const { - if (music_enabled_ && music_.state == MusicState::PLAYING) { + if (music_enabled_ && getRealMusicState() == MusicState::PLAYING) { #ifndef NO_AUDIO JA_FadeOutMusic(milliseconds); #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 void Audio::setSoundVolume(int sound_volume, Group group) const { if (sound_enabled_) { diff --git a/source/audio.h b/source/audio.h index 213ef16..996ee97 100644 --- a/source/audio.h +++ b/source/audio.h @@ -13,6 +13,12 @@ class Audio { INTERFACE = 1 // Sonidos de la interfaz }; + enum class MusicState { + PLAYING, // Reproduciendo música + PAUSED, // Música pausada + STOPPED, // Música detenida + }; + // --- Constantes --- static constexpr int MAX_VOLUME = 100; // Volumen máximo 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 setMusicVolume(int volume) const; // Ajustar volumen de música - private: - // --- Enums privados --- - enum class MusicState { - PLAYING, // Reproduciendo música - PAUSED, // Música pausada - STOPPED, // Música detenida - }; + // --- Getters para debug --- + bool isEnabled() const { return enabled_; } + bool isSoundEnabled() const { return sound_enabled_; } + bool isMusicEnabled() const { return music_enabled_; } + MusicState getMusicState() const { return music_.state; } + MusicState getRealMusicState() const; // Consulta directamente a jailaudio + const std::string& getCurrentMusicName() const { return music_.name; } + private: // --- Estructuras privadas --- struct Music { MusicState state; // Estado actual de la música (reproduciendo, detenido, en pausa) diff --git a/source/fade.h b/source/fade.h index 3bb6da7..4981c66 100644 --- a/source/fade.h +++ b/source/fade.h @@ -37,19 +37,19 @@ class Fade { ~Fade(); // --- Métodos principales --- - void reset(); // Resetea variables para reutilizar el fade - void render(); // Dibuja la transición en pantalla - void update(); // Actualiza el estado interno (ya usa tiempo real) - void update(float delta_time); // Compatibilidad delta-time (ignora el parámetro) - void activate(); // Activa el fade + void reset(); // Resetea variables para reutilizar el fade + void render(); // Dibuja la transición en pantalla + void update(); // Actualiza el estado interno (ya usa tiempo real) + void update(float delta_time); // Compatibilidad delta-time (ignora el parámetro) + void activate(); // Activa el fade // --- Configuración --- - void setColor(Uint8 r, Uint8 g, Uint8 b); // Establece el color RGB del fade - void setColor(Color color); // Establece el color del fade - void setType(Type type) { type_ = type; } // Establece el tipo 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 setPreDuration(int value) { pre_duration_ = value; } // Duración previa al fade en milisegundos + void setColor(Uint8 r, Uint8 g, Uint8 b); // Establece el color RGB del fade + void setColor(Color color); // Establece el color del fade + void setType(Type type) { type_ = type; } // Establece el tipo de fade + void setMode(Mode mode) { mode_ = mode; } // Establece el modo de fade + void setPostDuration(int milliseconds) { post_duration_ = milliseconds; } // Duración posterior al fade en milisegundos + void setPreDuration(int milliseconds) { pre_duration_ = milliseconds; } // Duración previa al fade en milisegundos // --- Getters --- [[nodiscard]] auto getValue() const -> int { return value_; } diff --git a/source/sections/credits.cpp b/source/sections/credits.cpp index 0c8417b..e9b0c3a 100644 --- a/source/sections/credits.cpp +++ b/source/sections/credits.cpp @@ -49,13 +49,13 @@ Credits::Credits() fade_in_->setColor(param.fade.color); fade_in_->setType(Fade::Type::FULLSCREEN); - fade_in_->setPostDuration(static_cast(50 * (1000.0f / 60.0f))); // 50 frames = ~833ms + fade_in_->setPostDuration(800); fade_in_->setMode(Fade::Mode::IN); fade_in_->activate(); fade_out_->setColor(0, 0, 0); fade_out_->setType(Fade::Type::FULLSCREEN); - fade_out_->setPostDuration(static_cast(400 * (1000.0f / 60.0f))); // 400 frames = ~6667ms + fade_out_->setPostDuration(7000); updateRedRect(); tiled_bg_->setColor(Color(255, 96, 96)); @@ -487,12 +487,12 @@ void Credits::updateAllFades(float deltaTime) { updateRedRect(); } - fade_in_->update(); // Fade ya usa tiempo interno - if (fade_in_->hasEnded()) { + fade_in_->update(); + if (fade_in_->hasEnded() && Audio::get()->getMusicState() != Audio::MusicState::PLAYING) { Audio::get()->playMusic("credits.ogg"); } - fade_out_->update(); // Fade ya usa tiempo interno + fade_out_->update(); if (fade_out_->hasEnded()) { Section::name = Section::Name::HI_SCORE_TABLE; } diff --git a/source/sections/game.cpp b/source/sections/game.cpp index 98a61c9..e8617f6 100644 --- a/source/sections/game.cpp +++ b/source/sections/game.cpp @@ -117,8 +117,11 @@ Game::~Game() { auto manager = std::make_unique(Options::settings.hi_score_table); manager->saveToFile(Asset::get()->get("score.bin")); Section::attract_mode = Section::AttractMode::TITLE_TO_DEMO; - Audio::get()->stopMusic(); if (Options::audio.enabled) { + // Musica + Audio::get()->stopMusic(); + Audio::get()->setMusicVolume(Options::audio.music.volume); + // Sonidos Audio::get()->stopAllSounds(); 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 void Game::handleGameOverEvents() { 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) { createMessage({paths_.at(2), paths_.at(3)}, Resource::get()->getTexture("game_text_game_over")); Audio::get()->fadeOutMusic(1000);