From f661da5215cf84b6cf500cc1e334649e84e97923 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Fri, 30 May 2025 10:17:41 +0200 Subject: [PATCH] tots els singletons tornats a fer a la vieja y gorda usanza --- source/asset.cpp | 24 ++---- source/asset.h | 46 +++++------- source/audio.cpp | 17 ++++- source/audio.h | 30 ++++---- source/balloon.cpp | 2 +- source/balloon_manager.cpp | 2 +- source/credits.cpp | 10 +-- source/credits.h | 53 +++++++------- source/director.cpp | 30 +++++--- source/game.cpp | 62 ++++++++-------- source/game_logo.cpp | 4 +- source/global_inputs.cpp | 4 +- source/hiscore_table.cpp | 2 +- source/input.cpp | 25 ++----- source/input.h | 98 +++++++++---------------- source/instructions.cpp | 2 +- source/intro.cpp | 4 +- source/logo.cpp | 6 +- source/notifier.cpp | 27 +++---- source/notifier.h | 146 +++++++++++++++++-------------------- source/player.cpp | 8 +- source/resource.cpp | 30 +++----- source/resource.h | 2 +- source/screen.cpp | 16 ++-- source/screen.h | 2 +- source/service_menu.cpp | 13 ++++ source/service_menu.h | 24 +++--- source/tabe.cpp | 2 +- source/title.cpp | 10 +-- 29 files changed, 322 insertions(+), 379 deletions(-) diff --git a/source/asset.cpp b/source/asset.cpp index ae76b9f..cd3f5e6 100644 --- a/source/asset.cpp +++ b/source/asset.cpp @@ -5,27 +5,17 @@ #include // Para allocator, string, char_traits, operator+ #include "utils.h" // Para getFileName -// Instancia estática del singleton -std::unique_ptr Asset::instance_ = nullptr; +// Singleton +Asset *Asset::instance_ = nullptr; // Inicializa la instancia única del singleton -void Asset::init(const std::string &executable_path) -{ - if (!instance_) - instance_ = std::unique_ptr(new Asset(executable_path)); -} +void Asset::init(const std::string &executable_path) { Asset::instance_ = new Asset(executable_path); } -// Libera la instancia única -void Asset::destroy() -{ - instance_.reset(); -} +// Libera la instancia +void Asset::destroy() { delete Asset::instance_; } -// Obtiene la instancia única -Asset *Asset::get() -{ - return instance_.get(); -} + // Obtiene la instancia +Asset *Asset::get() { return Asset::instance_; } // Añade un elemento a la lista void Asset::add(const std::string &file, AssetType type, bool required, bool absolute) diff --git a/source/asset.h b/source/asset.h index 1f38a7e..ecc299a 100644 --- a/source/asset.h +++ b/source/asset.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "utils.h" // Tipos de recursos gestionados por Asset @@ -24,31 +25,19 @@ enum class AssetType : int class Asset { public: - // Inicializa la instancia única del singleton - static void init(const std::string &executable_path); + // --- Métodos de singleton --- + static void init(const std::string &executable_path); // Inicializa el objeto Asset + static void destroy(); // Libera el objeto Asset + static Asset *get(); // Obtiene el puntero al objeto Asset - // Libera la instancia única - static void destroy(); - - // Obtiene la instancia única - static Asset *get(); - - // Añade un recurso a la lista - void add(const std::string &file, AssetType type, bool required = true, bool absolute = false); - - // Obtiene la ruta completa de un recurso a partir de su nombre - std::string get(const std::string &text) const; - - // Verifica la existencia de todos los recursos requeridos - bool check() const; - - // Devuelve una lista de archivos de un tipo concreto - std::vector getListByType(AssetType type) const; + // --- Métodos para la gestión de recursos --- + void add(const std::string &file, AssetType type, bool required = true, bool absolute = false); // Añade un recurso a la lista + std::string get(const std::string &text) const; // Obtiene la ruta completa de un recurso a partir de su nombre + bool check() const; // Verifica la existencia de todos los recursos requeridos + std::vector getListByType(AssetType type) const; // Devuelve una lista de archivos de un tipo concreto private: - friend std::unique_ptr::deleter_type; - - // Estructura interna para almacenar información de cada recurso + // --- Estructura interna para almacenar información de cada recurso --- struct AssetItem { std::string file; // Ruta del fichero desde la raíz del directorio @@ -59,21 +48,22 @@ private: : file(filePath), type(assetType), required(isRequired) {} }; - // Variables internas + // --- Variables internas --- int longest_name_ = 0; // Longitud del nombre más largo std::vector file_list_; // Lista con todas las rutas de recursos std::string executable_path_; // Ruta del ejecutable - // Métodos internos + // --- Métodos internos --- bool checkFile(const std::string &path) const; // Verifica si un archivo existe std::string getTypeName(AssetType type) const; // Devuelve el nombre textual del tipo de recurso - // Patrón Singleton: constructor y destructor privados, sin copia ni asignación - Asset(const std::string &executable_path) - : executable_path_(executable_path) {}; + // --- Patrón Singleton --- + explicit Asset(const std::string &executable_path) + : executable_path_(executable_path) {} ~Asset() = default; Asset(const Asset &) = delete; Asset &operator=(const Asset &) = delete; - static std::unique_ptr instance_; + // --- Singleton --- + static Asset *instance_; }; \ No newline at end of file diff --git a/source/audio.cpp b/source/audio.cpp index 3b462ba..376a16a 100644 --- a/source/audio.cpp +++ b/source/audio.cpp @@ -4,6 +4,18 @@ #include "resource.h" #include +// Singleton +Audio *Audio::instance_ = nullptr; + +// Inicializa la instancia única del singleton +void Audio::init() { Audio::instance_ = new Audio(); } + +// Libera la instancia +void Audio::destroy() { delete Audio::instance_; } + +// Obtiene la instancia +Audio *Audio::get() { return Audio::instance_; } + // Constructor Audio::Audio() { @@ -26,10 +38,7 @@ Audio::Audio() } // Destructor -Audio::~Audio() -{ - JA_Quit(); -} +Audio::~Audio() { JA_Quit(); } // Reproduce la música void Audio::playMusic(const std::string &name, const int loop) diff --git a/source/audio.h b/source/audio.h index c9b9675..7caa6db 100644 --- a/source/audio.h +++ b/source/audio.h @@ -6,55 +6,55 @@ class Audio { public: - // === Singleton === - // Obtención de la instancia única (Meyers Singleton) - static Audio &get() - { - static Audio instance; - return instance; - } + // --- Métodos de singleton --- + static void init(); // Inicializa el objeto Audio + static void destroy(); // Libera el objeto Audio + static Audio *get(); // Obtiene el puntero al objeto Audio - // === Control de Música === + // --- Control de Música --- void playMusic(const std::string &name, int loop = -1); // Reproducir música en bucle void pauseMusic(); // Pausar reproducción de música void stopMusic(); // Detener completamente la música void fadeOutMusic(int milliseconds); // Fundido de salida de la música - // === Control de Sonidos === + // --- Control de Sonidos --- void playSound(const std::string &name); // Reproducir sonido puntual void stopAllSounds(); // Detener todos los sonidos - // === Configuración General === + // --- Configuración General --- void enable() { enabled_ = true; } // Habilitar audio void disable() { enabled_ = false; } // Deshabilitar audio void enable(bool value) { enabled_ = value; } // Establecer estado general void toggleEnabled() { enabled_ = !enabled_; } // Alternar estado general - // === Configuración de Sonidos === + // --- Configuración de Sonidos --- void enableSound() { sound_enabled_ = true; } // Habilitar sonidos void disableSound() { sound_enabled_ = false; } // Deshabilitar sonidos void enableSound(bool value) { sound_enabled_ = value; } // Establecer estado de sonidos void toggleSound() { sound_enabled_ = !sound_enabled_; } // Alternar estado de sonidos - // === Configuración de Música === + // --- Configuración de Música --- void enableMusic() { music_enabled_ = true; } // Habilitar música void disableMusic() { music_enabled_ = false; } // Deshabilitar música void enableMusic(bool value) { music_enabled_ = value; } // Establecer estado de música void toggleMusic() { music_enabled_ = !music_enabled_; } // Alternar estado de música - // === Control de Volumen === + // --- Control de Volumen --- void setSoundVolume(int volume); // Ajustar volumen de efectos void setMusicVolume(int volume); // Ajustar volumen de música private: - // === Variables de Estado === + // --- Variables de Estado --- bool enabled_ = true; // Estado general del audio bool sound_enabled_ = true; // Estado de los efectos de sonido bool music_enabled_ = true; // Estado de la música - // === Patrón Singleton === + // --- Patrón Singleton --- Audio(); // Constructor privado ~Audio(); // Destructor privado Audio(const Audio &) = delete; // Evitar copia Audio &operator=(const Audio &) = delete; // Evitar asignación + + // --- Singleton --- + static Audio *instance_; }; \ No newline at end of file diff --git a/source/balloon.cpp b/source/balloon.cpp index 6a2b49b..12e98b0 100644 --- a/source/balloon.cpp +++ b/source/balloon.cpp @@ -414,6 +414,6 @@ void Balloon::playSound() { if (sound_enabled_) { - Audio::get().playSound(sound_); + Audio::get()->playSound(sound_); } } \ No newline at end of file diff --git a/source/balloon_manager.cpp b/source/balloon_manager.cpp index 185e4c3..889d306 100644 --- a/source/balloon_manager.cpp +++ b/source/balloon_manager.cpp @@ -320,7 +320,7 @@ int BalloonManager::destroyAllBalloons() } balloon_deploy_counter_ = 300; - Audio::get().playSound("power_ball_explosion.wav"); + Audio::get()->playSound("power_ball_explosion.wav"); Screen::get()->flash(FLASH_COLOR, 3); Screen::get()->shake(); diff --git a/source/credits.cpp b/source/credits.cpp index f20f231..1f4cb57 100644 --- a/source/credits.cpp +++ b/source/credits.cpp @@ -71,7 +71,7 @@ Credits::~Credits() SDL_DestroyTexture(text_texture_); SDL_DestroyTexture(canvas_); resetVolume(); - Audio::get().stopMusic(); + Audio::get()->stopMusic(); } // Bucle principal @@ -437,7 +437,7 @@ void Credits::updateBlackRects() { // Si los rectangulos izquierdo y derecho han llegado al centro setVolume(0); - Audio::get().stopMusic(); + Audio::get()->stopMusic(); if (counter_pre_fade_ == 400) { fade_out_->activate(); @@ -471,7 +471,7 @@ void Credits::updateAllFades() fade_in_->update(); if (fade_in_->hasEnded()) { - Audio::get().playMusic("credits.ogg"); + Audio::get()->playMusic("credits.ogg"); } fade_out_->update(); @@ -485,14 +485,14 @@ void Credits::updateAllFades() void Credits::setVolume(int amount) { options.audio.music.volume = std::clamp(amount, 0, 100); - Audio::get().setMusicVolume(options.audio.music.volume); + Audio::get()->setMusicVolume(options.audio.music.volume); } // Reestablece el nivel de volumen void Credits::resetVolume() { options.audio.music.volume = initial_volume_; - Audio::get().setMusicVolume(options.audio.music.volume); + Audio::get()->setMusicVolume(options.audio.music.volume); } // Cambia el color del fondo diff --git a/source/credits.h b/source/credits.h index 25ea4a5..4724323 100644 --- a/source/credits.h +++ b/source/credits.h @@ -16,48 +16,51 @@ class Fade; class Player; class TiledBG; -constexpr int PLAY_AREA_HEIGHT = 200; - class Credits { public: + // --- Constructores y destructor --- Credits(); ~Credits(); - void run(); // Bucle principal + // --- Bucle principal --- + void run(); private: - // === Objetos Principales === + // --- Constantes de clase --- + static constexpr int PLAY_AREA_HEIGHT = 200; + + // --- Objetos principales --- std::unique_ptr balloon_manager_; // Gestión de globos std::unique_ptr tiled_bg_; // Mosaico animado de fondo std::unique_ptr fade_in_; // Fundido de entrada std::unique_ptr fade_out_; // Fundido de salida std::vector> players_; // Vector de jugadores - // === Gestión de Texturas === - SDL_Texture *text_texture_; // Textura con el texto - SDL_Texture *canvas_; // Textura donde dibujarlo todo + // --- Gestión de texturas --- + SDL_Texture *text_texture_; // Textura con el texto de créditos + SDL_Texture *canvas_; // Textura donde se dibuja todo - // === Temporización y Contadores === + // --- Temporización y contadores --- Uint64 ticks_ = 0; // Control de velocidad del programa Uint32 counter_ = 0; // Contador principal de lógica Uint32 counter_pre_fade_ = 0; // Activación del fundido final Uint32 counter_prevent_endless_ = 0; // Prevención de bucle infinito - // === Variables de Estado === + // --- Variables de estado --- bool fading_ = false; // Estado del fade final bool want_to_pass_ = false; // Jugador quiere saltarse créditos bool mini_logo_on_position_ = false; // Minilogo en posición final - // === Diseño y Posicionamiento === - float black_bars_size_ = (param.game.game_area.rect.h - PLAY_AREA_HEIGHT) / 2; - int mini_logo_final_pos_ = 0; // Posición final del minilogo + // --- Diseño y posicionamiento --- + float black_bars_size_ = (param.game.game_area.rect.h - PLAY_AREA_HEIGHT) / 2; // Tamaño de las barras negras + int mini_logo_final_pos_ = 0; // Posición final del minilogo - // === Control de Audio === + // --- Control de audio --- int initial_volume_ = options.audio.music.volume; // Volumen inicial int steps_ = 0; // Pasos para reducir audio - // === Rectángulos de Renderizado === + // --- Rectángulos de renderizado --- // Texto de créditos SDL_FRect credits_rect_src_ = param.game.game_area.rect; SDL_FRect credits_rect_dst_ = param.game.game_area.rect; @@ -98,28 +101,28 @@ private: // Borde para la ventana SDL_FRect red_rect = play_area_; // Delimitador de ventana - // === Métodos del Bucle Principal === - void update(); // Actualización principal - void render(); // Renderizado + // --- Métodos del bucle principal --- + void update(); // Actualización principal de la lógica + void render(); // Renderizado de la escena void checkEvents(); // Manejo de eventos void checkInput(); // Procesamiento de entrada - // === Métodos de Renderizado === - void fillTextTexture(); // Crear textura de texto - void fillCanvas(); // Renderizar todos los sprites + // --- Métodos de renderizado --- + void fillTextTexture(); // Crear textura de texto de créditos + void fillCanvas(); // Renderizar todos los sprites y fondos void updateTextureDstRects(); // Actualizar destinos de texturas - // === Métodos de Lógica del Juego === + // --- Métodos de lógica del juego --- void throwBalloons(); // Lanzar globos al escenario void initPlayers(); // Inicializar jugadores void updateAllFades(); // Actualizar estados de fade void cycleColors(); // Cambiar colores de fondo - // === Métodos de Interfaz === - void updateBlackRects(); // Actualizar rectángulos negros - void updateRedRect(); // Actualizar rectángulo rojo + // --- Métodos de interfaz --- + void updateBlackRects(); // Actualizar rectángulos negros (letterbox) + void updateRedRect(); // Actualizar rectángulo rojo (borde) - // === Métodos de Audio === + // --- Métodos de audio --- void setVolume(int amount); // Establecer volumen void resetVolume(); // Restablecer volumen }; \ No newline at end of file diff --git a/source/director.cpp b/source/director.cpp index e96d098..52a463f 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -34,6 +34,7 @@ #include "resource.h" // Para Resource #include "screen.h" // Para Screen #include "section.h" // Para Name, Options, name, options +#include "service_menu.h" // Para ServiceMenu #include "title.h" // Para Title #include "utils.h" // Para Overrides, overrides @@ -91,13 +92,14 @@ void Director::init() loadParams(); // Carga los parámetros del programa loadScoreFile(); // Carga el archivo de puntuaciones - // Inicialización de subsistemas + // Inicialización de subsistemas principales lang::loadFromFile(getLangFile(static_cast(options.game.language))); // Carga el archivo de idioma Screen::init(); // Inicializa la pantalla y el sistema de renderizado - Audio::get(); // Activa el sistema de audio + Audio::init(); // Activa el sistema de audio Resource::init(); // Inicializa el sistema de gestión de recursos Input::init(Asset::get()->get("gamecontrollerdb.txt")); // Carga configuración de controles bindInputs(); // Asigna los controles a la entrada del sistema + ServiceMenu::init(); // Inicializa el menú de servicio // Inicialización del sistema de notificaciones Notifier::init(std::string(), Resource::get()->getText("8bithud")); @@ -109,20 +111,26 @@ void Director::init() #endif } -// Cierra todo +// Cierra todo y libera recursos del sistema y de los singletons void Director::close() { + // Guarda las opciones actuales en el archivo de configuración saveOptionsFile(Asset::get()->get("config.txt")); - Notifier::destroy(); - Input::destroy(); - Resource::destroy(); - Screen::destroy(); - Asset::destroy(); + // Libera los singletons y recursos en orden inverso al de inicialización + Notifier::destroy(); // Libera el sistema de notificaciones + ServiceMenu::destroy(); // Libera el sistema de menú de servicio + Input::destroy(); // Libera el sistema de entrada + Resource::destroy(); // Libera el sistema de recursos gráficos y de texto + Audio::destroy(); // Libera el sistema de audio + Screen::destroy(); // Libera el sistema de pantalla y renderizado + Asset::destroy(); // Libera el gestor de archivos + // Libera todos los recursos de SDL SDL_Quit(); #ifdef ARCADE + // Si está en modo arcade, apaga el sistema si corresponde shutdownSystem(section::options == section::Options::QUIT_WITH_CONTROLLER); #endif } @@ -460,7 +468,7 @@ void Director::setFileList() void Director::checkProgramArguments(int argc, const char *argv[]) { // Establece la ruta del programa - executable_path_ = argv[0]; + executable_path_ = getPath(argv[0]); // Comprueba el resto de parámetros for (int i = 1; i < argc; ++i) @@ -605,8 +613,8 @@ void Director::runDemoGame() // Ejecuta la sección init void Director::runInit() { - Audio::get().stopMusic(); - Audio::get().stopAllSounds(); + Audio::get()->stopMusic(); + Audio::get()->stopAllSounds(); if (section::options == section::Options::RELOAD || true) { Resource::get()->reload(); diff --git a/source/game.cpp b/source/game.cpp index 319046c..0d768dc 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -101,7 +101,7 @@ Game::~Game() // [Modo DEMO] Vuelve a activar los sonidos if (demo_.enabled) { - Audio::get().enableSound(); + Audio::get()->enableSound(); } else { @@ -109,7 +109,7 @@ Game::~Game() auto manager = std::make_unique(options.game.hi_score_table); manager->saveToFile(Asset::get()->get("score.bin")); section::attract_mode = section::AttractMode::TITLE_TO_DEMO; - Audio::get().stopMusic(); + Audio::get()->stopMusic(); } #ifdef RECORDING @@ -201,7 +201,7 @@ void Game::updateHiScore() if (hi_score_achieved_ == false) { hi_score_achieved_ = true; - Audio::get().playSound("hi_score_achieved.wav"); + Audio::get()->playSound("hi_score_achieved.wav"); } } } @@ -259,7 +259,7 @@ void Game::updateStage() // Cambio de fase Stage::power = Stage::get(Stage::number).power_to_complete - Stage::power; ++Stage::number; - Audio::get().playSound("stage_change.wav"); + Audio::get()->playSound("stage_change.wav"); balloon_manager_->resetBalloonSpeed(); screen_->flash(FLASH_COLOR, 3); screen_->shake(); @@ -311,7 +311,7 @@ void Game::updateGameStateGameOver() if (game_over_counter_ == GAME_OVER_COUNTER_) { createMessage({paths_.at(2), paths_.at(3)}, Resource::get()->getTexture("game_text_game_over")); - Audio::get().fadeOutMusic(1000); + Audio::get()->fadeOutMusic(1000); balloon_manager_->setSounds(true); } @@ -328,7 +328,7 @@ void Game::updateGameStateGameOver() if (options.audio.enabled) { const float VOL = static_cast(64 * (100 - fade_out_->getValue())) / 100.0f; - Audio::get().setSoundVolume(static_cast(VOL)); + Audio::get()->setSoundVolume(static_cast(VOL)); } } @@ -347,8 +347,8 @@ void Game::updateGameStateGameOver() section::options = section::Options::HI_SCORE_AFTER_PLAYING; if (options.audio.enabled) { - Audio::get().stopAllSounds(); - Audio::get().setSoundVolume(options.audio.sound.volume); + Audio::get()->stopAllSounds(); + Audio::get()->setSoundVolume(options.audio.sound.volume); } } } @@ -481,7 +481,7 @@ void Game::checkPlayerItemCollision(std::shared_ptr &player) player->addScore(1000); const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(0)->getWidth()) / 2; createItemText(x, game_text_textures_.at(0)); - Audio::get().playSound("item_pickup.wav"); + Audio::get()->playSound("item_pickup.wav"); break; } case ItemType::GAVINA: @@ -489,7 +489,7 @@ void Game::checkPlayerItemCollision(std::shared_ptr &player) player->addScore(2500); const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(1)->getWidth()) / 2; createItemText(x, game_text_textures_.at(1)); - Audio::get().playSound("item_pickup.wav"); + Audio::get()->playSound("item_pickup.wav"); break; } case ItemType::PACMAR: @@ -497,7 +497,7 @@ void Game::checkPlayerItemCollision(std::shared_ptr &player) player->addScore(5000); const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(2)->getWidth()) / 2; createItemText(x, game_text_textures_.at(2)); - Audio::get().playSound("item_pickup.wav"); + Audio::get()->playSound("item_pickup.wav"); break; } case ItemType::DEBIAN: @@ -505,7 +505,7 @@ void Game::checkPlayerItemCollision(std::shared_ptr &player) player->addScore(100000); const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(6)->getWidth()) / 2; createItemText(x, game_text_textures_.at(6)); - Audio::get().playSound("debian_pickup.wav"); + Audio::get()->playSound("debian_pickup.wav"); break; } case ItemType::CLOCK: @@ -513,7 +513,7 @@ void Game::checkPlayerItemCollision(std::shared_ptr &player) enableTimeStopItem(); const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(5)->getWidth()) / 2; createItemText(x, game_text_textures_.at(5)); - Audio::get().playSound("item_pickup.wav"); + Audio::get()->playSound("item_pickup.wav"); break; } case ItemType::COFFEE: @@ -530,7 +530,7 @@ void Game::checkPlayerItemCollision(std::shared_ptr &player) const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(4)->getWidth()) / 2; createItemText(x, game_text_textures_.at(4)); } - Audio::get().playSound("voice_coffee.wav"); + Audio::get()->playSound("voice_coffee.wav"); break; } case ItemType::COFFEE_MACHINE: @@ -539,7 +539,7 @@ void Game::checkPlayerItemCollision(std::shared_ptr &player) coffee_machine_enabled_ = false; const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(3)->getWidth()) / 2; createItemText(x, game_text_textures_.at(3)); - Audio::get().playSound("voice_power_up.wav"); + Audio::get()->playSound("voice_power_up.wav"); break; } default: @@ -568,7 +568,7 @@ void Game::checkBulletCollision() if (tabe_->tryToGetBonus()) { createItem(ItemType::DEBIAN, pos.x, pos.y); - Audio::get().playSound("debian_drop.wav"); + Audio::get()->playSound("debian_drop.wav"); } else { @@ -576,7 +576,7 @@ void Game::checkBulletCollision() { createItem(ItemType::COFFEE, pos.x, pos.y); } - Audio::get().playSound("tabe_hit.wav"); + Audio::get()->playSound("tabe_hit.wav"); } break; } @@ -598,7 +598,7 @@ void Game::checkBulletCollision() if (dropped_item != ItemType::COFFEE_MACHINE) { createItem(dropped_item, balloon->getPosX(), balloon->getPosY()); - Audio::get().playSound("item_drop.wav"); + Audio::get()->playSound("item_drop.wav"); } else { @@ -620,7 +620,7 @@ void Game::checkBulletCollision() updateHiScore(); // Sonido de explosión - Audio::get().playSound("balloon.wav"); + Audio::get()->playSound("balloon.wav"); // Deshabilita la bala bullet->disable(); @@ -676,7 +676,7 @@ void Game::updateItems() item->update(); if (item->isOnFloor()) { - Audio::get().playSound("title.wav"); + Audio::get()->playSound("title.wav"); screen_->shake(); } } @@ -903,16 +903,16 @@ void Game::killPlayer(std::shared_ptr &player) // Lo pierde player->removeExtraHit(); throwCoffee(player->getPosX() + (player->getWidth() / 2), player->getPosY() + (player->getHeight() / 2)); - Audio::get().playSound("coffee_out.wav"); + Audio::get()->playSound("coffee_out.wav"); screen_->shake(); } else { // Si no tiene cafes, muere balloon_manager_->stopAllBalloons(); - Audio::get().playSound("player_collision.wav"); + Audio::get()->playSound("player_collision.wav"); screen_->shake(); - Audio::get().playSound("voice_no.wav"); + Audio::get()->playSound("voice_no.wav"); player->setPlayingState(PlayerState::DYING); if (allPlayersAreNotPlaying()) { @@ -932,7 +932,7 @@ void Game::updateTimeStopped() { if (time_stopped_counter_ % 30 == 0) { - Audio::get().playSound("clock.wav"); + Audio::get()->playSound("clock.wav"); } } else @@ -940,12 +940,12 @@ void Game::updateTimeStopped() if (time_stopped_counter_ % 30 == 0) { balloon_manager_->normalColorsToAllBalloons(); - Audio::get().playSound("clock.wav"); + Audio::get()->playSound("clock.wav"); } else if (time_stopped_counter_ % 30 == 15) { balloon_manager_->reverseColorsToAllBalloons(); - Audio::get().playSound("clock.wav"); + Audio::get()->playSound("clock.wav"); } } } @@ -1427,7 +1427,7 @@ void Game::handleFireInput(const std::shared_ptr &player, BulletType bul player->setInput(bulletType == BulletType::UP ? InputAction::FIRE_CENTER : bulletType == BulletType::LEFT ? InputAction::FIRE_LEFT : InputAction::FIRE_RIGHT); createBullet(player->getPosX() + (player->getWidth() / 2) - 6, player->getPosY() + (player->getHeight() / 2), bulletType, player->isPowerUp(), player->getId()); - Audio::get().playSound("bullet.wav"); + Audio::get()->playSound("bullet.wav"); // Establece un tiempo de espera para el próximo disparo. const int cooldown = player->isPowerUp() ? 5 : options.game.autofire ? 10 @@ -1629,7 +1629,7 @@ void Game::initDemo(int player_id) } // Deshabilita los sonidos - Audio::get().disableSound(); + Audio::get()->disableSound(); // Configura los marcadores scoreboard_->setMode(SCOREBOARD_LEFT_PANEL, ScoreboardMode::DEMO); @@ -1731,7 +1731,7 @@ void Game::initPlayers(int player_id) // Hace sonar la música void Game::playMusic() { - Audio::get().playMusic("playing.ogg"); + Audio::get()->playMusic("playing.ogg"); } // Detiene la música @@ -1739,7 +1739,7 @@ void Game::stopMusic() { if (!demo_.enabled) { - Audio::get().stopMusic(); + Audio::get()->stopMusic(); } } @@ -1823,7 +1823,7 @@ void Game::updateGameStateEnteringPlayer() { setState(GameState::SHOWING_GET_READY_MESSAGE); createMessage({paths_.at(0), paths_.at(1)}, Resource::get()->getTexture("game_text_get_ready")); - Audio::get().playSound("voice_get_ready.wav"); + Audio::get()->playSound("voice_get_ready.wav"); } } } diff --git a/source/game_logo.cpp b/source/game_logo.cpp index 814d3bd..ebf0fce 100644 --- a/source/game_logo.cpp +++ b/source/game_logo.cpp @@ -123,7 +123,7 @@ void GameLogo::update() coffee_crisis_status_ = Status::SHAKING; // Reproduce el efecto sonoro - Audio::get().playSound("title.wav"); + Audio::get()->playSound("title.wav"); Screen::get()->flash(Color(0xFF, 0xFF, 0xFF), FLASH_LENGHT, FLASH_DELAY); Screen::get()->shake(); } @@ -187,7 +187,7 @@ void GameLogo::update() zoom_ = 1.0f; arcade_edition_sprite_->setZoom(zoom_); shake_.init(1, 2, 8, arcade_edition_sprite_->getX()); - Audio::get().playSound("title.wav"); + Audio::get()->playSound("title.wav"); Screen::get()->flash(Color(0xFF, 0xFF, 0xFF), FLASH_LENGHT, FLASH_DELAY); Screen::get()->shake(); } diff --git a/source/global_inputs.cpp b/source/global_inputs.cpp index 095636c..0916f64 100644 --- a/source/global_inputs.cpp +++ b/source/global_inputs.cpp @@ -60,7 +60,7 @@ namespace globalInputs void toggleAudio() { options.audio.enabled = !options.audio.enabled; - Audio::get().enable(options.audio.enabled); + Audio::get()->enable(options.audio.enabled); Notifier::get()->show({"Audio " + boolToOnOff(options.audio.enabled)}); } @@ -151,7 +151,7 @@ namespace globalInputs switch (section::name) { case section::Name::INTRO: - Audio::get().stopMusic(); + Audio::get()->stopMusic(); /* Continua en el case de abajo */ case section::Name::LOGO: case section::Name::HI_SCORE_TABLE: diff --git a/source/hiscore_table.cpp b/source/hiscore_table.cpp index 67c3678..3410f62 100644 --- a/source/hiscore_table.cpp +++ b/source/hiscore_table.cpp @@ -150,7 +150,7 @@ void HiScoreTable::checkInput() // Bucle para la pantalla de instrucciones void HiScoreTable::run() { - Audio::get().playMusic("title.ogg"); + Audio::get()->playMusic("title.ogg"); while (section::name == section::Name::HI_SCORE_TABLE) { checkInput(); diff --git a/source/input.cpp b/source/input.cpp index 855693b..69462ef 100644 --- a/source/input.cpp +++ b/source/input.cpp @@ -8,26 +8,17 @@ #include // Para unordered_map, operator==, _Node_cons... #include // Para pair -// [SINGLETON] -Input *Input::input_ = nullptr; +// Singleton +Input *Input::instance_ = nullptr; -// [SINGLETON] Crearemos el objeto con esta función estática -void Input::init(const std::string &game_controller_db_path) -{ - Input::input_ = new Input(game_controller_db_path); -} +// Inicializa la instancia única del singleton +void Input::init(const std::string &game_controller_db_path) { Input::instance_ = new Input(game_controller_db_path); } -// [SINGLETON] Destruiremos el objeto con esta función estática -void Input::destroy() -{ - delete Input::input_; -} +// Libera la instancia +void Input::destroy() { delete Input::instance_; } -// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él -Input *Input::get() -{ - return Input::input_; -} +// Obtiene la instancia +Input *Input::get() { return Input::instance_; } // Constructor Input::Input(const std::string &game_controller_db_path) diff --git a/source/input.h b/source/input.h index 872ae2d..5fbaf38 100644 --- a/source/input.h +++ b/source/input.h @@ -69,66 +69,40 @@ enum class InputDeviceToUse : int class Input { public: - // [SINGLETON] Crearemos el objeto con esta función estática - static void init(const std::string &game_controller_db_path); + // --- Métodos de singleton --- + static void init(const std::string &game_controller_db_path); // Inicializa el singleton + static void destroy(); // Libera el singleton + static Input *get(); // Obtiene la instancia - // [SINGLETON] Destruiremos el objeto con esta función estática - static void destroy(); + // --- Métodos de configuración de controles --- + void bindKey(InputAction input, SDL_Scancode code); // Asigna inputs a teclas + void bindGameControllerButton(int controller_index, InputAction input, SDL_GamepadButton button); // Asigna inputs a botones del mando + void bindGameControllerButton(int controller_index, InputAction inputTarget, InputAction inputSource); // Asigna inputs a otros inputs del mando - // [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él - static Input *get(); + // --- Métodos de consulta de entrada --- + bool checkInput(InputAction input, bool repeat = true, InputDeviceToUse device = InputDeviceToUse::ANY, int controller_index = 0); // Comprueba si un input está activo + bool checkAnyInput(InputDeviceToUse device = InputDeviceToUse::ANY, int controller_index = 0); // Comprueba si hay al menos un input activo + int checkAnyButtonPressed(bool repeat = INPUT_DO_NOT_ALLOW_REPEAT); // Comprueba si hay algún botón pulsado - // Asigna inputs a teclas - void bindKey(InputAction input, SDL_Scancode code); + // --- Métodos de gestión de mandos --- + bool discoverGameControllers(); // Busca si hay mandos conectados + bool gameControllerFound(); // Comprueba si hay algún mando conectado + int getNumControllers() const; // Obtiene el número de mandos conectados + std::string getControllerName(int controller_index) const; // Obtiene el nombre de un mando de juego + int getJoyIndex(SDL_JoystickID id) const; // Obtiene el índice del controlador a partir de un event.id - // Asigna inputs a botones del mando - void bindGameControllerButton(int controller_index, InputAction input, SDL_GamepadButton button); - void bindGameControllerButton(int controller_index, InputAction inputTarget, InputAction inputSource); - - // Comprueba si un input está activo - bool checkInput(InputAction input, bool repeat = true, InputDeviceToUse device = InputDeviceToUse::ANY, int controller_index = 0); - - // Comprueba si hay al menos un input activo - bool checkAnyInput(InputDeviceToUse device = InputDeviceToUse::ANY, int controller_index = 0); - - // Comprueba si hay algún botón pulsado - int checkAnyButtonPressed(bool repeat = INPUT_DO_NOT_ALLOW_REPEAT); - - // Busca si hay mandos conectados - bool discoverGameControllers(); - - // Comprueba si hay algún mando conectado - bool gameControllerFound(); - - // Obtiene el número de mandos conectados - int getNumControllers() const; - - // Obtiene el nombre de un mando de juego - std::string getControllerName(int controller_index) const; - - // Obtiene el índice del controlador a partir de un event.id - int getJoyIndex(SDL_JoystickID id) const; - - // Muestra por consola los controles asignados - void printBindings(InputDeviceToUse device = InputDeviceToUse::KEYBOARD, int controller_index = 0) const; - - // Obtiene el SDL_GamepadButton asignado a un input - SDL_GamepadButton getControllerBinding(int controller_index, InputAction input) const; - - // Convierte un InputAction a std::string - std::string to_string(InputAction input) const; - - // Convierte un std::string a InputAction - InputAction to_inputs_e(const std::string &name) const; - - // Obtiene el índice a partir del nombre del mando - int getIndexByName(const std::string &name) const; + // --- Métodos de consulta y utilidades --- + void printBindings(InputDeviceToUse device = InputDeviceToUse::KEYBOARD, int controller_index = 0) const; // Muestra por consola los controles asignados + SDL_GamepadButton getControllerBinding(int controller_index, InputAction input) const; // Obtiene el SDL_GamepadButton asignado a un input + std::string to_string(InputAction input) const; // Convierte un InputAction a std::string + InputAction to_inputs_e(const std::string &name) const; // Convierte un std::string a InputAction + int getIndexByName(const std::string &name) const; // Obtiene el índice a partir del nombre del mando private: - // [SINGLETON] Objeto privado - static Input *input_; + // --- Singleton --- + static Input *instance_; - // Estructura para asociar teclas a acciones + // --- Estructuras internas --- struct KeyBindings { Uint8 scancode; // Scancode asociado @@ -138,7 +112,6 @@ private: : scancode(sc), active(act) {} }; - // Estructura para asociar botones de mando a acciones struct ControllerBindings { SDL_GamepadButton button; // GameControllerButton asociado @@ -149,7 +122,7 @@ private: : button(btn), active(act), axis_active(axis_act) {} }; - // Variables internas + // --- Variables internas --- std::vector connected_controllers_; // Vector con todos los mandos conectados std::vector joysticks_; // Vector con todos los joysticks conectados std::vector key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos @@ -160,14 +133,11 @@ private: int num_gamepads_ = 0; // Número de mandos conectados std::string game_controller_db_path_; // Ruta al archivo gamecontrollerdb.txt - void initSDL(); // Inicializa SDL para la gestión de mandos + // --- Métodos internos --- + void initSDL(); // Inicializa SDL para la gestión de mandos + bool checkAxisInput(InputAction input, int controller_index, bool repeat); // Comprueba el eje del mando - // Comprueba el eje del mando - bool checkAxisInput(InputAction input, int controller_index, bool repeat); - - // Constructor privado - explicit Input(const std::string &game_controller_db_path); - - // Destructor - ~Input() = default; + // --- Constructor y destructor --- + explicit Input(const std::string &game_controller_db_path); // Constructor privado + ~Input() = default; // Destructor privado }; \ No newline at end of file diff --git a/source/instructions.cpp b/source/instructions.cpp index d3bbb57..0833d4a 100644 --- a/source/instructions.cpp +++ b/source/instructions.cpp @@ -272,7 +272,7 @@ void Instructions::checkInput() // Bucle para la pantalla de instrucciones void Instructions::run() { - Audio::get().playMusic("title.ogg"); + Audio::get()->playMusic("title.ogg"); while (section::name == section::Name::INSTRUCTIONS) { checkInput(); diff --git a/source/intro.cpp b/source/intro.cpp index 3ff52be..e8bfb1c 100644 --- a/source/intro.cpp +++ b/source/intro.cpp @@ -281,7 +281,7 @@ void Intro::render() // Bucle principal void Intro::run() { - Audio::get().playMusic("intro.ogg", 0); + Audio::get()->playMusic("intro.ogg", 0); while (section::name == section::Name::INTRO) { checkInput(); @@ -513,7 +513,7 @@ void Intro::updatePostState() // Finaliza la intro después de 1 segundo if (ELAPSED_TIME >= 1000) { - Audio::get().stopMusic(); + Audio::get()->stopMusic(); section::name = section::Name::TITLE; section::options = section::Options::TITLE_1; } diff --git a/source/logo.cpp b/source/logo.cpp index cee60d9..5fbe87e 100644 --- a/source/logo.cpp +++ b/source/logo.cpp @@ -60,7 +60,7 @@ Logo::~Logo() { jail_texture_->setColor(255, 255, 255); since_texture_->setColor(255, 255, 255); - Audio::get().stopAllSounds(); + Audio::get()->stopAllSounds(); } // Comprueba el manejador de eventos @@ -84,7 +84,7 @@ void Logo::updateJAILGAMES() { if (counter_ == 30) { - Audio::get().playSound("logo.wav"); + Audio::get()->playSound("logo.wav"); } if (counter_ > 30) @@ -181,7 +181,7 @@ void Logo::render() // Bucle para el logo del juego void Logo::run() { - Audio::get().fadeOutMusic(300); + Audio::get()->fadeOutMusic(300); while (section::name == section::Name::LOGO) { checkInput(); diff --git a/source/notifier.cpp b/source/notifier.cpp index d02be25..932d7c7 100644 --- a/source/notifier.cpp +++ b/source/notifier.cpp @@ -12,26 +12,17 @@ #include "texture.h" // Para Texture #include "resource.h" -// [SINGLETON] -Notifier *Notifier::notifier_ = nullptr; +// Singleton +Notifier *Notifier::instance_ = nullptr; -// [SINGLETON] Crearemos el objeto con esta función estática -void Notifier::init(const std::string &icon_file, std::shared_ptr text) -{ - Notifier::notifier_ = new Notifier(icon_file, text); -} +// Inicializa la instancia única del singleton +void Notifier::init(const std::string &icon_file, std::shared_ptr text) { Notifier::instance_ = new Notifier(icon_file, text); } -// [SINGLETON] Destruiremos el objeto con esta función estática -void Notifier::destroy() -{ - delete Notifier::notifier_; -} +// Libera la instancia +void Notifier::destroy() { delete Notifier::instance_; } -// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él -Notifier *Notifier::get() -{ - return Notifier::notifier_; -} +// Obtiene la instancia +Notifier *Notifier::get() { return Notifier::instance_; } // Constructor Notifier::Notifier(std::string icon_file, std::shared_ptr text) @@ -76,7 +67,7 @@ void Notifier::update() if (notifications_[i].state == NotificationStatus::RISING) { // Reproduce el sonido de la notificación - Audio::get().playSound("notify.wav"); + Audio::get()->playSound("notify.wav"); } } } diff --git a/source/notifier.h b/source/notifier.h index 0946279..e9c2719 100644 --- a/source/notifier.h +++ b/source/notifier.h @@ -1,11 +1,11 @@ #pragma once -#include // Para SDL_FRect +#include // Para SDL_FRect #include // Para SDL_Renderer -#include // Para shared_ptr -#include // Para string -#include // Para vector -#include "utils.h" // Para Color +#include // Para shared_ptr +#include // Para string +#include // Para vector +#include "utils.h" // Para Color class Sprite; class Text; @@ -15,89 +15,77 @@ class Texture; class Notifier { public: - // [SINGLETON] Crearemos el objeto con esta función estática - static void init(const std::string &icon_file, std::shared_ptr text); + // --- Métodos de singleton --- + static void init(const std::string &icon_file, std::shared_ptr text); // Inicializa el singleton + static void destroy(); // Libera el singleton + static Notifier *get(); // Obtiene la instancia - // [SINGLETON] Destruiremos el objeto con esta función estática - static void destroy(); + // --- Métodos principales --- + void render(); // Dibuja las notificaciones por pantalla + void update(); // Actualiza el estado de las notificaciones - // [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él - static Notifier *get(); - - // Dibuja las notificaciones por pantalla - void render(); - - // Actualiza el estado de las notificaciones - void update(); - - // Muestra una notificación de texto por pantalla - void show(std::vector texts, int icon = -1, const std::string &code = std::string()); - - // Indica si hay notificaciones activas - bool isActive() const { return !notifications_.empty(); } - - // Obtiene los códigos de las notificaciones activas - std::vector getCodes(); - - // Comprueba si hay alguna notificación con un código concreto - bool checkCode(const std::string &code) { return stringInVector(getCodes(), code); } + // --- Gestión de notificaciones --- + void show(std::vector texts, int icon = -1, const std::string &code = std::string()); // Muestra una notificación de texto por pantalla + bool isActive() const { return !notifications_.empty(); } // Indica si hay notificaciones activas + std::vector getCodes(); // Obtiene los códigos de las notificaciones activas + bool checkCode(const std::string &code) { return stringInVector(getCodes(), code); } // Comprueba si hay alguna notificación con un código concreto private: - // [SINGLETON] Objeto notifier - static Notifier *notifier_; + // --- Singleton --- + static Notifier *instance_; - // --- Tipos internos --- - enum class NotificationStatus - { - RISING, - STAY, - VANISHING, - FINISHED, - }; + // --- Tipos internos --- + enum class NotificationStatus + { + RISING, + STAY, + VANISHING, + FINISHED, + }; - enum class NotificationShape - { - ROUNDED, - SQUARED, - }; + enum class NotificationShape + { + ROUNDED, + SQUARED, + }; - // --- Estructura Notification --- - struct Notification - { - std::shared_ptr texture; // Textura de la notificación - std::shared_ptr sprite; // Sprite asociado - std::vector texts; // Textos a mostrar - int counter; // Contador de tiempo - NotificationStatus state; // Estado de la notificación - NotificationShape shape; // Forma de la notificación - SDL_FRect rect; // Rectángulo de la notificación - int y; // Posición vertical - int travel_dist; // Distancia a recorrer - std::string code; // Código identificador de la notificación + // --- Estructura Notification --- + struct Notification + { + std::shared_ptr texture; // Textura de la notificación + std::shared_ptr sprite; // Sprite asociado + std::vector texts; // Textos a mostrar + int counter; // Contador de tiempo + NotificationStatus state; // Estado de la notificación + NotificationShape shape; // Forma de la notificación + SDL_FRect rect; // Rectángulo de la notificación + int y; // Posición vertical + int travel_dist; // Distancia a recorrer + std::string code; // Código identificador de la notificación - // Constructor - explicit Notification() - : texture(nullptr), sprite(nullptr), texts(), counter(0), state(NotificationStatus::RISING), - shape(NotificationShape::SQUARED), rect{0, 0, 0, 0}, y(0), travel_dist(0), code("") {} - }; + // Constructor + explicit Notification() + : texture(nullptr), sprite(nullptr), texts(), counter(0), state(NotificationStatus::RISING), + shape(NotificationShape::SQUARED), rect{0, 0, 0, 0}, y(0), travel_dist(0), code("") {} + }; - // --- Objetos y punteros --- - SDL_Renderer *renderer_; // El renderizador de la ventana - std::shared_ptr icon_texture_; // Textura para los iconos de las notificaciones - std::shared_ptr text_; // Objeto para dibujar texto + // --- Objetos y punteros --- + SDL_Renderer *renderer_; // El renderizador de la ventana + std::shared_ptr icon_texture_; // Textura para los iconos de las notificaciones + std::shared_ptr text_; // Objeto para dibujar texto - // --- Variables de estado --- - Color bg_color_; // Color de fondo de las notificaciones - int wait_time_; // Tiempo que se ve la notificación - std::vector notifications_; // Lista de notificaciones activas - bool stack_; // Indica si las notificaciones se apilan - bool has_icons_; // Indica si el notificador tiene textura para iconos + // --- Variables de estado --- + Color bg_color_; // Color de fondo de las notificaciones + int wait_time_; // Tiempo que se ve la notificación + std::vector notifications_; // Lista de notificaciones activas + bool stack_; // Indica si las notificaciones se apilan + bool has_icons_; // Indica si el notificador tiene textura para iconos - // --- Métodos internos --- - void clearFinishedNotifications(); // Elimina las notificaciones finalizadas - void clearAllNotifications(); // Finaliza y elimina todas las notificaciones activas + // --- Métodos internos --- + void clearFinishedNotifications(); // Elimina las notificaciones finalizadas + void clearAllNotifications(); // Finaliza y elimina todas las notificaciones activas - // [SINGLETON] Constructor y destructor privados - Notifier(std::string icon_file, std::shared_ptr text); - ~Notifier() = default; -}; + // --- Constructor y destructor --- + Notifier(std::string icon_file, std::shared_ptr text); // Constructor privado + ~Notifier() = default; // Destructor privado +}; \ No newline at end of file diff --git a/source/player.cpp b/source/player.cpp index b28b888..a8f4397 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -221,7 +221,7 @@ void Player::move() ++step_counter_; if (step_counter_ % 10 == 0) { - Audio::get().playSound("walk.wav"); + Audio::get()->playSound("walk.wav"); } switch (id_) @@ -252,7 +252,7 @@ void Player::move() ++step_counter_; if (step_counter_ % 10 == 0) { - Audio::get().playSound("walk.wav"); + Audio::get()->playSound("walk.wav"); } switch (id_) @@ -752,7 +752,7 @@ void Player::decContinueCounter() } else { - Audio::get().playSound("continue_clock.wav"); + Audio::get()->playSound("continue_clock.wav"); } } @@ -798,5 +798,5 @@ void Player::shiftSprite() void Player::playRandomBubbleSound() { const std::vector sounds = {"bubble1.wav", "bubble2.wav", "bubble3.wav", "bubble4.wav"}; - Audio::get().playSound(sounds.at(rand() % sounds.size())); + Audio::get()->playSound(sounds.at(rand() % sounds.size())); } \ No newline at end of file diff --git a/source/resource.cpp b/source/resource.cpp index 1bc09da..1c4ddba 100644 --- a/source/resource.cpp +++ b/source/resource.cpp @@ -10,32 +10,20 @@ struct JA_Music_t; // lines 11-11 struct JA_Sound_t; // lines 12-12 -// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado -Resource *Resource::resource_ = nullptr; +// Singleton +Resource *Resource::instance_ = nullptr; -// [SINGLETON] Crearemos el objeto screen con esta función estática -void Resource::init() -{ - Resource::resource_ = new Resource(); -} +// Inicializa la instancia única del singleton +void Resource::init() { Resource::instance_ = new Resource(); } -// [SINGLETON] Destruiremos el objeto screen con esta función estática -void Resource::destroy() -{ - delete Resource::resource_; -} +// Libera la instancia +void Resource::destroy() { delete Resource::instance_; } -// [SINGLETON] Con este método obtenemos el objeto screen y podemos trabajar con él -Resource *Resource::get() -{ - return Resource::resource_; -} +// Obtiene la instancia +Resource *Resource::get() { return Resource::instance_; } // Constructor -Resource::Resource() -{ - load(); -} +Resource::Resource() { load(); } // Vacia todos los vectores de recursos void Resource::clear() diff --git a/source/resource.h b/source/resource.h index 59e0704..330b91a 100644 --- a/source/resource.h +++ b/source/resource.h @@ -97,7 +97,7 @@ public: private: // --- Singleton --- - static Resource *resource_; + static Resource *instance_; // --- Vectores de recursos --- std::vector sounds_; // Vector con los sonidos diff --git a/source/screen.cpp b/source/screen.cpp index e990011..6d7a94b 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -20,17 +20,17 @@ #include "resource.h" // Para Resource #include "text.h" // Para Text -// [SINGLETON] -Screen *Screen::screen_ = nullptr; +// Singleton +Screen *Screen::instance_ = nullptr; -// [SINGLETON] Crearemos el objeto con esta función estática -void Screen::init() { Screen::screen_ = new Screen(); } +// Inicializa la instancia única del singleton +void Screen::init() { Screen::instance_ = new Screen(); } -// [SINGLETON] Destruiremos el objeto con esta función estática -void Screen::destroy() { delete Screen::screen_; } +// Libera la instancia +void Screen::destroy() { delete Screen::instance_; } -// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él -Screen *Screen::get() { return Screen::screen_; } +// Obtiene la instancia +Screen *Screen::get() { return Screen::instance_; } // Constructor Screen::Screen() diff --git a/source/screen.h b/source/screen.h index a67b968..f7265cb 100644 --- a/source/screen.h +++ b/source/screen.h @@ -178,7 +178,7 @@ private: #endif // --- Singleton --- - static Screen *screen_; + static Screen *instance_; // --- Objetos y punteros --- SDL_Window *window_; // Ventana de la aplicación diff --git a/source/service_menu.cpp b/source/service_menu.cpp index 1d0fa72..71f43b7 100644 --- a/source/service_menu.cpp +++ b/source/service_menu.cpp @@ -1,6 +1,19 @@ #include "service_menu.h" #include +// Singleton +ServiceMenu *ServiceMenu::instance_ = nullptr; + +// Inicializa la instancia única del singleton +void ServiceMenu::init() { ServiceMenu::instance_ = new ServiceMenu(); } + +// Libera la instancia +void ServiceMenu::destroy() { delete ServiceMenu::instance_; } + +// Obtiene la instancia +ServiceMenu *ServiceMenu::get() { return ServiceMenu::instance_; } + +// Constructor ServiceMenu::ServiceMenu() { // Inicializa los valores por defecto del menú de servicio is_active = false; diff --git a/source/service_menu.h b/source/service_menu.h index 3ed29b4..395ad98 100644 --- a/source/service_menu.h +++ b/source/service_menu.h @@ -6,15 +6,10 @@ class ServiceMenu { public: - static ServiceMenu &get_instance() - { - static ServiceMenu instance; - return instance; - } - - // Eliminar copia y asignación - ServiceMenu(const ServiceMenu &) = delete; - ServiceMenu &operator=(const ServiceMenu &) = delete; + // --- Métodos de singleton --- + static void init(); // Inicializa el objeto ServiceMenu + static void destroy(); // Libera el objeto ServiceMenu + static ServiceMenu *get(); // Obtiene el puntero al objeto ServiceMenu void show(); void render(); @@ -22,9 +17,16 @@ public: void execute_option(size_t option); private: - ServiceMenu(); - ~ServiceMenu() = default; + // --- Patrón Singleton --- + ServiceMenu(); // Constructor privado + ~ServiceMenu() = default; // Destructor privado + ServiceMenu(const ServiceMenu &) = delete; // Evitar copia + ServiceMenu &operator=(const ServiceMenu &) = delete; // Evitar asignación + // --- Singleton --- + static ServiceMenu *instance_; + + // -- Variables internas --- bool is_active; size_t selected_option; std::vector options; diff --git a/source/tabe.cpp b/source/tabe.cpp index af1e253..8f4331a 100644 --- a/source/tabe.cpp +++ b/source/tabe.cpp @@ -131,7 +131,7 @@ void Tabe::setRandomFlyPath(TabeDirection direction, int lenght) direction_ = direction; fly_distance_ = lenght; waiting_counter_ = 5 + rand() % 15; - Audio::get().playSound("tabe.wav"); + Audio::get()->playSound("tabe.wav"); constexpr float SPEED = 2.0f; diff --git a/source/title.cpp b/source/title.cpp index 0d8f254..dea174f 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -55,7 +55,7 @@ Title::Title() Title::~Title() { Resource::get()->getTexture("smb2.gif")->setPalette(0); - Audio::get().stopAllSounds(); + Audio::get()->stopAllSounds(); } // Actualiza las variables del objeto @@ -200,8 +200,8 @@ void Title::checkInput() { if ((state_ == TitleState::LOGO_FINISHED || ALLOW_TITLE_ANIMATION_SKIP) && !fade_->isEnabled()) { - Audio::get().playSound("game_start.wav"); - Audio::get().fadeOutMusic(1500); + Audio::get()->playSound("game_start.wav"); + Audio::get()->fadeOutMusic(1500); switch (CONTROLLER.player_id) { case 1: @@ -322,7 +322,7 @@ void Title::updateFade() // Se ha pulsado para jugar section::name = section::Name::GAME; section::options = selection_; - Audio::get().stopMusic(); + Audio::get()->stopMusic(); } } } @@ -339,7 +339,7 @@ void Title::updateState() if (game_logo_->hasFinished()) { state_ = TitleState::LOGO_FINISHED; - Audio::get().playMusic("title.ogg"); + Audio::get()->playMusic("title.ogg"); } break; }