diff --git a/source/director.cpp b/source/director.cpp index fb5ce5c..4d52d05 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -34,6 +34,7 @@ #include "on_screen_help.h" // for OnScreenHelp #include "options.h" // for options, loadOptionsFile, saveO... #include "param.h" // for param, loadParamsFromFile +#include "resource.h" //for Resource #include "screen.h" // for Screen #include "section.h" // for Name, name, Options, options #include "title.h" // for Title @@ -106,6 +107,8 @@ Director::Director(int argc, const char *argv[]) // Crea los objetos lang::loadFromFile(getLangFile((lang::Code)options.game.language)); + Resource::init(); + Input::init(Asset::get()->get("gamecontrollerdb.txt")); initInput(); @@ -115,12 +118,6 @@ Director::Director(int argc, const char *argv[]) OnScreenHelp::init(); - // Carga los sonidos del juego - loadSounds(); - - // Carga las musicas del juego - loadMusics(); - globalInputs::init(); } @@ -129,13 +126,12 @@ Director::~Director() saveOptionsFile(Asset::get()->get("config.txt")); Asset::destroy(); + Resource::destroy(); Input::destroy(); Screen::destroy(); Notifier::destroy(); OnScreenHelp::destroy(); - sounds_.clear(); - musics_.clear(); SDL_DestroyRenderer(renderer_); SDL_DestroyWindow(window_); @@ -567,38 +563,6 @@ void Director::createSystemFolder(const std::string &folder) } } -// Carga los sonidos del juego -void Director::loadSounds() -{ - // Obtiene la lista con las rutas a los ficheros de sonidos - auto list = Asset::get()->getListByType(AssetType::SOUND); - sounds_.clear(); - - for (const auto &l : list) - { - auto last_index = l.find_last_of('/') + 1; - auto name = l.substr(last_index); - - sounds_.emplace_back(SoundFile{name, JA_LoadSound(l.c_str())}); - } -} - -// Carga las musicas del juego -void Director::loadMusics() -{ - // Obtiene la lista con las rutas a los ficheros musicales - auto list = Asset::get()->getListByType(AssetType::MUSIC); - musics_.clear(); - - for (const auto &l : list) - { - auto last_index = l.find_last_of('/') + 1; - auto name = l.substr(last_index); - - musics_.emplace_back(MusicFile{name, JA_LoadMusic(l.c_str())}); - } -} - // Ejecuta la sección con el logo void Director::runLogo() { @@ -609,14 +573,14 @@ void Director::runLogo() // Ejecuta la sección con la secuencia de introducción void Director::runIntro() { - auto intro = std::make_unique(getMusic(musics_, "intro.ogg")); + auto intro = std::make_unique(); intro->run(); } // Ejecuta la sección con el título del juego void Director::runTitle() { - auto title = std::make_unique(getMusic(musics_, "title.ogg")); + auto title = std::make_unique<Title>(); title->run(); } @@ -625,21 +589,21 @@ void Director::runGame() { const auto player_id = section::options == section::Options::GAME_PLAY_1P ? 1 : 2; constexpr auto current_stage = 0; - auto game = std::make_unique<Game>(player_id, current_stage, GAME_MODE_DEMO_OFF, getMusic(musics_, "playing.ogg")); + auto game = std::make_unique<Game>(player_id, current_stage, GAME_MODE_DEMO_OFF); game->run(); } // Ejecuta la sección donde se muestran las instrucciones void Director::runInstructions() { - auto instructions = std::make_unique<Instructions>(getMusic(musics_, "title.ogg")); + auto instructions = std::make_unique<Instructions>(); instructions->run(); } // Ejecuta la sección donde se muestra la tabla de puntuaciones void Director::runHiScoreTable() { - auto hi_score_table = std::make_unique<HiScoreTable>(getMusic(musics_, "title.ogg")); + auto hi_score_table = std::make_unique<HiScoreTable>(); hi_score_table->run(); } @@ -648,7 +612,7 @@ void Director::runDemoGame() { const auto player_id = (rand() % 2) + 1; constexpr auto current_stage = 0; - auto game = std::make_unique<Game>(player_id, current_stage, GAME_MODE_DEMO_ON, nullptr); + auto game = std::make_unique<Game>(player_id, current_stage, GAME_MODE_DEMO_ON); game->run(); } @@ -705,7 +669,6 @@ int Director::run() const auto return_code = (section::options == section::Options::QUIT_NORMAL) ? "keyboard" : "controller"; std::cout << "\nGame end with " << return_code << std::endl; - #ifndef VERBOSE // Habilita de nuevo los std::cout std::cout.rdbuf(orig_buf); diff --git a/source/director.h b/source/director.h index 0832fb1..8632744 100644 --- a/source/director.h +++ b/source/director.h @@ -8,8 +8,8 @@ namespace lang { enum class Code : int; } -struct MusicFile; -struct SoundFile; +struct ResourceMusic; +struct ResourceSound; // Textos constexpr char WINDOW_CAPTION[] = "Coffee Crisis Arcade Edition"; @@ -18,16 +18,14 @@ class Director { private: // Objetos y punteros - SDL_Window *window_; // La ventana donde dibujamos - SDL_Renderer *renderer_; // El renderizador de la ventana + SDL_Window *window_; // La ventana donde dibujamos + SDL_Renderer *renderer_; // El renderizador de la ventana std::streambuf *orig_buf; ///< Puntero al buffer de flujo original para restaurar std::cout // Variables std::string executable_path_; // Path del ejecutable std::string system_folder_; // Carpeta del sistema donde guardar datos std::string param_file_argument_; // Argumento para gestionar el fichero con los parametros del programa - std::vector<SoundFile> sounds_; // Vector con los sonidos - std::vector<MusicFile> musics_; // Vector con las musicas // Inicializa jail_audio void initJailAudio(); @@ -44,12 +42,6 @@ private: // Crea el indice de ficheros bool setFileList(); - // Carga los sonidos del juego - void loadSounds(); - - // Carga las musicas del juego - void loadMusics(); - // Comprueba los parametros del programa void checkProgramArguments(int argc, const char *argv[]); diff --git a/source/game.cpp b/source/game.cpp index cbbcbf9..6f9e951 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -22,13 +22,14 @@ #include "global_inputs.h" // for check #include "input.h" // for InputType, Input, INPUT_DO_NOT_ALL... #include "item.h" // for Item, ItemType::COFFEE_MACHINE, ItemType::CLOCK -#include "jail_audio.h" // for JA_PlaySound, JA_DeleteSound, JA_L... +#include "jail_audio.h" // for JA_PlaySound #include "lang.h" // for getText #include "manage_hiscore_table.h" // for ManageHiScoreTable #include "notifier.h" // for Notifier #include "options.h" // for options #include "param.h" // for param #include "player.h" // for Player, PlayerStatus +#include "resource.h" // for Resource #include "scoreboard.h" // for Scoreboard, ScoreboardMode, SCOREB... #include "screen.h" // for Screen #include "section.h" // for Name, name, Options, options @@ -39,9 +40,8 @@ struct JA_Music_t; // lines 35-35 struct JA_Sound_t; // lines 36-36 // Constructor -Game::Game(int player_id, int current_stage, bool demo, JA_Music_t *music) - : music_(music), - current_stage_(current_stage) +Game::Game(int player_id, int current_stage, bool demo) + : current_stage_(current_stage) { // Copia los punteros asset_ = Asset::get(); @@ -429,25 +429,6 @@ void Game::loadMedia() text_nokia2_big_ = std::make_unique<Text>(asset_->get("nokia_big2.png"), asset_->get("nokia_big2.txt"), renderer_); } - // Sonidos - { - balloon_sound_ = JA_LoadSound(asset_->get("balloon.wav").c_str()); - bubble1_sound_ = JA_LoadSound(asset_->get("bubble1.wav").c_str()); - bubble2_sound_ = JA_LoadSound(asset_->get("bubble2.wav").c_str()); - bubble3_sound_ = JA_LoadSound(asset_->get("bubble3.wav").c_str()); - bubble4_sound_ = JA_LoadSound(asset_->get("bubble4.wav").c_str()); - bullet_sound_ = JA_LoadSound(asset_->get("bullet.wav").c_str()); - clock_sound_ = JA_LoadSound(asset_->get("clock.wav").c_str()); - coffee_out_sound_ = JA_LoadSound(asset_->get("coffeeout.wav").c_str()); - hi_score_sound_ = JA_LoadSound(asset_->get("hiscore.wav").c_str()); - item_drop_sound_ = JA_LoadSound(asset_->get("itemdrop.wav").c_str()); - item_pick_up_sound_ = JA_LoadSound(asset_->get("itempickup.wav").c_str()); - player_collision_sound_ = JA_LoadSound(asset_->get("player_collision.wav").c_str()); - power_ball_sound_ = JA_LoadSound(asset_->get("powerball.wav").c_str()); - stage_change_sound_ = JA_LoadSound(asset_->get("stage_change.wav").c_str()); - coffee_machine_sound_ = JA_LoadSound(asset_->get("title.wav").c_str()); - } - std::cout << "** RESOURCES FOR GAME SECTION LOADED\n" << std::endl; } @@ -467,23 +448,6 @@ void Game::unloadMedia() balloon_animations_.clear(); explosions_animations_.clear(); item_animations_.clear(); - - // Sonidos - JA_DeleteSound(balloon_sound_); - JA_DeleteSound(bullet_sound_); - JA_DeleteSound(player_collision_sound_); - JA_DeleteSound(hi_score_sound_); - JA_DeleteSound(item_drop_sound_); - JA_DeleteSound(item_pick_up_sound_); - JA_DeleteSound(coffee_out_sound_); - JA_DeleteSound(stage_change_sound_); - JA_DeleteSound(bubble1_sound_); - JA_DeleteSound(bubble2_sound_); - JA_DeleteSound(bubble3_sound_); - JA_DeleteSound(bubble4_sound_); - JA_DeleteSound(clock_sound_); - JA_DeleteSound(power_ball_sound_); - JA_DeleteSound(coffee_machine_sound_); } // Carga el fichero de datos para la demo @@ -649,7 +613,7 @@ void Game::updateHiScore() if (hi_score_achieved_ == false) { hi_score_achieved_ = true; - JA_PlaySound(hi_score_sound_); + JA_PlaySound(Resource::get()->getSound("hiscore.wav")); } } } @@ -725,7 +689,7 @@ void Game::updateStage() updateHiScore(); JA_StopMusic(); } - JA_PlaySound(stage_change_sound_); + JA_PlaySound(Resource::get()->getSound("stage_change.wav")); stage_bitmap_counter_ = 0; balloon_speed_ = default_balloon_speed_; setBalloonSpeed(balloon_speed_); @@ -763,7 +727,11 @@ void Game::updateGameOver() { // Hace sonar aleatoriamente uno de los 4 sonidos de burbujas const auto index = rand() % 4; - JA_Sound_t *sound[4] = {bubble1_sound_, bubble2_sound_, bubble3_sound_, bubble4_sound_}; + JA_Sound_t *sound[4] = { + Resource::get()->getSound("bubble1.wav"), + Resource::get()->getSound("bubble2.wav"), + Resource::get()->getSound("bubble3.wav"), + Resource::get()->getSound("bubble4.wav")}; JA_PlaySound(sound[index], 0); } @@ -991,7 +959,7 @@ void Game::destroyAllBalloons() } balloon_deploy_counter_ = 300; - JA_PlaySound(power_ball_sound_); + JA_PlaySound(Resource::get()->getSound("powerball.wav")); screen_->flash(flash_color, 5); screen_->shake(); } @@ -1119,7 +1087,7 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player) } updateHiScore(); - JA_PlaySound(item_pick_up_sound_); + JA_PlaySound(Resource::get()->getSound("itempickup.wav")); item->disable(); } } @@ -1154,7 +1122,7 @@ void Game::checkBulletBalloonCollision() if (droppeditem != ItemType::COFFEE_MACHINE) { createItem(droppeditem, balloon->getPosX(), balloon->getPosY()); - JA_PlaySound(item_drop_sound_); + JA_PlaySound(Resource::get()->getSound("itemdrop.wav")); } else { @@ -1167,7 +1135,7 @@ void Game::checkBulletBalloonCollision() popBalloon(balloon); // Sonido de explosión - JA_PlaySound(balloon_sound_); + JA_PlaySound(Resource::get()->getSound("balloon.wav")); // Deshabilita la bala bullet->disable(); @@ -1209,8 +1177,7 @@ void Game::renderBullets() // Crea un objeto bala void Game::createBullet(int x, int y, BulletType kind, bool powered_up, int owner) { - auto b = std::make_unique<Bullet>(x, y, kind, powered_up, owner, &(param.game.play_area.rect), bullet_texture_); - bullets_.push_back(std::move(b)); + bullets_.emplace_back(std::make_unique<Bullet>(x, y, kind, powered_up, owner, &(param.game.play_area.rect), bullet_texture_)); } // Vacia el vector de balas @@ -1238,7 +1205,7 @@ void Game::updateItems() item->update(); if (item->isOnFloor()) { - JA_PlaySound(coffee_machine_sound_); + JA_PlaySound(Resource::get()->getSound("title.wav")); screen_->shake(); } } @@ -1439,7 +1406,7 @@ void Game::killPlayer(std::shared_ptr<Player> &player) // Lo pierde player->removeExtraHit(); throwCoffee(player->getPosX() + (player->getWidth() / 2), player->getPosY() + (player->getHeight() / 2)); - JA_PlaySound(coffee_out_sound_); + JA_PlaySound(Resource::get()->getSound("coffeeout.wav")); screen_->shake(); } else @@ -1450,9 +1417,9 @@ void Game::killPlayer(std::shared_ptr<Player> &player) JA_PauseMusic(); } stopAllBalloons(10); - JA_PlaySound(player_collision_sound_); + JA_PlaySound(Resource::get()->getSound("player_collision.wav")); screen_->shake(); - JA_PlaySound(coffee_out_sound_); + JA_PlaySound(Resource::get()->getSound("coffeeout.wav")); player->setStatusPlaying(PlayerStatus::DYING); if (!demo_.enabled) { @@ -1772,14 +1739,14 @@ void Game::renderMessages() { if (time_stopped_counter_ % 30 == 0) { - JA_PlaySound(clock_sound_); + JA_PlaySound(Resource::get()->getSound("clock.wav")); } } else { if (time_stopped_counter_ % 15 == 0) { - JA_PlaySound(clock_sound_); + JA_PlaySound(Resource::get()->getSound("clock.wav")); } } } @@ -1843,7 +1810,7 @@ void Game::checkMusicStatus() if (JA_GetMusicState() == JA_MUSIC_INVALID || JA_GetMusicState() == JA_MUSIC_STOPPED) { // Si se ha completado el juego o los jugadores han terminado, detiene la música - game_completed_ || allPlayersAreGameOver() ? JA_StopMusic() : JA_PlayMusic(music_); + game_completed_ || allPlayersAreGameOver() ? JA_StopMusic() : JA_PlayMusic(Resource::get()->getMusic("playing.ogg")); } } @@ -2352,6 +2319,7 @@ void Game::handleFireInput(const std::shared_ptr<Player> &player, BulletType bul player->setInput(bulletType == BulletType::UP ? InputType::FIRE_CENTER : bulletType == BulletType::LEFT ? InputType::FIRE_LEFT : InputType::FIRE_RIGHT); createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), bulletType, player->isPowerUp(), player->getId()); + JA_PlaySound(Resource::get()->getSound("bullet.wav")); player->setFireCooldown(10); // Establece un tiempo de espera para el próximo disparo. } } diff --git a/source/game.h b/source/game.h index 13f98b7..fdf1744 100644 --- a/source/game.h +++ b/source/game.h @@ -145,24 +145,6 @@ private: std::unique_ptr<Fade> fade_; // Objeto para renderizar fades - JA_Sound_t *balloon_sound_; // Sonido para la explosión del globo - JA_Sound_t *bullet_sound_; // Sonido para los disparos - JA_Sound_t *player_collision_sound_; // Sonido para la colisión del jugador con un enemigo - JA_Sound_t *hi_score_sound_; // Sonido para cuando se alcanza la máxima puntuación - JA_Sound_t *item_drop_sound_; // Sonido para cuando se genera un item - JA_Sound_t *item_pick_up_sound_; // Sonido para cuando se recoge un item - JA_Sound_t *coffee_out_sound_; // Sonido para cuando el jugador pierde el café al recibir un impacto - JA_Sound_t *stage_change_sound_; // Sonido para cuando se cambia de fase - JA_Sound_t *bubble1_sound_; // Sonido para cuando el jugador muere - JA_Sound_t *bubble2_sound_; // Sonido para cuando el jugador muere - JA_Sound_t *bubble3_sound_; // Sonido para cuando el jugador muere - JA_Sound_t *bubble4_sound_; // Sonido para cuando el jugador muere - JA_Sound_t *clock_sound_; // Sonido para cuando se detiene el tiempo con el item reloj - JA_Sound_t *power_ball_sound_; // Sonido para cuando se explota una Power Ball - JA_Sound_t *coffee_machine_sound_; // Sonido para cuando la máquina de café toca el suelo - - JA_Music_t *music_; // Musica de fondo - // Variables Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_speed_; // Velocidad a la que se repiten los bucles del programa @@ -468,7 +450,7 @@ private: public: // Constructor - Game(int playerID, int current_stage, bool demo, JA_Music_t *music); + Game(int playerID, int current_stage, bool demo); // Destructor ~Game(); diff --git a/source/game_logo.cpp b/source/game_logo.cpp index f7afcb5..37343f1 100644 --- a/source/game_logo.cpp +++ b/source/game_logo.cpp @@ -3,8 +3,9 @@ #include <algorithm> // for max #include "animated_sprite.h" // for SpriteAnimated #include "asset.h" // for Asset -#include "jail_audio.h" // for JA_DeleteSound, JA_LoadSound, JA_PlaySound +#include "jail_audio.h" // JA_PlaySound #include "param.h" // for param +#include "resource.h" // for Resource #include "screen.h" // for Screen #include "smart_sprite.h" // for SpriteSmart #include "sprite.h" // for Sprite @@ -26,7 +27,6 @@ GameLogo::GameLogo(int x, int y) arcade_edition_sprite_(std::make_unique<Sprite>(arcade_edition_texture_, (param.game.width - arcade_edition_texture_->getWidth()) / 2, param.title.arcade_edition_position, arcade_edition_texture_->getWidth(), arcade_edition_texture_->getHeight())), - crash_sound_(JA_LoadSound(Asset::get()->get("title.wav").c_str())), x_(x), y_(y) @@ -35,12 +35,6 @@ GameLogo::GameLogo(int x, int y) init(); } -// Destructor -GameLogo::~GameLogo() -{ - JA_DeleteSound(crash_sound_); -} - // Inicializa las variables void GameLogo::init() { @@ -137,7 +131,7 @@ void GameLogo::update() status_ = Status::SHAKING; // Reproduce el efecto sonoro - JA_PlaySound(crash_sound_); + JA_PlaySound(Resource::get()->getSound("title.wav")); } break; diff --git a/source/game_logo.h b/source/game_logo.h index 7904d9a..2e6880f 100644 --- a/source/game_logo.h +++ b/source/game_logo.h @@ -1,8 +1,8 @@ #pragma once #include <memory> // for unique_ptr, shared_ptr -class AnimatedSprite; -class SmartSprite; +#include "animated_sprite.h" +#include "smart_sprite.h" class Sprite; class Texture; struct JA_Sound_t; // lines 10-10 @@ -43,8 +43,6 @@ private: std::unique_ptr<Sprite> arcade_edition_sprite_; // Sprite con los graficos de "Arcade Edition" - JA_Sound_t *crash_sound_; // Sonido con el impacto del título - // Variables int x_; // Posición donde dibujar el logo int y_; // Posición donde dibujar el logo @@ -63,7 +61,7 @@ public: GameLogo(int x, int y); // Destructor - ~GameLogo(); + ~GameLogo() = default; // Pinta la clase en pantalla void render(); diff --git a/source/hiscore_table.cpp b/source/hiscore_table.cpp index ae6624b..8722ecf 100644 --- a/source/hiscore_table.cpp +++ b/source/hiscore_table.cpp @@ -15,14 +15,14 @@ #include "lang.h" // for getText #include "options.h" // for options #include "param.h" // for param +#include "resource.h" // for Resource #include "screen.h" // for Screen #include "section.h" // for Name, name, Options, options #include "text.h" // for Text, TEXT_CENTER, TEXT_SHADOW, TEXT... #include "utils.h" // for Param, ParamGame, Color, HiScoreEntry // Constructor -HiScoreTable::HiScoreTable(JA_Music_t *music) - : music_(music) +HiScoreTable::HiScoreTable() { // Copia punteros renderer_ = Screen::get()->getRenderer(); @@ -78,7 +78,7 @@ void HiScoreTable::update() // Mantiene la música sonando if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED)) { - JA_PlayMusic(music_); + JA_PlayMusic(Resource::get()->getMusic("title.ogg")); } // Actualiza el objeto screen diff --git a/source/hiscore_table.h b/source/hiscore_table.h index b80358d..594683a 100644 --- a/source/hiscore_table.h +++ b/source/hiscore_table.h @@ -9,7 +9,6 @@ class Background; // lines 8-8 class Fade; // lines 9-9 class Text; // lines 10-10 enum class FadeMode : Uint8; // lines 11-11 -struct JA_Music_t; // lines 12-12 /* Esta clase gestiona un estado del programa. Se encarga de mostrar la tabla con las puntuaciones @@ -28,7 +27,6 @@ private: // Objetos y punteros SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Texture *backbuffer_; // Textura para usar como backbuffer - JA_Music_t *music_; // Musica de fondo std::unique_ptr<Fade> fade_; // Objeto para renderizar fades std::unique_ptr<Background> background_; // Objeto para dibujar el fondo del juego @@ -68,7 +66,7 @@ private: public: // Constructor - explicit HiScoreTable(JA_Music_t *music); + HiScoreTable(); // Destructor ~HiScoreTable(); diff --git a/source/instructions.cpp b/source/instructions.cpp index de1be26..5b7d026 100644 --- a/source/instructions.cpp +++ b/source/instructions.cpp @@ -13,6 +13,7 @@ #include "jail_audio.h" // for JA_GetMusicState, JA_Music_state #include "lang.h" // for getText #include "param.h" // for param +#include "resource.h" // for Resource #include "screen.h" // for Screen #include "section.h" // for Name, name, Options, options #include "sprite.h" // for Sprite @@ -23,8 +24,7 @@ struct JA_Music_t; // lines 22-22 // Constructor -Instructions::Instructions(JA_Music_t *music) - : music_(music) +Instructions::Instructions() { // Copia los punteros renderer_ = Screen::get()->getRenderer(); @@ -80,21 +80,12 @@ Instructions::~Instructions() void Instructions::iniSprites() { // Inicializa las texturas - auto item1 = std::make_shared<Texture>(renderer_, Asset::get()->get("item_points1_disk.png")); - item_textures_.push_back(item1); - - auto item2 = std::make_shared<Texture>(renderer_, Asset::get()->get("item_points2_gavina.png")); - item_textures_.push_back(item2); - - auto item3 = std::make_shared<Texture>(renderer_, Asset::get()->get("item_points3_pacmar.png")); - item_textures_.push_back(item3); - - auto item4 = std::make_shared<Texture>(renderer_, Asset::get()->get("item_clock.png")); - item_textures_.push_back(item4); - - auto item5 = std::make_shared<Texture>(renderer_, Asset::get()->get("item_coffee.png")); - item_textures_.push_back(item5); - + item_textures_.emplace_back(std::make_shared<Texture>(renderer_, Asset::get()->get("item_points1_disk.png"))); + item_textures_.emplace_back(std::make_shared<Texture>(renderer_, Asset::get()->get("item_points2_gavina.png"))); + item_textures_.emplace_back(std::make_shared<Texture>(renderer_, Asset::get()->get("item_points3_pacmar.png"))); + item_textures_.emplace_back(std::make_shared<Texture>(renderer_, Asset::get()->get("item_clock.png"))); + item_textures_.emplace_back(std::make_shared<Texture>(renderer_, Asset::get()->get("item_coffee.png"))); + // Inicializa los sprites for (int i = 0; i < (int)item_textures_.size(); ++i) { @@ -231,7 +222,7 @@ void Instructions::update() // Mantiene la música sonando if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED)) - JA_PlayMusic(music_); + JA_PlayMusic(Resource::get()->getMusic("title.ogg")); // Actualiza el objeto screen Screen::get()->update(); diff --git a/source/instructions.h b/source/instructions.h index 3b543db..1a3cb32 100644 --- a/source/instructions.h +++ b/source/instructions.h @@ -37,7 +37,6 @@ private: std::unique_ptr<Fade> fade_; // Objeto para renderizar fades SDL_Renderer *renderer_; // El renderizador de la ventana - JA_Music_t *music_; // Musica de fondo SDL_Texture *texture_; // Textura fija con el texto SDL_Texture *backbuffer_; // Textura para usar como backbuffer @@ -79,7 +78,7 @@ private: public: // Constructor - explicit Instructions(JA_Music_t *music); + Instructions(); // Destructor ~Instructions(); diff --git a/source/intro.cpp b/source/intro.cpp index 9f0a6c0..cfedb83 100644 --- a/source/intro.cpp +++ b/source/intro.cpp @@ -9,6 +9,7 @@ #include "jail_audio.h" // for JA_StopMusic, JA_PlayMusic #include "lang.h" // for getText #include "param.h" // for param +#include "resource.h" // for Resource #include "screen.h" // for Screen #include "section.h" // for Name, name, Options, options #include "smart_sprite.h" // for SpriteSmart @@ -19,8 +20,7 @@ struct JA_Music_t; // lines 19-19 // Constructor -Intro::Intro(JA_Music_t *music) - : music_(music) +Intro::Intro() { // Copia los punteros auto renderer = Screen::get()->getRenderer(); @@ -425,7 +425,7 @@ void Intro::render() // Bucle principal void Intro::run() { - JA_PlayMusic(music_, 0); + JA_PlayMusic(Resource::get()->getMusic("intro.ogg"), 0); while (section::name == section::Name::INTRO) { diff --git a/source/intro.h b/source/intro.h index 9c4dbf3..eb0e739 100644 --- a/source/intro.h +++ b/source/intro.h @@ -28,7 +28,6 @@ private: // Variables Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa Uint8 ticks_speed_; // Velocidad a la que se repiten los bucles del programa - JA_Music_t *music_; // Musica para la intro int scene_; // Indica que escena está activa // Actualiza las variables del objeto @@ -51,7 +50,7 @@ private: public: // Constructor - explicit Intro(JA_Music_t *music); + Intro(); // Destructor ~Intro() = default; diff --git a/source/jail_audio.cpp b/source/jail_audio.cpp index 700e0b4..9b04a88 100644 --- a/source/jail_audio.cpp +++ b/source/jail_audio.cpp @@ -223,7 +223,7 @@ JA_Sound_t *JA_LoadSound(const char* filename) { int JA_PlaySound(JA_Sound_t *sound, const int loop) { - if (!JA_soundEnabled) return 0; + if (!JA_soundEnabled || !sound) return 0; int channel = 0; while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; } diff --git a/source/resource.cpp b/source/resource.cpp new file mode 100644 index 0000000..b3e74d4 --- /dev/null +++ b/source/resource.cpp @@ -0,0 +1,101 @@ +#include "resource.h" +#include "asset.h" + +// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado +Resource *Resource::resource_ = nullptr; + +// [SINGLETON] Crearemos el objeto screen con esta función estática +void Resource::init() +{ + Resource::resource_ = new Resource(); +} + +// [SINGLETON] Destruiremos el objeto screen con esta función estática +void Resource::destroy() +{ + delete Resource::resource_; +} + +// [SINGLETON] Con este método obtenemos el objeto screen y podemos trabajar con él +Resource *Resource::get() +{ + return Resource::resource_; +} + +// Constructor +Resource::Resource() +{ + loadSounds(); + loadMusics(); +} + +// Destructor +Resource::~Resource() +{ + sounds_.clear(); + musics_.clear(); +} + +// Obtiene el fichero de sonido a partir de un nombre +JA_Sound_t *Resource::getSound(const std::string &name) +{ + for (const auto &s : sounds_) + { + if (s.name == name) + { + return s.sound; + } + } + return nullptr; +} + +// Obtiene el fichero de música a partir de un nombre +JA_Music_t *Resource::getMusic(const std::string &name) +{ + for (const auto &m : musics_) + { + if (m.name == name) + { + return m.music; + } + } + return nullptr; +} + +// Carga los sonidos del juego +void Resource::loadSounds() +{ + // Obtiene la lista con las rutas a los ficheros de sonidos + auto list = Asset::get()->getListByType(AssetType::SOUND); + sounds_.clear(); + + for (const auto &l : list) + { + // Encuentra el último índice de '/' + auto last_index = l.find_last_of('/') + 1; + + // Obtiene la subcadena desde el último '/' + auto name = l.substr(last_index); + + sounds_.emplace_back(ResourceSound{name, JA_LoadSound(l.c_str())}); + } +} + +// Carga las musicas del juego +void Resource::loadMusics() +{ + // Obtiene la lista con las rutas a los ficheros musicales + auto list = Asset::get()->getListByType(AssetType::MUSIC); + musics_.clear(); + + for (const auto &l : list) + { + // Encuentra el último índice de '/' + auto last_index = l.find_last_of('/') + 1; + + // Obtiene la subcadena desde el último '/' + auto name = l.substr(last_index); + + musics_.emplace_back(ResourceMusic{name, JA_LoadMusic(l.c_str())}); + } +} \ No newline at end of file diff --git a/source/resource.h b/source/resource.h new file mode 100644 index 0000000..e301ae6 --- /dev/null +++ b/source/resource.h @@ -0,0 +1,60 @@ +#pragma once + +#include <SDL2/SDL.h> +#include <vector> +#include <string> +#include "jail_audio.h" + +// Estructura para almacenar ficheros de sonido y su nombre +struct ResourceSound +{ + std::string name; // Nombre del sonido + JA_Sound_t *sound; // Fichero con el sonido +}; + +// Estructura para almacenar ficheros musicales y su nombre +struct ResourceMusic +{ + std::string name; // Nombre de la musica + JA_Music_t *music; // Fichero con la música +}; + +class Resource +{ +private: + // [SINGLETON] Objeto resource privado para Don Melitón + static Resource *resource_; + + std::vector<ResourceSound> sounds_; // Vector con los sonidos + std::vector<ResourceMusic> musics_; // Vector con las musicas + + // Carga los sonidos del juego + void loadSounds(); + + // Carga las musicas del juego + void loadMusics(); + + // [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos resource desde fuera + + // Constructor + Resource(); + + // Destructor + ~Resource(); + +public: + // [SINGLETON] Crearemos el objeto resource con esta función estática + static void init(); + + // [SINGLETON] Destruiremos el objeto resource con esta función estática + static void destroy(); + + // [SINGLETON] Con este método obtenemos el objeto resource y podemos trabajar con él + static Resource *get(); + + // Obtiene el fichero de sonido a partir de un nombre + JA_Sound_t *getSound(const std::string &name); + + // Obtiene el fichero de música a partir de un nombre + JA_Music_t *getMusic(const std::string &name); +}; \ No newline at end of file diff --git a/source/title.cpp b/source/title.cpp index c979d8b..18e997d 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -15,6 +15,7 @@ #include "notifier.h" // for Notifier #include "options.h" // for options #include "param.h" // for param +#include "resource.h" // for Resource #include "screen.h" // for Screen #include "section.h" // for Options, options, Name, name #include "texture.h" // for Texture @@ -22,13 +23,10 @@ struct JA_Music_t; // lines 17-17 // Constructor -Title::Title(JA_Music_t *music) - : music_(music) +Title::Title() { // Copia las direcciones de los punteros y objetos - input_ = Input::get(); - screen_ = Screen::get(); - SDL_Renderer *renderer = screen_->getRenderer(); + SDL_Renderer *renderer = Screen::get()->getRenderer(); // Reserva memoria y crea los objetos fade_ = std::make_unique<Fade>(renderer); @@ -66,7 +64,7 @@ void Title::init() fade_->setType(FadeType::RANDOM_SQUARE); fade_->setPost(param.fade.post_duration); demo_ = true; - num_controllers_ = input_->getNumControllers(); + num_controllers_ = Input::get()->getNumControllers(); } // Actualiza las variables del objeto @@ -79,7 +77,7 @@ void Title::update() ticks_ = SDL_GetTicks(); // Actualiza el objeto screen - screen_->update(); + Screen::get()->update(); // Comprueba el fade_ y si se ha acabado fade_->update(); @@ -116,7 +114,7 @@ void Title::update() // Reproduce la música if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED)) { - JA_PlayMusic(music_); + JA_PlayMusic(Resource::get()->getMusic("title.ogg")); } // Actualiza el logo con el título del juego @@ -138,10 +136,10 @@ void Title::update() void Title::render() { // Prepara para empezar a dibujar en la textura de juego - screen_->start(); + Screen::get()->start(); // Limpia la pantalla - screen_->clean(bg_color); + Screen::get()->clean(bg_color); // Dibuja el mosacico de fondo tiled_bg_->render(); @@ -176,7 +174,7 @@ void Title::render() fade_->render(); // Vuelca el contenido del renderizador en pantalla - screen_->blit(); + Screen::get()->blit(); } // Comprueba los eventos @@ -241,7 +239,7 @@ void Title::checkInput() if (!define_buttons_->isEnabled()) { // Comprueba el teclado para empezar a jugar - if (input_->checkInput(InputType::START, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_KEYBOARD)) + if (Input::get()->checkInput(InputType::START, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_KEYBOARD)) { if (section::options == section::Options::TITLE_2 || ALLOW_TITLE_ANIMATION_SKIP) { @@ -251,27 +249,27 @@ void Title::checkInput() } // Comprueba los mandos - for (int i = 0; i < input_->getNumControllers(); ++i) + for (int i = 0; i < Input::get()->getNumControllers(); ++i) { // Comprueba si se va a intercambiar la asignación de mandos a jugadores - if (input_->checkModInput(InputType::SERVICE, InputType::SWAP_CONTROLLERS, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_GAMECONTROLLER, i)) + if (Input::get()->checkModInput(InputType::SERVICE, InputType::SWAP_CONTROLLERS, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_GAMECONTROLLER, i)) { swapControllers(); return; } // Comprueba si algun mando quiere ser configurado - if (input_->checkModInput(InputType::SERVICE, InputType::CONFIG, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_GAMECONTROLLER, i)) + if (Input::get()->checkModInput(InputType::SERVICE, InputType::CONFIG, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_GAMECONTROLLER, i)) { define_buttons_->enable(i); return; } // Comprueba el botón de START de los mandos - if (input_->checkInput(InputType::START, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_GAMECONTROLLER, i)) + if (Input::get()->checkInput(InputType::START, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_GAMECONTROLLER, i)) { // Si no está el botón de servicio activo - if (!input_->checkInput(InputType::SERVICE, INPUT_ALLOW_REPEAT, INPUT_USE_GAMECONTROLLER, i)) + if (!Input::get()->checkInput(InputType::SERVICE, INPUT_ALLOW_REPEAT, INPUT_USE_GAMECONTROLLER, i)) { if (section::options == section::Options::TITLE_2 || ALLOW_TITLE_ANIMATION_SKIP) { @@ -285,7 +283,7 @@ void Title::checkInput() } // Comprueba el input para el resto de objetos - screen_->checkInput(); + Screen::get()->checkInput(); define_buttons_->checkInput(); // Comprueba los inputs que se pueden introducir en cualquier sección del juego @@ -320,7 +318,7 @@ void Title::resetCounter() // Intercambia la asignación de mandos a los jugadores void Title::swapControllers() { - const auto num_controllers = input_->getNumControllers(); + const auto num_controllers = Input::get()->getNumControllers(); if (num_controllers == 0) { diff --git a/source/title.h b/source/title.h index 8e820d8..b83cf7e 100644 --- a/source/title.h +++ b/source/title.h @@ -40,8 +40,6 @@ class Title { private: // Objetos y punteros - Screen *screen_; // Objeto encargado de dibujar en pantalla - Input *input_; // Objeto para leer las entradas de teclado o mando std::unique_ptr<Tiledbg> tiled_bg_; // Objeto para dibujar el mosaico animado de fondo std::unique_ptr<GameLogo> game_logo_; // Objeto para dibujar el logo con el título del juego std::unique_ptr<DefineButtons> define_buttons_; // Objeto para definir los botones del joystic @@ -52,8 +50,6 @@ private: std::unique_ptr<Text> text2_; // Objeto de texto para poder escribir textos en pantalla std::unique_ptr<Fade> fade_; // Objeto para realizar fundidos en pantalla - JA_Music_t *music_; // Musica para el titulo - // Variable int counter_; // Temporizador para la pantalla de titulo Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa @@ -89,7 +85,7 @@ private: public: // Constructor - explicit Title(JA_Music_t *music); + Title(); // Destructor ~Title() = default; diff --git a/source/utils.cpp b/source/utils.cpp index bd1f055..58ab02e 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -104,38 +104,6 @@ std::string toLower(const std::string &str) return result; } -// Obtiene el fichero de sonido a partir de un nombre -JA_Sound_t *getSound(const std::vector<SoundFile> &sounds, const std::string &name) -{ - for (const auto &s : sounds) - { - if (s.name == name) - { - return s.file; - } - } - return nullptr; -} - -// Obtiene el fichero de música a partir de un nombre -JA_Music_t *getMusic(const std::vector<MusicFile> &music, const std::string &name) -{ - for (const auto &m : music) - { - if (m.name == name) - { - return m.file; - } - } - return nullptr; -} - -// Ordena las entradas de la tabla de records -HiScoreEntry sortHiScoreTable(const HiScoreEntry &entry1, const HiScoreEntry &entry2) -{ - return (entry1.score > entry2.score) ? entry1 : entry2; -} - // Dibuja un circulo void DrawCircle(SDL_Renderer *renderer, int32_t centerX, int32_t centerY, int32_t radius) { diff --git a/source/utils.h b/source/utils.h index 3607b83..59471a8 100644 --- a/source/utils.h +++ b/source/utils.h @@ -215,19 +215,6 @@ struct Param ParamNotification notification; // Opciones para las notificaciones }; -// Estructura para almacenar ficheros de sonido y su nombre -struct SoundFile -{ - std::string name; // Nombre del sonido - JA_Sound_t *file; // Fichero con el sonido -}; - -// Estructura para almacenar ficheros musicales y su nombre -struct MusicFile -{ - std::string name; // Nombre de la musica - JA_Music_t *file; // Fichero con la música -}; // Calcula el cuadrado de la distancia entre dos puntos double distanceSquared(int x1, int y1, int x2, int y2); @@ -256,15 +243,6 @@ std::string boolToOnOff(bool value); // Convierte una cadena a minusculas std::string toLower(const std::string &str); -// Obtiene el fichero de sonido a partir de un nombre -JA_Sound_t *getSound(const std::vector<SoundFile> &sounds, const std::string &name); - -// Obtiene el fichero de música a partir de un nombre -JA_Music_t *getMusic(const std::vector<MusicFile> &music, const std::string &name); - -// Ordena las entradas de la tabla de records -HiScoreEntry sortHiScoreTable(const HiScoreEntry &entry1, const HiScoreEntry &entry2); - // Dibuja un circulo void DrawCircle(SDL_Renderer *renderer, int32_t centerX, int32_t centerY, int32_t radius);