diff --git a/source/animated_sprite.cpp b/source/animated_sprite.cpp index 7e32ac6..ec5787d 100644 --- a/source/animated_sprite.cpp +++ b/source/animated_sprite.cpp @@ -5,6 +5,29 @@ #include // for back_insert_iterator, back_inserter #include // for basic_stringstream #include "texture.h" // for Texture +#include "utils.h" + +// Carga las animaciones en un vector(Animations) desde un fichero +Animations loadAnimationsFromFile(const std::string &file_path) +{ + std::vector buffer; + std::ifstream file(file_path); + if (!file) + { + std::cerr << "Error: Fichero no encontrado " << file_path << std::endl; + throw std::runtime_error("Fichero no encontrado: " + file_path); + } + + std::string line; + printWithDots("Animation : ", file_path.substr(file_path.find_last_of("\\/") + 1), "[ LOADED ]"); + + while (std::getline(file, line)) + { + buffer.push_back(line); + } + + return buffer; +} // Constructor AnimatedSprite::AnimatedSprite(std::shared_ptr texture, const std::string &file_path) @@ -18,7 +41,7 @@ AnimatedSprite::AnimatedSprite(std::shared_ptr texture, const std::stri } } -AnimatedSprite::AnimatedSprite(std::shared_ptr texture, const std::vector &animations) +AnimatedSprite::AnimatedSprite(std::shared_ptr texture, const Animations &animations) : MovingSprite(texture), current_animation_(0) { @@ -372,7 +395,7 @@ std::vector AnimatedSprite::loadFromFile(const std::string &file_path } // Carga la animación desde un vector -bool AnimatedSprite::loadFromVector(const std::vector &source) +bool AnimatedSprite::loadFromVector(const Animations &source) { // Inicializa variables auto frames_per_row = 0; diff --git a/source/animated_sprite.h b/source/animated_sprite.h index f8f69b1..855177e 100644 --- a/source/animated_sprite.h +++ b/source/animated_sprite.h @@ -21,6 +21,11 @@ struct Animation Animation() : name(std::string()), speed(5), loop(0), completed(false), current_frame(0), counter(0) {} }; +using Animations = std::vector; + +// Carga las animaciones en un vector(Animations) desde un fichero +Animations loadAnimationsFromFile(const std::string &file_path); + class AnimatedSprite : public MovingSprite { protected: @@ -35,12 +40,12 @@ protected: std::vector loadFromFile(const std::string &file_path); // Carga la animación desde un vector - bool loadFromVector(const std::vector &source); + bool loadFromVector(const Animations &source); public: // Constructor AnimatedSprite(std::shared_ptr texture, const std::string &file_path); - AnimatedSprite(std::shared_ptr texture, const std::vector &animations); + AnimatedSprite(std::shared_ptr texture, const Animations &animations); explicit AnimatedSprite(std::shared_ptr texture); // Destructor diff --git a/source/asset.cpp b/source/asset.cpp index 60b4e27..54d8b3d 100644 --- a/source/asset.cpp +++ b/source/asset.cpp @@ -1,4 +1,5 @@ #include "asset.h" +#include "utils.h" #include // for SDL_RWFromFile, SDL_RWclose, SDL_RWops #include // for SDL_max #include // for size_t @@ -68,10 +69,10 @@ bool Asset::check() const { bool success = true; - std::cout << "\n** Checking files" << std::endl; + std::cout << "\n** CHECKING FILES" << std::endl; - std::cout << "Executable path is: " << executable_path_ << std::endl; - std::cout << "Sample filepath: " << file_list_.back().file << std::endl; + // std::cout << "Executable path is: " << executable_path_ << std::endl; + // std::cout << "Sample filepath: " << file_list_.back().file << std::endl; // Comprueba la lista de ficheros clasificandolos por tipo for (int type = 0; type < static_cast(AssetType::MAX_ASSET_TYPE); ++type) @@ -99,11 +100,13 @@ bool Asset::check() const success &= checkFile(f.file); } } + if (success) + std::cout << " All files are OK." << std::endl; } } // Resultado - std::cout << (success ? "\n** All files OK.\n" : "\n** A file is missing. Exiting.\n") << std::endl; + std::cout << (success ? "\n** CHECKING FILES COMPLETED.\n" : "\n** CHECKING FILES FAILED.\n") << std::endl; return success; } @@ -123,12 +126,8 @@ bool Asset::checkFile(const std::string &path) const } const std::string file_name = path.substr(path.find_last_of("\\/") + 1); - std::cout.setf(std::ios::left, std::ios::adjustfield); - std::cout << "Checking file: "; - std::cout.width(longest_name_ + 2); - std::cout.fill('.'); - std::cout << file_name; - std::cout << (success ? " [OK]" : " [ERROR]") << std::endl; + if (!success) + printWithDots("Checking file : ", file_name, (success ? " [ OK ]" : " [ ERROR ]")); return success; } diff --git a/source/background.cpp b/source/background.cpp index 526fdfe..a93b0b0 100644 --- a/source/background.cpp +++ b/source/background.cpp @@ -3,19 +3,20 @@ #include // for SDL_PIXELFORMAT_RGBA8888 #include // for clamp, max #include "asset.h" // for Asset -#include "moving_sprite.h" // for MovingSprite +#include "moving_sprite.h" // for MovingSprite #include "param.h" // for param +#include "resource.h" // for Resource #include "sprite.h" // for Sprite #include "texture.h" // for Texture // Constructor Background::Background(SDL_Renderer *renderer) : renderer_(renderer), - buildings_texture_(std::make_shared(renderer, Asset::get()->get("game_buildings.png"))), - top_clouds_texture_(std::make_shared(renderer, Asset::get()->get("game_clouds1.png"))), - bottom_clouds_texture_(std::make_shared(renderer, Asset::get()->get("game_clouds2.png"))), - grass_texture_(std::make_shared(renderer, Asset::get()->get("game_grass.png"))), - gradients_texture_(std::make_shared(renderer, Asset::get()->get("game_sky_colors.png"))) + buildings_texture_(Resource::get()->getTexture("game_buildings.png")), + top_clouds_texture_(Resource::get()->getTexture("game_clouds1.png")), + bottom_clouds_texture_(Resource::get()->getTexture("game_clouds2.png")), + grass_texture_(Resource::get()->getTexture("game_grass.png")), + gradients_texture_(Resource::get()->getTexture("game_sky_colors.png")) { // Inicializa variables diff --git a/source/director.cpp b/source/director.cpp index 4d52d05..15be44d 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -74,11 +74,8 @@ Director::Director(int argc, const char *argv[]) // Crea el objeto que controla los ficheros de recursos Asset::init(executable_path_); - // Si falta algún fichero no inicia el programa - if (!setFileList()) - { - exit(EXIT_FAILURE); - } + // Crea el indice de ficheros + setFileList(); // Carga el fichero de configuración loadOptionsFile(Asset::get()->get("config.txt")); @@ -107,14 +104,15 @@ Director::Director(int argc, const char *argv[]) // Crea los objetos lang::loadFromFile(getLangFile((lang::Code)options.game.language)); + Screen::init(window_, renderer_); + Resource::init(); Input::init(Asset::get()->get("gamecontrollerdb.txt")); - initInput(); + bindInputs(); - Screen::init(window_, renderer_); - - Notifier::init(renderer_, std::string(), Asset::get()->get("8bithud.png"), Asset::get()->get("8bithud.txt"), Asset::get()->get("notify.wav")); + auto notifier_text = std::make_shared(Resource::get()->getTexture("8bithud.png"), Resource::get()->getTextFile("8bithud.txt")); + Notifier::init(std::string(), notifier_text, Asset::get()->get("notify.wav")); OnScreenHelp::init(); @@ -132,19 +130,15 @@ Director::~Director() Notifier::destroy(); OnScreenHelp::destroy(); - SDL_DestroyRenderer(renderer_); SDL_DestroyWindow(window_); SDL_Quit(); } -/// Inicializa el objeto input -void Director::initInput() +// Asigna los botones y teclas al objeto Input +void Director::bindInputs() { - // Busca si hay mandos conectados - Input::get()->discoverGameControllers(); - // Teclado - Movimiento del jugador Input::get()->bindKey(InputType::UP, SDL_SCANCODE_UP); Input::get()->bindKey(InputType::DOWN, SDL_SCANCODE_DOWN); @@ -331,7 +325,7 @@ bool Director::initSDL() } // Crea el indice de ficheros -bool Director::setFileList() +void Director::setFileList() { #ifdef MACOS_BUNDLE const std::string prefix = "/../Resources"; @@ -456,17 +450,17 @@ bool Director::setFileList() Asset::get()->add(prefix + "/data/gfx/player/player_power.ani", AssetType::ANIMATION); // Fuentes de texto - Asset::get()->add(prefix + "/data/font/8bithud.png", AssetType::FONT); + Asset::get()->add(prefix + "/data/font/8bithud.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/font/8bithud.txt", AssetType::FONT); - Asset::get()->add(prefix + "/data/font/nokia.png", AssetType::FONT); - Asset::get()->add(prefix + "/data/font/nokia_big2.png", AssetType::FONT); + Asset::get()->add(prefix + "/data/font/nokia.png", AssetType::BITMAP); + Asset::get()->add(prefix + "/data/font/nokia_big2.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/font/nokia.txt", AssetType::FONT); - Asset::get()->add(prefix + "/data/font/nokia2.png", AssetType::FONT); + Asset::get()->add(prefix + "/data/font/nokia2.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/font/nokia2.txt", AssetType::FONT); Asset::get()->add(prefix + "/data/font/nokia_big2.txt", AssetType::FONT); - Asset::get()->add(prefix + "/data/font/smb2_big.png", AssetType::FONT); + Asset::get()->add(prefix + "/data/font/smb2_big.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/font/smb2_big.txt", AssetType::FONT); - Asset::get()->add(prefix + "/data/font/smb2.gif", AssetType::FONT); + Asset::get()->add(prefix + "/data/font/smb2.gif", AssetType::BITMAP); Asset::get()->add(prefix + "/data/font/smb2_pal1.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/font/smb2.txt", AssetType::FONT); @@ -475,7 +469,9 @@ bool Director::setFileList() Asset::get()->add(prefix + "/data/lang/en_UK.txt", AssetType::LANG); Asset::get()->add(prefix + "/data/lang/ba_BA.txt", AssetType::LANG); - return Asset::get()->check(); + // Si falta algun fichero, sale del programa + if (!Asset::get()->check()) + throw std::runtime_error("Falta algun fichero"); } // Carga los parametros para configurar el juego diff --git a/source/director.h b/source/director.h index 8632744..1993504 100644 --- a/source/director.h +++ b/source/director.h @@ -20,7 +20,7 @@ private: // Objetos y punteros 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 + std::streambuf *orig_buf; // Puntero al buffer de flujo original para restaurar std::cout // Variables std::string executable_path_; // Path del ejecutable @@ -33,14 +33,14 @@ private: // Arranca SDL y crea la ventana bool initSDL(); - // Inicializa el objeto input - void initInput(); + // Asigna los botones y teclas al objeto Input + void bindInputs(); // Carga los parametros para configurar el juego void loadParams(const std::string &file_path); // Crea el indice de ficheros - bool setFileList(); + void setFileList(); // Comprueba los parametros del programa void checkProgramArguments(int argc, const char *argv[]); diff --git a/source/fade.cpp b/source/fade.cpp index 649b648..7fce218 100644 --- a/source/fade.cpp +++ b/source/fade.cpp @@ -4,11 +4,12 @@ #include // for rand #include // for min, max #include "param.h" // for param +#include "screen.h" #include "utils.h" // for Param, ParamGame, ParamFade // Constructor -Fade::Fade(SDL_Renderer *renderer) - : renderer_(renderer) +Fade::Fade() + : renderer_(Screen::get()->getRenderer()) { // Crea la textura donde dibujar el fade backbuffer_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height); diff --git a/source/fade.h b/source/fade.h index fb7323a..e52928e 100644 --- a/source/fade.h +++ b/source/fade.h @@ -54,7 +54,7 @@ private: public: // Constructor - explicit Fade(SDL_Renderer *renderer); + Fade(); // Destructor ~Fade(); diff --git a/source/game.cpp b/source/game.cpp index 6f9e951..dd27525 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -57,7 +57,7 @@ Game::Game(int player_id, int current_stage, bool demo) // Crea los objetos Scoreboard::init(renderer_); scoreboard_ = Scoreboard::get(); - fade_ = std::make_unique(renderer_); + fade_ = std::make_unique(); background_ = std::make_unique(renderer_); explosions_ = std::make_unique(); @@ -300,74 +300,58 @@ void Game::init(int player_id) // Carga los recursos necesarios para la sección 'Game' void Game::loadMedia() { - std::cout << "\n** LOADING RESOURCES FOR GAME SECTION" << std::endl; - - // Limpia - { - // Texturas - game_text_textures_.clear(); - balloon_textures_.clear(); - explosions_textures_.clear(); - item_textures_.clear(); - player_textures_.clear(); - - // Animaciones - player_animations_.clear(); - balloon_animations_.clear(); - explosions_animations_.clear(); - item_animations_.clear(); - } + unloadMedia(); // Texturas { - bullet_texture_ = std::make_shared(renderer_, asset_->get("bullet.png")); + bullet_texture_ = Resource::get()->getTexture("bullet.png"); } // Texturas - Game_text { - game_text_textures_.emplace_back(std::make_shared(renderer_, asset_->get("game_text_1000_points.png"))); - game_text_textures_.emplace_back(std::make_shared(renderer_, asset_->get("game_text_2500_points.png"))); - game_text_textures_.emplace_back(std::make_shared(renderer_, asset_->get("game_text_5000_points.png"))); - game_text_textures_.emplace_back(std::make_shared(renderer_, asset_->get("game_text_powerup.png"))); - game_text_textures_.emplace_back(std::make_shared(renderer_, asset_->get("game_text_one_hit.png"))); + game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_1000_points.png")); + game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_2500_points.png")); + game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_5000_points.png")); + game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_powerup.png")); + game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_one_hit.png")); } // Texturas - Globos { - balloon_textures_.emplace_back(std::make_shared(renderer_, asset_->get("balloon1.png"))); - balloon_textures_.emplace_back(std::make_shared(renderer_, asset_->get("balloon2.png"))); - balloon_textures_.emplace_back(std::make_shared(renderer_, asset_->get("balloon3.png"))); - balloon_textures_.emplace_back(std::make_shared(renderer_, asset_->get("balloon4.png"))); - balloon_textures_.emplace_back(std::make_shared(renderer_, asset_->get("powerball.png"))); + balloon_textures_.emplace_back(Resource::get()->getTexture("balloon1.png")); + balloon_textures_.emplace_back(Resource::get()->getTexture("balloon2.png")); + balloon_textures_.emplace_back(Resource::get()->getTexture("balloon3.png")); + balloon_textures_.emplace_back(Resource::get()->getTexture("balloon4.png")); + balloon_textures_.emplace_back(Resource::get()->getTexture("powerball.png")); } // Texturas - Explosiones { - explosions_textures_.emplace_back(std::make_shared(renderer_, asset_->get("explosion1.png"))); - explosions_textures_.emplace_back(std::make_shared(renderer_, asset_->get("explosion2.png"))); - explosions_textures_.emplace_back(std::make_shared(renderer_, asset_->get("explosion3.png"))); - explosions_textures_.emplace_back(std::make_shared(renderer_, asset_->get("explosion4.png"))); + explosions_textures_.emplace_back(Resource::get()->getTexture("explosion1.png")); + explosions_textures_.emplace_back(Resource::get()->getTexture("explosion2.png")); + explosions_textures_.emplace_back(Resource::get()->getTexture("explosion3.png")); + explosions_textures_.emplace_back(Resource::get()->getTexture("explosion4.png")); } // Texturas - Items { - item_textures_.emplace_back(std::make_shared(renderer_, asset_->get("item_points1_disk.png"))); - item_textures_.emplace_back(std::make_shared(renderer_, asset_->get("item_points2_gavina.png"))); - item_textures_.emplace_back(std::make_shared(renderer_, asset_->get("item_points3_pacmar.png"))); - item_textures_.emplace_back(std::make_shared(renderer_, asset_->get("item_clock.png"))); - item_textures_.emplace_back(std::make_shared(renderer_, asset_->get("item_coffee.png"))); - item_textures_.emplace_back(std::make_shared(renderer_, asset_->get("item_coffee_machine.png"))); + item_textures_.emplace_back(Resource::get()->getTexture("item_points1_disk.png")); + item_textures_.emplace_back(Resource::get()->getTexture("item_points2_gavina.png")); + item_textures_.emplace_back(Resource::get()->getTexture("item_points3_pacmar.png")); + item_textures_.emplace_back(Resource::get()->getTexture("item_clock.png")); + item_textures_.emplace_back(Resource::get()->getTexture("item_coffee.png")); + item_textures_.emplace_back(Resource::get()->getTexture("item_coffee_machine.png")); } // Texturas - Player1 { std::vector> player_texture; - player_texture.emplace_back(std::make_shared(renderer_, asset_->get("player1.gif"))); + player_texture.emplace_back(Resource::get()->getTexture("player1.gif")); player_texture.back()->addPalette(asset_->get("player1_pal1.gif")); player_texture.back()->addPalette(asset_->get("player1_pal2.gif")); player_texture.back()->addPalette(asset_->get("player1_pal3.gif")); - player_texture.emplace_back(std::make_shared(renderer_, asset_->get("player_power.gif"))); + player_texture.emplace_back(Resource::get()->getTexture("player_power.gif")); player_texture.back()->addPalette(asset_->get("player_power_pal.gif")); player_textures_.push_back(player_texture); @@ -376,12 +360,12 @@ void Game::loadMedia() // Texturas - Player2 { std::vector> player_texture; - player_texture.emplace_back(std::make_shared(renderer_, asset_->get("player2.gif"))); + player_texture.emplace_back(Resource::get()->getTexture("player2.gif")); player_texture.back()->addPalette(asset_->get("player2_pal1.gif")); player_texture.back()->addPalette(asset_->get("player2_pal2.gif")); player_texture.back()->addPalette(asset_->get("player2_pal3.gif")); - player_texture.emplace_back(std::make_shared(renderer_, asset_->get("player_power.gif"))); + player_texture.emplace_back(Resource::get()->getTexture("player_power.gif")); player_texture.back()->addPalette(asset_->get("player_power_pal.gif")); player_texture.back()->setPalette(1); @@ -390,47 +374,44 @@ void Game::loadMedia() // Animaciones -- Jugador { - player_animations_.emplace_back(loadAnimations(asset_->get("player.ani"))); - player_animations_.emplace_back(loadAnimations(asset_->get("player_power.ani"))); + player_animations_.emplace_back(Resource::get()->getAnimation("player.ani")); + player_animations_.emplace_back(Resource::get()->getAnimation("player_power.ani")); } // Animaciones -- Globos { - balloon_animations_.emplace_back(loadAnimations(asset_->get("balloon1.ani"))); - balloon_animations_.emplace_back(loadAnimations(asset_->get("balloon2.ani"))); - balloon_animations_.emplace_back(loadAnimations(asset_->get("balloon3.ani"))); - balloon_animations_.emplace_back(loadAnimations(asset_->get("balloon4.ani"))); - balloon_animations_.emplace_back(loadAnimations(asset_->get("powerball.ani"))); + balloon_animations_.emplace_back(Resource::get()->getAnimation("balloon1.ani")); + balloon_animations_.emplace_back(Resource::get()->getAnimation("balloon2.ani")); + balloon_animations_.emplace_back(Resource::get()->getAnimation("balloon3.ani")); + balloon_animations_.emplace_back(Resource::get()->getAnimation("balloon4.ani")); + balloon_animations_.emplace_back(Resource::get()->getAnimation("powerball.ani")); } // Animaciones -- Explosiones { - explosions_animations_.emplace_back(loadAnimations(asset_->get("explosion1.ani"))); - explosions_animations_.emplace_back(loadAnimations(asset_->get("explosion2.ani"))); - explosions_animations_.emplace_back(loadAnimations(asset_->get("explosion3.ani"))); - explosions_animations_.emplace_back(loadAnimations(asset_->get("explosion4.ani"))); + explosions_animations_.emplace_back(Resource::get()->getAnimation("explosion1.ani")); + explosions_animations_.emplace_back(Resource::get()->getAnimation("explosion2.ani")); + explosions_animations_.emplace_back(Resource::get()->getAnimation("explosion3.ani")); + explosions_animations_.emplace_back(Resource::get()->getAnimation("explosion4.ani")); } // Animaciones -- Items { - item_animations_.emplace_back(loadAnimations(asset_->get("item_points1_disk.ani"))); - item_animations_.emplace_back(loadAnimations(asset_->get("item_points2_gavina.ani"))); - item_animations_.emplace_back(loadAnimations(asset_->get("item_points3_pacmar.ani"))); - item_animations_.emplace_back(loadAnimations(asset_->get("item_clock.ani"))); - item_animations_.emplace_back(loadAnimations(asset_->get("item_coffee.ani"))); - item_animations_.emplace_back(loadAnimations(asset_->get("item_coffee_machine.ani"))); + item_animations_.emplace_back(Resource::get()->getAnimation("item_points1_disk.ani")); + item_animations_.emplace_back(Resource::get()->getAnimation("item_points2_gavina.ani")); + item_animations_.emplace_back(Resource::get()->getAnimation("item_points3_pacmar.ani")); + item_animations_.emplace_back(Resource::get()->getAnimation("item_clock.ani")); + item_animations_.emplace_back(Resource::get()->getAnimation("item_coffee.ani")); + item_animations_.emplace_back(Resource::get()->getAnimation("item_coffee_machine.ani")); } // Texto { - text_ = std::make_unique(asset_->get("smb2.gif"), asset_->get("smb2.txt"), renderer_); - text_big_ = std::make_unique(asset_->get("smb2_big.png"), asset_->get("smb2_big.txt"), renderer_); - text_nokia2_ = std::make_unique(asset_->get("nokia2.png"), asset_->get("nokia2.txt"), renderer_); - text_nokia2_big_ = std::make_unique(asset_->get("nokia_big2.png"), asset_->get("nokia_big2.txt"), renderer_); + text_ = std::make_unique(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt")); + text_big_ = std::make_unique(Resource::get()->getTexture("smb2_big.png"), Resource::get()->getTextFile("smb2_big.txt")); + text_nokia2_ = std::make_unique(Resource::get()->getTexture("nokia2.png"), Resource::get()->getTextFile("nokia2.txt")); + text_nokia2_big_ = std::make_unique(Resource::get()->getTexture("nokia_big2.png"), Resource::get()->getTextFile("nokia_big2.txt")); } - - std::cout << "** RESOURCES FOR GAME SECTION LOADED\n" - << std::endl; } // Libera los recursos previamente cargados @@ -2082,27 +2063,6 @@ void Game::checkEvents() } } -// Carga las animaciones -std::vector Game::loadAnimations(const std::string &file_path) -{ - std::vector buffer; - std::ifstream file(file_path); - if (!file) - { - std::cerr << "Error: no se pudo abrir el archivo " << file_path << std::endl; - return buffer; - } - - std::string line; - std::cout << "Animation loaded: " << file_path.substr(file_path.find_last_of("\\/") + 1) << std::endl; - while (std::getline(file, line)) - { - buffer.push_back(line); - } - - return buffer; -} - // Elimina todos los objetos contenidos en vectores void Game::deleteAllVectorObjects() { diff --git a/source/game.h b/source/game.h index fdf1744..5549d03 100644 --- a/source/game.h +++ b/source/game.h @@ -381,9 +381,6 @@ private: // Comprueba si todos los jugadores han terminado de jugar bool allPlayersAreNotPlaying(); - // Carga las animaciones - std::vector loadAnimations(const std::string &file_path); - // Elimina todos los objetos contenidos en vectores void deleteAllVectorObjects(); diff --git a/source/game_logo.cpp b/source/game_logo.cpp index 37343f1..89b7595 100644 --- a/source/game_logo.cpp +++ b/source/game_logo.cpp @@ -14,13 +14,13 @@ // Constructor GameLogo::GameLogo(int x, int y) - : dust_texture_(std::make_shared(Screen::get()->getRenderer(), Asset::get()->get("title_dust.png"))), - coffee_texture_(std::make_shared(Screen::get()->getRenderer(), Asset::get()->get("title_coffee.png"))), - crisis_texture_(std::make_shared(Screen::get()->getRenderer(), Asset::get()->get("title_crisis.png"))), - arcade_edition_texture_(std::make_shared(Screen::get()->getRenderer(), Asset::get()->get("title_arcade_edition.png"))), + : dust_texture_(Resource::get()->getTexture("title_dust.png")), + coffee_texture_(Resource::get()->getTexture("title_coffee.png")), + crisis_texture_(Resource::get()->getTexture("title_crisis.png")), + arcade_edition_texture_(Resource::get()->getTexture("title_arcade_edition.png")), - dust_left_sprite_(std::make_unique(dust_texture_, Asset::get()->get("title_dust.ani"))), - dust_right_sprite_(std::make_unique(dust_texture_, Asset::get()->get("title_dust.ani"))), + dust_left_sprite_(std::make_unique(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))), + dust_right_sprite_(std::make_unique(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))), coffee_sprite_(std::make_unique(coffee_texture_)), crisis_sprite_(std::make_unique(crisis_texture_)), diff --git a/source/hiscore_table.cpp b/source/hiscore_table.cpp index 8722ecf..921d1c6 100644 --- a/source/hiscore_table.cpp +++ b/source/hiscore_table.cpp @@ -15,7 +15,7 @@ #include "lang.h" // for getText #include "options.h" // for options #include "param.h" // for param -#include "resource.h" // for Resource +#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... @@ -28,9 +28,9 @@ HiScoreTable::HiScoreTable() renderer_ = Screen::get()->getRenderer(); // Objetos - fade_ = std::make_unique(renderer_); + fade_ = std::make_unique(); background_ = std::make_unique(renderer_); - text_ = std::make_unique(Asset::get()->get("smb2.gif"), Asset::get()->get("smb2.txt"), renderer_); + text_ = std::make_unique(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt")); // Crea un backbuffer para el renderizador backbuffer_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height); diff --git a/source/instructions.cpp b/source/instructions.cpp index 5b7d026..928cafd 100644 --- a/source/instructions.cpp +++ b/source/instructions.cpp @@ -19,7 +19,7 @@ #include "sprite.h" // for Sprite #include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR, TEXT_... #include "texture.h" // for Texture -#include "tiled_bg.h" // for Tiledbg, TILED_MODE_STATIC +#include "tiled_bg.h" // for TiledBG, TILED_MODE_STATIC #include "utils.h" // for Param, ParamGame, Color, shdw_txt_color struct JA_Music_t; // lines 22-22 @@ -30,9 +30,9 @@ Instructions::Instructions() renderer_ = Screen::get()->getRenderer(); // Crea objetos - text_ = std::make_unique(Asset::get()->get("smb2.gif"), Asset::get()->get("smb2.txt"), renderer_); - tiled_bg_ = std::make_unique(Asset::get()->get("title_bg_tile.png"), (SDL_Rect){0, 0, param.game.width, param.game.height}, TILED_MODE_STATIC); - fade_ = std::make_unique(renderer_); + text_ = std::make_unique(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt")); + tiled_bg_ = std::make_unique((SDL_Rect){0, 0, param.game.width, param.game.height}, TILED_MODE_STATIC); + fade_ = std::make_unique(); // Crea un backbuffer para el renderizador backbuffer_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height); @@ -80,12 +80,12 @@ Instructions::~Instructions() void Instructions::iniSprites() { // Inicializa las texturas - item_textures_.emplace_back(std::make_shared(renderer_, Asset::get()->get("item_points1_disk.png"))); - item_textures_.emplace_back(std::make_shared(renderer_, Asset::get()->get("item_points2_gavina.png"))); - item_textures_.emplace_back(std::make_shared(renderer_, Asset::get()->get("item_points3_pacmar.png"))); - item_textures_.emplace_back(std::make_shared(renderer_, Asset::get()->get("item_clock.png"))); - item_textures_.emplace_back(std::make_shared(renderer_, Asset::get()->get("item_coffee.png"))); - + item_textures_.emplace_back(Resource::get()->getTexture("item_points1_disk.png")); + item_textures_.emplace_back(Resource::get()->getTexture("item_points2_gavina.png")); + item_textures_.emplace_back(Resource::get()->getTexture("item_points3_pacmar.png")); + item_textures_.emplace_back(Resource::get()->getTexture("item_clock.png")); + item_textures_.emplace_back(Resource::get()->getTexture("item_coffee.png")); + // Inicializa los sprites for (int i = 0; i < (int)item_textures_.size(); ++i) { diff --git a/source/instructions.h b/source/instructions.h index 1a3cb32..5d060c0 100644 --- a/source/instructions.h +++ b/source/instructions.h @@ -1,16 +1,16 @@ #pragma once -#include // for SDL_Point, SDL_Rect -#include // for SDL_Texture, SDL_Renderer -#include // for Uint32 -#include // for unique_ptr, shared_ptr -#include // for vector +#include // for SDL_Point, SDL_Rect +#include // for SDL_Texture, SDL_Renderer +#include // for Uint32 +#include // for unique_ptr, shared_ptr +#include // for vector class Fade; class Sprite; class Text; class Texture; -class Tiledbg; -struct JA_Music_t; // lines 14-14 +class TiledBG; +struct JA_Music_t; // lines 14-14 /* Esta clase gestiona un estado del programa. Se encarga de poner en pantalla @@ -33,7 +33,7 @@ private: std::vector> item_textures_; // Vector con las texturas de los items std::vector> sprites_; // Vector con los sprites de los items std::unique_ptr text_; // Objeto para escribir texto - std::unique_ptr tiled_bg_; // Objeto para dibujar el mosaico animado de fondo + std::unique_ptr tiled_bg_; // Objeto para dibujar el mosaico animado de fondo std::unique_ptr fade_; // Objeto para renderizar fades SDL_Renderer *renderer_; // El renderizador de la ventana diff --git a/source/intro.cpp b/source/intro.cpp index cfedb83..a44d6a8 100644 --- a/source/intro.cpp +++ b/source/intro.cpp @@ -22,12 +22,9 @@ struct JA_Music_t; // lines 19-19 // Constructor Intro::Intro() { - // Copia los punteros - auto renderer = Screen::get()->getRenderer(); - // Reserva memoria para los objetos - texture_ = std::make_shared(renderer, Asset::get()->get("intro.png")); - text_ = std::make_shared(Asset::get()->get("nokia.png"), Asset::get()->get("nokia.txt"), renderer); + texture_ = Resource::get()->getTexture("intro.png"); + text_ = std::make_shared(Resource::get()->getTexture("nokia.png"), Resource::get()->getTextFile("nokia.txt")); // Inicializa variables section::name = section::Name::INTRO; diff --git a/source/jail_audio.cpp b/source/jail_audio.cpp index 9b04a88..e5fc310 100644 --- a/source/jail_audio.cpp +++ b/source/jail_audio.cpp @@ -129,7 +129,7 @@ JA_Music_t *JA_LoadMusic(const char* filename) { void JA_PlayMusic(JA_Music_t *music, const int loop) { - if (!JA_musicEnabled) return; + if (!JA_musicEnabled || !music) return; if (current_music != NULL) { current_music->pos = 0; diff --git a/source/logo.cpp b/source/logo.cpp index 1fde7b6..40e3164 100644 --- a/source/logo.cpp +++ b/source/logo.cpp @@ -9,6 +9,7 @@ #include "input.h" // for Input #include "jail_audio.h" // for JA_StopMusic #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 @@ -16,14 +17,10 @@ // Constructor Logo::Logo() + : since_texture_(Resource::get()->getTexture("logo_since_1998.png")), + since_sprite_(std::make_unique(since_texture_)), + jail_texture_(Resource::get()->getTexture("logo_jailgames.png")) { - // Copia la dirección de los objetos - SDL_Renderer *renderer = Screen::get()->getRenderer(); - - // Reserva memoria para los punteros - jail_texture_ = std::make_shared(renderer, Asset::get()->get("logo_jailgames.png")); - since_texture_ = std::make_shared(renderer, Asset::get()->get("logo_since_1998.png")); - since_sprite_ = std::make_unique(since_texture_, (param.game.width - since_texture_->getWidth()) / 2, 83 + jail_texture_->getHeight() + 5, since_texture_->getWidth(), since_texture_->getHeight()); // Inicializa variables counter_ = 0; @@ -31,6 +28,7 @@ Logo::Logo() ticks_ = 0; dest_.x = param.game.game_area.center_x - jail_texture_->getWidth() / 2; dest_.y = param.game.game_area.center_y - jail_texture_->getHeight() / 2; + since_sprite_->setPosition({(param.game.width - since_texture_->getWidth()) / 2, 83 + jail_texture_->getHeight() + 5, since_texture_->getWidth(), since_texture_->getHeight()}); since_sprite_->setY(dest_.y + jail_texture_->getHeight() + 5); since_sprite_->setSpriteClip(0, 0, since_texture_->getWidth(), since_texture_->getHeight()); since_texture_->setColor(0x00, 0x00, 0x00); // Esto en linux no hace nada ?? diff --git a/source/notifier.cpp b/source/notifier.cpp index 10a96b0..ddf3103 100644 --- a/source/notifier.cpp +++ b/source/notifier.cpp @@ -4,6 +4,8 @@ #include // for string #include "jail_audio.h" // for JA_DeleteSound, JA_LoadSound, JA_Pla... #include "param.h" // for param +#include "resource.h" // for Resource +#include "screen.h" // for Screen #include "sprite.h" // for Sprite #include "text.h" // for Text #include "texture.h" // for Texture @@ -12,9 +14,9 @@ Notifier *Notifier::notifier_ = nullptr; // [SINGLETON] Crearemos el objeto screen con esta función estática -void Notifier::init(SDL_Renderer *renderer, std::string icon_file, std::string bitmap_file, std::string text_file, const std::string &sound_file) +void Notifier::init(std::string icon_file, std::shared_ptr text, const std::string &sound_file) { - Notifier::notifier_ = new Notifier(renderer, icon_file, bitmap_file, text_file, sound_file); + Notifier::notifier_ = new Notifier(icon_file, text, sound_file); } // [SINGLETON] Destruiremos el objeto screen con esta función estática @@ -30,9 +32,9 @@ Notifier *Notifier::get() } // Constructor -Notifier::Notifier(SDL_Renderer *renderer, std::string icon_file, std::string bitmap_file, std::string text_file, const std::string &sound_file) - : renderer_(renderer), - text_(std::make_unique(bitmap_file, text_file, renderer)), +Notifier::Notifier(std::string icon_file, std::shared_ptr text, const std::string &sound_file) + : renderer_(Screen::get()->getRenderer()), + text_(text), bg_color_(param.notification.color), wait_time_(150), stack_(false), @@ -42,7 +44,7 @@ Notifier::Notifier(SDL_Renderer *renderer, std::string icon_file, std::string bi has_icons_ = !icon_file.empty(); // Crea objetos - icon_texture_ = has_icons_ ? std::make_unique(renderer, icon_file) : nullptr; + icon_texture_ = has_icons_ ? std::make_unique(renderer_, icon_file) : nullptr; } // Destructor diff --git a/source/notifier.h b/source/notifier.h index de6216c..4527fbf 100644 --- a/source/notifier.h +++ b/source/notifier.h @@ -63,7 +63,7 @@ private: SDL_Renderer *renderer_; // El renderizador de la ventana std::shared_ptr icon_texture_; // Textura para los iconos de las notificaciones - std::unique_ptr text_; // Objeto para dibujar texto + std::shared_ptr text_; // Objeto para dibujar texto // Variables Color bg_color_; // Color de fondo de las notificaciones @@ -82,14 +82,14 @@ private: // [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos notifier desde fuera // Constructor - Notifier(SDL_Renderer *renderer, std::string icon_file, std::string bitmap_file, std::string text_file, const std::string &sound_file); + Notifier(std::string icon_file, std::shared_ptr text, const std::string &sound_file); // Destructor ~Notifier(); public: // [SINGLETON] Crearemos el objeto notifier con esta función estática - static void init(SDL_Renderer *renderer, std::string icon_file, std::string bitmap_file, std::string text_file, const std::string &sound_file); + static void init(std::string icon_file, std::shared_ptr text, const std::string &sound_file); // [SINGLETON] Destruiremos el objeto notifier con esta función estática static void destroy(); diff --git a/source/on_screen_help.cpp b/source/on_screen_help.cpp index ff0fbb9..c7cca75 100644 --- a/source/on_screen_help.cpp +++ b/source/on_screen_help.cpp @@ -1,15 +1,16 @@ #include "on_screen_help.h" -#include // for SDL_BLENDMODE_BLEND -#include // for SDL_PIXELFORMAT_RGBA8888 -#include // for make_unique, make_shared, unique_ptr -#include "asset.h" // for Asset -#include "lang.h" // for getText -#include "param.h" // for param -#include "screen.h" // for Screen -#include "sprite.h" // for Sprite -#include "text.h" // for Text -#include "texture.h" // for Texture -#include "utils.h" // for easeInOutSine, Param, ParamGame +#include // for SDL_BLENDMODE_BLEND +#include // for SDL_PIXELFORMAT_RGBA8888 +#include // for make_unique, make_shared, unique_ptr +#include "asset.h" // for Asset +#include "lang.h" // for getText +#include "param.h" // for param +#include "resource.h" // for Resource +#include "screen.h" // for Screen +#include "sprite.h" // for Sprite +#include "text.h" // for Text +#include "texture.h" // for Texture +#include "utils.h" // for easeInOutSine, Param, ParamGame // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado OnScreenHelp *OnScreenHelp::onScreenHelp = nullptr; @@ -95,10 +96,10 @@ void OnScreenHelp::fillTexture() SDL_SetRenderTarget(Screen::get()->getRenderer(), texture); // Crea el objeto para el texto - auto text = std::make_unique(Asset::get()->get("8bithud.png"), Asset::get()->get("8bithud.txt"), Screen::get()->getRenderer()); + auto text = std::make_unique(Resource::get()->getTexture("8bithud.png"), Resource::get()->getTextFile("8bithud.txt")); // Crea la textura con los gráficos - auto controllersTexture = std::make_shared(Screen::get()->getRenderer(), Asset::get()->get("controllers.png")); + auto controllersTexture = Resource::get()->getTexture("controllers.png"); // Crea el sprite para dibujar los gráficos auto sprite = std::make_unique(controllersTexture, (SDL_Rect){0, 0, 16, 16}); @@ -170,7 +171,7 @@ void OnScreenHelp::toggleState() // Calcula la longitud en pixels del texto más largo auto OnScreenHelp::getLargestStringSize() -> int const { - auto text = std::make_unique(Asset::get()->get("8bithud.png"), Asset::get()->get("8bithud.txt"), Screen::get()->getRenderer()); + auto text = std::make_unique(Resource::get()->getTexture("8bithud.png"), Resource::get()->getTextFile("8bithud.txt")); auto size = 0; for (int i = 107; i <= 113; ++i) diff --git a/source/resource.cpp b/source/resource.cpp index b3e74d4..c477042 100644 --- a/source/resource.cpp +++ b/source/resource.cpp @@ -1,5 +1,7 @@ +#include #include "resource.h" #include "asset.h" +#include "screen.h" // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado Resource *Resource::resource_ = nullptr; @@ -25,8 +27,13 @@ Resource *Resource::get() // Constructor Resource::Resource() { + std::cout << "** LOADING RESOURCES" << std::endl; loadSounds(); loadMusics(); + loadTextures(); + loadTextFiles(); + loadAnimations(); + std::cout << "\n** RESOURCES LOADED" << std::endl; } // Destructor @@ -34,9 +41,12 @@ Resource::~Resource() { sounds_.clear(); musics_.clear(); + textures_.clear(); + text_files_.clear(); + animations_.clear(); } -// Obtiene el fichero de sonido a partir de un nombre +// Obtiene el sonido a partir de un nombre JA_Sound_t *Resource::getSound(const std::string &name) { for (const auto &s : sounds_) @@ -46,10 +56,11 @@ JA_Sound_t *Resource::getSound(const std::string &name) return s.sound; } } - return nullptr; + std::cerr << "Error: Sonido no encontrado " << name << std::endl; + throw std::runtime_error("Sonido no encontrado: " + name); } -// Obtiene el fichero de música a partir de un nombre +// Obtiene la música a partir de un nombre JA_Music_t *Resource::getMusic(const std::string &name) { for (const auto &m : musics_) @@ -59,12 +70,57 @@ JA_Music_t *Resource::getMusic(const std::string &name) return m.music; } } - return nullptr; + std::cerr << "Error: Música no encontrada " << name << std::endl; + throw std::runtime_error("Música no encontrada: " + name); } -// Carga los sonidos del juego +// Obtiene la textura a partir de un nombre +std::shared_ptr Resource::getTexture(const std::string &name) +{ + for (const auto &t : textures_) + { + if (t.name == name) + { + return t.texture; + } + } + std::cerr << "Error: Imagen no encontrada " << name << std::endl; + throw std::runtime_error("Imagen no encontrada: " + name); +} + +// Obtiene el fichero de texto a partir de un nombre +std::shared_ptr Resource::getTextFile(const std::string &name) +{ + for (const auto &t : text_files_) + { + if (t.name == name) + { + return t.text_file; + } + } + std::cerr << "Error: TextFile no encontrado " << name << std::endl; + throw std::runtime_error("TextFile no encontrado: " + name); +} + +// Obtiene la animación a partir de un nombre +Animations &Resource::getAnimation(const std::string &name) +{ + for (auto &a : animations_) + { + if (a.name == name) + { + return a.animation; + } + } + std::cerr << "Error: Animación no encontrada " << name << std::endl; + throw std::runtime_error("Animación no encontrada: " + name); +} + +// Carga los sonidos void Resource::loadSounds() { + std::cout << "\n>> SOUND FILES" << std::endl; + // Obtiene la lista con las rutas a los ficheros de sonidos auto list = Asset::get()->getListByType(AssetType::SOUND); sounds_.clear(); @@ -77,13 +133,16 @@ void Resource::loadSounds() // Obtiene la subcadena desde el último '/' auto name = l.substr(last_index); - sounds_.emplace_back(ResourceSound{name, JA_LoadSound(l.c_str())}); + sounds_.emplace_back(ResourceSound(name, JA_LoadSound(l.c_str()))); + printWithDots("Sound : ", name, "[ LOADED ]"); } } -// Carga las musicas del juego +// Carga las musicas void Resource::loadMusics() { + std::cout << "\n>> MUSIC FILES" << std::endl; + // Obtiene la lista con las rutas a los ficheros musicales auto list = Asset::get()->getListByType(AssetType::MUSIC); musics_.clear(); @@ -96,6 +155,68 @@ void Resource::loadMusics() // Obtiene la subcadena desde el último '/' auto name = l.substr(last_index); - musics_.emplace_back(ResourceMusic{name, JA_LoadMusic(l.c_str())}); + musics_.emplace_back(ResourceMusic(name, JA_LoadMusic(l.c_str()))); + printWithDots("Music : ", name, "[ LOADED ]"); + } +} + +// Carga las texturas +void Resource::loadTextures() +{ + std::cout << "\n>> TEXTURES" << std::endl; + + // Obtiene la lista con las rutas a los ficheros png + auto list = Asset::get()->getListByType(AssetType::BITMAP); + textures_.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); + + textures_.emplace_back(ResourceTexture(name, std::make_shared(Screen::get()->getRenderer(), l))); + } +} + +// Carga los ficheros de texto +void Resource::loadTextFiles() +{ + std::cout << "\n>> TEXT FILES" << std::endl; + // Obtiene la lista con las rutas a los ficheros png + auto list = Asset::get()->getListByType(AssetType::FONT); + text_files_.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); + + text_files_.emplace_back(ResourceTextFile(name, loadTextFile(l))); + } +} + +// Carga las animaciones +void Resource::loadAnimations() +{ + std::cout << "\n>> ANIMATIONS" << std::endl; + // Obtiene la lista con las rutas a los ficheros ani + auto list = Asset::get()->getListByType(AssetType::ANIMATION); + animations_.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); + + animations_.emplace_back(ResourceAnimation(name, loadAnimationsFromFile(l))); } } \ No newline at end of file diff --git a/source/resource.h b/source/resource.h index e301ae6..ca021a2 100644 --- a/source/resource.h +++ b/source/resource.h @@ -2,21 +2,66 @@ #include #include +#include #include #include "jail_audio.h" +#include "texture.h" +#include "text.h" +#include "animated_sprite.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 + JA_Sound_t *sound; // Objeto con el sonido + + // Constructor + ResourceSound(const std::string &name, JA_Sound_t *sound) + : name(name), sound(sound) {} }; // 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 + JA_Music_t *music; // Objeto con la música + + // Constructor + ResourceMusic(const std::string &name, JA_Music_t *music) + : name(name), music(music) {} +}; + +// Estructura para almacenar objetos Texture y su nombre +struct ResourceTexture +{ + std::string name; // Nombre de la textura + std::shared_ptr texture; // Objeto con la textura + + // Constructor + ResourceTexture(const std::string &name, std::shared_ptr texture) + : name(name), texture(texture) {} +}; + +// Estructura para almacenar ficheros TextFile y su nombre +struct ResourceTextFile +{ + std::string name; // Nombre del fichero + std::shared_ptr text_file; // Objeto con los descriptores de la fuente de texto + + // Constructor + ResourceTextFile(const std::string &name, std::shared_ptr text_file) + : name(name), text_file(text_file) {} +}; + +// Estructura para almacenar ficheros animaciones y su nombre +struct ResourceAnimation +{ + std::string name; // Nombre del fichero + Animations animation; // Objeto con las animaciones + + // Constructor + ResourceAnimation(const std::string &name, Animations animation) + : name(name), animation(animation) {} }; class Resource @@ -25,15 +70,27 @@ private: // [SINGLETON] Objeto resource privado para Don Melitón static Resource *resource_; - std::vector sounds_; // Vector con los sonidos - std::vector musics_; // Vector con las musicas + std::vector sounds_; // Vector con los sonidos + std::vector musics_; // Vector con las musicas + std::vector textures_; // Vector con las musicas + std::vector text_files_; // Vector con los ficheros de texto + std::vector animations_; // Vector con las animaciones - // Carga los sonidos del juego + // Carga los sonidos void loadSounds(); - // Carga las musicas del juego + // Carga las musicas void loadMusics(); + // Carga las texturas + void loadTextures(); + + // Carga los ficheros de texto + void loadTextFiles(); + + // Carga las animaciones + void loadAnimations(); + // [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos resource desde fuera // Constructor @@ -52,9 +109,18 @@ public: // [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 + // Obtiene el 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 + // Obtiene la música a partir de un nombre JA_Music_t *getMusic(const std::string &name); + + // Obtiene la textura a partir de un nombre + std::shared_ptr getTexture(const std::string &name); + + // Obtiene el fichero de texto a partir de un nombre + std::shared_ptr getTextFile(const std::string &name); + + // Obtiene la animación a partir de un nombre + Animations &getAnimation(const std::string &name); }; \ No newline at end of file diff --git a/source/scoreboard.cpp b/source/scoreboard.cpp index c7004c5..14e0046 100644 --- a/source/scoreboard.cpp +++ b/source/scoreboard.cpp @@ -5,11 +5,12 @@ #include // for roundf #include #include -#include "asset.h" // for Asset -#include "lang.h" // for getText -#include "sprite.h" // for Sprite -#include "text.h" // for Text -#include "texture.h" // for Texture +#include "asset.h" // for Asset +#include "lang.h" // for getText +#include "resource.h" // for Resource +#include "sprite.h" // for Sprite +#include "text.h" // for Text +#include "texture.h" // for Texture // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado Scoreboard *Scoreboard::scoreboard_ = nullptr; @@ -35,11 +36,11 @@ Scoreboard *Scoreboard::get() // Constructor Scoreboard::Scoreboard(SDL_Renderer *renderer) : renderer_(renderer), - - game_power_meter_texture_(std::make_shared(renderer, Asset::get()->get("game_power_meter.png"))), + + game_power_meter_texture_(Resource::get()->getTexture("game_power_meter.png")), power_meter_sprite_(std::make_unique(game_power_meter_texture_)), - text_scoreboard_(std::make_unique(Asset::get()->get("8bithud.png"), Asset::get()->get("8bithud.txt"), renderer)), - + text_scoreboard_(std::make_unique(Resource::get()->getTexture("8bithud.png"), Resource::get()->getTextFile("8bithud.txt"))), + stage_(1), hi_score_(0), power_(0), diff --git a/source/text.cpp b/source/text.cpp index de201d7..55c2130 100644 --- a/source/text.cpp +++ b/source/text.cpp @@ -2,23 +2,24 @@ #include // for SDL_Rect #include // for basic_ostream, basic_ifstream, basic_istream #include // for cout +#include "resource.h" // for Resource #include "sprite.h" // for Sprite #include "texture.h" // for Texture #include "utils.h" // for Color // Llena una estructuta TextFile desde un fichero -TextFile LoadTextFile(std::string file_path) +std::shared_ptr loadTextFile(const std::string &file_path) { - TextFile tf; + auto tf = std::make_shared(); // Inicializa a cero el vector con las coordenadas for (int i = 0; i < 128; ++i) { - tf.offset[i].x = 0; - tf.offset[i].y = 0; - tf.offset[i].w = 0; - tf.box_width = 0; - tf.box_height = 0; + tf->offset[i].x = 0; + tf->offset[i].y = 0; + tf->offset[i].w = 0; + tf->box_width = 0; + tf->box_height = 0; } // Abre el fichero para leer los valores @@ -32,11 +33,11 @@ TextFile LoadTextFile(std::string file_path) // Lee los dos primeros valores del fichero std::getline(file, buffer); std::getline(file, buffer); - tf.box_width = std::stoi(buffer); + tf->box_width = std::stoi(buffer); std::getline(file, buffer); std::getline(file, buffer); - tf.box_height = std::stoi(buffer); + tf->box_height = std::stoi(buffer); // lee el resto de datos del fichero auto index = 32; @@ -46,7 +47,7 @@ TextFile LoadTextFile(std::string file_path) // Almacena solo las lineas impares if (line_read % 2 == 1) { - tf.offset[index++].w = std::stoi(buffer); + tf->offset[index++].w = std::stoi(buffer); } // Limpia el buffer @@ -55,21 +56,22 @@ TextFile LoadTextFile(std::string file_path) }; // Cierra el fichero - std::cout << "Text loaded: " << file_name << std::endl; + printWithDots("Text File : ", file_name, "[ LOADED ]"); file.close(); } // El fichero no se puede abrir else { - std::cout << "Warning: Unable to open " << file_name << " file" << std::endl; + std::cerr << "Error: Fichero no encontrado " << file_path << std::endl; + throw std::runtime_error("Fichero no encontrado: " + file_path); } // Establece las coordenadas para cada caracter ascii de la cadena y su ancho for (int i = 32; i < 128; ++i) { - tf.offset[i].x = ((i - 32) % 15) * tf.box_width; - tf.offset[i].y = ((i - 32) / 15) * tf.box_height; + tf->offset[i].x = ((i - 32) % 15) * tf->box_width; + tf->offset[i].y = ((i - 32) / 15) * tf->box_height; } return tf; @@ -79,16 +81,16 @@ TextFile LoadTextFile(std::string file_path) Text::Text(const std::string &bitmap_file, const std::string &text_file, SDL_Renderer *renderer) { // Carga los offsets desde el fichero - auto tf = LoadTextFile(text_file); + auto tf = loadTextFile(text_file); // Inicializa variables desde la estructura - box_height_ = tf.box_height; - box_width_ = tf.box_width; + box_height_ = tf->box_height; + box_width_ = tf->box_width; for (int i = 0; i < 128; ++i) { - offset_[i].x = tf.offset[i].x; - offset_[i].y = tf.offset[i].y; - offset_[i].w = tf.offset[i].w; + offset_[i].x = tf->offset[i].x; + offset_[i].y = tf->offset[i].y; + offset_[i].w = tf->offset[i].w; } // Crea los objetos @@ -100,19 +102,20 @@ Text::Text(const std::string &bitmap_file, const std::string &text_file, SDL_Ren } // Constructor -Text::Text(const std::string &text_file, std::shared_ptr texture) +Text::Text(std::shared_ptr texture, const std::string &text_file) + : texture_(texture) { // Carga los offsets desde el fichero - auto tf = LoadTextFile(text_file); + auto tf = loadTextFile(text_file); // Inicializa variables desde la estructura - box_height_ = tf.box_height; - box_width_ = tf.box_width; + box_height_ = tf->box_height; + box_width_ = tf->box_width; for (int i = 0; i < 128; ++i) { - offset_[i].x = tf.offset[i].x; - offset_[i].y = tf.offset[i].y; - offset_[i].w = tf.offset[i].w; + offset_[i].x = tf->offset[i].x; + offset_[i].y = tf->offset[i].y; + offset_[i].w = tf->offset[i].w; } // Crea los objetos @@ -123,7 +126,8 @@ Text::Text(const std::string &text_file, std::shared_ptr texture) } // Constructor -Text::Text(TextFile *text_file, std::shared_ptr texture) +Text::Text(std::shared_ptr texture, std::shared_ptr text_file) + : texture_(texture) { // Inicializa variables desde la estructura box_height_ = text_file->box_height; diff --git a/source/text.h b/source/text.h index 2ffd385..8241219 100644 --- a/source/text.h +++ b/source/text.h @@ -26,7 +26,7 @@ struct TextFile }; // Llena una estructuta TextFile desde un fichero -TextFile LoadTextFile(std::string file); +std::shared_ptr loadTextFile(const std::string &file_path); // Clase texto. Pinta texto en pantalla a partir de un bitmap class Text @@ -45,8 +45,8 @@ private: public: // Constructor Text(const std::string &bitmap_file, const std::string &text_file, SDL_Renderer *renderer); - Text(const std::string &text_file, std::shared_ptr texture); - Text(TextFile *text_file, std::shared_ptr texture); + Text(std::shared_ptr texture, const std::string &text_file); + Text(std::shared_ptr texture, std::shared_ptr text_file); // Destructor ~Text() = default; diff --git a/source/texture.cpp b/source/texture.cpp index 4b3b031..859308a 100644 --- a/source/texture.cpp +++ b/source/texture.cpp @@ -1,5 +1,6 @@ #include "texture.h" +#include "utils.h" #include // for SDL_GetError #include // for SDL_CreateRGBSurfaceWithFormatFrom #include // for SEEK_END, SEEK_SET @@ -54,20 +55,20 @@ Texture::~Texture() } // Carga una imagen desde un fichero -bool Texture::loadFromFile(const std::string &path) +bool Texture::loadFromFile(const std::string &file_path) { int req_format = STBI_rgb_alpha; int width, height, orig_format; - unsigned char *data = stbi_load(path.c_str(), &width, &height, &orig_format, req_format); + unsigned char *data = stbi_load(file_path.c_str(), &width, &height, &orig_format, req_format); if (!data) { - std::cout << "Loading image failed: " << stbi_failure_reason() << std::endl; - exit(1); + std::cerr << "Error: Fichero no encontrado " << file_path << std::endl; + throw std::runtime_error("Fichero no encontrado: " + file_path); } else { - const std::string file_name = path.substr(path.find_last_of("\\/") + 1); - std::cout << "Image loaded: " << file_name << std::endl; + const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1); + printWithDots("Image : ", file_name, "[ LOADED ]"); } int depth, pitch; @@ -95,7 +96,7 @@ bool Texture::loadFromFile(const std::string &path) auto loadedSurface = SDL_CreateRGBSurfaceWithFormatFrom(static_cast(data), width, height, depth, pitch, pixel_format); if (loadedSurface == nullptr) { - std::cout << "Unable to load image " << path << std::endl; + std::cout << "Unable to load image " << file_path << std::endl; } else { @@ -103,7 +104,7 @@ bool Texture::loadFromFile(const std::string &path) newTexture = SDL_CreateTextureFromSurface(renderer_, loadedSurface); if (newTexture == nullptr) { - std::cout << "Unable to create texture from " << path << "! SDL Error: " << SDL_GetError() << std::endl; + std::cout << "Unable to create texture from " << file_path << "! SDL Error: " << SDL_GetError() << std::endl; } else { diff --git a/source/tiled_bg.cpp b/source/tiled_bg.cpp index 4d6495d..c8fd6a3 100644 --- a/source/tiled_bg.cpp +++ b/source/tiled_bg.cpp @@ -1,105 +1,84 @@ #include "tiled_bg.h" -#include // for SDL_PIXELFORMAT_RGBA8888 -#include // for SDL_sinf -#include // for rand -#include // for unique_ptr, make_shared, make_unique -#include "screen.h" // for Screen -#include "sprite.h" // for Sprite -#include "texture.h" // for Texture +#include // for SDL_PIXELFORMAT_RGBA8888 +#include // for rand +#include // for unique_ptr, make_shared, make_unique +#include // for sinf +#include "resource.h" // for Resource +#include "screen.h" // for Screen +#include "sprite.h" // for Sprite +#include "texture.h" // for Texture // Constructor -Tiledbg::Tiledbg(std::string texture_path, SDL_Rect pos, int mode) - : texture_path_(texture_path), pos_(pos), mode_(mode) +TiledBG::TiledBG(SDL_Rect pos, int mode) + : renderer_(Screen::get()->getRenderer()), + pos_(pos), + counter_(0), + mode_(mode == TILED_MODE_RANDOM ? rand() % 2 : mode) { - // Copia los punteros - renderer_ = Screen::get()->getRenderer(); - // Crea la textura para el mosaico de fondo canvas_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, pos_.w * 2, pos_.h * 2); - // Inicializa las variables - init(); -} - -// Destructor -Tiledbg::~Tiledbg() -{ - SDL_DestroyTexture(canvas_); -} - -// Inicializa las variables -void Tiledbg::init() -{ - counter_ = 0; - if (mode_ == TILED_MODE_RANDOM) - { - mode_ = rand() % 2; - } - tile_width_ = 64; - tile_height_ = 64; - // Rellena la textura con el contenido fillTexture(); // Coloca la ventana que recorre el mosaico de fondo de manera que coincida // con el mosaico que hay pintado en el titulo al iniciar - window_.x = 128; - window_.y = 96; - window_.w = pos_.w; - window_.h = pos_.h; + window_ = {128, 96, pos_.w, pos_.h}; // Inicializa los valores del vector con los valores del seno for (int i = 0; i < 360; ++i) { - sin_[i] = SDL_sinf((float)i * 3.14f / 180.0f); + sin_[i] = std::sinf(i * 3.14159f / 180.0f); // Convierte grados a radianes y calcula el seno } } +// Destructor +TiledBG::~TiledBG() +{ + SDL_DestroyTexture(canvas_); +} + // Rellena la textura con el contenido -void Tiledbg::fillTexture() +void TiledBG::fillTexture() { // Crea los objetos para pintar en la textura de fondo - auto bg_tile_texture = std::make_shared(renderer_, texture_path_); - auto tile = std::make_unique(bg_tile_texture, (SDL_Rect){0, 0, tile_width_, tile_height_}); + auto tile = std::make_unique(Resource::get()->getTexture("title_bg_tile.png"), (SDL_Rect){0, 0, TILE_WIDTH_, TILE_HEIGHT_}); // Prepara para dibujar sobre la textura auto temp = SDL_GetRenderTarget(renderer_); SDL_SetRenderTarget(renderer_, canvas_); // Rellena la textura con el tile - const auto i_max = pos_.w * 2 / tile_width_; - const auto j_max = pos_.h * 2 / tile_height_; - tile->setSpriteClip(0, 0, tile_width_, tile_height_); + const auto i_max = pos_.w * 2 / TILE_WIDTH_; + const auto j_max = pos_.h * 2 / TILE_HEIGHT_; + tile->setSpriteClip(0, 0, TILE_WIDTH_, TILE_HEIGHT_); for (int i = 0; i < i_max; ++i) { for (int j = 0; j < j_max; ++j) { - tile->setX(i * tile_width_); - tile->setY(j * tile_height_); + tile->setX(i * TILE_WIDTH_); + tile->setY(j * TILE_HEIGHT_); tile->render(); } } // Vuelve a colocar el renderizador como estaba SDL_SetRenderTarget(renderer_, temp); - - // Libera la memoria utilizada por los objetos - bg_tile_texture->unload(); } // Pinta la clase en pantalla -void Tiledbg::render() +void TiledBG::render() { SDL_RenderCopy(renderer_, canvas_, &window_, &pos_); } // Actualiza la lógica de la clase -void Tiledbg::update() +void TiledBG::update() { if (mode_ == TILED_MODE_DIAGONAL) { // El tileado de fondo se desplaza en diagonal - ++window_.x %= tile_width_; - ++window_.y %= tile_height_; + ++window_.x %= TILE_WIDTH_; + ++window_.y %= TILE_HEIGHT_; } else if (mode_ == TILED_MODE_CIRCLE) { // El tileado de fondo se desplaza en circulo @@ -110,7 +89,7 @@ void Tiledbg::update() } // Recarga las texturas -void Tiledbg::reLoad() +void TiledBG::reLoad() { fillTexture(); } \ No newline at end of file diff --git a/source/tiled_bg.h b/source/tiled_bg.h index 57dae37..a7089cf 100644 --- a/source/tiled_bg.h +++ b/source/tiled_bg.h @@ -16,36 +16,34 @@ textura en pantalla */ -// Clase Tiledbg -class Tiledbg +// Clase TiledBG +class TiledBG { private: + // Constantes + static constexpr int TILE_WIDTH_ = 64; // Ancho del tile + static constexpr int TILE_HEIGHT_ = 64; // Alto del tile + // Objetos y punteros SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Rect window_; // Ventana visible para la textura de fondo del titulo SDL_Texture *canvas_; // Textura donde dibujar el fondo formado por tiles // Variables - std::string texture_path_; // Fichero para usar en la textura - SDL_Rect pos_; // Posición y tamaña del mosaico - int counter_; // Contador - int mode_; // Tipo de movimiento del mosaico - float sin_[360]; // Vector con los valores del seno precalculados - int tile_width_; // Ancho del tile - int tile_height_; // Alto del tile - - // Inicializa las variables - void init(); + SDL_Rect pos_; // Posición y tamaño del mosaico + int counter_; // Contador + int mode_; // Tipo de movimiento del mosaico + float sin_[360]; // Vector con los valores del seno precalculados // Rellena la textura con el contenido void fillTexture(); public: // Constructor - Tiledbg(std::string texture_path, SDL_Rect pos, int mode); + TiledBG(SDL_Rect pos, int mode); // Destructor - ~Tiledbg(); + ~TiledBG(); // Pinta la clase en pantalla void render(); diff --git a/source/title.cpp b/source/title.cpp index 18e997d..f66f4e4 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -25,21 +25,18 @@ struct JA_Music_t; // lines 17-17 // Constructor Title::Title() { - // Copia las direcciones de los punteros y objetos - SDL_Renderer *renderer = Screen::get()->getRenderer(); - // Reserva memoria y crea los objetos - fade_ = std::make_unique(renderer); + fade_ = std::make_unique(); - text1_ = std::make_unique(Asset::get()->get("smb2.gif"), Asset::get()->get("smb2.txt"), renderer); + text1_ = std::make_unique(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt")); text1_->addPalette(Asset::get()->get("smb2_pal1.gif")); text1_->setPalette(1); - text2_ = std::make_unique(Asset::get()->get("8bithud.png"), Asset::get()->get("8bithud.txt"), renderer); + text2_ = std::make_unique(Resource::get()->getTexture("8bithud.png"), Resource::get()->getTextFile("8bithud.txt")); - mini_logo_texture_ = std::make_shared(renderer, Asset::get()->get("logo_jailgames_mini.png")); + mini_logo_texture_ = Resource::get()->getTexture("logo_jailgames_mini.png"); mini_logo_sprite_ = std::make_unique(mini_logo_texture_, param.game.game_area.center_x - mini_logo_texture_->getWidth() / 2, 0, mini_logo_texture_->getWidth(), mini_logo_texture_->getHeight()); - tiled_bg_ = std::make_unique(Asset::get()->get("title_bg_tile.png"), (SDL_Rect){0, 0, param.game.width, param.game.height}, TILED_MODE_RANDOM); + tiled_bg_ = std::make_unique((SDL_Rect){0, 0, param.game.width, param.game.height}, TILED_MODE_RANDOM); game_logo_ = std::make_unique(param.game.game_area.center_x, param.title.title_c_c_position); game_logo_->enable(); diff --git a/source/title.h b/source/title.h index b83cf7e..a7feb83 100644 --- a/source/title.h +++ b/source/title.h @@ -1,18 +1,21 @@ #pragma once -#include // for Uint32 -#include // for unique_ptr, shared_ptr -#include "define_buttons.h" // for DefineButtons -#include "fade.h" // for Fade -#include "game_logo.h" // for GameLogo -#include "sprite.h" // for Sprite -#include "text.h" // for Text -#include "tiled_bg.h" // for Tiledbg -class Input; // lines 17-17 -class Screen; // lines 18-18 -class Texture; // lines 20-20 -namespace section { enum class Name; } -struct JA_Music_t; // lines 21-21 +#include // for Uint32 +#include // for unique_ptr, shared_ptr +#include "define_buttons.h" // for DefineButtons +#include "fade.h" // for Fade +#include "game_logo.h" // for GameLogo +#include "sprite.h" // for Sprite +#include "text.h" // for Text +#include "tiled_bg.h" // for TiledBG +class Input; // lines 17-17 +class Screen; // lines 18-18 +class Texture; // lines 20-20 +namespace section +{ + enum class Name; +} +struct JA_Music_t; // lines 21-21 // Textos constexpr const char TEXT_COPYRIGHT[] = "@2020,2024 JailDesigner"; @@ -40,7 +43,7 @@ class Title { private: // Objetos y punteros - std::unique_ptr tiled_bg_; // Objeto para dibujar el mosaico animado de fondo + std::unique_ptr tiled_bg_; // Objeto para dibujar el mosaico animado de fondo std::unique_ptr game_logo_; // Objeto para dibujar el logo con el título del juego std::unique_ptr define_buttons_; // Objeto para definir los botones del joystic std::shared_ptr mini_logo_texture_; // Textura con el logo de JailGames mini @@ -51,13 +54,13 @@ private: std::unique_ptr fade_; // Objeto para realizar fundidos en pantalla // Variable - int counter_; // Temporizador para la pantalla de titulo - Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa - Uint32 ticks_speed_; // Velocidad a la que se repiten los bucles del programa - bool demo_; // Indica si el modo demo estará activo + int counter_; // Temporizador para la pantalla de titulo + Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa + Uint32 ticks_speed_; // Velocidad a la que se repiten los bucles del programa + bool demo_; // Indica si el modo demo estará activo section::Name next_section_; // Indica cual es la siguiente sección a cargar cuando termine el contador del titulo - int post_fade_; // Opción a realizar cuando termina el fundido - int num_controllers_; // Número de mandos conectados + int post_fade_; // Opción a realizar cuando termina el fundido + int num_controllers_; // Número de mandos conectados // Inicializa los valores de las variables void init(); diff --git a/source/utils.cpp b/source/utils.cpp index 58ab02e..6b52b70 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -1,4 +1,6 @@ #include "utils.h" +#include +#include #include // for min, clamp, find_if_not, transform #include // for tolower, isspace #include // for cos, pow, M_PI @@ -188,3 +190,16 @@ bool stringInVector(const std::vector &vec, const std::string &str) { return std::find(vec.begin(), vec.end(), str) != vec.end(); } + +// Imprime por pantalla una linea de texto de tamaño fijo rellena con puntos +void printWithDots(const std::string &text1, const std::string &text2, const std::string &text3) +{ + std::cout.setf(std::ios::left, std::ios::adjustfield); + std::cout << text1; + + std::cout.width(70 - text1.length() - text3.length()); + std::cout.fill('.'); + std::cout << text2; + + std::cout << text3 << std::endl; +} \ No newline at end of file diff --git a/source/utils.h b/source/utils.h index 59471a8..f20b526 100644 --- a/source/utils.h +++ b/source/utils.h @@ -264,6 +264,9 @@ double easeInOutSine(double t); // Comprueba si una vector contiene una cadena bool stringInVector(const std::vector &vec, const std::string &str); +// Imprime por pantalla una linea de texto de tamaño fijo rellena con puntos +void printWithDots(const std::string &text1, const std::string &text2, const std::string &text3); + // Colores extern const Color bg_color; extern const Color no_color;