Precàrrega de tots els recursos al inici del joc

8.000.000 de cherrypickings que he anat fent pel codi
This commit is contained in:
2024-10-20 11:06:10 +02:00
parent f23dcae5b6
commit a4b4e188cd
32 changed files with 532 additions and 364 deletions

View File

@@ -5,6 +5,29 @@
#include <iterator> // for back_insert_iterator, back_inserter
#include <sstream> // 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<std::string> 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> texture, const std::string &file_path)
@@ -18,7 +41,7 @@ AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const std::stri
}
}
AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const std::vector<std::string> &animations)
AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const Animations &animations)
: MovingSprite(texture),
current_animation_(0)
{
@@ -372,7 +395,7 @@ std::vector<Animation> AnimatedSprite::loadFromFile(const std::string &file_path
}
// Carga la animación desde un vector
bool AnimatedSprite::loadFromVector(const std::vector<std::string> &source)
bool AnimatedSprite::loadFromVector(const Animations &source)
{
// Inicializa variables
auto frames_per_row = 0;

View File

@@ -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<std::string>;
// 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<Animation> loadFromFile(const std::string &file_path);
// Carga la animación desde un vector
bool loadFromVector(const std::vector<std::string> &source);
bool loadFromVector(const Animations &source);
public:
// Constructor
AnimatedSprite(std::shared_ptr<Texture> texture, const std::string &file_path);
AnimatedSprite(std::shared_ptr<Texture> texture, const std::vector<std::string> &animations);
AnimatedSprite(std::shared_ptr<Texture> texture, const Animations &animations);
explicit AnimatedSprite(std::shared_ptr<Texture> texture);
// Destructor

View File

@@ -1,4 +1,5 @@
#include "asset.h"
#include "utils.h"
#include <SDL2/SDL_rwops.h> // for SDL_RWFromFile, SDL_RWclose, SDL_RWops
#include <SDL2/SDL_stdinc.h> // for SDL_max
#include <stddef.h> // 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<int>(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;
}

View File

@@ -3,19 +3,20 @@
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <algorithm> // 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<Texture>(renderer, Asset::get()->get("game_buildings.png"))),
top_clouds_texture_(std::make_shared<Texture>(renderer, Asset::get()->get("game_clouds1.png"))),
bottom_clouds_texture_(std::make_shared<Texture>(renderer, Asset::get()->get("game_clouds2.png"))),
grass_texture_(std::make_shared<Texture>(renderer, Asset::get()->get("game_grass.png"))),
gradients_texture_(std::make_shared<Texture>(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

View File

@@ -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<Text>(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

View File

@@ -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[]);

View File

@@ -4,11 +4,12 @@
#include <stdlib.h> // for rand
#include <algorithm> // 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);

View File

@@ -54,7 +54,7 @@ private:
public:
// Constructor
explicit Fade(SDL_Renderer *renderer);
Fade();
// Destructor
~Fade();

View File

@@ -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<Fade>(renderer_);
fade_ = std::make_unique<Fade>();
background_ = std::make_unique<Background>(renderer_);
explosions_ = std::make_unique<Explosions>();
@@ -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<Texture>(renderer_, asset_->get("bullet.png"));
bullet_texture_ = Resource::get()->getTexture("bullet.png");
}
// Texturas - Game_text
{
game_text_textures_.emplace_back(std::make_shared<Texture>(renderer_, asset_->get("game_text_1000_points.png")));
game_text_textures_.emplace_back(std::make_shared<Texture>(renderer_, asset_->get("game_text_2500_points.png")));
game_text_textures_.emplace_back(std::make_shared<Texture>(renderer_, asset_->get("game_text_5000_points.png")));
game_text_textures_.emplace_back(std::make_shared<Texture>(renderer_, asset_->get("game_text_powerup.png")));
game_text_textures_.emplace_back(std::make_shared<Texture>(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<Texture>(renderer_, asset_->get("balloon1.png")));
balloon_textures_.emplace_back(std::make_shared<Texture>(renderer_, asset_->get("balloon2.png")));
balloon_textures_.emplace_back(std::make_shared<Texture>(renderer_, asset_->get("balloon3.png")));
balloon_textures_.emplace_back(std::make_shared<Texture>(renderer_, asset_->get("balloon4.png")));
balloon_textures_.emplace_back(std::make_shared<Texture>(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<Texture>(renderer_, asset_->get("explosion1.png")));
explosions_textures_.emplace_back(std::make_shared<Texture>(renderer_, asset_->get("explosion2.png")));
explosions_textures_.emplace_back(std::make_shared<Texture>(renderer_, asset_->get("explosion3.png")));
explosions_textures_.emplace_back(std::make_shared<Texture>(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<Texture>(renderer_, asset_->get("item_points1_disk.png")));
item_textures_.emplace_back(std::make_shared<Texture>(renderer_, asset_->get("item_points2_gavina.png")));
item_textures_.emplace_back(std::make_shared<Texture>(renderer_, asset_->get("item_points3_pacmar.png")));
item_textures_.emplace_back(std::make_shared<Texture>(renderer_, asset_->get("item_clock.png")));
item_textures_.emplace_back(std::make_shared<Texture>(renderer_, asset_->get("item_coffee.png")));
item_textures_.emplace_back(std::make_shared<Texture>(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<std::shared_ptr<Texture>> player_texture;
player_texture.emplace_back(std::make_shared<Texture>(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<Texture>(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<std::shared_ptr<Texture>> player_texture;
player_texture.emplace_back(std::make_shared<Texture>(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<Texture>(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<Text>(asset_->get("smb2.gif"), asset_->get("smb2.txt"), renderer_);
text_big_ = std::make_unique<Text>(asset_->get("smb2_big.png"), asset_->get("smb2_big.txt"), renderer_);
text_nokia2_ = std::make_unique<Text>(asset_->get("nokia2.png"), asset_->get("nokia2.txt"), renderer_);
text_nokia2_big_ = std::make_unique<Text>(asset_->get("nokia_big2.png"), asset_->get("nokia_big2.txt"), renderer_);
text_ = std::make_unique<Text>(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt"));
text_big_ = std::make_unique<Text>(Resource::get()->getTexture("smb2_big.png"), Resource::get()->getTextFile("smb2_big.txt"));
text_nokia2_ = std::make_unique<Text>(Resource::get()->getTexture("nokia2.png"), Resource::get()->getTextFile("nokia2.txt"));
text_nokia2_big_ = std::make_unique<Text>(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<std::string> Game::loadAnimations(const std::string &file_path)
{
std::vector<std::string> 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()
{

View File

@@ -381,9 +381,6 @@ private:
// Comprueba si todos los jugadores han terminado de jugar
bool allPlayersAreNotPlaying();
// Carga las animaciones
std::vector<std::string> loadAnimations(const std::string &file_path);
// Elimina todos los objetos contenidos en vectores
void deleteAllVectorObjects();

View File

@@ -14,13 +14,13 @@
// Constructor
GameLogo::GameLogo(int x, int y)
: dust_texture_(std::make_shared<Texture>(Screen::get()->getRenderer(), Asset::get()->get("title_dust.png"))),
coffee_texture_(std::make_shared<Texture>(Screen::get()->getRenderer(), Asset::get()->get("title_coffee.png"))),
crisis_texture_(std::make_shared<Texture>(Screen::get()->getRenderer(), Asset::get()->get("title_crisis.png"))),
arcade_edition_texture_(std::make_shared<Texture>(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<AnimatedSprite>(dust_texture_, Asset::get()->get("title_dust.ani"))),
dust_right_sprite_(std::make_unique<AnimatedSprite>(dust_texture_, Asset::get()->get("title_dust.ani"))),
dust_left_sprite_(std::make_unique<AnimatedSprite>(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))),
dust_right_sprite_(std::make_unique<AnimatedSprite>(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))),
coffee_sprite_(std::make_unique<SmartSprite>(coffee_texture_)),
crisis_sprite_(std::make_unique<SmartSprite>(crisis_texture_)),

View File

@@ -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<Fade>(renderer_);
fade_ = std::make_unique<Fade>();
background_ = std::make_unique<Background>(renderer_);
text_ = std::make_unique<Text>(Asset::get()->get("smb2.gif"), Asset::get()->get("smb2.txt"), renderer_);
text_ = std::make_unique<Text>(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);

View File

@@ -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<Text>(Asset::get()->get("smb2.gif"), Asset::get()->get("smb2.txt"), renderer_);
tiled_bg_ = std::make_unique<Tiledbg>(Asset::get()->get("title_bg_tile.png"), (SDL_Rect){0, 0, param.game.width, param.game.height}, TILED_MODE_STATIC);
fade_ = std::make_unique<Fade>(renderer_);
text_ = std::make_unique<Text>(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt"));
tiled_bg_ = std::make_unique<TiledBG>((SDL_Rect){0, 0, param.game.width, param.game.height}, TILED_MODE_STATIC);
fade_ = std::make_unique<Fade>();
// 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<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")));
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)
{

View File

@@ -1,16 +1,16 @@
#pragma once
#include <SDL2/SDL_rect.h> // for SDL_Point, SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Texture, SDL_Renderer
#include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for unique_ptr, shared_ptr
#include <vector> // for vector
#include <SDL2/SDL_rect.h> // for SDL_Point, SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Texture, SDL_Renderer
#include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for unique_ptr, shared_ptr
#include <vector> // 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<std::shared_ptr<Texture>> item_textures_; // Vector con las texturas de los items
std::vector<std::unique_ptr<Sprite>> sprites_; // Vector con los sprites de los items
std::unique_ptr<Text> text_; // Objeto para escribir texto
std::unique_ptr<Tiledbg> tiled_bg_; // Objeto para dibujar el mosaico animado de fondo
std::unique_ptr<TiledBG> tiled_bg_; // Objeto para dibujar el mosaico animado de fondo
std::unique_ptr<Fade> fade_; // Objeto para renderizar fades
SDL_Renderer *renderer_; // El renderizador de la ventana

View File

@@ -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<Texture>(renderer, Asset::get()->get("intro.png"));
text_ = std::make_shared<Text>(Asset::get()->get("nokia.png"), Asset::get()->get("nokia.txt"), renderer);
texture_ = Resource::get()->getTexture("intro.png");
text_ = std::make_shared<Text>(Resource::get()->getTexture("nokia.png"), Resource::get()->getTextFile("nokia.txt"));
// Inicializa variables
section::name = section::Name::INTRO;

View File

@@ -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;

View File

@@ -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<Sprite>(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<Texture>(renderer, Asset::get()->get("logo_jailgames.png"));
since_texture_ = std::make_shared<Texture>(renderer, Asset::get()->get("logo_since_1998.png"));
since_sprite_ = std::make_unique<Sprite>(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 ??

View File

@@ -4,6 +4,8 @@
#include <string> // 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> 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<Text>(bitmap_file, text_file, renderer)),
Notifier::Notifier(std::string icon_file, std::shared_ptr<Text> 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<Texture>(renderer, icon_file) : nullptr;
icon_texture_ = has_icons_ ? std::make_unique<Texture>(renderer_, icon_file) : nullptr;
}
// Destructor

View File

@@ -63,7 +63,7 @@ private:
SDL_Renderer *renderer_; // El renderizador de la ventana
std::shared_ptr<Texture> icon_texture_; // Textura para los iconos de las notificaciones
std::unique_ptr<Text> text_; // Objeto para dibujar texto
std::shared_ptr<Text> 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> 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> text, const std::string &sound_file);
// [SINGLETON] Destruiremos el objeto notifier con esta función estática
static void destroy();

View File

@@ -1,15 +1,16 @@
#include "on_screen_help.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <memory> // 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 <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <memory> // 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<Text>(Asset::get()->get("8bithud.png"), Asset::get()->get("8bithud.txt"), Screen::get()->getRenderer());
auto text = std::make_unique<Text>(Resource::get()->getTexture("8bithud.png"), Resource::get()->getTextFile("8bithud.txt"));
// Crea la textura con los gráficos
auto controllersTexture = std::make_shared<Texture>(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<Sprite>(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<Text>(Asset::get()->get("8bithud.png"), Asset::get()->get("8bithud.txt"), Screen::get()->getRenderer());
auto text = std::make_unique<Text>(Resource::get()->getTexture("8bithud.png"), Resource::get()->getTextFile("8bithud.txt"));
auto size = 0;
for (int i = 107; i <= 113; ++i)

View File

@@ -1,5 +1,7 @@
#include <iostream>
#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<Texture> 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<TextFile> 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<Texture>(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)));
}
}

View File

@@ -2,21 +2,66 @@
#include <SDL2/SDL.h>
#include <vector>
#include <memory>
#include <string>
#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> texture; // Objeto con la textura
// Constructor
ResourceTexture(const std::string &name, std::shared_ptr<Texture> texture)
: name(name), texture(texture) {}
};
// Estructura para almacenar ficheros TextFile y su nombre
struct ResourceTextFile
{
std::string name; // Nombre del fichero
std::shared_ptr<TextFile> text_file; // Objeto con los descriptores de la fuente de texto
// Constructor
ResourceTextFile(const std::string &name, std::shared_ptr<TextFile> 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<ResourceSound> sounds_; // Vector con los sonidos
std::vector<ResourceMusic> musics_; // Vector con las musicas
std::vector<ResourceSound> sounds_; // Vector con los sonidos
std::vector<ResourceMusic> musics_; // Vector con las musicas
std::vector<ResourceTexture> textures_; // Vector con las musicas
std::vector<ResourceTextFile> text_files_; // Vector con los ficheros de texto
std::vector<ResourceAnimation> 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<Texture> getTexture(const std::string &name);
// Obtiene el fichero de texto a partir de un nombre
std::shared_ptr<TextFile> getTextFile(const std::string &name);
// Obtiene la animación a partir de un nombre
Animations &getAnimation(const std::string &name);
};

View File

@@ -5,11 +5,12 @@
#include <math.h> // for roundf
#include <iomanip>
#include <sstream>
#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<Texture>(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<Sprite>(game_power_meter_texture_)),
text_scoreboard_(std::make_unique<Text>(Asset::get()->get("8bithud.png"), Asset::get()->get("8bithud.txt"), renderer)),
text_scoreboard_(std::make_unique<Text>(Resource::get()->getTexture("8bithud.png"), Resource::get()->getTextFile("8bithud.txt"))),
stage_(1),
hi_score_(0),
power_(0),

View File

@@ -2,23 +2,24 @@
#include <SDL2/SDL_rect.h> // for SDL_Rect
#include <fstream> // for basic_ostream, basic_ifstream, basic_istream
#include <iostream> // 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<TextFile> loadTextFile(const std::string &file_path)
{
TextFile tf;
auto tf = std::make_shared<TextFile>();
// 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> texture)
Text::Text(std::shared_ptr<Texture> 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> texture)
}
// Constructor
Text::Text(TextFile *text_file, std::shared_ptr<Texture> texture)
Text::Text(std::shared_ptr<Texture> texture, std::shared_ptr<TextFile> text_file)
: texture_(texture)
{
// Inicializa variables desde la estructura
box_height_ = text_file->box_height;

View File

@@ -26,7 +26,7 @@ struct TextFile
};
// Llena una estructuta TextFile desde un fichero
TextFile LoadTextFile(std::string file);
std::shared_ptr<TextFile> 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> texture);
Text(TextFile *text_file, std::shared_ptr<Texture> texture);
Text(std::shared_ptr<Texture> texture, const std::string &text_file);
Text(std::shared_ptr<Texture> texture, std::shared_ptr<TextFile> text_file);
// Destructor
~Text() = default;

View File

@@ -1,5 +1,6 @@
#include "texture.h"
#include "utils.h"
#include <SDL2/SDL_error.h> // for SDL_GetError
#include <SDL2/SDL_surface.h> // for SDL_CreateRGBSurfaceWithFormatFrom
#include <fcntl.h> // 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<void *>(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
{

View File

@@ -1,105 +1,84 @@
#include "tiled_bg.h"
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_stdinc.h> // for SDL_sinf
#include <stdlib.h> // for rand
#include <memory> // for unique_ptr, make_shared, make_unique
#include "screen.h" // for Screen
#include "sprite.h" // for Sprite
#include "texture.h" // for Texture
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <stdlib.h> // for rand
#include <memory> // for unique_ptr, make_shared, make_unique
#include <cmath> // 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<Texture>(renderer_, texture_path_);
auto tile = std::make_unique<Sprite>(bg_tile_texture, (SDL_Rect){0, 0, tile_width_, tile_height_});
auto tile = std::make_unique<Sprite>(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();
}

View File

@@ -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();

View File

@@ -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<Fade>(renderer);
fade_ = std::make_unique<Fade>();
text1_ = std::make_unique<Text>(Asset::get()->get("smb2.gif"), Asset::get()->get("smb2.txt"), renderer);
text1_ = std::make_unique<Text>(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<Text>(Asset::get()->get("8bithud.png"), Asset::get()->get("8bithud.txt"), renderer);
text2_ = std::make_unique<Text>(Resource::get()->getTexture("8bithud.png"), Resource::get()->getTextFile("8bithud.txt"));
mini_logo_texture_ = std::make_shared<Texture>(renderer, Asset::get()->get("logo_jailgames_mini.png"));
mini_logo_texture_ = Resource::get()->getTexture("logo_jailgames_mini.png");
mini_logo_sprite_ = std::make_unique<Sprite>(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<Tiledbg>(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<TiledBG>((SDL_Rect){0, 0, param.game.width, param.game.height}, TILED_MODE_RANDOM);
game_logo_ = std::make_unique<GameLogo>(param.game.game_area.center_x, param.title.title_c_c_position);
game_logo_->enable();

View File

@@ -1,18 +1,21 @@
#pragma once
#include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // 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 <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // 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<Tiledbg> tiled_bg_; // Objeto para dibujar el mosaico animado de fondo
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
std::shared_ptr<Texture> mini_logo_texture_; // Textura con el logo de JailGames mini
@@ -51,13 +54,13 @@ private:
std::unique_ptr<Fade> 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();

View File

@@ -1,4 +1,6 @@
#include "utils.h"
#include <iostream>
#include <string>
#include <algorithm> // for min, clamp, find_if_not, transform
#include <cctype> // for tolower, isspace
#include <cmath> // for cos, pow, M_PI
@@ -188,3 +190,16 @@ bool stringInVector(const std::vector<std::string> &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;
}

View File

@@ -264,6 +264,9 @@ double easeInOutSine(double t);
// Comprueba si una vector contiene una cadena
bool stringInVector(const std::vector<std::string> &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;