canvi de pc enmig de la enfangà

This commit is contained in:
2025-02-25 13:18:56 +01:00
parent 817140825a
commit c9da5135b2
29 changed files with 878 additions and 1042 deletions

View File

@@ -82,7 +82,7 @@ void AnimatedSprite::animate()
// Si alcanza el final de la animación, reinicia el contador de la animación
// en función de la variable loop y coloca el nuevo frame
if (animations_[current_animation_].current_frame >= (int)animations_[current_animation_].frames.size())
if (animations_[current_animation_].current_frame >= static_cast<int>(animations_[current_animation_].frames.size()))
{
if (animations_[current_animation_].loop == -1)
{ // Si no hay loop, deja el último frame
@@ -248,3 +248,20 @@ void AnimatedSprite::loadFromAnimationsFileBuffer(const AnimationsFileBuffer &so
setWidth(frame_width);
setHeight(frame_height);
}
// Establece el frame actual de la animación
void AnimatedSprite::setCurrentAnimationFrame(int num)
{
// Descarta valores fuera de rango
if (num < 0 || num >= static_cast<int>(animations_[current_animation_].frames.size()))
{
num = 0;
}
// Cambia el valor de la variable
animations_[current_animation_].current_frame = num;
animations_[current_animation_].counter = 0;
// Escoge el frame correspondiente de la animación
setClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
}

View File

@@ -63,4 +63,10 @@ public:
// Reinicia la animación
void resetAnimation();
// Establece el frame actual de la animación
void setCurrentAnimationFrame(int num);
// Obtiene el numero de frames de la animación actual
int getCurrentAnimationSize() { return static_cast<int>(animations_[current_animation_].frames.size()); }
};

View File

@@ -118,10 +118,18 @@ std::string Asset::getTypeName(AssetType type) const
{
switch (type)
{
case AssetType::DATA:
return "DATA";
break;
case AssetType::BITMAP:
return "BITMAP";
break;
case AssetType::ANIMATION:
return "ANIMATION";
break;
case AssetType::MUSIC:
return "MUSIC";
break;
@@ -134,24 +142,12 @@ std::string Asset::getTypeName(AssetType type) const
return "FONT";
break;
case AssetType::LANG:
return "LANG";
case AssetType::ROOM:
return "ROOM";
break;
case AssetType::DATA:
return "DATA";
break;
case AssetType::ANIMATION:
return "ANIMATION";
break;
case AssetType::PALETTE:
return "PALETTE";
break;
case AssetType::ITEM:
return "ITEM";
case AssetType::TILEMAP:
return "TILEMAP";
break;
default:

View File

@@ -6,15 +6,14 @@
enum class AssetType : int
{
DATA,
BITMAP,
ANIMATION,
MUSIC,
SOUND,
FONT,
LANG,
DATA,
ROOM,
ENEMY,
ITEM,
TILEMAP,
MAX_ASSET_TYPE
};

View File

@@ -5,7 +5,7 @@
#include "texture.h" // Para Texture
#include "utils.h"
#include "screen.h"
#include "asset.h"
#include "resource.h"
// [SINGLETON]
Debug *Debug::debug_ = nullptr;
@@ -32,19 +32,11 @@ Debug *Debug::get()
Debug::Debug()
// Copia la dirección de los objetos
: screen_(Screen::get()),
renderer_(Screen::get()->getRenderer()),
asset_(Asset::get())
renderer_(Screen::get()->getRenderer())
{
// Reserva memoria para los punteros
texture_ = new Texture(renderer_, asset_->get("debug.png"));
text_ = new Text(asset_->get("debug.txt"), texture_, renderer_);
}
// Destructor
Debug::~Debug()
{
delete texture_;
delete text_;
texture_ = Resource::get()->getTexture("debug.png");
text_ = Resource::get()->getText("debug.txt");
}
// Actualiza las variables
@@ -84,45 +76,3 @@ void Debug::setPos(SDL_Point p)
x_ = p.x;
y_ = p.y;
}
// Añade un texto para mostrar
void Debug::add(std::string text)
{
slot_.push_back(text);
}
// Borra la información de debug
void Debug::clear()
{
slot_.clear();
}
// Añade un texto para mostrar en el apartado log
void Debug::addToLog(std::string text)
{
log_.push_back(text);
}
// Borra la información de debug del apartado log
void Debug::clearLog()
{
log_.clear();
}
// Establece el valor de la variable
void Debug::setEnabled(bool value)
{
enabled_ = value;
}
// Obtiene el valor de la variable
bool Debug::getEnabled()
{
return enabled_;
}
// Cambia el valor de la variable
void Debug::switchEnabled()
{
enabled_ = !enabled_;
}

View File

@@ -4,6 +4,7 @@
#include <SDL2/SDL_render.h> // Para SDL_Renderer
#include <string> // Para string
#include <vector> // Para vector
#include <memory>
class Asset;
class Screen;
class Text;
@@ -17,11 +18,10 @@ private:
static Debug *debug_;
// Objetos y punteros
Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer_; // El renderizador de la ventana
Asset *asset_; // Objeto con los ficheros de recursos
Text *text_; // Objeto encargado de escribir texto en pantalla
Texture *texture_; // Textura para el texto
Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer_; // El renderizador de la ventana
std::shared_ptr<Text> text_; // Objeto encargado de escribir texto en pantalla
std::shared_ptr<Texture> texture_; // Textura para el texto
// Variables
std::vector<std::string> slot_; // Vector con los textos a escribir
@@ -34,7 +34,7 @@ private:
Debug();
// Destructor
~Debug();
~Debug() = default;
public:
// [SINGLETON] Crearemos el objeto con esta función estática
@@ -55,24 +55,14 @@ public:
// Establece la posición donde se colocará la información de debug
void setPos(SDL_Point p);
// Añade un texto para mostrar
void add(std::string text);
// Getters
bool getEnabled() { return enabled_; }
// Borra la información de debug
void clear();
// Añade un texto para mostrar en el apartado log
void addToLog(std::string text);
// Borra la información de debug del apartado log
void clearLog();
// Establece el valor de la variable
void setEnabled(bool value);
// Obtiene el valor de la variable
bool getEnabled();
// Cambia el valor de la variable
void switchEnabled();
// Setters
void add(std::string text) { slot_.push_back(text); }
void clear() { slot_.clear(); }
void addToLog(std::string text) { log_.push_back(text); }
void clearLog() { log_.clear(); }
void setEnabled(bool value) { enabled_ = value; }
void switchEnabled() { enabled_ = !enabled_; }
};

View File

@@ -42,8 +42,8 @@ Demo::Demo()
// Crea los objetos
itemTracker = std::make_unique<ItemTracker>();
scoreboard = std::make_unique<Scoreboard>(&board);
room = std::make_shared<Room>(resource->getRoom(currentRoom), itemTracker, &board.items, false);
text = resource->getText("smb2.txt");
room = std::make_shared<Room>(resource->getRoom(currentRoom), itemTracker, &board.items, false);
text = resource->getText("smb2.txt");
// Inicializa el resto de variables
counter = 0;
@@ -137,7 +137,7 @@ void Demo::renderRoomName()
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF);
SDL_RenderFillRect(renderer, &rect);
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, 16 * 8 + 4, room->getName(), 1, room->getBGColor());
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, 16 * 8 + 4, room->getName(), 1, room->getBGColor());
}
// Recarga todas las texturas
@@ -177,21 +177,19 @@ bool Demo::changeRoom(std::string file)
{
// En las habitaciones los limites tienen la cadena del fichero o un 0 en caso de no limitar con nada
if (file != "0")
{
// Verifica que exista el fichero que se va a cargar
if (asset->get(file) != "")
{
// Elimina la habitación actual
delete room;
room = nullptr;
// Crea un objeto habitación nuevo a partir del fichero
room = new Room(resource->getRoom(file), itemTracker, &board.items, false);
// Crea un objeto habitación a partir del fichero
room = std::make_shared<Room>(resource->getRoom(file), itemTracker, &board.items, false);
// Pone el color del marcador en función del color del borde de la habitación
setScoreBoardColor();
return true;
}
}
return false;
}

View File

@@ -24,14 +24,14 @@ private:
// Objetos y punteros
Screen *screen; // Objeto encargado de manejar el renderizador
SDL_Renderer *renderer; // El renderizador de la ventana
std::shared_ptr<Room> room; // Objeto encargado de gestionar cada habitación del juego
Resource *resource; // Objeto con los recursos
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Input *input; // Objeto pata gestionar la entrada
Debug *debug; // Objeto para gestionar la información de debug
std::shared_ptr<Room> room; // Objeto encargado de gestionar cada habitación del juego
std::shared_ptr<Text> text; // Objeto para los textos del juego
std::unique_ptr<Scoreboard> scoreboard; // Objeto encargado de gestionar el marcador
std::unique_ptr<ItemTracker> itemTracker; // Lleva el control de los objetos recogidos
Debug *debug; // Objeto para gestionar la información de debug
// Variables
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa

View File

@@ -381,15 +381,15 @@ bool Director::setFileList()
#endif
// Texto
Asset::get()->add(prefix + "/data/font/smb2.png", AssetType::FONT);
Asset::get()->add(prefix + "/data/font/smb2.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/font/smb2.txt", AssetType::FONT);
Asset::get()->add(prefix + "/data/font/debug.png", AssetType::FONT);
Asset::get()->add(prefix + "/data/font/debug.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/font/debug.txt", AssetType::FONT);
Asset::get()->add(prefix + "/data/font/gauntlet.png", AssetType::FONT);
Asset::get()->add(prefix + "/data/font/gauntlet.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/font/gauntlet.txt", AssetType::FONT);
Asset::get()->add(prefix + "/data/font/subatomic.png", AssetType::FONT);
Asset::get()->add(prefix + "/data/font/subatomic.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/font/subatomic.txt", AssetType::FONT);
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);
// Shaders
@@ -471,194 +471,194 @@ bool Director::setFileList()
Asset::get()->add(prefix + "/data/room/60.room", AssetType::ROOM);
// Tilemaps
Asset::get()->add(prefix + "/data/room/01.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/02.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/03.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/04.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/05.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/06.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/07.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/08.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/09.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/10.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/11.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/12.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/13.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/14.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/15.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/16.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/17.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/18.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/19.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/20.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/21.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/22.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/23.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/24.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/25.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/26.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/27.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/28.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/29.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/30.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/31.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/32.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/33.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/34.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/35.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/36.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/37.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/38.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/39.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/40.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/41.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/42.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/43.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/44.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/45.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/46.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/47.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/48.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/49.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/50.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/51.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/52.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/53.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/54.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/55.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/56.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/57.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/58.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/59.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/60.tmx", AssetType::ROOM);
Asset::get()->add(prefix + "/data/room/01.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/02.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/03.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/04.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/05.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/06.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/07.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/08.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/09.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/10.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/11.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/12.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/13.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/14.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/15.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/16.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/17.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/18.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/19.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/20.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/21.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/22.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/23.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/24.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/25.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/26.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/27.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/28.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/29.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/30.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/31.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/32.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/33.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/34.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/35.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/36.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/37.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/38.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/39.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/40.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/41.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/42.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/43.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/44.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/45.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/46.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/47.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/48.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/49.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/50.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/51.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/52.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/53.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/54.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/55.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/56.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/57.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/58.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/59.tmx", AssetType::TILEMAP);
Asset::get()->add(prefix + "/data/room/60.tmx", AssetType::TILEMAP);
// Tilesets
Asset::get()->add(prefix + "/data/tilesets/standard.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/tilesets/standard_zxarne.png", AssetType::BITMAP);
// Enemigos
Asset::get()->add(prefix + "/data/enemies/abad_bell.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/abad_bell.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/abad_bell.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/abad.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/abad.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/abad.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/amstrad_cs.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/amstrad_cs.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/amstrad_cs.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/flying_arounder.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/flying_arounder.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/flying_arounder.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/stopped_arounder.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/stopped_arounder.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/stopped_arounder.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/walking_arounder.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/walking_arounder.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/walking_arounder.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/arounders_door.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/arounders_door.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/arounders_door.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/arounders_machine.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/arounders_machine.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/arounders_machine.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/bat.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/bat.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/bat.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/batman_bell.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/batman_bell.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/batman_bell.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/batman_fire.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/batman_fire.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/batman_fire.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/batman.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/batman.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/batman.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/bell.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/bell.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/bell.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/bin.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/bin.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/bin.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/bird.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/bird.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/bird.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/breakout.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/breakout.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/breakout.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/bry.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/bry.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/bry.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/chip.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/chip.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/chip.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/code.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/code.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/code.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/congo.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/congo.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/congo.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/crosshair.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/crosshair.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/crosshair.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/demon.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/demon.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/demon.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/dimallas.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/dimallas.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/dimallas.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/floppy.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/floppy.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/floppy.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/dong.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/dong.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/dong.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/guitar.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/guitar.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/guitar.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/heavy.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/heavy.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/heavy.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/jailer_#1.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/jailer_#1.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/jailer_#1.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/jailer_#2.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/jailer_#2.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/jailer_#2.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/jailer_#3.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/jailer_#3.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/jailer_#3.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/jailbattle_alien.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/jailbattle_alien.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/jailbattle_alien.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/jailbattle_human.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/jailbattle_human.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/jailbattle_human.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/jeannine.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/jeannine.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/jeannine.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/lamp.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/lamp.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/lamp.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/lord_abad.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/lord_abad.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/lord_abad.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/matatunos.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/matatunos.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/matatunos.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/mummy.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/mummy.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/mummy.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/paco.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/paco.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/paco.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/elsa.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/elsa.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/elsa.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/qvoid.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/qvoid.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/qvoid.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/robot.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/robot.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/robot.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/sam.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/sam.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/sam.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/shock.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/shock.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/shock.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/sigmasua.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/sigmasua.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/sigmasua.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/spark.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/spark.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/spark.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/special/aerojailer.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/special/aerojailer.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/special/aerojailer.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/special/arounder.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/special/arounder.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/special/arounder.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/special/pepe_rosita_job.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/special/pepe_rosita_job.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/special/pepe_rosita_job.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/special/shooting_star.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/special/shooting_star.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/special/shooting_star.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/spider.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/spider.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/spider.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/tree_thing.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/tree_thing.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/tree_thing.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/tuno.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/tuno.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/tuno.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/tv_panel.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/tv_panel.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/tv_panel.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/tv.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/tv.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/tv.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/upv_student.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/upv_student.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/upv_student.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/wave.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/wave.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/wave.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/enemies/z80.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/enemies/z80.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/enemies/z80.png", AssetType::BITMAP);
// Jugador
Asset::get()->add(prefix + "/data/player/player.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/player/player.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/player/player.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/player/player2.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/player/player2.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/player/player2.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/player/player_game_over.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/player/player_game_over.ani", AssetType::DATA);
Asset::get()->add(prefix + "/data/player/player_game_over.ani", AssetType::ANIMATION);
// Items
Asset::get()->add(prefix + "/data/items/items.png", AssetType::BITMAP);
@@ -728,7 +728,7 @@ bool Director::setFileList()
// Credits
Asset::get()->add(prefix + "/data/credits/shine.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/credits/shine.ani", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/credits/shine.ani", AssetType::ANIMATION);
return Asset::get()->check();
}

View File

@@ -1,4 +1,5 @@
#include "enemy.h"
#include <SDL2/SDL.h>
#include <stdlib.h> // Para rand
#include <algorithm> // Para min
#include "animated_sprite.h" // Para AnimatedSprite
@@ -8,112 +9,102 @@
Enemy::Enemy(enemy_t enemy)
{
// Crea objetos
sprite = new AnimatedSprite(enemy.renderer, enemy.animation);
sprite_ = std::make_shared<AnimatedSprite>(falta_la_textura, enemy.animation);
// Obten el resto de valores
x1 = enemy.x1;
x2 = enemy.x2;
y1 = enemy.y1;
y2 = enemy.y2;
palette = enemy.palette;
colorString = enemy.color;
color = stringToColor(palette, colorString);
sprite->setPosX(enemy.x);
sprite->setPosY(enemy.y);
sprite->setVelX(enemy.vx);
sprite->setVelY(enemy.vy);
sprite->setWidth(enemy.w);
sprite->setHeight(enemy.h);
doFlip = enemy.flip;
mirror = enemy.mirror;
if (doFlip)
{
if (enemy.vx < 0.0f)
{
sprite->setFlipH(true);
}
}
sprite->setFlipV(mirror);
x1_ = enemy.x1;
x2_ = enemy.x2;
y1_ = enemy.y1;
y2_ = enemy.y2;
palette_ = enemy.palette;
color_string_ = enemy.color;
color_ = stringToColor(palette_, color_string_);
sprite_->setPosX(enemy.x);
sprite_->setPosY(enemy.y);
sprite_->setVelX(enemy.vx);
sprite_->setVelY(enemy.vy);
sprite_->setWidth(enemy.w);
sprite_->setHeight(enemy.h);
should_flip_ = enemy.flip;
should_mirror_ = enemy.mirror;
collider = getRect();
const SDL_RendererFlip flip = (should_flip_ && enemy.vx < 0.0f) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
const SDL_RendererFlip mirror = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
sprite_->setFlip(static_cast<SDL_RendererFlip>(flip | mirror));
collider_ = getRect();
// Coloca un frame al azar o el designado
if (enemy.frame == -1)
{
sprite->setCurrentFrame(rand() % sprite->getNumFrames());
sprite_->setCurrentAnimationFrame(rand() % sprite_->getCurrentAnimationSize());
}
else
{
sprite->setCurrentFrame(std::min(enemy.frame, sprite->getNumFrames() - 1));
sprite_->setCurrentAnimationFrame(enemy.frame);
}
}
// Destructor
Enemy::~Enemy()
{
delete sprite;
}
// Pinta el enemigo en pantalla
void Enemy::render()
{
sprite->getTexture()->setColor(color.r, color.g, color.b);
sprite->render();
sprite->getTexture()->setColor(255, 255, 255);
sprite_->getTexture()->setColor(color_.r, color_.g, color_.b);
sprite_->render();
sprite_->getTexture()->setColor(255, 255, 255);
}
// Actualiza las variables del objeto
void Enemy::update()
{
sprite->update();
sprite_->update();
checkPath();
collider = getRect();
collider_ = getRect();
}
// Comprueba si ha llegado al limite del recorrido para darse media vuelta
void Enemy::checkPath()
{
if (sprite->getPosX() > x2 || sprite->getPosX() < x1)
if (sprite_->getPosX() > x2_ || sprite_->getPosX() < x1_)
{
// Recoloca
if (sprite->getPosX() > x2)
if (sprite_->getPosX() > x2_)
{
sprite->setPosX(x2);
sprite_->setPosX(x2_);
}
else
{
sprite->setPosX(x1);
sprite_->setPosX(x1_);
}
// Cambia el sentido
sprite->setVelX(sprite->getVelX() * (-1));
sprite_->setVelX(sprite_->getVelX() * (-1));
// Invierte el sprite
if (doFlip)
if (should_flip_)
{
sprite->flipH();
sprite_->flip();
}
}
if (sprite->getPosY() > y2 || sprite->getPosY() < y1)
if (sprite_->getPosY() > y2_ || sprite_->getPosY() < y1_)
{
// Recoloca
if (sprite->getPosY() > y2)
if (sprite_->getPosY() > y2_)
{
sprite->setPosY(y2);
sprite_->setPosY(y2_);
}
else
{
sprite->setPosY(y1);
sprite_->setPosY(y1_);
}
// Cambia el sentido
sprite->setVelY(sprite->getVelY() * (-1));
sprite_->setVelY(sprite_->getVelY() * (-1));
// Invierte el sprite
if (doFlip)
if (should_flip_)
{
sprite->flipH();
sprite_->flip();
}
}
}
@@ -121,24 +112,24 @@ void Enemy::checkPath()
// Devuelve el rectangulo que contiene al enemigo
SDL_Rect Enemy::getRect()
{
return sprite->getRect();
return sprite_->getRect();
}
// Obtiene el rectangulo de colision del enemigo
SDL_Rect &Enemy::getCollider()
{
return collider;
return collider_;
}
// Recarga la textura
void Enemy::reLoadTexture()
{
sprite->getTexture()->reLoad();
sprite_->getTexture()->reLoad();
}
// Asigna la paleta
void Enemy::setPalette(Palette pal)
{
palette = pal;
color = stringToColor(palette, colorString);
palette_ = pal;
color_ = stringToColor(palette_, color_string_);
}

View File

@@ -4,6 +4,7 @@
#include <SDL2/SDL_render.h> // Para SDL_Renderer
#include <string> // Para basic_string, string
#include "utils.h" // Para palette_e, color_t
#include <memory> // Para shared_ptr
class AnimatedSprite;
struct animatedSprite_t;
@@ -12,7 +13,7 @@ struct enemy_t
{
SDL_Renderer *renderer; // El renderizador de la ventana
animatedSprite_t *animation; // Puntero a las animaciones del enemigo
std::string animationString; // Ruta al fichero con la animación
std::string animation_path; // Ruta al fichero con la animación
int w; // Anchura del enemigo
int h; // Altura del enemigo
float x; // Posición inicial en el eje X
@@ -34,19 +35,19 @@ class Enemy
{
private:
// Objetos y punteros
AnimatedSprite *sprite; // Sprite del enemigo
std::shared_ptr<AnimatedSprite> sprite_; // Sprite del enemigo
// Variables
Color color; // Color del enemigo
std::string colorString; // Color del enemigo en formato texto
Palette palette; // Paleta de colores
int x1; // Limite izquierdo de la ruta en el eje X
int x2; // Limite derecho de la ruta en el eje X
int y1; // Limite superior de la ruta en el eje Y
int y2; // Limite inferior de la ruta en el eje Y
SDL_Rect collider; // Caja de colisión
bool doFlip; // Indica si el enemigo hace flip al terminar su ruta
bool mirror; // Indica si el enemigo se dibuja volteado verticalmente
Color color_; // Color del enemigo
std::string color_string_; // Color del enemigo en formato texto
Palette palette_; // Paleta de colores
int x1_; // Limite izquierdo de la ruta en el eje X
int x2_; // Limite derecho de la ruta en el eje X
int y1_; // Limite superior de la ruta en el eje Y
int y2_; // Limite inferior de la ruta en el eje Y
SDL_Rect collider_; // Caja de colisión
bool should_flip_; // Indica si el enemigo hace flip al terminar su ruta
bool should_mirror_; // Indica si el enemigo se dibuja volteado verticalmente
// Comprueba si ha llegado al limite del recorrido para darse media vuelta
void checkPath();
@@ -56,7 +57,7 @@ public:
Enemy(enemy_t enemy);
// Destructor
~Enemy();
~Enemy() = default;
// Pinta el enemigo en pantalla
void render();

View File

@@ -32,7 +32,8 @@ Game::Game()
asset_(Asset::get()),
input_(Input::get()),
resource_(Resource::get()),
debug_(Debug::get())
debug_(Debug::get()),
cheevos_(Cheevos::get())
{
// Inicia algunas variables
board_.iniClock = SDL_GetTicks();
@@ -50,19 +51,18 @@ Game::Game()
#endif
// Crea los objetos
cheevos_ = Cheevos::get();
scoreboard_ = new Scoreboard(&board_);
item_tracker_ = new ItemTracker();
room_tracker_ = new RoomTracker();
room_ = new Room(resource_->getRoom(current_room_), item_tracker_, &board_.items, false);
scoreboard_ = std::make_shared<Scoreboard>(&board_);
item_tracker_ = std::make_shared<ItemTracker>();
room_tracker_ = std::make_shared<RoomTracker>();
room_ = std::make_shared<Room>(resource_->getRoom(current_room_), item_tracker_, &board_.items, false);
const std::string playerPNG = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png";
const std::string playerANI = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani";
const player_t player = {spawn_point_, playerPNG, playerANI, room_};
player_ = new Player(player);
text_ = new Text(resource_->getOffset("smb2.txt"), resource_->getTexture("smb2.png"), renderer_);
music_ = JA_LoadMusic(asset_->get("game.ogg").c_str());
player_ = std::make_shared<Player>(player);
text_ = resource_->getText("smb2.txt");
music_ = resource_->getMusic("game.ogg");
death_sound_ = JA_LoadSound(asset_->get("death.wav").c_str());
stats_ = new Stats(asset_->get("stats.csv"), asset_->get("stats_buffer.csv"));
stats_ = std::make_shared<Stats>(asset_->get("stats.csv"), asset_->get("stats_buffer.csv"));
// Crea la textura para poner el nombre de la habitación
room_name_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, text_->getCharacterSize() * 2);
@@ -111,18 +111,7 @@ Game::Game()
Game::~Game()
{
// Libera la memoria de los objetos
delete scoreboard_;
delete item_tracker_;
delete room_tracker_;
delete room_;
delete player_;
delete text_;
delete stats_;
SDL_DestroyTexture(room_name_texture_);
JA_DeleteMusic(music_);
JA_DeleteSound(death_sound_);
}
// Comprueba los eventos de la cola
@@ -146,7 +135,7 @@ void Game::checkEvents()
break;
case SDL_SCANCODE_R:
resource_->reLoad();
resource_->reload();
break;
case SDL_SCANCODE_W:
@@ -292,9 +281,9 @@ void Game::render()
// Pasa la información de debug
void Game::updateDebugInfo()
{
debug_->add("X = " + std::to_string(static_cast<int>(player_->x)) + ", Y = " + std::to_string(static_cast<int>(player_->y)));
debug_->add("VX = " + std::to_string(player_->vx).substr(0, 4) + ", VY = " + std::to_string(player_->vy).substr(0, 4));
debug_->add("STATE = " + std::to_string(player_->state));
debug_->add("X = " + std::to_string(static_cast<int>(player_->x_)) + ", Y = " + std::to_string(static_cast<int>(player_->y_)));
debug_->add("VX = " + std::to_string(player_->vx_).substr(0, 4) + ", VY = " + std::to_string(player_->vy_).substr(0, 4));
debug_->add("STATE = " + std::to_string(player_->state_));
}
// Pone la información de debug en pantalla
@@ -346,12 +335,8 @@ bool Game::changeRoom(std::string file)
// Verifica que exista el fichero que se va a cargar
if (asset_->get(file) != "")
{
// Elimina la habitación actual
delete room_;
room_ = nullptr;
// Crea un objeto habitación nuevo a partir del fichero
room_ = new Room(resource_->getRoom(file), item_tracker_, &board_.items, board_.jail_is_open);
room_ = std::make_shared<Room>(resource_->getRoom(file), item_tracker_, &board_.items, board_.jail_is_open);
// Pone el nombre de la habitación en la textura
fillRoomNameTexture();
@@ -448,10 +433,6 @@ void Game::killPlayer()
// Invalida el logro de pasarse el juego sin morir
cheevos_->invalidate(11);
// Destruye la habitacion y el jugador
delete room_;
delete this->player_;
// Sonido
JA_PlaySound(death_sound_);
@@ -459,11 +440,11 @@ void Game::killPlayer()
setBlackScreen();
// Crea la nueva habitación y el nuevo jugador
room_ = new Room(resource_->getRoom(current_room_), item_tracker_, &board_.items, board_.jail_is_open);
room_ = std::make_shared<Room>(resource_->getRoom(current_room_), item_tracker_, &board_.items, board_.jail_is_open);
const std::string playerPNG = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png";
const std::string playerANI = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani";
const player_t player = {spawn_point_, playerPNG, playerANI, room_};
player_ = new Player(player);
player_ = std::make_shared<Player>(player);
// Pone los objetos en pausa mientras esta la habitación en negro
room_->pause();
@@ -558,10 +539,9 @@ bool Game::checkEndGame()
int Game::getTotalItems()
{
int items = 0;
std::vector<res_room_t> *rooms = new std::vector<res_room_t>;
rooms = resource_->getAllRooms();
auto rooms = resource_->getRooms();
for (auto room : *rooms)
for (auto room : rooms)
{
items += room.room->items.size();
}
@@ -632,10 +612,9 @@ void Game::checkRestoringJail()
// Inicializa el diccionario de las estadísticas
void Game::initStats()
{
std::vector<res_room_t> *rooms = new std::vector<res_room_t>;
rooms = resource_->getAllRooms();
auto rooms = resource_->getRooms();
for (auto room : *rooms)
for (auto room : rooms)
{
stats_->addDictionary(room.room->number, room.room->name);
}
@@ -655,7 +634,7 @@ void Game::fillRoomNameTexture()
SDL_RenderClear(renderer_);
// Escribe el texto en la textura
text_->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, text_->getCharacterSize() / 2, room_->getName(), 1, room_->getBGColor());
text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, text_->getCharacterSize() / 2, room_->getName(), 1, room_->getBGColor());
// Deja el renderizador por defecto
SDL_SetRenderTarget(renderer_, nullptr);

View File

@@ -27,21 +27,21 @@ class Game
{
private:
// Objetos y punteros
Screen *screen_; // Objeto encargado de manejar el renderizador
SDL_Renderer *renderer_; // El renderizador de la ventana
Room *room_; // Objeto encargado de gestionar cada habitación del juego
Player *player_; // Objeto con el jugador
ItemTracker *item_tracker_; // Lleva el control de los objetos recogidos
RoomTracker *room_tracker_; // Lleva el control de las habitaciones visitadas
Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos
Input *input_; // Objeto pata gestionar la entrada
Text *text_; // Objeto para los textos del juego
Scoreboard *scoreboard_; // Objeto encargado de gestionar el marcador
Cheevos *cheevos_; // Objeto encargado de gestionar los logros del juego
Resource *resource_; // Objeto con los recursos
Debug *debug_; // Objeto para gestionar la información de debug
Stats *stats_; // Objeto encargado de gestionar las estadísticas
SDL_Texture *room_name_texture_; // Textura para escribir el nombre de la habitación
Screen *screen_; // Objeto encargado de manejar el renderizador
SDL_Renderer *renderer_; // El renderizador de la ventana
Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos
Input *input_; // Objeto pata gestionar la entrada
Resource *resource_; // Objeto con los recursos
Debug *debug_; // Objeto para gestionar la información de debug
Cheevos *cheevos_; // Objeto encargado de gestionar los logros del juego
std::shared_ptr<Room> room_; // Objeto encargado de gestionar cada habitación del juego
std::shared_ptr<Player> player_; // Objeto con el jugador
std::shared_ptr<ItemTracker> item_tracker_; // Lleva el control de los objetos recogidos
std::shared_ptr<RoomTracker> room_tracker_; // Lleva el control de las habitaciones visitadas
std::shared_ptr<Text> text_; // Objeto para los textos del juego
std::shared_ptr<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador
std::shared_ptr<Stats> stats_; // Objeto encargado de gestionar las estadísticas
SDL_Texture *room_name_texture_; // Textura para escribir el nombre de la habitación
// Variables
JA_Music_t *music_; // Musica que suena durante el juego

View File

@@ -5,6 +5,7 @@
#include <SDL2/SDL_stdinc.h> // Para Uint32
#include <vector> // Para vector
#include "utils.h" // Para color_t
#include <memory> // Para shared_ptr
class AnimatedSprite;
class Asset;
class Input;

View File

@@ -5,13 +5,13 @@
// Constructor
Item::Item(item_t item)
{
const int itemSize = 8;
constexpr int ITEMSIZE = 8;
// Crea objetos;
sprite = new Sprite(item.x, item.y, itemSize, itemSize, item.texture, item.renderer);
sprite = std::make_shared<Sprite>(item.texture, item.x, item.y, ITEMSIZE, ITEMSIZE);
// Inicia variables
sprite->setClip((item.tile % 10) * itemSize, (item.tile / 10) * itemSize, itemSize, itemSize);
sprite->setClip((item.tile % 10) * ITEMSIZE, (item.tile / 10) * ITEMSIZE, ITEMSIZE, ITEMSIZE);
collider = sprite->getRect();
colorChangeSpeed = 4;
counter = item.counter * colorChangeSpeed;
@@ -26,12 +26,6 @@ Item::Item(item_t item)
color.push_back(c);
}
// Destructor
Item::~Item()
{
delete sprite;
}
// Pinta el objeto en pantalla
void Item::render()
{
@@ -41,30 +35,13 @@ void Item::render()
sprite->getTexture()->setColor(255, 255, 255);
}
// Actualiza las variables del objeto
void Item::update()
{
counter++;
}
// Obtiene el rectangulo de colision del objeto
SDL_Rect &Item::getCollider()
{
return collider;
}
// Obtiene su ubicación
SDL_Point Item::getPos()
{
const SDL_Point p = {sprite->getPosX(), sprite->getPosY()};
const SDL_Point p = {sprite->getX(), sprite->getY()};
return p;
}
// Recarga la textura
void Item::reLoadTexture()
{
sprite->getTexture()->reLoad();
}
// Asigna los colores del objeto
void Item::setColors(Color col1, Color col2)

View File

@@ -5,13 +5,15 @@
#include <string> // Para basic_string, string
#include <vector> // Para vector
#include "utils.h" // Para color_t
class Sprite;
#include <memory> // Para shared_ptr
#include "sprite.h"
#include "texture.h"
class Texture;
struct item_t
{
SDL_Renderer *renderer; // El renderizador de la ventana
Texture *texture; // Textura con los gráficos del item
std::shared_ptr<Texture> texture; // Textura con los gráficos del item
std::string tileSetFile; // Ruta al fichero con los gráficos del item
int x; // Posición del item en pantalla
int y; // Posición del item en pantalla
@@ -28,7 +30,7 @@ class Item
{
private:
// Objetos y punteros
Sprite *sprite; // Sprite del objeto
std::shared_ptr<Sprite> sprite; // Sprite del objeto
// Variables
std::vector<Color> color; // Vector con los colores del objeto
@@ -41,23 +43,24 @@ public:
Item(item_t item);
// Destructor
~Item();
~Item() = default;
// Pinta el objeto en pantalla
void render();
// Actualiza las variables del objeto
void update();
void update() { counter++; }
// Obtiene el rectangulo de colision del objeto
SDL_Rect &getCollider();
SDL_Rect &getCollider() { return collider; }
// Obtiene su ubicación
SDL_Point getPos();
// Recarga la textura
void reLoadTexture();
void reLoadTexture() { sprite->getTexture()->reLoad(); }
// Asigna los colores del objeto
void setColors(Color col1, Color col2);
};

View File

@@ -78,42 +78,6 @@ void MovingSprite::render()
texture_->render(pos_.x, pos_.y, &clip_, zoom_w_, zoom_h_, rotate_.angle, rotate_.center, flip_);
}
// Establece el valor de la variable
void MovingSprite::setZoomW(float value)
{
zoom_w_ = value;
}
// Establece el valor de la variable
void MovingSprite::setZoomH(float value)
{
zoom_h_ = value;
}
// Establece el valor de la variable
void MovingSprite::setAngle(double value)
{
rotate_.angle = value;
}
// Establece el valor de la variable
void MovingSprite::setRotatingCenter(SDL_Point *point)
{
rotate_.center = point;
}
// Incrementa el valor del ángulo
void MovingSprite::updateAngle()
{
rotate_.angle += rotate_.amount;
}
// Obtiene el valor de la variable
bool MovingSprite::isRotating() const
{
return rotate_.enabled;
}
// Establece la rotacion
void MovingSprite::rotate()
{
@@ -135,43 +99,6 @@ void MovingSprite::setRotate(bool enable)
rotate_.counter = 0;
}
// Establece el valor de la variable
void MovingSprite::setRotateSpeed(int value)
{
rotate_.speed = std::max(1, value);
}
// Establece el valor de la variable
void MovingSprite::setRotateAmount(double value)
{
rotate_.amount = value;
}
// Cambia el sentido de la rotación
void MovingSprite::switchRotate()
{
rotate_.amount *= -1;
}
// Establece el valor de la variable
void MovingSprite::setFlip(SDL_RendererFlip flip)
{
flip_ = flip;
}
// Gira el sprite horizontalmente
void MovingSprite::flip()
{
flip_ = (flip_ == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL;
}
// Obtiene el valor de la variable
SDL_RendererFlip MovingSprite::getFlip()
{
return flip_;
}
// Establece la posición y_ el tamaño del objeto
void MovingSprite::setPos(SDL_Rect rect)
{
@@ -204,27 +131,3 @@ void MovingSprite::setPosY(float value)
y_ = value;
pos_.y = static_cast<int>(y_);
}
// Establece el valor de la variable
void MovingSprite::setVelX(float value)
{
vx_ = value;
}
// Establece el valor de la variable
void MovingSprite::setVelY(float value)
{
vy_ = value;
}
// Establece el valor de la variable
void MovingSprite::setAccelX(float value)
{
ax_ = value;
}
// Establece el valor de la variable
void MovingSprite::setAccelY(float value)
{
ay_ = value;
}

View File

@@ -38,7 +38,7 @@ protected:
SDL_RendererFlip flip_; // Indica como se voltea el sprite
// Incrementa el valor del ángulo
void updateAngle();
void updateAngle() { rotate_.angle += rotate_.amount; }
// Mueve el sprite
void move();
@@ -73,40 +73,40 @@ public:
float getAccelY() const { return ay_; }
// Establece la variable
void setVelX(float value);
void setVelY(float value);
void setAccelX(float value);
void setAccelY(float value);
void setVelX(float value) { vx_ = value; }
void setVelY(float value) { vy_ = value; }
void setAccelX(float value) { ax_ = value; }
void setAccelY(float value) { ay_ = value; }
// Obten el valor de la variable
bool isRotating() const;
bool isRotating() const { return rotate_.enabled; }
// Establece el valor de la variable
void setZoomW(float value);
void setZoomH(float value);
void setZoomW(float value) { zoom_w_ = value; }
void setZoomH(float value) { zoom_h_ = value; }
// Establece el valor de la variable
void setAngle(double vaue);
void setRotatingCenter(SDL_Point *point);
void setAngle(double value) { rotate_.angle = value; }
void setRotatingCenter(SDL_Point *point) { rotate_.center = point; }
// Activa o desactiva el efecto de rotación
void setRotate(bool enable);
// Establece el valor de la variable
void setRotateSpeed(int value);
void setRotateAmount(double value);
void setRotateSpeed(int value) { rotate_.speed = std::max(1, value); }
void setRotateAmount(double value) { rotate_.amount = value; }
// Cambia el sentido de la rotación
void switchRotate();
void switchRotate() { rotate_.amount *= -1; }
// Establece el valor de la variable
void setFlip(SDL_RendererFlip flip);
void setFlip(SDL_RendererFlip flip) { flip_ = flip; }
// Gira el sprite horizontalmente
void flip();
void flip() { flip_ = (flip_ == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL; }
// Obtiene el valor de la variable
SDL_RendererFlip getFlip();
SDL_RendererFlip getFlip() { return flip_; }
// Establece la posición y_ el tamaño del objeto
void setPos(SDL_Rect rect);

View File

@@ -1,20 +1,24 @@
#include "notifier.h"
#include <SDL2/SDL_blendmode.h> // Para SDL_BLENDMODE_BLEND
#include <string> // Para basic_string, string, char_traits
#include "jail_audio.h" // Para JA_DeleteSound, JA_LoadSound, JA_Pla...
#include "sprite.h" // Para Sprite
#include "text.h" // Para Text
#include "texture.h" // Para Texture
#include "screen.h"
#include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888
#include <string> // Para string
#include <algorithm>
#include <vector>
#include "jail_audio.h" // Para JA_DeleteSound, JA_LoadSound, JA_Pla...
#include "screen.h" // Para Screen
#include "sprite.h" // Para Sprite
#include "text.h" // Para Text
#include "texture.h" // Para Texture
#include "resource.h"
#include "options.h"
// [SINGLETON]
Notifier *Notifier::notifier_ = nullptr;
// [SINGLETON] Crearemos el objeto con esta función estática
void Notifier::init(std::string iconFile, std::string bitmapFile, std::string textFile, std::string soundFile)
void Notifier::init(const std::string &icon_file, std::shared_ptr<Text> text)
{
Notifier::notifier_ = new Notifier(iconFile, bitmapFile, textFile, soundFile);
Notifier::notifier_ = new Notifier(icon_file, text);
}
// [SINGLETON] Destruiremos el objeto con esta función estática
@@ -30,45 +34,21 @@ Notifier *Notifier::get()
}
// Constructor
Notifier::Notifier(std::string iconFile, std::string bitmapFile, std::string textFile, std::string soundFile)
{
// Inicializa variables
renderer_ = Screen::get()->getRenderer();
bg_color_ = options.notifications.color;
wait_time_ = 300;
// Crea objetos
icon_texture_ = new Texture(renderer_, iconFile);
text_texture_ = new Texture(renderer_, bitmapFile);
text_ = new Text(textFile, text_texture_, renderer_);
sound_ = JA_LoadSound(soundFile.c_str());
}
// Destructor
Notifier::~Notifier()
{
// Libera la memoria de los objetos
delete text_texture_;
delete icon_texture_;
delete text_;
JA_DeleteSound(sound_);
for (auto notification : notifications_)
{
delete notification.sprite;
delete notification.texture;
}
}
Notifier::Notifier(std::string icon_file, std::shared_ptr<Text> text)
: renderer_(Screen::get()->getRenderer()),
icon_texture_(!icon_file.empty() ? std::make_unique<Texture>(renderer_, icon_file) : nullptr),
text_(text),
bg_color_(options.notifications.color),
wait_time_(150),
stack_(false),
has_icons_(!icon_file.empty()) {}
// Dibuja las notificaciones por pantalla
void Notifier::render()
{
if (active())
for (int i = (int)notifications_.size() - 1; i >= 0; --i)
{
for (auto it = notifications_.rbegin(); it != notifications_.rend(); ++it)
{
it->sprite->render();
}
notifications_[i].sprite->render();
}
}
@@ -80,7 +60,7 @@ void Notifier::update()
// Si la notificación anterior está "saliendo", no hagas nada
if (i > 0)
{
if (notifications_[i - 1].state == ns_rising)
if (notifications_[i - 1].state == NotificationStatus::RISING)
{
break;
}
@@ -93,24 +73,25 @@ void Notifier::update()
{
if (options.notifications.sound)
{
if (notifications_[i].state == ns_rising)
{ // Reproduce el sonido de la notificación
JA_PlaySound(sound_);
if (notifications_[i].state == NotificationStatus::RISING)
{
// Reproduce el sonido de la notificación
JA_PlaySound(Resource::get()->getSound("notify.wav"));
}
}
}
// Comprueba los estados
if (notifications_[i].state == ns_rising)
if (notifications_[i].state == NotificationStatus::RISING)
{
const float step = ((float)notifications_[i].counter / notifications_[i].travelDist);
const float step = ((float)notifications_[i].counter / notifications_[i].travel_dist);
const int alpha = 255 * step;
if (options.notifications.getVerticalPosition() == "UPPER")
if (options.notifications.getVerticalPosition() == "TOP")
{
notifications_[i].rect.y++;
}
else if (options.notifications.getVerticalPosition() == "BOTTOM")
else
{
notifications_[i].rect.y--;
}
@@ -118,43 +99,43 @@ void Notifier::update()
if (notifications_[i].rect.y == notifications_[i].y)
{
notifications_[i].state = ns_stay;
notifications_[i].state = NotificationStatus::STAY;
notifications_[i].texture->setAlpha(255);
notifications_[i].counter = 0;
}
}
else if (notifications_[i].state == ns_stay)
else if (notifications_[i].state == NotificationStatus::STAY)
{
if (notifications_[i].counter == wait_time_)
{
notifications_[i].state = ns_vanishing;
notifications_[i].state = NotificationStatus::VANISHING;
notifications_[i].counter = 0;
}
}
else if (notifications_[i].state == ns_vanishing)
else if (notifications_[i].state == NotificationStatus::VANISHING)
{
const float step = (notifications_[i].counter / (float)notifications_[i].travelDist);
const float step = (notifications_[i].counter / (float)notifications_[i].travel_dist);
const int alpha = 255 * (1 - step);
if (options.notifications.getVerticalPosition() == "UPPER")
if (options.notifications.getVerticalPosition() == "TOP")
{
notifications_[i].rect.y--;
}
else if (options.notifications.getVerticalPosition() == "BOTTOM")
else
{
notifications_[i].rect.y++;
}
notifications_[i].texture->setAlpha(alpha);
if (notifications_[i].rect.y == notifications_[i].y - notifications_[i].travelDist)
if (notifications_[i].rect.y == notifications_[i].y - notifications_[i].travel_dist)
{
notifications_[i].state = ns_finished;
notifications_[i].state = NotificationStatus::FINISHED;
}
}
notifications_[i].sprite->setRect(notifications_[i].rect);
notifications_[i].sprite->setPosition(notifications_[i].rect);
}
clearFinishedNotifications();
@@ -165,87 +146,95 @@ void Notifier::clearFinishedNotifications()
{
for (int i = (int)notifications_.size() - 1; i >= 0; --i)
{
if (notifications_[i].state == ns_finished)
if (notifications_[i].state == NotificationStatus::FINISHED)
{
delete notifications_[i].sprite;
delete notifications_[i].texture;
notifications_.erase(notifications_.begin() + i);
}
}
}
// Muestra una notificación de texto por pantalla;
void Notifier::show(std::string text1, std::string text2, int icon)
void Notifier::show(std::vector<std::string> texts, int icon, const std::string &code)
{
// Si no hay texto, acaba
if (texts.empty())
{
return;
}
// Si las notificaciones no se apilan, elimina las anteriores
if (!stack_)
{
clearNotifications();
}
// Elimina las cadenas vacías
texts.erase(std::remove_if(texts.begin(), texts.end(), [](const std::string &s)
{ return s.empty(); }),
texts.end());
// Encuentra la cadena más larga
std::string longest;
for (const auto &text : texts)
{
if (text.length() > longest.length())
longest = text;
}
// Inicializa variables
const int iconSize = 16;
const int padding = text_->getCharacterSize();
const int iconSpace = icon >= 0 ? iconSize + padding : 0;
const std::string txt = text1.length() > text2.length() ? text1 : text2;
const int width = text_->lenght(txt) + (padding * 2) + iconSpace;
const int height = (text_->getCharacterSize() * 2) + (padding * 2);
constexpr int icon_size = 16;
constexpr int padding_out = 1;
const auto padding_in_h = text_->getCharacterSize();
const auto padding_in_v = text_->getCharacterSize() / 2;
const int icon_space = icon >= 0 ? icon_size + padding_in_h : 0;
const int width = text_->lenght(longest) + (padding_in_h * 2) + icon_space;
const int height = (text_->getCharacterSize() * texts.size()) + (padding_in_v * 2);
const auto shape = NotificationShape::SQUARED;
// Posición horizontal
int despH = 0;
auto desp_h = 0;
if (options.notifications.getHorizontalPosition() == "LEFT")
{
despH = padding;
desp_h = padding_out;
}
else if (options.notifications.getHorizontalPosition() == "CENTER")
{
despH = (options.game.width - width) / 2;
desp_h = ((param.game.width / 2) - (width / 2));
}
else if (options.notifications.getHorizontalPosition() == "RIGHT")
else
{
despH = options.game.width - width - padding;
desp_h = param.game.width - width - padding_out;
}
// Posición vertical
int despV = 0;
if (options.notifications.getVerticalPosition() == "UPPER")
{
despV = padding;
}
else
{
despV = options.game.height - height - padding;
}
const int travelDist = height + padding;
const int desp_v = (param.notification.pos_v == NotifyPosition::TOP) ? padding_out : (param.game.height - height - padding_out);
// Offset
int offset = 0;
if (options.notifications.getVerticalPosition() == "UPPER")
const auto travel_dist = height + padding_out;
auto offset = 0;
if (param.notification.pos_v == NotifyPosition::TOP)
{
offset = static_cast<int>(notifications_.size()) > 0 ? notifications_.back().y + travelDist : despV;
offset = !notifications_.empty() ? notifications_.back().y + travel_dist : desp_v;
}
else
{
offset = static_cast<int>(notifications_.size()) > 0 ? notifications_.back().y - travelDist : despV;
offset = !notifications_.empty() ? notifications_.back().y - travel_dist : desp_v;
}
// Crea la notificacion
notification_t n;
Notification n;
// Inicializa variables
n.code = code;
n.y = offset;
n.travelDist = travelDist;
n.counter = 0;
n.state = ns_rising;
n.text1 = text1;
n.text2 = text2;
if (options.notifications.getVerticalPosition() == "UPPER")
{
n.rect = {despH, offset - travelDist, width, height};
}
else
{
n.rect = {despH, offset + travelDist, width, height};
}
n.travel_dist = travel_dist;
n.texts = texts;
n.shape = shape;
auto y_pos = offset + (param.notification.pos_v == NotifyPosition::TOP ? -travel_dist : travel_dist);
n.rect = {desp_h, y_pos, width, height};
// Crea la textura
n.texture = new Texture(renderer_);
n.texture->createBlank(renderer_, width, height, SDL_TEXTUREACCESS_TARGET);
n.texture = std::make_shared<Texture>(renderer_);
n.texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
n.texture->setBlendMode(SDL_BLENDMODE_BLEND);
// Prepara para dibujar en la textura
@@ -254,49 +243,78 @@ void Notifier::show(std::string text1, std::string text2, int icon)
// Dibuja el fondo de la notificación
SDL_SetRenderDrawColor(renderer_, bg_color_.r, bg_color_.g, bg_color_.b, 255);
SDL_Rect rect;
rect = {4, 0, width - (4 * 2), height};
SDL_RenderFillRect(renderer_, &rect);
if (shape == NotificationShape::ROUNDED)
{
rect = {4, 0, width - (4 * 2), height};
SDL_RenderFillRect(renderer_, &rect);
rect = {4 / 2, 1, width - 4, height - 2};
SDL_RenderFillRect(renderer_, &rect);
rect = {4 / 2, 1, width - 4, height - 2};
SDL_RenderFillRect(renderer_, &rect);
rect = {1, 4 / 2, width - 2, height - 4};
SDL_RenderFillRect(renderer_, &rect);
rect = {1, 4 / 2, width - 2, height - 4};
SDL_RenderFillRect(renderer_, &rect);
rect = {0, 4, width, height - (4 * 2)};
SDL_RenderFillRect(renderer_, &rect);
rect = {0, 4, width, height - (4 * 2)};
SDL_RenderFillRect(renderer_, &rect);
}
else if (shape == NotificationShape::SQUARED)
{
SDL_RenderClear(renderer_);
}
// Dibuja el icono de la notificación
if (icon >= 0)
if (has_icons_ && icon >= 0 && texts.size() >= 2)
{
Sprite *sp = new Sprite({0, 0, iconSize, iconSize}, icon_texture_, renderer_);
sp->setPos({padding, padding, iconSize, iconSize});
sp->setClip({iconSize * (icon % 10), iconSize * (icon / 10), iconSize, iconSize});
auto sp = std::make_unique<Sprite>(icon_texture_, (SDL_Rect){0, 0, icon_size, icon_size});
sp->setPosition({padding_in_h, padding_in_v, icon_size, icon_size});
sp->setSpriteClip({icon_size * (icon % 10), icon_size * (icon / 10), icon_size, icon_size});
sp->render();
delete sp;
}
// Escribe el texto de la notificación
Color color = {255, 255, 255};
if (text2 != "")
{ // Dos lineas de texto
text_->writeColored(padding + iconSpace, padding, text1, color);
text_->writeColored(padding + iconSpace, padding + text_->getCharacterSize() + 1, text2, color);
}
else
{ // Una linea de texto
text_->writeColored(padding + iconSpace, (height / 2) - (text_->getCharacterSize() / 2), text1, color);
const Color color{255, 255, 255};
int iterator = 0;
for (const auto &text : texts)
{
text_->writeColored(padding_in_h + icon_space, padding_in_v + iterator * (text_->getCharacterSize() + 1), text, color);
++iterator;
}
// Deja de dibujar en la textura
SDL_SetRenderTarget(renderer_, nullptr);
// Crea el sprite de la notificación
n.sprite = new Sprite(n.rect, n.texture, renderer_);
n.sprite = std::make_shared<Sprite>(n.texture, n.rect);
// Deja la notificación invisible
n.texture->setAlpha(0);
// Añade la notificación a la lista
notifications_.push_back(n);
notifications_.emplace_back(n);
}
// Indica si hay notificaciones activas
bool Notifier::isActive() { return !notifications_.empty(); }
// Finaliza y elimnina todas las notificaciones activas
void Notifier::clearNotifications()
{
for (auto &notification : notifications_)
{
notification.state = NotificationStatus::FINISHED;
}
clearFinishedNotifications();
}
// Obtiene los códigos de las notificaciones
std::vector<std::string> Notifier::getCodes()
{
std::vector<std::string> codes;
for (const auto &notification : notifications_)
{
codes.emplace_back(notification.code);
}
return codes;
}

View File

@@ -2,13 +2,13 @@
#include <SDL2/SDL_rect.h> // Para SDL_Rect
#include <SDL2/SDL_render.h> // Para SDL_Renderer
#include <string> // Para basic_string, string
#include <memory> // Para shared_ptr
#include <string> // Para string, basic_string
#include <vector> // Para vector
#include "utils.h" // Para color_t
class Sprite;
class Text;
class Texture;
struct JA_Sound_t;
#include "utils.h" // Para Color
class Sprite; // lines 9-9
class Text; // lines 10-10
class Texture; // lines 11-11
class Notifier
{
@@ -16,64 +16,69 @@ private:
// [SINGLETON] Objeto notifier
static Notifier *notifier_;
enum notification_state_e
enum class NotificationStatus
{
ns_rising,
ns_stay,
ns_vanishing,
ns_finished
RISING,
STAY,
VANISHING,
FINISHED,
};
enum notification_position_e
enum class NotificationShape
{
upperLeft,
upperCenter,
upperRight,
middleLeft,
middleRight,
bottomLeft,
bottomCenter,
bottomRight
ROUNDED,
SQUARED,
};
struct notification_t
struct Notification
{
std::string text1;
std::string text2;
std::shared_ptr<Texture> texture;
std::shared_ptr<Sprite> sprite;
std::vector<std::string> texts;
int counter;
notification_state_e state;
notification_position_e position;
Texture *texture;
Sprite *sprite;
NotificationStatus state;
NotificationShape shape;
SDL_Rect rect;
int y;
int travelDist;
int travel_dist;
std::string code; // Permite asignar un código a la notificación
// Constructor
explicit Notification()
: texture(nullptr), sprite(nullptr), texts(), counter(0), state(NotificationStatus::RISING),
shape(NotificationShape::SQUARED), rect{0, 0, 0, 0}, y(0), travel_dist(0), code("") {}
};
// Objetos y punteros
SDL_Renderer *renderer_; // El renderizador de la ventana
Texture *text_texture_; // Textura para la fuente de las notificaciones
Texture *icon_texture_; // Textura para los iconos de las notificaciones
Text *text_; // Objeto para dibujar texto
std::shared_ptr<Texture> icon_texture_; // Textura para los iconos de las notificaciones
std::shared_ptr<Text> text_; // Objeto para dibujar texto
// Variables
Color bg_color_; // Color de fondo de las notificaciones
int wait_time_; // Tiempo que se ve la notificación
std::vector<notification_t> notifications_; // La lista de notificaciones activas
JA_Sound_t *sound_; // Sonido a reproducir cuando suena la notificación
Color bg_color_; // Color de fondo de las notificaciones
int wait_time_; // Tiempo que se ve la notificación
std::vector<Notification> notifications_; // La lista de notificaciones activas
bool stack_; // Indica si las notificaciones se apilan
bool has_icons_; // Indica si el notificador tiene textura para iconos
// Elimina las notificaciones finalizadas
void clearFinishedNotifications();
// Finaliza y elimnina todas las notificaciones activas
void clearNotifications();
// [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos notifier desde fuera
// Constructor
Notifier(std::string iconFile, std::string bitmapFile, std::string textFile, std::string soundFile);
Notifier(std::string icon_file, std::shared_ptr<Text> text);
// Destructor
~Notifier();
~Notifier() = default;
public:
// [SINGLETON] Crearemos el objeto con esta función estática
static void init(std::string iconFile, std::string bitmapFile, std::string textFile, std::string soundFile);
static void init(const std::string &icon_file, std::shared_ptr<Text> text);
// [SINGLETON] Destruiremos el objeto con esta función estática
static void destroy();
@@ -87,9 +92,12 @@ public:
// Actualiza el estado de las notificaiones
void update();
// Muestra una notificación de texto por pantalla;
void show(std::string text1 = "", std::string text2 = "", int icon = -1);
// Muestra una notificación de texto por pantalla
void show(std::vector<std::string> texts, int icon = -1, const std::string &code = std::string());
// Getters
bool active() const { return !notifications_.empty(); }
// Indica si hay notificaciones activas
bool isActive();
// Obtiene los códigos de las notificaciones
std::vector<std::string> getCodes();
};

View File

@@ -3,6 +3,8 @@
#include "screen.h"
#include <fstream> // Para basic_ofstream, basic_ifstream
#include <iostream> // Para basic_ostream, operator<<, cout
#include <unordered_map> // Para unordered_map
#include <functional> // Para std::function
// Variables
Options options;

View File

@@ -25,86 +25,84 @@ Player::Player(player_t player)
debug_(Debug::get())
{
// Crea objetos
sprite_ = new AnimatedSprite(renderer_, resource_->getAnimation(player.animation));
sprite_ = std::make_shared<AnimatedSprite>(resource_->getAnimation(player.animation));
// Inicializa variables
reLoadPalette();
onBorder = false;
border = BORDER_TOP;
autoMovement = false;
alive = true;
maxFallHeight = BLOCK * 4;
paused = false;
is_on_border_ = false;
border_ = BORDER_TOP;
auto_movement_ = false;
is_alive_ = true;
is_paused_ = false;
jumpIni = player.spawn.jumpIni;
state = player.spawn.state;
prevState = state;
jump_init_pos_ = player.spawn.jump_init_pos;
state_ = player.spawn.state;
previous_state_ = state_;
x = player.spawn.x;
y = player.spawn.y;
vx = player.spawn.vx;
vy = player.spawn.vy;
w = 8;
h = 16;
maxVY = 1.2f;
x_ = player.spawn.x;
y_ = player.spawn.y;
vx_ = player.spawn.vx;
vy_ = player.spawn.vy;
w_ = 8;
h_ = 16;
sprite_->setPosX(player.spawn.x);
sprite_->setPosY(player.spawn.y);
sprite_->setWidth(8);
sprite_->setHeight(16);
sprite_->setFlipH(player.spawn.flipH);
sprite_->setFlip(player.spawn.flip);
sprite_->setCurrentAnimation("walk");
sprite_->animate();
sprite_->update();
lastPosition = getRect();
colliderBox = getRect();
last_position_ = getRect();
collider_box_ = getRect();
const SDL_Point p = {0, 0};
colliderPoints.insert(colliderPoints.end(), {p, p, p, p, p, p, p, p});
underFeet.insert(underFeet.end(), {p, p});
feet.insert(feet.end(), {p, p});
jumpSound.push_back(JA_LoadSound(asset_->get("jump1.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump2.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump3.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump4.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump5.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump6.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump7.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump8.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump9.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump10.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump11.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump12.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump13.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump14.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump15.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump16.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump17.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump18.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump19.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump20.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump21.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump22.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump23.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset_->get("jump24.wav").c_str()));
collider_points_.insert(collider_points_.end(), {p, p, p, p, p, p, p, p});
under_feet_.insert(under_feet_.end(), {p, p});
feet_.insert(feet_.end(), {p, p});
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump1.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump2.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump3.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump4.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump5.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump6.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump7.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump8.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump9.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump10.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump11.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump12.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump13.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump14.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump15.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump16.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump17.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump18.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump19.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump20.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump21.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump22.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump23.wav").c_str()));
jumping_sound_.push_back(JA_LoadSound(asset_->get("jump24.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset_->get("jump11.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset_->get("jump12.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset_->get("jump13.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset_->get("jump14.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset_->get("jump15.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset_->get("jump16.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset_->get("jump17.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset_->get("jump18.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset_->get("jump19.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset_->get("jump20.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset_->get("jump21.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset_->get("jump22.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset_->get("jump23.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset_->get("jump24.wav").c_str()));
falling_sound_.push_back(JA_LoadSound(asset_->get("jump11.wav").c_str()));
falling_sound_.push_back(JA_LoadSound(asset_->get("jump12.wav").c_str()));
falling_sound_.push_back(JA_LoadSound(asset_->get("jump13.wav").c_str()));
falling_sound_.push_back(JA_LoadSound(asset_->get("jump14.wav").c_str()));
falling_sound_.push_back(JA_LoadSound(asset_->get("jump15.wav").c_str()));
falling_sound_.push_back(JA_LoadSound(asset_->get("jump16.wav").c_str()));
falling_sound_.push_back(JA_LoadSound(asset_->get("jump17.wav").c_str()));
falling_sound_.push_back(JA_LoadSound(asset_->get("jump18.wav").c_str()));
falling_sound_.push_back(JA_LoadSound(asset_->get("jump19.wav").c_str()));
falling_sound_.push_back(JA_LoadSound(asset_->get("jump20.wav").c_str()));
falling_sound_.push_back(JA_LoadSound(asset_->get("jump21.wav").c_str()));
falling_sound_.push_back(JA_LoadSound(asset_->get("jump22.wav").c_str()));
falling_sound_.push_back(JA_LoadSound(asset_->get("jump23.wav").c_str()));
falling_sound_.push_back(JA_LoadSound(asset_->get("jump24.wav").c_str()));
jumpCounter = 0;
fallCounter = 0;
jumping_counter_ = 0;
falling_counter_ = 0;
#ifdef DEBUG
rx = {0, 0, 0, 0};
@@ -114,21 +112,10 @@ Player::Player(player_t player)
#endif
}
// Destructor
Player::~Player()
{
delete sprite_;
for (auto s : jumpSound)
{
JA_DeleteSound(s);
}
}
// Pinta el jugador en pantalla
void Player::render()
{
sprite_->getTexture()->setColor(color.r, color.g, color.b);
sprite_->getTexture()->setColor(color_.r, color_.g, color_.b);
sprite_->render();
#ifdef DEBUG
@@ -167,7 +154,7 @@ void Player::render()
// Actualiza las variables del objeto
void Player::update()
{
if (paused)
if (is_paused_)
{ // Si está en modo pausa no se actualiza nada
return;
}
@@ -184,45 +171,45 @@ void Player::update()
void Player::checkInput()
{
// Solo comprueba las entradas de dirección cuando está sobre una superficie
if (state != s_standing)
if (state_ != s_standing)
{
return;
}
if (!autoMovement)
if (!auto_movement_)
{ // Comprueba las entradas de desplazamiento lateral solo en el caso de no estar enganchado a una superficie automatica
if (input_->checkInput(input_left))
{
vx = -0.6f;
sprite_->setFlipH(true);
vx_ = -0.6f;
sprite_->setFlip(SDL_FLIP_HORIZONTAL);
}
else if (input_->checkInput(input_right))
{
vx = 0.6f;
sprite_->setFlipH(false);
vx_ = 0.6f;
sprite_->setFlip(SDL_FLIP_NONE);
}
else
{ // No se pulsa ninguna dirección
vx = 0.0f;
vx_ = 0.0f;
if (isOnAutoSurface())
{ // Si deja de moverse sobre una superficie se engancha
autoMovement = true;
auto_movement_ = true;
}
}
}
else
{ // El movimiento lo proporciona la superficie
vx = 0.6f * room_->getAutoSurfaceDirection();
vx_ = 0.6f * room_->getAutoSurfaceDirection();
if (vx > 0.0f)
if (vx_ > 0.0f)
{
sprite_->setFlipH(false);
sprite_->setFlip(SDL_FLIP_NONE);
}
else
{
sprite_->setFlipH(true);
sprite_->setFlip(SDL_FLIP_HORIZONTAL);
}
}
@@ -236,9 +223,9 @@ void Player::checkInput()
if (isOnFloor() || isOnAutoSurface())
{
setState(s_jumping);
vy = -maxVY;
jumpIni = y;
jumpCounter = 0;
vy_ = -MAX_VY_;
jump_init_pos_ = y_;
jumping_counter_ = 0;
}
}
}
@@ -246,45 +233,45 @@ void Player::checkInput()
// Indica si el jugador esta en uno de los cuatro bordes de la pantalla
bool Player::getOnBorder()
{
return onBorder;
return is_on_border_;
}
// Indica en cual de los cuatro bordes se encuentra
int Player::getBorder()
{
return border;
return border_;
}
// Comprueba si está situado en alguno de los cuatro bordes de la habitación
void Player::checkBorders()
{
if (x < PLAY_AREA_LEFT)
if (x_ < PLAY_AREA_LEFT)
{
border = BORDER_LEFT;
onBorder = true;
border_ = BORDER_LEFT;
is_on_border_ = true;
}
else if (x > PLAY_AREA_RIGHT - w)
else if (x_ + w_ > PLAY_AREA_RIGHT)
{
border = BORDER_RIGHT;
onBorder = true;
border_ = BORDER_RIGHT;
is_on_border_ = true;
}
else if (y < PLAY_AREA_TOP)
else if (y_ < PLAY_AREA_TOP)
{
border = BORDER_TOP;
onBorder = true;
border_ = BORDER_TOP;
is_on_border_ = true;
}
else if (y > PLAY_AREA_BOTTOM - h)
else if (y_ + h_ > PLAY_AREA_BOTTOM)
{
border = BORDER_BOTTOM;
onBorder = true;
border_ = BORDER_BOTTOM;
is_on_border_ = true;
}
else
{
onBorder = false;
is_on_border_ = false;
}
}
@@ -292,37 +279,37 @@ void Player::checkBorders()
void Player::checkState()
{
// Actualiza las variables en función del estado
if (state == s_falling)
if (state_ == s_falling)
{
vx = 0.0f;
vy = maxVY;
fallCounter++;
vx_ = 0.0f;
vy_ = MAX_VY_;
falling_counter_++;
playFallSound();
}
else if (state == s_standing)
else if (state_ == s_standing)
{
if (prevState == s_falling && fallCounter > maxFallHeight)
if (previous_state_ == s_falling && falling_counter_ > MAX_FALLING_HEIGHT_)
{ // Si cae de muy alto, el jugador muere
alive = false;
is_alive_ = false;
}
vy = 0.0f;
jumpCounter = 0;
fallCounter = 0;
vy_ = 0.0f;
jumping_counter_ = 0;
falling_counter_ = 0;
if (!isOnFloor() && !isOnAutoSurface() && !isOnDownSlope())
{
setState(s_falling);
vx = 0.0f;
vy = maxVY;
fallCounter++;
vx_ = 0.0f;
vy_ = MAX_VY_;
falling_counter_++;
playFallSound();
}
}
else if (state == s_jumping)
else if (state_ == s_jumping)
{
fallCounter = 0;
jumpCounter++;
falling_counter_ = 0;
jumping_counter_++;
playJumpSound();
}
}
@@ -330,41 +317,41 @@ void Player::checkState()
// Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla
void Player::switchBorders()
{
if (border == BORDER_TOP)
if (border_ == BORDER_TOP)
{
y = PLAY_AREA_BOTTOM - h - 0 - BLOCK;
y_ = PLAY_AREA_BOTTOM - h_ - 0 - BLOCK;
setState(s_standing);
}
else if (border == BORDER_BOTTOM)
else if (border_ == BORDER_BOTTOM)
{
y = PLAY_AREA_TOP + 0;
y_ = PLAY_AREA_TOP + 0;
setState(s_standing);
}
else if (border == BORDER_RIGHT)
else if (border_ == BORDER_RIGHT)
{
x = PLAY_AREA_LEFT + 0;
x_ = PLAY_AREA_LEFT + 0;
}
if (border == BORDER_LEFT)
if (border_ == BORDER_LEFT)
{
x = PLAY_AREA_RIGHT - w - 0;
x_ = PLAY_AREA_RIGHT - w_ - 0;
}
onBorder = false;
is_on_border_ = false;
}
// Aplica gravedad al jugador
void Player::applyGravity()
{
const float gf = 0.035f;
constexpr float GF = 0.035f;
// La gravedad solo se aplica cuando el jugador esta saltando
// Nunca mientras cae o esta de pie
if (state == s_jumping)
if (state_ == s_jumping)
{
vy += gf;
if (vy > maxVY)
vy_ += GF;
if (vy_ > MAX_VY_)
{
vy = maxVY;
vy_ = MAX_VY_;
}
}
}
@@ -372,36 +359,36 @@ void Player::applyGravity()
// Obtiene el rectangulo que delimita al jugador
SDL_Rect Player::getRect()
{
return {(int)x, (int)y, w, h};
return {static_cast<int>(x_), static_cast<int>(y_), w_, h_};
}
// Obtiene el rectangulo de colision del jugador
SDL_Rect &Player::getCollider()
{
colliderBox = getRect();
return colliderBox;
collider_box_ = getRect();
return collider_box_;
}
// Recalcula la posición del jugador y su animación
void Player::move()
{
lastPosition = {(int)x, (int)y}; // Guarda la posicion actual antes de modificarla
applyGravity(); // Aplica gravedad al jugador
checkState(); // Comprueba el estado del jugador
last_position_ = {static_cast<int>(x_), static_cast<int>(y_)}; // Guarda la posicion actual antes de modificarla
applyGravity(); // Aplica gravedad al jugador
checkState(); // Comprueba el estado del jugador
#ifdef DEBUG
debugColor = {0, 255, 0};
#endif
// Se mueve hacia la izquierda
if (vx < 0.0f)
if (vx_ < 0.0f)
{
// Crea el rectangulo de proyección en el eje X para ver si colisiona
SDL_Rect proj;
proj.x = (int)(x + vx);
proj.y = (int)y;
proj.h = h;
proj.w = ceil(abs(vx)); // Para evitar que tenga un ancho de 0 pixels
proj.x = static_cast<int>(x_ + vx_);
proj.y = static_cast<int>(y_);
proj.h = h_;
proj.w = ceil(abs(vx_)); // Para evitar que tenga un ancho de 0 pixels
#ifdef DEBUG
rx = proj;
@@ -412,41 +399,43 @@ void Player::move()
// Calcula la nueva posición
if (pos == -1)
{ // Si no hay colisión
x += vx;
{
// Si no hay colisión
x_ += vx_;
}
else
{ // Si hay colisión lo mueve hasta donde no colisiona
x = pos + 1;
{
// Si hay colisión lo mueve hasta donde no colisiona
x_ = pos + 1;
}
// Si ha tocado alguna rampa mientras camina (sin saltar), asciende
if (state != s_jumping)
if (state_ != s_jumping)
{
v_line_t leftSide = {(int)x, (int)y + h - 2, (int)y + h - 1}; // Comprueba solo los dos pixels de abajo
v_line_t leftSide = {static_cast<int>(x_), static_cast<int>(y_) + h_ - 2, static_cast<int>(y_) + h_ - 1}; // Comprueba solo los dos pixels de abajo
const int ly = room_->checkLeftSlopes(&leftSide);
if (ly > -1)
{
y = ly - h;
y_ = ly - h_;
}
}
// Si está bajando la rampa, recoloca al jugador
if (isOnDownSlope() && state != s_jumping)
if (isOnDownSlope() && state_ != s_jumping)
{
y += 1;
y_ += 1;
}
}
// Se mueve hacia la derecha
else if (vx > 0.0f)
else if (vx_ > 0.0f)
{
// Crea el rectangulo de proyección en el eje X para ver si colisiona
SDL_Rect proj;
proj.x = (int)x + w;
proj.y = (int)y;
proj.h = h;
proj.w = ceil(vx); // Para evitar que tenga un ancho de 0 pixels
proj.x = static_cast<int>(x_) + w_;
proj.y = static_cast<int>(y_);
proj.h = h_;
proj.w = ceil(vx_); // Para evitar que tenga un ancho de 0 pixels
#ifdef DEBUG
rx = proj;
@@ -457,57 +446,59 @@ void Player::move()
// Calcula la nueva posición
if (pos == -1)
{ // Si no hay colisión
x += vx;
{
// Si no hay colisión
x_ += vx_;
}
else
{ // Si hay colisión lo mueve hasta donde no colisiona
x = pos - w;
{
// Si hay colisión lo mueve hasta donde no colisiona
x_ = pos - w_;
}
// Si ha tocado alguna rampa mientras camina (sin saltar), asciende
if (state != s_jumping)
if (state_ != s_jumping)
{
v_line_t rightSide = {(int)x + w - 1, (int)y + h - 2, (int)y + h - 1}; // Comprueba solo los dos pixels de abajo
v_line_t rightSide = {static_cast<int>(x_) + w_ - 1, static_cast<int>(y_) + h_ - 2, static_cast<int>(y_) + h_ - 1}; // Comprueba solo los dos pixels de abajo
const int ry = room_->checkRightSlopes(&rightSide);
if (ry > -1)
{
y = ry - h;
y_ = ry - h_;
}
}
// Si está bajando la rampa, recoloca al jugador
if (isOnDownSlope() && state != s_jumping)
if (isOnDownSlope() && state_ != s_jumping)
{
y += 1;
y_ += 1;
}
}
// Si ha salido del suelo, el jugador cae
if (state == s_standing && !isOnFloor())
if (state_ == s_standing && !isOnFloor())
{
setState(s_falling);
// Deja de estar enganchado a la superficie automatica
autoMovement = false;
auto_movement_ = false;
}
// Si ha salido de una superficie automatica, detiene el movimiento automatico
if (state == s_standing && isOnFloor() && !isOnAutoSurface())
if (state_ == s_standing && isOnFloor() && !isOnAutoSurface())
{
// Deja de estar enganchado a la superficie automatica
autoMovement = false;
auto_movement_ = false;
}
// Se mueve hacia arriba
if (vy < 0.0f)
if (vy_ < 0.0f)
{
// Crea el rectangulo de proyección en el eje Y para ver si colisiona
SDL_Rect proj;
proj.x = (int)x;
proj.y = (int)(y + vy);
proj.h = ceil(abs(vy)); // Para evitar que tenga una altura de 0 pixels
proj.w = w;
proj.x = static_cast<int>(x_);
proj.y = static_cast<int>(y_ + vy_);
proj.h = ceil(abs(vy_)); // Para evitar que tenga una altura de 0 pixels
proj.w = w_;
#ifdef DEBUG
ry = proj;
@@ -518,25 +509,27 @@ void Player::move()
// Calcula la nueva posición
if (pos == -1)
{ // Si no hay colisión
y += vy;
{
// Si no hay colisión
y_ += vy_;
}
else
{ // Si hay colisión lo mueve hasta donde no colisiona y entra en caída
y = pos + 1;
{
// Si hay colisión lo mueve hasta donde no colisiona y entra en caída
y_ = pos + 1;
setState(s_falling);
}
}
// Se mueve hacia abajo
else if (vy > 0.0f)
else if (vy_ > 0.0f)
{
// Crea el rectangulo de proyección en el eje Y para ver si colisiona
SDL_Rect proj;
proj.x = (int)x;
proj.y = (int)y + h;
proj.h = ceil(vy); // Para evitar que tenga una altura de 0 pixels
proj.w = w;
proj.x = static_cast<int>(x_);
proj.y = static_cast<int>(y_) + h_;
proj.h = ceil(vy_); // Para evitar que tenga una altura de 0 pixels
proj.w = w_;
#ifdef DEBUG
ry = proj;
@@ -545,24 +538,27 @@ void Player::move()
// Comprueba la colisión con las superficies normales y las automáticas
const int pos = std::max(room_->checkTopSurfaces(&proj), room_->checkAutoSurfaces(&proj));
if (pos > -1)
{ // Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre la superficie
y = pos - h;
{
// Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre la superficie
y_ = pos - h_;
setState(s_standing);
// Deja de estar enganchado a la superficie automatica
autoMovement = false;
auto_movement_ = false;
}
else
{ // Si no hay colisión con los muros, comprueba la colisión con las rampas
if (state != s_jumping)
{
// Si no hay colisión con los muros, comprueba la colisión con las rampas
if (state_ != s_jumping)
{ // Las rampas no se miran si se está saltando
v_line_t leftSide = {proj.x, proj.y, proj.y + proj.h - 1};
v_line_t rightSide = {proj.x + proj.w - 1, proj.y, proj.y + proj.h - 1};
const int p = std::max(room_->checkRightSlopes(&rightSide), room_->checkLeftSlopes(&leftSide));
if (p > -1)
{ // No está saltando y hay colisión con una rampa
{
// No está saltando y hay colisión con una rampa
// Calcula la nueva posición
y = p - h;
y_ = p - h_;
setState(s_standing);
#ifdef DEBUG
debugColor = {255, 255, 0};
@@ -570,25 +566,27 @@ void Player::move()
#endif
}
else
{ // No está saltando y no hay colisón con una rampa
{
// No está saltando y no hay colisón con una rampa
// Calcula la nueva posición
y += vy;
y_ += vy_;
#ifdef DEBUG
debugColor = {255, 0, 0};
#endif
}
}
else
{ // Esta saltando y no hay colisión con los muros
{
// Esta saltando y no hay colisión con los muros
// Calcula la nueva posición
y += vy;
y_ += vy_;
}
}
}
// Actualiza la posición del sprite
sprite_->setPosX(x);
sprite_->setPosY(y);
sprite_->setPosX(x_);
sprite_->setPosY(y_);
#ifdef DEBUG
debug_->add("RECT_X: " + std::to_string(rx.x) + "," + std::to_string(rx.y) + "," + std::to_string(rx.w) + "," + std::to_string(rx.h));
@@ -599,24 +597,25 @@ void Player::move()
// Establece la animación del jugador
void Player::animate()
{
if (vx != 0)
if (vx_ != 0)
{
sprite_->animate();
sprite_->update();
}
}
// Comprueba si ha finalizado el salto al alcanzar la altura de inicio
void Player::checkJumpEnd()
{
if (state == s_jumping)
if (state_ == s_jumping)
{
if (vy > 0)
if (vy_ > 0)
{
if (y >= jumpIni)
{ // Si alcanza la altura de salto inicial, pasa al estado de caída
if (y_ >= jump_init_pos_)
{
// Si alcanza la altura de salto inicial, pasa al estado de caída
setState(s_falling);
vy = maxVY;
jumpCounter = 0;
vy_ = MAX_VY_;
jumping_counter_ = 0;
}
}
}
@@ -625,9 +624,9 @@ void Player::checkJumpEnd()
// Calcula y reproduce el sonido de salto
void Player::playJumpSound()
{
if (jumpCounter % 4 == 0)
if (jumping_counter_ % 4 == 0)
{
JA_PlaySound(jumpSound[jumpCounter / 4]);
JA_PlaySound(jumping_sound_[jumping_counter_ / 4]);
}
#ifdef DEBUG
@@ -638,9 +637,9 @@ void Player::playJumpSound()
// Calcula y reproduce el sonido de caer
void Player::playFallSound()
{
if (fallCounter % 4 == 0)
if (falling_counter_ % 4 == 0)
{
JA_PlaySound(fallSound[std::min((fallCounter / 4), (int)fallSound.size() - 1)]);
JA_PlaySound(falling_sound_[std::min((falling_counter_ / 4), (int)falling_sound_.size() - 1)]);
}
#ifdef DEBUG
@@ -658,15 +657,15 @@ bool Player::isOnFloor()
updateFeet();
// Comprueba las superficies
for (auto f : underFeet)
for (auto f : under_feet_)
{
onFloor |= room_->checkTopSurfaces(&f);
onFloor |= room_->checkAutoSurfaces(&f);
}
// Comprueba las rampas
onSlopeL = room_->checkLeftSlopes(&underFeet[0]);
onSlopeR = room_->checkRightSlopes(&underFeet[1]);
onSlopeL = room_->checkLeftSlopes(&under_feet_[0]);
onSlopeR = room_->checkRightSlopes(&under_feet_[1]);
#ifdef DEBUG
if (onFloor)
@@ -696,7 +695,7 @@ bool Player::isOnAutoSurface()
updateFeet();
// Comprueba las superficies
for (auto f : underFeet)
for (auto f : under_feet_)
{
onAutoSurface |= room_->checkAutoSurfaces(&f);
}
@@ -720,12 +719,12 @@ bool Player::isOnDownSlope()
// Cuando el jugador baja una escalera, se queda volando
// Hay que mirar otro pixel más por debajo
underFeet[0].y += 1;
underFeet[1].y += 1;
under_feet_[0].y += 1;
under_feet_[1].y += 1;
// Comprueba las rampas
onSlope |= room_->checkLeftSlopes(&underFeet[0]);
onSlope |= room_->checkRightSlopes(&underFeet[1]);
onSlope |= room_->checkLeftSlopes(&under_feet_[0]);
onSlope |= room_->checkRightSlopes(&under_feet_[1]);
#ifdef DEBUG
if (onSlope)
@@ -746,7 +745,7 @@ bool Player::checkKillingTiles()
// Comprueba si hay contacto
bool check = false;
for (auto c : colliderPoints)
for (auto c : collider_points_)
{
check |= (room_->getTile(c) == t_kill);
}
@@ -754,7 +753,7 @@ bool Player::checkKillingTiles()
// Mata al jugador si hay colisión
if (check)
{
alive = false;
is_alive_ = false;
}
return check;
@@ -765,13 +764,13 @@ playerSpawn_t Player::getSpawnParams()
{
playerSpawn_t params;
params.x = x;
params.y = y;
params.vx = vx;
params.vy = vy;
params.jumpIni = jumpIni;
params.state = state;
params.flipH = sprite_->getFlipH();
params.x = x_;
params.y = y_;
params.vx = vx_;
params.vy = vy_;
params.jump_init_pos = jump_init_pos_;
params.state = state_;
params.flip = sprite_->getFlip();
return params;
}
@@ -785,60 +784,54 @@ void Player::reLoadTexture()
// Recarga la paleta
void Player::reLoadPalette()
{
color = stringToColor(options.video.palette, "white");
color_ = stringToColor(options.video.palette, "white");
if (options.cheats.infinite_lives == Cheat::CheatState::ENABLED)
{
color = stringToColor(options.video.palette, "green");
}
{
color = stringToColor(options.video.palette, "yellow");
color_ = stringToColor(options.video.palette, "yellow");
}
if (options.cheats.invincible == Cheat::CheatState::ENABLED)
{
color = stringToColor(options.video.palette, "green");
}
{
color = stringToColor(options.video.palette, "cyan");
color_ = stringToColor(options.video.palette, "cyan");
}
}
// Establece el valor de la variable
void Player::setRoom(Room *room)
void Player::setRoom(std::shared_ptr<Room> room)
{
this->room_ = room;
room_ = room;
}
// Actualiza los puntos de colisión
void Player::updateColliderPoints()
{
const SDL_Rect rect = getRect();
colliderPoints[0] = {rect.x, rect.y};
colliderPoints[1] = {rect.x + 7, rect.y};
colliderPoints[2] = {rect.x + 7, rect.y + 7};
colliderPoints[3] = {rect.x, rect.y + 7};
colliderPoints[4] = {rect.x, rect.y + 8};
colliderPoints[5] = {rect.x + 7, rect.y + 8};
colliderPoints[6] = {rect.x + 7, rect.y + 15};
colliderPoints[7] = {rect.x, rect.y + 15};
collider_points_[0] = {rect.x, rect.y};
collider_points_[1] = {rect.x + 7, rect.y};
collider_points_[2] = {rect.x + 7, rect.y + 7};
collider_points_[3] = {rect.x, rect.y + 7};
collider_points_[4] = {rect.x, rect.y + 8};
collider_points_[5] = {rect.x + 7, rect.y + 8};
collider_points_[6] = {rect.x + 7, rect.y + 15};
collider_points_[7] = {rect.x, rect.y + 15};
}
// Actualiza los puntos de los pies
void Player::updateFeet()
{
const SDL_Point p = {(int)x, (int)y};
const SDL_Point p = {static_cast<int>(x_), static_cast<int>(y_)};
underFeet[0] = {p.x, p.y + h};
underFeet[1] = {p.x + 7, p.y + h};
under_feet_[0] = {p.x, p.y + h_};
under_feet_[1] = {p.x + 7, p.y + h_};
feet[0] = {p.x, p.y + h - 1};
feet[1] = {p.x + 7, p.y + h - 1};
feet_[0] = {p.x, p.y + h_ - 1};
feet_[1] = {p.x + 7, p.y + h_ - 1};
}
// Cambia el estado del jugador
void Player::setState(state_e value)
{
prevState = state;
state = value;
previous_state_ = state_;
state_ = value;
checkState();
}
@@ -846,17 +839,17 @@ void Player::setState(state_e value)
// Comprueba si el jugador esta vivo
bool Player::isAlive()
{
return alive;
return is_alive_;
}
// Pone el jugador en modo pausa
void Player::pause()
{
paused = true;
is_paused_ = true;
}
// Quita el modo pausa del jugador
void Player::resume()
{
paused = false;
is_paused_ = false;
}

View File

@@ -4,6 +4,7 @@
#include <SDL2/SDL_render.h> // Para SDL_Renderer
#include <string> // Para basic_string, string
#include <vector> // Para vector
#include <memory> // Para shared_ptr
#include "utils.h" // Para color_t
class AnimatedSprite;
class Asset;
@@ -26,9 +27,9 @@ struct playerSpawn_t
float y;
float vx;
float vy;
int jumpIni;
int jump_init_pos;
state_e state;
bool flipH;
SDL_RendererFlip flip;
};
struct player_t
@@ -36,48 +37,50 @@ struct player_t
playerSpawn_t spawn;
std::string png;
std::string animation;
Room *room;
std::shared_ptr<Room> room;
};
class Player
{
public:
// Constantes
static const int MAX_FALLING_HEIGHT_ = BLOCK * 4; // Altura maxima permitida de caída.
static const float MAX_VY_ = 1.2f; // Velocidad máxima que puede alcanzar al desplazarse en vertical
// Objetos y punteros
SDL_Renderer *renderer_; // El renderizador de la ventana
Input *input_; // Objeto para gestionar la entrada
Resource *resource_; // Objeto con los recursos
Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos
Room *room_; // Objeto encargado de gestionar cada habitación del juego
AnimatedSprite *sprite_; // Sprite del jugador
Debug *debug_; // Objeto para gestionar la información de debug
SDL_Renderer *renderer_; // El renderizador de la ventana
Input *input_; // Objeto para gestionar la entrada
Resource *resource_; // Objeto con los recursos
Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos
Debug *debug_; // Objeto para gestionar la información de debug
std::shared_ptr<Room> room_; // Objeto encargado de gestionar cada habitación del juego
std::shared_ptr<AnimatedSprite> sprite_; // Sprite del jugador
// Variables
float x; // Posición del jugador en el eje X
float y; // Posición del jugador en el eje Y
float vx; // Velocidad/desplazamiento del jugador en el eje X
float vy; // Velocidad/desplazamiento del jugador en el eje Y
int w; // Ancho del jugador
int h; // ALto del jugador
Color color; // Color del jugador
SDL_Rect colliderBox; // Caja de colisión con los enemigos u objetos
std::vector<SDL_Point> colliderPoints; // Puntos de colisión con el mapa
std::vector<SDL_Point> underFeet; // Contiene los puntos que hay bajo cada pie del jugador
std::vector<SDL_Point> feet; // Contiene los puntos que hay en el pie del jugador
state_e state; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo
state_e prevState; // Estado previo en el que se encontraba el jugador
bool onBorder; // Indica si el jugador esta en uno de los cuatro bordes de la pantalla
int border; // Indica en cual de los cuatro bordes se encuentra
bool autoMovement; // Indica si esta siendo arrastrado por una superficie automatica
bool paused; // Indica si el jugador esta en modo pausa
SDL_Rect lastPosition; // Contiene la ultima posición del jugador, por si hay que deshacer algun movimiento
int jumpIni; // Valor del eje Y en el que se inicia el salto
float maxVY; // Velocidad máxima que puede alcanzar al desplazarse en vertical
std::vector<JA_Sound_t *> jumpSound; // Vecor con todos los sonidos del salto
std::vector<JA_Sound_t *> fallSound; // Vecor con todos los sonidos de la caída
int jumpCounter; // Cuenta el tiempo de salto
int fallCounter; // Cuenta el tiempo de caida
bool alive; // Indica si el jugador esta vivo o no
int maxFallHeight; // Altura maxima permitida de caída.
float x_; // Posición del jugador en el eje X
float y_; // Posición del jugador en el eje Y
float vx_; // Velocidad/desplazamiento del jugador en el eje X
float vy_; // Velocidad/desplazamiento del jugador en el eje Y
int w_; // Ancho del jugador
int h_; // ALto del jugador
Color color_; // Color del jugador
SDL_Rect collider_box_; // Caja de colisión con los enemigos u objetos
std::vector<SDL_Point> collider_points_; // Puntos de colisión con el mapa
std::vector<SDL_Point> under_feet_; // Contiene los puntos que hay bajo cada pie del jugador
std::vector<SDL_Point> feet_; // Contiene los puntos que hay en el pie del jugador
state_e state_; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo
state_e previous_state_; // Estado previo en el que se encontraba el jugador
bool is_on_border_; // Indica si el jugador esta en uno de los cuatro bordes de la pantalla
int border_; // Indica en cual de los cuatro bordes se encuentra
bool auto_movement_; // Indica si esta siendo arrastrado por una superficie automatica
bool is_paused_; // Indica si el jugador esta en modo pausa
SDL_Rect last_position_; // Contiene la ultima posición del jugador, por si hay que deshacer algun movimiento
int jump_init_pos_; // Valor del eje Y en el que se inicia el salto
std::vector<JA_Sound_t *> jumping_sound_; // Vecor con todos los sonidos del salto
std::vector<JA_Sound_t *> falling_sound_; // Vecor con todos los sonidos de la caída
int jumping_counter_; // Cuenta el tiempo de salto
int falling_counter_; // Cuenta el tiempo de caida
bool is_alive_; // Indica si el jugador esta vivo o no
#ifdef DEBUG
SDL_Rect rx; // Rectangulo de desplazamiento para el modo debug
@@ -142,7 +145,7 @@ public:
Player(player_t player);
// Destructor
~Player();
~Player() = default;
// Pinta el enemigo en pantalla
void render();
@@ -175,7 +178,7 @@ public:
void reLoadPalette();
// Establece el valor de la variable
void setRoom(Room *room);
void setRoom(std::shared_ptr<Room> room);
// Comprueba si el jugador esta vivo
bool isAlive();

View File

@@ -5,7 +5,6 @@
#include <utility> // Para pair
#include "asset.h" // Para Asset, AssetType
#include "jail_audio.h" // Para JA_LoadMusic, JA_LoadSound
#include "lang.h" // Para getText
#include "screen.h" // Para Screen
#include "text.h" // Para Text, loadTextFile
struct JA_Music_t; // lines 10-10
@@ -47,7 +46,6 @@ void Resource::clear()
text_files_.clear();
texts_.clear();
animations_.clear();
demos_.clear();
}
// Carga todos los recursos
@@ -59,10 +57,7 @@ void Resource::load()
loadTextures();
loadTextFiles();
loadAnimations();
loadDemoData();
addPalettes();
createText();
createTextures();
std::cout << "\n** RESOURCES LOADED" << std::endl;
}
@@ -193,6 +188,12 @@ std::shared_ptr<room_t> Resource::getRoom(const std::string &name)
throw std::runtime_error("Habitación no encontrada: " + name);
}
// Obtiene todas las habitaciones
std::vector<ResourceRoom> &Resource::getRooms()
{
return rooms_;
}
// Carga los sonidos
void Resource::loadSounds()
{
@@ -275,7 +276,7 @@ void Resource::loadTileMaps()
for (const auto &l : list)
{
auto name = getFileName(l);
tile_maps_.emplace_back(ResourceTileMap(name, std::make_shared<std::vector<int>>(loadRoomTileFile(l))));
tile_maps_.emplace_back(ResourceTileMap(name, loadRoomTileFile(l)));
}
}

View File

@@ -192,6 +192,9 @@ public:
// Obtiene la habitación a partir de un nombre
std::shared_ptr<room_t> getRoom(const std::string &name);
// Obtiene todas las habitaciones
std::vector<ResourceRoom> &getRooms();
// Recarga todos los recursos
void reload();
};

View File

@@ -275,7 +275,7 @@ bool setEnemy(enemy_t *enemy, std::string var, std::string value)
if (var == "animation")
{
enemy->animationString = value;
enemy->animation_path = value;
}
else if (var == "width")
@@ -404,7 +404,7 @@ bool setItem(item_t *item, std::string var, std::string value)
}
// Constructor
Room::Room(room_t *room, ItemTracker *itemTracker, int *itemsPicked, bool jailEnabled)
Room::Room(std::shared_ptr<room_t> room, std::shared_ptr<ItemTracker> itemTracker, int *itemsPicked, bool jailEnabled)
: screen(Screen::get()),
renderer(Screen::get()->getRenderer()),
asset(Asset::get()),
@@ -427,7 +427,7 @@ Room::Room(room_t *room, ItemTracker *itemTracker, int *itemsPicked, bool jailEn
autoSurfaceDirection = room->autoSurfaceDirection;
textureA = room->textureA;
textureB = room->textureB;
tileMap = *room->tileMap;
tileMap = room->tileMap;
texture = (options.video.palette == Palette::ZXSPECTRUM) ? textureA : textureB;
this->jailEnabled = jailEnabled;
@@ -566,7 +566,7 @@ void Room::fillMapTexture()
{
clip.x = (tileMap[index] % tileSetWidth) * tileSize;
clip.y = (tileMap[index] / tileSetWidth) * tileSize;
texture->render(renderer, x * tileSize, y * tileSize, &clip);
texture->render(x * tileSize, y * tileSize, &clip);
#ifdef DEBUG
// ****

View File

@@ -7,6 +7,7 @@
#include "enemy.h" // Para enemy_t
#include "item.h" // Para item_t
#include "utils.h" // Para h_line_t, color_t, d_line_t, v_line_t
#include <memory> // Para shared_ptr
class Asset;
class Debug;
class ItemTracker;
@@ -28,30 +29,30 @@ enum tile_e
struct aTile_t
{
Sprite *sprite; // Sprite para dibujar el tile
int xcOrig; // Poicion X donde se encuentra el primer tile de la animacion en la tilesheet
std::shared_ptr<Sprite> sprite; // Sprite para dibujar el tile
int xcOrig; // Poicion X donde se encuentra el primer tile de la animacion en la tilesheet
};
struct room_t
{
std::string number; // Numero de la habitación
std::string name; // Nombre de la habitación
std::string bgColor; // Color de fondo de la habitación
std::string borderColor; // Color del borde de la pantalla
std::string itemColor1; // Color 1 para los items de la habitación
std::string itemColor2; // Color 2 para los items de la habitación
std::string roomUp; // Identificador de la habitación que se encuentra arriba
std::string roomDown; // Identificador de la habitación que se encuentra abajp
std::string roomLeft; // Identificador de la habitación que se encuentra a la izquierda
std::string roomRight; // Identificador de la habitación que se encuentra a la derecha
std::string tileSetFile; // Imagen con los graficos para la habitación
std::string tileMapFile; // Fichero con el mapa de indices de tile
std::vector<int> *tileMap; // Indice de los tiles a dibujar en la habitación
int autoSurfaceDirection; // Sentido en el que arrastran las superficies automáticas de la habitación
std::vector<enemy_t> enemies; // Listado con los enemigos de la habitación
std::vector<item_t> items; // Listado con los items que hay en la habitación
Texture *textureA; // Textura con los graficos de la habitación
Texture *textureB; // Textura con los graficos de la habitación
std::string number; // Numero de la habitación
std::string name; // Nombre de la habitación
std::string bgColor; // Color de fondo de la habitación
std::string borderColor; // Color del borde de la pantalla
std::string itemColor1; // Color 1 para los items de la habitación
std::string itemColor2; // Color 2 para los items de la habitación
std::string roomUp; // Identificador de la habitación que se encuentra arriba
std::string roomDown; // Identificador de la habitación que se encuentra abajp
std::string roomLeft; // Identificador de la habitación que se encuentra a la izquierda
std::string roomRight; // Identificador de la habitación que se encuentra a la derecha
std::string tileSetFile; // Imagen con los graficos para la habitación
std::string tileMapFile; // Fichero con el mapa de indices de tile
std::vector<int> tileMap; // Indice de los tiles a dibujar en la habitación
int autoSurfaceDirection; // Sentido en el que arrastran las superficies automáticas de la habitación
std::vector<enemy_t> enemies; // Listado con los enemigos de la habitación
std::vector<item_t> items; // Listado con los items que hay en la habitación
std::shared_ptr<Texture> textureA; // Textura con los graficos de la habitación
std::shared_ptr<Texture> textureB; // Textura con los graficos de la habitación
};
// Carga las variables desde un fichero de mapa
@@ -73,18 +74,18 @@ class Room
{
private:
// Objetos y punteros
Screen *screen; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Debug *debug; // Objeto para gestionar la información de debug
std::vector<Enemy *> enemies; // Listado con los enemigos de la habitación
std::vector<Item *> items; // Listado con los items que hay en la habitación
Texture *texture; // Textura con los graficos de la habitación
Texture *textureA; // Textura con los graficos de la habitación
Texture *textureB; // Textura con los graficos de la habitación
ItemTracker *itemTracker; // Lleva el control de los objetos recogidos
SDL_Texture *mapTexture; // Textura para dibujar el mapa de la habitación
int *itemsPicked; // Puntero a la cantidad de items recogidos que lleva el juego
Screen *screen; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Debug *debug; // Objeto para gestionar la información de debug
std::vector<Enemy *> enemies; // Listado con los enemigos de la habitación
std::vector<Item *> items; // Listado con los items que hay en la habitación
std::shared_ptr<Texture> texture; // Textura con los graficos de la habitación
std::shared_ptr<Texture> textureA; // Textura con los graficos de la habitación
std::shared_ptr<Texture> textureB; // Textura con los graficos de la habitación
std::shared_ptr<ItemTracker> itemTracker; // Lleva el control de los objetos recogidos
SDL_Texture *mapTexture; // Textura para dibujar el mapa de la habitación
int *itemsPicked; // Puntero a la cantidad de items recogidos que lleva el juego
// Variables
std::string number; // Numero de la habitación
@@ -159,7 +160,7 @@ private:
public:
// Constructor
Room(room_t *room, ItemTracker *itemTracker, int *itemsPicked, bool jailEnabled);
Room(std::shared_ptr<room_t> room, std::shared_ptr<ItemTracker> itemTracker, int *itemsPicked, bool jailEnabled);
// Destructor
~Room();

View File

@@ -9,6 +9,7 @@
#include "options.h"
#include "screen.h"
#include "asset.h"
#include "resource.h"
class Asset;
// Constructor
@@ -21,9 +22,9 @@ Scoreboard::Scoreboard(board_t *board)
// Reserva memoria para los objetos
itemTexture = resource->getTexture("items.png");
const std::string playerANI = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani";
sprite = new AnimatedSprite(renderer, resource->getAnimation(playerANI));
sprite = std::make_shared<AnimatedSprite>(falta_la_textura, resource->getAnimation(playerANI));
sprite->setCurrentAnimation("walk_menu");
text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer);
text = Resource::get()->getText("smb2.txt");
// Inicializa las variables
counter = 0;
@@ -41,13 +42,6 @@ Scoreboard::Scoreboard(board_t *board)
}
}
// Destructor
Scoreboard::~Scoreboard()
{
delete sprite;
delete text;
}
// Pinta el objeto en pantalla
void Scoreboard::render()
{
@@ -63,7 +57,7 @@ void Scoreboard::render()
// Dibuja las vidas
const int desp = (counter / 40) % 8;
const int frame = desp % 4;
sprite->setCurrentFrame(frame);
sprite->setCurrentAnimationFrame(frame);
sprite->setPosY(line2);
for (int i = 0; i < board->lives; ++i)
{
@@ -79,7 +73,7 @@ void Scoreboard::render()
const Color c = board->color;
SDL_Rect clip = {0, 8, 8, 8};
itemTexture->setColor(c.r, c.g, c.b);
itemTexture->render(renderer, 20 * BLOCK, line2, &clip);
itemTexture->render(20 * BLOCK, line2, &clip);
}
// Escribe los textos
@@ -105,7 +99,8 @@ void Scoreboard::update()
updateItemsColor();
if (!paused)
{ // Si está en pausa no se actualiza el reloj
{
// Si está en pausa no se actualiza el reloj
clock = getTime();
}
}

View File

@@ -5,6 +5,7 @@
#include <string> // Para basic_string, string
#include <vector> // Para vector
#include "utils.h" // Para color_t
#include <memory> // Para shared_ptr
class AnimatedSprite;
class Asset;
class Resource;
@@ -34,13 +35,13 @@ private:
};
// Objetos y punteros
AnimatedSprite *sprite; // Sprite para mostrar las vidas en el marcador
SDL_Renderer *renderer; // El renderizador de la ventana
Resource *resource; // Objeto con los recursos
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Text *text; // Objeto para escribir texto
Texture *itemTexture; // Textura con los graficos para las vidas
board_t *board; // Contiene las variables a mostrar en el marcador
std::shared_ptr<AnimatedSprite> sprite; // Sprite para mostrar las vidas en el marcador
std::shared_ptr<Texture> itemTexture; // Textura con los graficos para las vidas
std::shared_ptr<board_t> board; // Contiene las variables a mostrar en el marcador
// Variables
std::vector<Color> color; // Vector con los colores del objeto
@@ -63,7 +64,7 @@ public:
Scoreboard(board_t *board);
// Destructor
~Scoreboard();
~Scoreboard() = default;
// Pinta el objeto en pantalla
void render();