Compare commits
19 Commits
2457517f2b
...
v1.09
| Author | SHA1 | Date | |
|---|---|---|---|
| 4e525642a0 | |||
| c7db6aeaa3 | |||
| 5ff04daf20 | |||
| 5bb2b5e7c4 | |||
| 7a685c0cc8 | |||
| 07e83fc811 | |||
| 3167251eae | |||
| 4efbb61fbc | |||
| 3992fc08bf | |||
| 366fe404ca | |||
| 217781c621 | |||
| 212b2b481c | |||
| 59e766f5c3 | |||
| 2e11fec2cb | |||
| 0d7ab830c9 | |||
| 0cec9f8556 | |||
| c6474cb2da | |||
| e6fd4225a2 | |||
| 85ab5ea03f |
BIN
data/test.gif
Normal file
BIN
data/test.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 630 B |
@@ -8,7 +8,7 @@
|
||||
#include "utils.h" // Para printWithDots
|
||||
|
||||
// Carga las animaciones en un vector(Animations) desde un fichero
|
||||
AnimationsFileBuffer loadAnimationsFromFile(const std::string &file_path)
|
||||
Animations loadAnimationsFromFile(const std::string &file_path)
|
||||
{
|
||||
std::ifstream file(file_path);
|
||||
if (!file)
|
||||
@@ -37,18 +37,18 @@ AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const std::stri
|
||||
// Carga las animaciones
|
||||
if (!file_path.empty())
|
||||
{
|
||||
AnimationsFileBuffer v = loadAnimationsFromFile(file_path);
|
||||
loadFromAnimationsFileBuffer(v);
|
||||
Animations v = loadAnimationsFromFile(file_path);
|
||||
setAnimations(v);
|
||||
}
|
||||
}
|
||||
|
||||
// Constructor
|
||||
AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const AnimationsFileBuffer &animations)
|
||||
AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const Animations &animations)
|
||||
: MovingSprite(texture)
|
||||
{
|
||||
if (!animations.empty())
|
||||
{
|
||||
loadFromAnimationsFileBuffer(animations);
|
||||
setAnimations(animations);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,7 @@ void AnimatedSprite::setCurrentAnimation(const std::string &name)
|
||||
animations_[current_animation_].current_frame = 0;
|
||||
animations_[current_animation_].counter = 0;
|
||||
animations_[current_animation_].completed = false;
|
||||
setClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +136,7 @@ void AnimatedSprite::setCurrentAnimation(int index)
|
||||
animations_[current_animation_].current_frame = 0;
|
||||
animations_[current_animation_].counter = 0;
|
||||
animations_[current_animation_].completed = false;
|
||||
setClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +156,7 @@ void AnimatedSprite::resetAnimation()
|
||||
}
|
||||
|
||||
// Carga la animación desde un vector de cadenas
|
||||
void AnimatedSprite::loadFromAnimationsFileBuffer(const AnimationsFileBuffer &source)
|
||||
void AnimatedSprite::setAnimations(const Animations &animations)
|
||||
{
|
||||
int frame_width = 1;
|
||||
int frame_height = 1;
|
||||
@@ -162,9 +164,9 @@ void AnimatedSprite::loadFromAnimationsFileBuffer(const AnimationsFileBuffer &so
|
||||
int max_tiles = 1;
|
||||
|
||||
size_t index = 0;
|
||||
while (index < source.size())
|
||||
while (index < animations.size())
|
||||
{
|
||||
std::string line = source.at(index);
|
||||
std::string line = animations.at(index);
|
||||
|
||||
// Parsea el fichero para buscar variables y valores
|
||||
if (line != "[animation]")
|
||||
@@ -194,11 +196,11 @@ void AnimatedSprite::loadFromAnimationsFileBuffer(const AnimationsFileBuffer &so
|
||||
// Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación
|
||||
if (line == "[animation]")
|
||||
{
|
||||
Animation animation;
|
||||
AnimationData animation;
|
||||
do
|
||||
{
|
||||
index++;
|
||||
line = source.at(index);
|
||||
line = animations.at(index);
|
||||
size_t pos = line.find("=");
|
||||
|
||||
if (pos != std::string::npos)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "moving_sprite.h" // Para MovingSprite
|
||||
class Texture; // lines 9-9
|
||||
|
||||
struct Animation
|
||||
struct AnimationData
|
||||
{
|
||||
std::string name; // Nombre de la animacion
|
||||
std::vector<SDL_Rect> frames; // Cada uno de los frames que componen la animación
|
||||
@@ -17,31 +17,31 @@ struct Animation
|
||||
int current_frame; // Frame actual
|
||||
int counter; // Contador para las animaciones
|
||||
|
||||
Animation() : name(std::string()), speed(5), loop(0), completed(false), current_frame(0), counter(0) {}
|
||||
AnimationData() : name(std::string()), speed(5), loop(0), completed(false), current_frame(0), counter(0) {}
|
||||
};
|
||||
|
||||
using AnimationsFileBuffer = std::vector<std::string>;
|
||||
using Animations = std::vector<std::string>;
|
||||
|
||||
// Carga las animaciones en un vector(Animations) desde un fichero
|
||||
AnimationsFileBuffer loadAnimationsFromFile(const std::string &file_path);
|
||||
Animations loadAnimationsFromFile(const std::string &file_path);
|
||||
|
||||
class AnimatedSprite : public MovingSprite
|
||||
{
|
||||
protected:
|
||||
// Variables
|
||||
std::vector<Animation> animations_; // Vector con las diferentes animaciones
|
||||
std::vector<AnimationData> animations_; // Vector con las diferentes animaciones
|
||||
int current_animation_ = 0; // Animacion activa
|
||||
|
||||
// Calcula el frame correspondiente a la animación actual
|
||||
void animate();
|
||||
|
||||
// Carga la animación desde un vector de cadenas
|
||||
void loadFromAnimationsFileBuffer(const AnimationsFileBuffer &source);
|
||||
void setAnimations(const Animations &animations);
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
AnimatedSprite(std::shared_ptr<Texture> texture, const std::string &file_path);
|
||||
AnimatedSprite(std::shared_ptr<Texture> texture, const AnimationsFileBuffer &animations);
|
||||
AnimatedSprite(std::shared_ptr<Texture> texture, const Animations &animations);
|
||||
explicit AnimatedSprite(std::shared_ptr<Texture> texture)
|
||||
: MovingSprite(texture) {}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ void Cheevos::unlock(int id)
|
||||
// Marcar el logro como completado
|
||||
cheevos_list_.at(index).completed = true;
|
||||
// Mostrar notificación en la pantalla
|
||||
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", cheevos_list_.at(index).caption}, cheevos_list_.at(index).icon);
|
||||
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", cheevos_list_.at(index).caption}, NotificationText::LEFT, cheevos_list_.at(index).icon);
|
||||
// Guardar el estado de los logros
|
||||
saveToFile();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ Credits::Credits()
|
||||
{
|
||||
// Reserva memoria para los punteros
|
||||
text_ = resource_->getText("smb2");
|
||||
sprite_ = std::make_shared<AnimatedSprite>(resource_->getTexture("shine.png"), resource_->getAnimation("shine.ani"));
|
||||
sprite_ = std::make_shared<AnimatedSprite>(resource_->getTexture("shine.png"), resource_->getAnimations("shine.ani"));
|
||||
|
||||
// Inicializa variables
|
||||
options.section.section = Section::CREDITS;
|
||||
@@ -255,7 +255,7 @@ void Credits::updateCounter()
|
||||
void Credits::update()
|
||||
{
|
||||
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
|
||||
if (SDL_GetTicks() - ticks_ > ticks_speed_)
|
||||
if (SDL_GetTicks() - ticks_ > GAME_SPEED)
|
||||
{
|
||||
// Actualiza el contador de ticks
|
||||
ticks_ = SDL_GetTicks();
|
||||
|
||||
@@ -38,7 +38,6 @@ private:
|
||||
bool counter_enabled_ = true; // Indica si esta activo el contador
|
||||
int sub_counter_ = 0; // Contador secundario
|
||||
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
||||
Uint32 ticks_speed_ = 15; // Velocidad a la que se repiten los bucles del programa
|
||||
std::vector<captions_t> texts_; // Vector con los textos
|
||||
|
||||
// Actualiza las variables
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
// Textos
|
||||
constexpr const char *WINDOW_CAPTION = "JailDoctor's Dilemma";
|
||||
constexpr const char *TEXT_COPYRIGHT = "@2022 JailDesigner";
|
||||
constexpr const char *VERSION = "0.7";
|
||||
constexpr const char *VERSION = "1.09";
|
||||
|
||||
// Velocidad del juego
|
||||
constexpr Uint32 GAME_SPEED = 1000 / 60;
|
||||
|
||||
// Tamaño de bloque
|
||||
constexpr int BLOCK = 8;
|
||||
|
||||
128
source/demo.cpp
128
source/demo.cpp
@@ -19,49 +19,55 @@
|
||||
|
||||
// Constructor
|
||||
Demo::Demo()
|
||||
: screen(Screen::get()),
|
||||
renderer(Screen::get()->getRenderer()),
|
||||
resource(Resource::get()),
|
||||
asset(Asset::get()),
|
||||
input(Input::get()),
|
||||
debug(Debug::get())
|
||||
: screen_(Screen::get()),
|
||||
renderer_(Screen::get()->getRenderer()),
|
||||
resource_(Resource::get()),
|
||||
asset_(Asset::get()),
|
||||
input_(Input::get()),
|
||||
debug_(Debug::get())
|
||||
{
|
||||
// Inicia algunas variables
|
||||
board.iniClock = SDL_GetTicks();
|
||||
rooms.push_back("04.room");
|
||||
rooms.push_back("54.room");
|
||||
rooms.push_back("20.room");
|
||||
rooms.push_back("09.room");
|
||||
rooms.push_back("05.room");
|
||||
rooms.push_back("11.room");
|
||||
rooms.push_back("31.room");
|
||||
rooms.push_back("44.room");
|
||||
board_ = std::make_shared<ScoreboardData>();
|
||||
board_->ini_clock = SDL_GetTicks();
|
||||
rooms_.push_back("04.room");
|
||||
rooms_.push_back("54.room");
|
||||
rooms_.push_back("20.room");
|
||||
rooms_.push_back("09.room");
|
||||
rooms_.push_back("05.room");
|
||||
rooms_.push_back("11.room");
|
||||
rooms_.push_back("31.room");
|
||||
rooms_.push_back("44.room");
|
||||
|
||||
roomIndex = 0;
|
||||
currentRoom = rooms[roomIndex];
|
||||
room_index_ = 0;
|
||||
current_room_ = rooms_[room_index_];
|
||||
|
||||
// Crea los objetos
|
||||
itemTracker = std::make_shared<ItemTracker>();
|
||||
scoreboard = std::make_shared<Scoreboard>(&board);
|
||||
room = std::make_shared<Room>(resource->getRoom(currentRoom), itemTracker, &board.items, false);
|
||||
text = resource->getText("smb2");
|
||||
ItemTracker::init();
|
||||
scoreboard_ = std::make_shared<Scoreboard>(board_);
|
||||
room_ = std::make_shared<Room>(resource_->getRoom(current_room_), board_);
|
||||
text_ = resource_->getText("smb2");
|
||||
|
||||
// Inicializa el resto de variables
|
||||
counter = 0;
|
||||
roomTime = 400;
|
||||
ticks = 0;
|
||||
ticksSpeed = 15;
|
||||
board.lives = 9;
|
||||
board.items = 0;
|
||||
board.rooms = 1;
|
||||
board.jail_is_open = false;
|
||||
board.music = true;
|
||||
counter_ = 0;
|
||||
room_time_ = 400;
|
||||
ticks_ = 0;
|
||||
board_->lives = 9;
|
||||
board_->items = 0;
|
||||
board_->rooms = 1;
|
||||
board_->jail_is_open = false;
|
||||
board_->music = true;
|
||||
setScoreBoardColor();
|
||||
|
||||
options.section.section = Section::DEMO;
|
||||
options.section.subsection = Subsection::NONE;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Demo::~Demo()
|
||||
{
|
||||
ItemTracker::destroy();
|
||||
}
|
||||
|
||||
// Comprueba los eventos de la cola
|
||||
void Demo::checkEvents()
|
||||
{
|
||||
@@ -93,21 +99,20 @@ void Demo::run()
|
||||
void Demo::update()
|
||||
{
|
||||
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
|
||||
if (SDL_GetTicks() - ticks > ticksSpeed)
|
||||
if (SDL_GetTicks() - ticks_ > GAME_SPEED)
|
||||
{
|
||||
// Actualiza el contador de ticks
|
||||
ticks = SDL_GetTicks();
|
||||
ticks_ = SDL_GetTicks();
|
||||
|
||||
// Comprueba las entradas
|
||||
checkInput();
|
||||
|
||||
// Actualiza los objetos
|
||||
room->update();
|
||||
scoreboard->update();
|
||||
screen->updateFX();
|
||||
room_->update();
|
||||
scoreboard_->update();
|
||||
checkRoomChange();
|
||||
|
||||
screen->update();
|
||||
screen_->update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,18 +120,17 @@ void Demo::update()
|
||||
void Demo::render()
|
||||
{
|
||||
// Prepara para dibujar el frame
|
||||
screen->start();
|
||||
screen_->start();
|
||||
|
||||
// Dibuja los elementos del juego en orden
|
||||
room->renderMap();
|
||||
room->renderEnemies();
|
||||
room->renderItems();
|
||||
room_->renderMap();
|
||||
room_->renderEnemies();
|
||||
room_->renderItems();
|
||||
renderRoomName();
|
||||
scoreboard->render();
|
||||
screen->renderFX();
|
||||
scoreboard_->render();
|
||||
|
||||
// Actualiza la pantalla
|
||||
screen->render();
|
||||
screen_->render();
|
||||
}
|
||||
|
||||
// Escribe el nombre de la pantalla
|
||||
@@ -135,10 +139,10 @@ void Demo::renderRoomName()
|
||||
// Texto en el centro de la pantalla
|
||||
SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK * 2};
|
||||
Color color = stringToColor(options.video.palette, "white");
|
||||
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF);
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
|
||||
SDL_RenderFillRect(renderer_, &rect);
|
||||
|
||||
text->writeDX(TEXT_CENTER | TEXT_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
|
||||
@@ -148,9 +152,9 @@ void Demo::reLoadTextures()
|
||||
{
|
||||
std::cout << "** RELOAD REQUESTED" << std::endl;
|
||||
}
|
||||
room->reLoadTexture();
|
||||
scoreboard->reLoadTexture();
|
||||
text->reLoadTexture();
|
||||
room_->reLoadTexture();
|
||||
scoreboard_->reLoadTexture();
|
||||
text_->reLoadTexture();
|
||||
}
|
||||
|
||||
// Cambia la paleta
|
||||
@@ -166,8 +170,8 @@ void Demo::switchPalette()
|
||||
options.video.palette = Palette::ZXSPECTRUM;
|
||||
}
|
||||
|
||||
room->reLoadPalette();
|
||||
scoreboard->reLoadPalette();
|
||||
room_->reLoadPalette();
|
||||
scoreboard_->reLoadPalette();
|
||||
|
||||
// Pone el color del marcador en función del color del borde de la habitación
|
||||
setScoreBoardColor();
|
||||
@@ -180,10 +184,10 @@ bool Demo::changeRoom(std::string file)
|
||||
if (file != "0")
|
||||
{
|
||||
// Verifica que exista el fichero que se va a cargar
|
||||
if (asset->get(file) != "")
|
||||
if (asset_->get(file) != "")
|
||||
{
|
||||
// Crea un objeto habitación a partir del fichero
|
||||
room = std::make_shared<Room>(resource->getRoom(file), itemTracker, &board.items, false);
|
||||
room_ = std::make_shared<Room>(resource_->getRoom(file), board_);
|
||||
|
||||
// Pone el color del marcador en función del color del borde de la habitación
|
||||
setScoreBoardColor();
|
||||
@@ -198,19 +202,19 @@ bool Demo::changeRoom(std::string file)
|
||||
// Comprueba si se ha de cambiar de habitación
|
||||
void Demo::checkRoomChange()
|
||||
{
|
||||
counter++;
|
||||
if (counter == roomTime)
|
||||
counter_++;
|
||||
if (counter_ == room_time_)
|
||||
{
|
||||
counter = 0;
|
||||
roomIndex++;
|
||||
if (roomIndex == (int)rooms.size())
|
||||
counter_ = 0;
|
||||
room_index_++;
|
||||
if (room_index_ == (int)rooms_.size())
|
||||
{
|
||||
options.section.section = Section::LOGO;
|
||||
options.section.subsection = Subsection::LOGO_TO_TITLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
changeRoom(rooms[roomIndex]);
|
||||
changeRoom(rooms_[room_index_]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,13 +223,13 @@ void Demo::checkRoomChange()
|
||||
void Demo::setScoreBoardColor()
|
||||
{
|
||||
// Obtiene el color del borde
|
||||
const Color color = room->getBorderColor();
|
||||
const Color color = room_->getBorderColor();
|
||||
|
||||
// Si el color es negro lo cambia a blanco
|
||||
const Color black_color = stringToColor(options.video.palette, "black");
|
||||
board.color = colorAreEqual(color, black_color) ? stringToColor(options.video.palette, "white") : color;
|
||||
board_->color = colorAreEqual(color, black_color) ? stringToColor(options.video.palette, "white") : color;
|
||||
|
||||
// Si el color es negro brillante lo cambia a blanco
|
||||
const Color bright_blac_color = stringToColor(options.video.palette, "bright_black");
|
||||
board.color = colorAreEqual(color, bright_blac_color) ? stringToColor(options.video.palette, "white") : color;
|
||||
board_->color = colorAreEqual(color, bright_blac_color) ? stringToColor(options.video.palette, "white") : color;
|
||||
}
|
||||
@@ -19,26 +19,24 @@ class Demo
|
||||
{
|
||||
private:
|
||||
// Objetos y punteros
|
||||
Screen *screen; // Objeto encargado de manejar el renderizador
|
||||
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
|
||||
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::shared_ptr<Scoreboard> scoreboard; // Objeto encargado de gestionar el marcador
|
||||
std::shared_ptr<ItemTracker> itemTracker; // Lleva el control de los objetos recogidos
|
||||
Screen *screen_; // Objeto encargado de manejar el renderizador
|
||||
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
|
||||
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::shared_ptr<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador
|
||||
|
||||
// Variables
|
||||
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
|
||||
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
|
||||
std::string currentRoom; // Fichero de la habitación actual
|
||||
board_t board; // Estructura con los datos del marcador
|
||||
int counter; // Contador para el modo demo
|
||||
int roomTime; // Tiempo que se muestra cada habitacion
|
||||
int roomIndex; // Indice para el vector de habitaciones
|
||||
std::vector<std::string> rooms; // Listado con los mapas de la demo
|
||||
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
|
||||
std::string current_room_; // Fichero de la habitación actual
|
||||
std::shared_ptr<ScoreboardData> board_; // Estructura con los datos del marcador
|
||||
int counter_; // Contador para el modo demo
|
||||
int room_time_; // Tiempo que se muestra cada habitacion
|
||||
int room_index_; // Indice para el vector de habitaciones
|
||||
std::vector<std::string> rooms_; // Listado con los mapas de la demo
|
||||
|
||||
// Actualiza el juego, las variables, comprueba la entrada, etc.
|
||||
void update();
|
||||
@@ -75,7 +73,7 @@ public:
|
||||
Demo();
|
||||
|
||||
// Destructor
|
||||
~Demo() = default;
|
||||
~Demo();
|
||||
|
||||
// Bucle para el juego
|
||||
void run();
|
||||
|
||||
@@ -79,11 +79,10 @@ Director::Director(int argc, const char *argv[])
|
||||
Screen::init(window_, renderer_);
|
||||
Screen::get()->setBorderColor(borderColor);
|
||||
Resource::init();
|
||||
Notifier::init(Asset::get()->get("notify.png"), Resource::get()->getText("smb2"));
|
||||
Notifier::init("notify.png", "8bithud");
|
||||
Input::init(Asset::get()->get("gamecontrollerdb.txt"));
|
||||
initInput();
|
||||
Debug::init();
|
||||
title_music_ = JA_LoadMusic(Asset::get()->get("title.ogg").c_str());
|
||||
Cheevos::init(Asset::get()->get("cheevos.bin"));
|
||||
}
|
||||
|
||||
@@ -101,8 +100,6 @@ Director::~Director()
|
||||
Resource::destroy();
|
||||
Cheevos::destroy();
|
||||
|
||||
JA_DeleteMusic(title_music_);
|
||||
|
||||
SDL_DestroyRenderer(renderer_);
|
||||
SDL_DestroyWindow(window_);
|
||||
SDL_Quit();
|
||||
@@ -280,6 +277,16 @@ void Director::initInput()
|
||||
void Director::initJailAudio()
|
||||
{
|
||||
JA_Init(48000, AUDIO_S16, 2);
|
||||
if (options.audio.enabled)
|
||||
{
|
||||
JA_SetMusicVolume(options.audio.music.volume);
|
||||
JA_SetSoundVolume(options.audio.sound.volume);
|
||||
}
|
||||
else
|
||||
{
|
||||
JA_SetMusicVolume(0);
|
||||
JA_SetSoundVolume(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Arranca SDL y crea la ventana
|
||||
@@ -353,8 +360,10 @@ bool Director::initSDL()
|
||||
// Inicializa el color de renderizado
|
||||
SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF);
|
||||
|
||||
// Establece el tamaño del buffer de renderizado
|
||||
SDL_RenderSetLogicalSize(renderer_, options.game.width, options.game.height);
|
||||
// Modifica el tamaño del renderizador
|
||||
const int extra_width = options.video.border.enabled ? options.video.border.width * 2 : 0;
|
||||
const int extra_height = options.video.border.enabled ? options.video.border.height * 2 : 0;
|
||||
SDL_RenderSetLogicalSize(renderer_, options.game.width + extra_width, options.game.height + extra_height);
|
||||
|
||||
// Establece el modo de mezcla
|
||||
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND);
|
||||
@@ -397,6 +406,9 @@ bool Director::setFileList()
|
||||
// Datos
|
||||
Asset::get()->add(prefix + "/data/input/gamecontrollerdb.txt", AssetType::DATA);
|
||||
|
||||
// Test
|
||||
Asset::get()->add(prefix + "/data/test.gif", AssetType::DATA);
|
||||
|
||||
// Ficheros de sistema
|
||||
Asset::get()->add(system_folder_ + "/config.txt", AssetType::DATA, false, true);
|
||||
Asset::get()->add(system_folder_ + "/stats_buffer.csv", AssetType::DATA, false, true);
|
||||
@@ -748,10 +760,6 @@ void Director::runLoadingScreen()
|
||||
// Ejecuta la seccion de juego con el titulo y los menus
|
||||
void Director::runTitle()
|
||||
{
|
||||
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
|
||||
{
|
||||
JA_PlayMusic(title_music_);
|
||||
}
|
||||
auto title = std::make_unique<Title>();
|
||||
title->run();
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ private:
|
||||
SDL_Renderer *renderer_; // El renderizador de la ventana
|
||||
|
||||
// Variables
|
||||
JA_Music_t *title_music_; // Musica del titulo
|
||||
std::string executable_path_; // Path del ejecutable
|
||||
std::string system_folder_; // Carpeta del sistema donde guardar datos
|
||||
|
||||
|
||||
@@ -23,25 +23,24 @@
|
||||
|
||||
// Constructor
|
||||
Ending::Ending()
|
||||
: screen(Screen::get()),
|
||||
renderer(Screen::get()->getRenderer()),
|
||||
resource(Resource::get()),
|
||||
asset(Asset::get()),
|
||||
input(Input::get())
|
||||
: screen_(Screen::get()),
|
||||
renderer_(Screen::get()->getRenderer()),
|
||||
resource_(Resource::get()),
|
||||
asset_(Asset::get()),
|
||||
input_(Input::get())
|
||||
{
|
||||
// Reserva memoria para los punteros a objetos
|
||||
text = resource->getText("smb2");
|
||||
music = resource->getMusic("ending1.ogg");
|
||||
text_ = resource_->getText("smb2");
|
||||
music = resource_->getMusic("ending1.ogg");
|
||||
|
||||
// Inicializa variables
|
||||
counter = -1;
|
||||
preCounter = 0;
|
||||
coverCounter = 0;
|
||||
counter_ = -1;
|
||||
pre_counter_ = 0;
|
||||
cover_counter_ = 0;
|
||||
options.section.section = Section::ENDING;
|
||||
options.section.subsection = Subsection::NONE;
|
||||
ticks = 0;
|
||||
ticksSpeed = 15;
|
||||
scene = 0;
|
||||
ticks_ = 0;
|
||||
current_scene_ = 0;
|
||||
|
||||
// Inicializa los textos
|
||||
iniTexts();
|
||||
@@ -53,18 +52,18 @@ Ending::Ending()
|
||||
iniScenes();
|
||||
|
||||
// Cambia el color del borde
|
||||
screen->setBorderColor(stringToColor(options.video.palette, "black"));
|
||||
screen_->setBorderColor(stringToColor(options.video.palette, "black"));
|
||||
|
||||
// Crea la textura para cubrir el rexto
|
||||
coverTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT + 8);
|
||||
if (coverTexture == nullptr)
|
||||
cover_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT + 8);
|
||||
if (cover_texture_ == nullptr)
|
||||
{
|
||||
if (options.console)
|
||||
{
|
||||
std::cout << "Error: canvasTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
}
|
||||
SDL_SetTextureBlendMode(coverTexture, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetTextureBlendMode(cover_texture_, SDL_BLENDMODE_BLEND);
|
||||
|
||||
// Rellena la textura para la cortinilla
|
||||
fillCoverTexture();
|
||||
@@ -74,17 +73,17 @@ Ending::Ending()
|
||||
Ending::~Ending()
|
||||
{
|
||||
// Libera la memoria de los objetos
|
||||
SDL_DestroyTexture(coverTexture);
|
||||
SDL_DestroyTexture(cover_texture_);
|
||||
}
|
||||
|
||||
// Actualiza el objeto
|
||||
void Ending::update()
|
||||
{
|
||||
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
|
||||
if (SDL_GetTicks() - ticks > ticksSpeed)
|
||||
if (SDL_GetTicks() - ticks_ > GAME_SPEED)
|
||||
{
|
||||
// Actualiza el contador de ticks
|
||||
ticks = SDL_GetTicks();
|
||||
ticks_ = SDL_GetTicks();
|
||||
|
||||
// Comprueba las entradas
|
||||
checkInput();
|
||||
@@ -101,7 +100,7 @@ void Ending::update()
|
||||
// Actualiza el volumen de la musica
|
||||
updateMusicVolume();
|
||||
|
||||
screen->update();
|
||||
screen_->update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,22 +108,22 @@ void Ending::update()
|
||||
void Ending::render()
|
||||
{
|
||||
// Prepara para empezar a dibujar en la textura de juego
|
||||
screen->start();
|
||||
screen_->start();
|
||||
|
||||
// Limpia la pantalla
|
||||
screen->clean(stringToColor(options.video.palette, "black"));
|
||||
screen_->clean(stringToColor(options.video.palette, "black"));
|
||||
|
||||
// Dibuja las imagenes de la escena
|
||||
spritePics[scene].sprite->render();
|
||||
spritePics[scene].coverSprite->render();
|
||||
sprite_pics_[current_scene_].sprite->render();
|
||||
sprite_pics_[current_scene_].cover_sprite->render();
|
||||
|
||||
// Dibuja los textos de la escena
|
||||
for (auto ti : scenes[scene].textIndex)
|
||||
for (auto ti : scenes_[current_scene_].text_index)
|
||||
{
|
||||
if (counter > ti.trigger)
|
||||
if (counter_ > ti.trigger)
|
||||
{
|
||||
spriteTexts[ti.index].sprite->render();
|
||||
spriteTexts[ti.index].coverSprite->render();
|
||||
sprite_texts_[ti.index].sprite->render();
|
||||
sprite_texts_[ti.index].cover_sprite->render();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +131,7 @@ void Ending::render()
|
||||
renderCoverTexture();
|
||||
|
||||
// Vuelca el contenido del renderizador en pantalla
|
||||
screen->render();
|
||||
screen_->render();
|
||||
}
|
||||
|
||||
// Comprueba el manejador de eventos
|
||||
@@ -155,7 +154,7 @@ void Ending::checkInput()
|
||||
void Ending::iniTexts()
|
||||
{
|
||||
// Vector con los textos
|
||||
std::vector<textAndPos_t> texts;
|
||||
std::vector<TextAndPosition> texts;
|
||||
|
||||
// Escena #0
|
||||
texts.push_back({"HE FINALLY MANAGED", 32});
|
||||
@@ -187,66 +186,66 @@ void Ending::iniTexts()
|
||||
texts.push_back({"WERE BORN...", 158});
|
||||
|
||||
// Crea los sprites
|
||||
spriteTexts.clear();
|
||||
sprite_texts_.clear();
|
||||
|
||||
for (auto t : texts)
|
||||
{
|
||||
endingTexture_t st;
|
||||
const int width = text->lenght(t.caption, 1) + 2 + 2;
|
||||
const int height = text->getCharacterSize() + 2 + 2;
|
||||
EndingTexture st;
|
||||
const int width = text_->lenght(t.caption, 1) + 2 + 2;
|
||||
const int height = text_->getCharacterSize() + 2 + 2;
|
||||
Color c = stringToColor(options.video.palette, "black");
|
||||
|
||||
// Crea la texture
|
||||
st.texture = std::make_shared<Texture>(renderer);
|
||||
st.texture = std::make_shared<Texture>(renderer_);
|
||||
st.texture->createBlank(width, height);
|
||||
st.texture->setAsRenderTarget(renderer);
|
||||
st.texture->setAsRenderTarget(renderer_);
|
||||
st.texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||
text->writeDX(TEXT_STROKE, 2, 2, t.caption, 1, c, 2, c);
|
||||
text_->writeDX(TEXT_STROKE, 2, 2, t.caption, 1, c, 2, c);
|
||||
|
||||
// Crea el sprite
|
||||
st.sprite = std::make_shared<Sprite>(st.texture, 0, 0, st.texture->getWidth(), st.texture->getHeight());
|
||||
st.sprite->setPosition((GAMECANVAS_WIDTH - st.texture->getWidth()) / 2, t.pos);
|
||||
|
||||
// Crea la coverTexture
|
||||
st.coverTexture = std::make_shared<Texture>(renderer);
|
||||
st.coverTexture->createBlank(width, height + 8);
|
||||
st.coverTexture->setAsRenderTarget(renderer);
|
||||
st.coverTexture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||
st.cover_texture = std::make_shared<Texture>(renderer_);
|
||||
st.cover_texture->createBlank(width, height + 8);
|
||||
st.cover_texture->setAsRenderTarget(renderer_);
|
||||
st.cover_texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||
|
||||
// Rellena la coverTexture con color transparente
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
|
||||
SDL_RenderClear(renderer_);
|
||||
|
||||
// Los primeros 8 pixels crea una malla
|
||||
c = stringToColor(options.video.palette, "black");
|
||||
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF);
|
||||
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF);
|
||||
for (int i = 0; i < width; i += 2)
|
||||
{
|
||||
SDL_RenderDrawPoint(renderer, i, 0);
|
||||
SDL_RenderDrawPoint(renderer, i, 2);
|
||||
SDL_RenderDrawPoint(renderer, i, 4);
|
||||
SDL_RenderDrawPoint(renderer, i, 6);
|
||||
SDL_RenderDrawPoint(renderer_, i, 0);
|
||||
SDL_RenderDrawPoint(renderer_, i, 2);
|
||||
SDL_RenderDrawPoint(renderer_, i, 4);
|
||||
SDL_RenderDrawPoint(renderer_, i, 6);
|
||||
|
||||
SDL_RenderDrawPoint(renderer, i + 1, 5);
|
||||
SDL_RenderDrawPoint(renderer, i + 1, 7);
|
||||
SDL_RenderDrawPoint(renderer_, i + 1, 5);
|
||||
SDL_RenderDrawPoint(renderer_, i + 1, 7);
|
||||
}
|
||||
|
||||
// El resto se rellena de color sólido
|
||||
SDL_Rect rect = {0, 8, width, height};
|
||||
c = stringToColor(options.video.palette, "black");
|
||||
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF);
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF);
|
||||
SDL_RenderFillRect(renderer_, &rect);
|
||||
|
||||
// Crea el sprite
|
||||
st.coverSprite = std::make_shared<Sprite>(st.coverTexture, 0, 0, st.coverTexture->getWidth(), st.coverTexture->getHeight() - 8);
|
||||
st.coverSprite->setPosition((GAMECANVAS_WIDTH - st.coverTexture->getWidth()) / 2, t.pos);
|
||||
st.coverSprite->setClip(0, 8, -1, -1);
|
||||
st.cover_sprite = std::make_shared<Sprite>(st.cover_texture, 0, 0, st.cover_texture->getWidth(), st.cover_texture->getHeight() - 8);
|
||||
st.cover_sprite->setPosition((GAMECANVAS_WIDTH - st.cover_texture->getWidth()) / 2, t.pos);
|
||||
st.cover_sprite->setClip(0, 8, -1, -1);
|
||||
|
||||
// Inicializa variables
|
||||
st.clipDesp = 8;
|
||||
st.clipHeight = height;
|
||||
st.clip_desp = 8;
|
||||
st.clip_height = height;
|
||||
|
||||
spriteTexts.push_back(st);
|
||||
sprite_texts_.push_back(st);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +253,7 @@ void Ending::iniTexts()
|
||||
void Ending::iniPics()
|
||||
{
|
||||
// Vector con las rutas y la posición
|
||||
std::vector<textAndPos_t> pics;
|
||||
std::vector<TextAndPosition> pics;
|
||||
|
||||
if (options.video.palette == Palette::ZXSPECTRUM)
|
||||
{
|
||||
@@ -274,14 +273,14 @@ void Ending::iniPics()
|
||||
}
|
||||
|
||||
// Crea los sprites
|
||||
spritePics.clear();
|
||||
sprite_pics_.clear();
|
||||
|
||||
for (auto p : pics)
|
||||
{
|
||||
endingTexture_t sp;
|
||||
EndingTexture sp;
|
||||
|
||||
// Crea la texture
|
||||
sp.texture = resource->getTexture(p.caption);
|
||||
sp.texture = resource_->getTexture(p.caption);
|
||||
const int width = sp.texture->getWidth();
|
||||
const int height = sp.texture->getHeight();
|
||||
|
||||
@@ -290,45 +289,45 @@ void Ending::iniPics()
|
||||
sp.sprite->setPosition((GAMECANVAS_WIDTH - width) / 2, p.pos);
|
||||
|
||||
// Crea la coverTexture
|
||||
sp.coverTexture = std::make_shared<Texture>(renderer);
|
||||
sp.coverTexture->createBlank(width, height + 8);
|
||||
sp.coverTexture->setAsRenderTarget(renderer);
|
||||
sp.coverTexture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||
sp.cover_texture = std::make_shared<Texture>(renderer_);
|
||||
sp.cover_texture->createBlank(width, height + 8);
|
||||
sp.cover_texture->setAsRenderTarget(renderer_);
|
||||
sp.cover_texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||
|
||||
// Rellena la coverTexture con color transparente
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
|
||||
SDL_RenderClear(renderer_);
|
||||
|
||||
// Los primeros 8 pixels crea una malla
|
||||
Color c = stringToColor(options.video.palette, "black");
|
||||
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF);
|
||||
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF);
|
||||
for (int i = 0; i < width; i += 2)
|
||||
{
|
||||
SDL_RenderDrawPoint(renderer, i, 0);
|
||||
SDL_RenderDrawPoint(renderer, i, 2);
|
||||
SDL_RenderDrawPoint(renderer, i, 4);
|
||||
SDL_RenderDrawPoint(renderer, i, 6);
|
||||
SDL_RenderDrawPoint(renderer_, i, 0);
|
||||
SDL_RenderDrawPoint(renderer_, i, 2);
|
||||
SDL_RenderDrawPoint(renderer_, i, 4);
|
||||
SDL_RenderDrawPoint(renderer_, i, 6);
|
||||
|
||||
SDL_RenderDrawPoint(renderer, i + 1, 5);
|
||||
SDL_RenderDrawPoint(renderer, i + 1, 7);
|
||||
SDL_RenderDrawPoint(renderer_, i + 1, 5);
|
||||
SDL_RenderDrawPoint(renderer_, i + 1, 7);
|
||||
}
|
||||
|
||||
// El resto se rellena de color sólido
|
||||
SDL_Rect rect = {0, 8, width, height};
|
||||
c = stringToColor(options.video.palette, "black");
|
||||
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF);
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF);
|
||||
SDL_RenderFillRect(renderer_, &rect);
|
||||
|
||||
// Crea el sprite
|
||||
sp.coverSprite = std::make_shared<Sprite>(sp.coverTexture, 0, 0, sp.coverTexture->getWidth(), sp.coverTexture->getHeight() - 8);
|
||||
sp.coverSprite->setPosition((GAMECANVAS_WIDTH - sp.coverTexture->getWidth()) / 2, p.pos);
|
||||
sp.coverSprite->setClip(0, 8, -1, -1);
|
||||
sp.cover_sprite = std::make_shared<Sprite>(sp.cover_texture, 0, 0, sp.cover_texture->getWidth(), sp.cover_texture->getHeight() - 8);
|
||||
sp.cover_sprite->setPosition((GAMECANVAS_WIDTH - sp.cover_texture->getWidth()) / 2, p.pos);
|
||||
sp.cover_sprite->setClip(0, 8, -1, -1);
|
||||
|
||||
// Inicializa variables
|
||||
sp.clipDesp = 8;
|
||||
sp.clipHeight = height;
|
||||
sp.clip_desp = 8;
|
||||
sp.clip_height = height;
|
||||
|
||||
spritePics.push_back(sp);
|
||||
sprite_pics_.push_back(sp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,79 +339,79 @@ void Ending::iniScenes()
|
||||
const int lapse = 80;
|
||||
|
||||
// Crea el contenedor
|
||||
scene_t sc;
|
||||
SceneData sc;
|
||||
|
||||
// Inicializa el vector
|
||||
scenes.clear();
|
||||
scenes_.clear();
|
||||
|
||||
// Crea la escena #0
|
||||
sc.counterEnd = 1000;
|
||||
sc.pictureIndex = 0;
|
||||
sc.textIndex.clear();
|
||||
sc.counter_end = 1000;
|
||||
sc.picture_index = 0;
|
||||
sc.text_index.clear();
|
||||
trigger = 85 * 2;
|
||||
trigger += lapse;
|
||||
sc.textIndex.push_back({0, trigger});
|
||||
sc.text_index.push_back({0, trigger});
|
||||
trigger += lapse;
|
||||
sc.textIndex.push_back({1, trigger});
|
||||
sc.text_index.push_back({1, trigger});
|
||||
trigger += lapse * 3;
|
||||
sc.textIndex.push_back({2, trigger});
|
||||
sc.text_index.push_back({2, trigger});
|
||||
trigger += lapse;
|
||||
sc.textIndex.push_back({3, trigger});
|
||||
scenes.push_back(sc);
|
||||
sc.text_index.push_back({3, trigger});
|
||||
scenes_.push_back(sc);
|
||||
|
||||
// Crea la escena #1
|
||||
sc.counterEnd = 1400;
|
||||
sc.pictureIndex = 1;
|
||||
sc.textIndex.clear();
|
||||
sc.counter_end = 1400;
|
||||
sc.picture_index = 1;
|
||||
sc.text_index.clear();
|
||||
trigger = 140 * 2;
|
||||
trigger += lapse;
|
||||
sc.textIndex.push_back({4, trigger});
|
||||
sc.text_index.push_back({4, trigger});
|
||||
trigger += lapse;
|
||||
sc.textIndex.push_back({5, trigger});
|
||||
sc.text_index.push_back({5, trigger});
|
||||
trigger += lapse;
|
||||
sc.textIndex.push_back({6, trigger});
|
||||
sc.text_index.push_back({6, trigger});
|
||||
trigger += lapse * 3;
|
||||
sc.textIndex.push_back({7, trigger});
|
||||
sc.text_index.push_back({7, trigger});
|
||||
trigger += lapse;
|
||||
sc.textIndex.push_back({8, trigger});
|
||||
sc.text_index.push_back({8, trigger});
|
||||
trigger += lapse * 3;
|
||||
sc.textIndex.push_back({9, trigger});
|
||||
scenes.push_back(sc);
|
||||
sc.text_index.push_back({9, trigger});
|
||||
scenes_.push_back(sc);
|
||||
|
||||
// Crea la escena #2
|
||||
sc.counterEnd = 1000;
|
||||
sc.pictureIndex = 2;
|
||||
sc.textIndex.clear();
|
||||
sc.counter_end = 1000;
|
||||
sc.picture_index = 2;
|
||||
sc.text_index.clear();
|
||||
trigger = 148 / 2;
|
||||
trigger += lapse;
|
||||
sc.textIndex.push_back({10, trigger});
|
||||
sc.text_index.push_back({10, trigger});
|
||||
trigger += lapse;
|
||||
sc.textIndex.push_back({11, trigger});
|
||||
scenes.push_back(sc);
|
||||
sc.text_index.push_back({11, trigger});
|
||||
scenes_.push_back(sc);
|
||||
|
||||
// Crea la escena #3
|
||||
sc.counterEnd = 800;
|
||||
sc.pictureIndex = 3;
|
||||
sc.textIndex.clear();
|
||||
sc.counter_end = 800;
|
||||
sc.picture_index = 3;
|
||||
sc.text_index.clear();
|
||||
trigger = 87 / 2;
|
||||
trigger += lapse;
|
||||
sc.textIndex.push_back({12, trigger});
|
||||
sc.text_index.push_back({12, trigger});
|
||||
trigger += lapse / 2;
|
||||
sc.textIndex.push_back({13, trigger});
|
||||
scenes.push_back(sc);
|
||||
sc.text_index.push_back({13, trigger});
|
||||
scenes_.push_back(sc);
|
||||
|
||||
// Crea la escena #4
|
||||
sc.counterEnd = 1000;
|
||||
sc.pictureIndex = 4;
|
||||
sc.textIndex.clear();
|
||||
sc.counter_end = 1000;
|
||||
sc.picture_index = 4;
|
||||
sc.text_index.clear();
|
||||
trigger = 91 * 2;
|
||||
trigger += lapse;
|
||||
sc.textIndex.push_back({14, trigger});
|
||||
sc.text_index.push_back({14, trigger});
|
||||
trigger += lapse * 2;
|
||||
sc.textIndex.push_back({15, trigger});
|
||||
sc.text_index.push_back({15, trigger});
|
||||
trigger += lapse * 3;
|
||||
sc.textIndex.push_back({16, trigger});
|
||||
scenes.push_back(sc);
|
||||
sc.text_index.push_back({16, trigger});
|
||||
scenes_.push_back(sc);
|
||||
}
|
||||
|
||||
// Bucle principal
|
||||
@@ -435,80 +434,80 @@ void Ending::run()
|
||||
void Ending::updateCounters()
|
||||
{
|
||||
// Incrementa el contador
|
||||
if (preCounter < 200)
|
||||
if (pre_counter_ < 200)
|
||||
{
|
||||
preCounter++;
|
||||
pre_counter_++;
|
||||
}
|
||||
else
|
||||
{
|
||||
counter++;
|
||||
counter_++;
|
||||
}
|
||||
|
||||
if (counter > scenes[scene].counterEnd - 100)
|
||||
if (counter_ > scenes_[current_scene_].counter_end - 100)
|
||||
{
|
||||
coverCounter++;
|
||||
cover_counter_++;
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza las cortinillas de los elementos
|
||||
void Ending::updateSpriteCovers()
|
||||
{ // Actualiza la cortinilla de los textos
|
||||
if (counter % 4 == 0)
|
||||
if (counter_ % 4 == 0)
|
||||
{
|
||||
for (auto ti : scenes[scene].textIndex)
|
||||
for (auto ti : scenes_[current_scene_].text_index)
|
||||
{
|
||||
if (counter > ti.trigger)
|
||||
if (counter_ > ti.trigger)
|
||||
{
|
||||
if (spriteTexts[ti.index].clipDesp > 0)
|
||||
if (sprite_texts_[ti.index].clip_desp > 0)
|
||||
{
|
||||
spriteTexts[ti.index].clipDesp -= 2;
|
||||
sprite_texts_[ti.index].clip_desp -= 2;
|
||||
}
|
||||
else if (spriteTexts[ti.index].clipHeight > 0)
|
||||
else if (sprite_texts_[ti.index].clip_height > 0)
|
||||
{
|
||||
spriteTexts[ti.index].clipHeight -= 2;
|
||||
spriteTexts[ti.index].coverSprite->setY(spriteTexts[ti.index].coverSprite->getY() + 2);
|
||||
sprite_texts_[ti.index].clip_height -= 2;
|
||||
sprite_texts_[ti.index].cover_sprite->setY(sprite_texts_[ti.index].cover_sprite->getY() + 2);
|
||||
}
|
||||
spriteTexts[ti.index].coverSprite->setClip(0, spriteTexts[ti.index].clipDesp, spriteTexts[ti.index].coverSprite->getWidth(), spriteTexts[ti.index].clipHeight);
|
||||
sprite_texts_[ti.index].cover_sprite->setClip(0, sprite_texts_[ti.index].clip_desp, sprite_texts_[ti.index].cover_sprite->getWidth(), sprite_texts_[ti.index].clip_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza la cortinilla de las imagenes
|
||||
if (counter % 2 == 0)
|
||||
if (counter_ % 2 == 0)
|
||||
{
|
||||
if (spritePics[scene].clipDesp > 0)
|
||||
if (sprite_pics_[current_scene_].clip_desp > 0)
|
||||
{
|
||||
spritePics[scene].clipDesp -= 2;
|
||||
sprite_pics_[current_scene_].clip_desp -= 2;
|
||||
}
|
||||
else if (spritePics[scene].clipHeight > 0)
|
||||
else if (sprite_pics_[current_scene_].clip_height > 0)
|
||||
{
|
||||
spritePics[scene].clipHeight -= 2;
|
||||
if (spritePics[scene].clipHeight < 0)
|
||||
sprite_pics_[current_scene_].clip_height -= 2;
|
||||
if (sprite_pics_[current_scene_].clip_height < 0)
|
||||
{
|
||||
spritePics[scene].clipHeight = 0;
|
||||
sprite_pics_[current_scene_].clip_height = 0;
|
||||
}
|
||||
spritePics[scene].coverSprite->setY(spritePics[scene].coverSprite->getY() + 2);
|
||||
sprite_pics_[current_scene_].cover_sprite->setY(sprite_pics_[current_scene_].cover_sprite->getY() + 2);
|
||||
}
|
||||
spritePics[scene].coverSprite->setClip(0, spritePics[scene].clipDesp, spritePics[scene].coverSprite->getWidth(), spritePics[scene].clipHeight);
|
||||
sprite_pics_[current_scene_].cover_sprite->setClip(0, sprite_pics_[current_scene_].clip_desp, sprite_pics_[current_scene_].cover_sprite->getWidth(), sprite_pics_[current_scene_].clip_height);
|
||||
}
|
||||
}
|
||||
|
||||
// Comprueba si se ha de cambiar de escena
|
||||
void Ending::checkChangeScene()
|
||||
{
|
||||
if (counter > scenes[scene].counterEnd)
|
||||
if (counter_ > scenes_[current_scene_].counter_end)
|
||||
{
|
||||
scene++;
|
||||
counter = 0;
|
||||
coverCounter = 0;
|
||||
if (scene == 5)
|
||||
current_scene_++;
|
||||
counter_ = 0;
|
||||
cover_counter_ = 0;
|
||||
if (current_scene_ == 5)
|
||||
{
|
||||
// Termina el bucle
|
||||
options.section.section = Section::ENDING2;
|
||||
|
||||
// Mantiene los valores anteriores
|
||||
scene = 4;
|
||||
coverCounter = 100;
|
||||
current_scene_ = 4;
|
||||
cover_counter_ = 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -517,49 +516,49 @@ void Ending::checkChangeScene()
|
||||
void Ending::fillCoverTexture()
|
||||
{
|
||||
// Rellena la textura que cubre el texto con color transparente
|
||||
SDL_SetRenderTarget(renderer, coverTexture);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_SetRenderTarget(renderer_, cover_texture_);
|
||||
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
|
||||
SDL_RenderClear(renderer_);
|
||||
|
||||
// Los primeros 8 pixels crea una malla
|
||||
const Color color = stringToColor(options.video.palette, "black");
|
||||
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF);
|
||||
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
|
||||
for (int i = 0; i < 256; i += 2)
|
||||
{
|
||||
SDL_RenderDrawPoint(renderer, i + 0, GAMECANVAS_HEIGHT + 0);
|
||||
SDL_RenderDrawPoint(renderer, i + 1, GAMECANVAS_HEIGHT + 1);
|
||||
SDL_RenderDrawPoint(renderer, i + 0, GAMECANVAS_HEIGHT + 2);
|
||||
SDL_RenderDrawPoint(renderer, i + 1, GAMECANVAS_HEIGHT + 3);
|
||||
SDL_RenderDrawPoint(renderer_, i + 0, GAMECANVAS_HEIGHT + 0);
|
||||
SDL_RenderDrawPoint(renderer_, i + 1, GAMECANVAS_HEIGHT + 1);
|
||||
SDL_RenderDrawPoint(renderer_, i + 0, GAMECANVAS_HEIGHT + 2);
|
||||
SDL_RenderDrawPoint(renderer_, i + 1, GAMECANVAS_HEIGHT + 3);
|
||||
|
||||
SDL_RenderDrawPoint(renderer, i, GAMECANVAS_HEIGHT + 4);
|
||||
SDL_RenderDrawPoint(renderer, i, GAMECANVAS_HEIGHT + 6);
|
||||
SDL_RenderDrawPoint(renderer_, i, GAMECANVAS_HEIGHT + 4);
|
||||
SDL_RenderDrawPoint(renderer_, i, GAMECANVAS_HEIGHT + 6);
|
||||
}
|
||||
|
||||
// El resto se rellena de color sólido
|
||||
SDL_Rect rect = {0, 0, 256, GAMECANVAS_HEIGHT};
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
SDL_RenderFillRect(renderer_, &rect);
|
||||
|
||||
SDL_SetRenderTarget(renderer, nullptr);
|
||||
SDL_SetRenderTarget(renderer_, nullptr);
|
||||
}
|
||||
|
||||
// Dibuja la cortinilla de cambio de escena
|
||||
void Ending::renderCoverTexture()
|
||||
{
|
||||
if (coverCounter > 0)
|
||||
if (cover_counter_ > 0)
|
||||
{ // Dibuja la textura que cubre el texto
|
||||
const int offset = std::min(coverCounter, 100);
|
||||
SDL_Rect srcRect = {0, 200 - (coverCounter * 2), 256, offset * 2};
|
||||
const int offset = std::min(cover_counter_, 100);
|
||||
SDL_Rect srcRect = {0, 200 - (cover_counter_ * 2), 256, offset * 2};
|
||||
SDL_Rect dstRect = {0, 0, 256, offset * 2};
|
||||
SDL_RenderCopy(renderer, coverTexture, &srcRect, &dstRect);
|
||||
SDL_RenderCopy(renderer_, cover_texture_, &srcRect, &dstRect);
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza el volumen de la musica
|
||||
void Ending::updateMusicVolume()
|
||||
{
|
||||
if (scene == 4 && coverCounter > 0)
|
||||
if (current_scene_ == 4 && cover_counter_ > 0)
|
||||
{
|
||||
const float step = (100.0f - coverCounter) / 100.0f;
|
||||
const float step = (100.0f - cover_counter_) / 100.0f;
|
||||
const int volume = 128 * step;
|
||||
JA_SetVolume(volume);
|
||||
}
|
||||
|
||||
@@ -18,17 +18,17 @@ class Ending
|
||||
{
|
||||
private:
|
||||
// Estructuras
|
||||
struct endingTexture_t // Estructura con dos texturas y sprites, uno para mostrar y el otro hace de cortinilla
|
||||
struct EndingTexture // Estructura con dos texturas y sprites, uno para mostrar y el otro hace de cortinilla
|
||||
{
|
||||
std::shared_ptr<Texture> texture; // Textura a mostrar
|
||||
std::shared_ptr<Sprite> sprite; // Sprite para mostrar la textura
|
||||
std::shared_ptr<Texture> coverTexture; // Textura que cubre a la otra textura
|
||||
std::shared_ptr<Sprite> coverSprite; // Sprite para mostrar la textura que cubre a la otra textura
|
||||
int clipDesp; // Desplazamiento del spriteClip de la textura de cobertura
|
||||
int clipHeight; // Altura del spriteClip de la textura de cobertura
|
||||
std::shared_ptr<Texture> cover_texture; // Textura que cubre a la otra textura
|
||||
std::shared_ptr<Sprite> cover_sprite; // Sprite para mostrar la textura que cubre a la otra textura
|
||||
int clip_desp; // Desplazamiento del spriteClip de la textura de cobertura
|
||||
int clip_height; // Altura del spriteClip de la textura de cobertura
|
||||
};
|
||||
|
||||
struct textAndPos_t // Estructura con un texto y su posición en el eje Y
|
||||
struct TextAndPosition // Estructura con un texto y su posición en el eje Y
|
||||
{
|
||||
std::string caption; // Texto
|
||||
int pos; // Posición
|
||||
@@ -40,32 +40,31 @@ private:
|
||||
int trigger;
|
||||
};
|
||||
|
||||
struct scene_t // Estructura para crear cada una de las escenas del final
|
||||
struct SceneData // Estructura para crear cada una de las escenas del final
|
||||
{
|
||||
std::vector<asdhk> textIndex; // Indices del vector de textos a mostrar y su disparador
|
||||
int pictureIndex; // Indice del vector de imagenes a mostrar
|
||||
int counterEnd; // Valor del contador en el que finaliza la escena
|
||||
std::vector<asdhk> text_index; // Indices del vector de textos a mostrar y su disparador
|
||||
int picture_index; // Indice del vector de imagenes a mostrar
|
||||
int counter_end; // Valor del contador en el que finaliza la escena
|
||||
};
|
||||
|
||||
// Objetos y punteros
|
||||
Screen *screen; // Objeto encargado de dibujar en pantalla
|
||||
SDL_Renderer *renderer; // El renderizador de la ventana
|
||||
Resource *resource; // Objeto con los recursos
|
||||
Asset *asset; // Objeto con los ficheros de recursos
|
||||
Input *input; // Objeto pata gestionar la entrada
|
||||
std::shared_ptr<Text> text; // Objeto para escribir texto en pantalla
|
||||
SDL_Texture *coverTexture; // Textura para cubrir el texto
|
||||
Screen *screen_; // Objeto encargado de dibujar en pantalla
|
||||
SDL_Renderer *renderer_; // El renderizador de la ventana
|
||||
Resource *resource_; // Objeto con los recursos
|
||||
Asset *asset_; // Objeto con los ficheros de recursos
|
||||
Input *input_; // Objeto pata gestionar la entrada
|
||||
std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
|
||||
SDL_Texture *cover_texture_; // Textura para cubrir el texto
|
||||
|
||||
// Variables
|
||||
int counter; // Contador
|
||||
int preCounter; // Contador previo
|
||||
int coverCounter; // Contador para la cortinilla
|
||||
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
|
||||
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
|
||||
std::vector<endingTexture_t> spriteTexts; // Vector con los sprites de texto con su cortinilla
|
||||
std::vector<endingTexture_t> spritePics; // Vector con los sprites de texto con su cortinilla
|
||||
int scene; // Escena actual
|
||||
std::vector<scene_t> scenes; // Vector con los textos e imagenes de cada escena
|
||||
int counter_; // Contador
|
||||
int pre_counter_; // Contador previo
|
||||
int cover_counter_; // Contador para la cortinilla
|
||||
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
|
||||
std::vector<EndingTexture> sprite_texts_; // Vector con los sprites de texto con su cortinilla
|
||||
std::vector<EndingTexture> sprite_pics_; // Vector con los sprites de texto con su cortinilla
|
||||
int current_scene_; // Escena actual
|
||||
std::vector<SceneData> scenes_; // Vector con los textos e imagenes de cada escena
|
||||
JA_Music_t *music; // Musica que suena durante el final
|
||||
|
||||
// Actualiza el objeto
|
||||
|
||||
@@ -21,40 +21,37 @@
|
||||
|
||||
// Constructor
|
||||
Ending2::Ending2()
|
||||
: screen(Screen::get()),
|
||||
renderer(Screen::get()->getRenderer()),
|
||||
resource(Resource::get()),
|
||||
asset(Asset::get()),
|
||||
input(Input::get())
|
||||
: screen_(Screen::get()),
|
||||
renderer_(Screen::get()->getRenderer()),
|
||||
resource_(Resource::get()),
|
||||
asset_(Asset::get()),
|
||||
input_(Input::get())
|
||||
{
|
||||
// Reserva memoria para los punteros a objetos
|
||||
text = resource->getText("smb2");
|
||||
music = resource->getMusic("ending2.ogg");
|
||||
text_ = resource_->getText("smb2");
|
||||
music_ = resource_->getMusic("ending2.ogg");
|
||||
|
||||
// Inicializa variables
|
||||
counterEnabled = false;
|
||||
preCounter = 0;
|
||||
postCounter = 0;
|
||||
postCounterEnabled = false;
|
||||
counter_enabled_ = false;
|
||||
pre_counter_ = 0;
|
||||
post_counter_ = 0;
|
||||
post_counter_enabled_ = false;
|
||||
options.section.section = Section::ENDING2;
|
||||
options.section.subsection = Subsection::NONE;
|
||||
ticks = 0;
|
||||
ticksSpeed = 15;
|
||||
distSpriteText = 8;
|
||||
distSpriteSprite = 0;
|
||||
despSpeed = -0.2f;
|
||||
firstCol = GAMECANVAS_FIRST_QUARTER_X + (GAMECANVAS_WIDTH / 16);
|
||||
secondCol = GAMECANVAS_THIRD_QUARTER_X - (GAMECANVAS_WIDTH / 16);
|
||||
ticks_ = 0;
|
||||
dist_sprite_text_ = 8;
|
||||
dist_sprite_sprite_ = 0;
|
||||
sprite_desp_speed_ = -0.2f;
|
||||
|
||||
// Inicializa el vector de colores
|
||||
const std::vector<std::string> color_list = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
|
||||
for (auto color : color_list)
|
||||
{
|
||||
colors.push_back(stringToColor(options.video.palette, color));
|
||||
colors_.push_back(stringToColor(options.video.palette, color));
|
||||
}
|
||||
|
||||
// Cambia el color del borde
|
||||
screen->setBorderColor(stringToColor(options.video.palette, "black"));
|
||||
screen_->setBorderColor(stringToColor(options.video.palette, "black"));
|
||||
|
||||
// Inicializa la lista de sprites
|
||||
iniSpriteList();
|
||||
@@ -76,10 +73,10 @@ Ending2::Ending2()
|
||||
void Ending2::update()
|
||||
{
|
||||
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
|
||||
if (SDL_GetTicks() - ticks > ticksSpeed)
|
||||
if (SDL_GetTicks() - ticks_ > GAME_SPEED)
|
||||
{
|
||||
// Actualiza el contador de ticks
|
||||
ticks = SDL_GetTicks();
|
||||
ticks_ = SDL_GetTicks();
|
||||
|
||||
// Comprueba las entradas
|
||||
checkInput();
|
||||
@@ -87,7 +84,7 @@ void Ending2::update()
|
||||
// Actualiza los contadores
|
||||
updateCounters();
|
||||
|
||||
if (counterEnabled)
|
||||
if (counter_enabled_)
|
||||
{
|
||||
// Actualiza los sprites
|
||||
updateSprites();
|
||||
@@ -105,7 +102,7 @@ void Ending2::update()
|
||||
// Actualiza el volumen de la musica
|
||||
updateMusicVolume();
|
||||
|
||||
screen->update();
|
||||
screen_->update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,10 +110,10 @@ void Ending2::update()
|
||||
void Ending2::render()
|
||||
{
|
||||
// Prepara para empezar a dibujar en la textura de juego
|
||||
screen->start();
|
||||
screen_->start();
|
||||
|
||||
// Limpia la pantalla
|
||||
screen->clean(stringToColor(options.video.palette, "black"));
|
||||
screen_->clean(stringToColor(options.video.palette, "black"));
|
||||
|
||||
// Dibuja los sprites
|
||||
renderSprites();
|
||||
@@ -127,7 +124,7 @@ void Ending2::render()
|
||||
// Dibuja los sprites con el texto del final
|
||||
renderTexts();
|
||||
|
||||
const std::string txt = std::to_string(postCounter);
|
||||
const std::string txt = std::to_string(post_counter_);
|
||||
// text->write(0, 192 - 8, txt);
|
||||
|
||||
// Dibuja la cuadricula
|
||||
@@ -147,24 +144,24 @@ void Ending2::render()
|
||||
|
||||
{
|
||||
// Dibuja una trama arriba y abajo
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xFF);
|
||||
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0xFF);
|
||||
for (int i = 0; i < 256; i += 2)
|
||||
{
|
||||
SDL_RenderDrawPoint(renderer, i + 0, 0);
|
||||
SDL_RenderDrawPoint(renderer, i + 1, 1);
|
||||
SDL_RenderDrawPoint(renderer, i + 0, 2);
|
||||
SDL_RenderDrawPoint(renderer, i + 1, 3);
|
||||
SDL_RenderDrawPoint(renderer_, i + 0, 0);
|
||||
SDL_RenderDrawPoint(renderer_, i + 1, 1);
|
||||
SDL_RenderDrawPoint(renderer_, i + 0, 2);
|
||||
SDL_RenderDrawPoint(renderer_, i + 1, 3);
|
||||
|
||||
SDL_RenderDrawPoint(renderer, i, 4);
|
||||
SDL_RenderDrawPoint(renderer, i, 6);
|
||||
SDL_RenderDrawPoint(renderer_, i, 4);
|
||||
SDL_RenderDrawPoint(renderer_, i, 6);
|
||||
|
||||
SDL_RenderDrawPoint(renderer, i + 0, 191);
|
||||
SDL_RenderDrawPoint(renderer, i + 1, 190);
|
||||
SDL_RenderDrawPoint(renderer, i + 0, 189);
|
||||
SDL_RenderDrawPoint(renderer, i + 1, 188);
|
||||
SDL_RenderDrawPoint(renderer_, i + 0, 191);
|
||||
SDL_RenderDrawPoint(renderer_, i + 1, 190);
|
||||
SDL_RenderDrawPoint(renderer_, i + 0, 189);
|
||||
SDL_RenderDrawPoint(renderer_, i + 1, 188);
|
||||
|
||||
SDL_RenderDrawPoint(renderer, i, 187);
|
||||
SDL_RenderDrawPoint(renderer, i, 185);
|
||||
SDL_RenderDrawPoint(renderer_, i, 187);
|
||||
SDL_RenderDrawPoint(renderer_, i, 185);
|
||||
}
|
||||
// SDL_RenderDrawLine(renderer, 0, 1, 255, 1);
|
||||
// SDL_RenderDrawLine(renderer, 0, 3, 255, 3);
|
||||
@@ -173,7 +170,7 @@ void Ending2::render()
|
||||
}
|
||||
|
||||
// Vuelca el contenido del renderizador en pantalla
|
||||
screen->render();
|
||||
screen_->render();
|
||||
}
|
||||
|
||||
// Comprueba el manejador de eventos
|
||||
@@ -195,7 +192,7 @@ void Ending2::checkInput()
|
||||
// Bucle principal
|
||||
void Ending2::run()
|
||||
{
|
||||
JA_PlayMusic(music);
|
||||
JA_PlayMusic(music_);
|
||||
|
||||
while (options.section.section == Section::ENDING2)
|
||||
{
|
||||
@@ -212,21 +209,21 @@ void Ending2::run()
|
||||
void Ending2::updateCounters()
|
||||
{
|
||||
// Incrementa el contador
|
||||
if (preCounter < 200)
|
||||
if (pre_counter_ < 200)
|
||||
{
|
||||
preCounter++;
|
||||
pre_counter_++;
|
||||
}
|
||||
else
|
||||
{
|
||||
counterEnabled = true;
|
||||
counter_enabled_ = true;
|
||||
}
|
||||
|
||||
if (postCounterEnabled)
|
||||
if (post_counter_enabled_)
|
||||
{
|
||||
postCounter++;
|
||||
post_counter_++;
|
||||
}
|
||||
|
||||
if (postCounter > 600)
|
||||
if (post_counter_ > 600)
|
||||
{
|
||||
options.section.section = Section::LOGO;
|
||||
options.section.subsection = Subsection::LOGO_TO_INTRO;
|
||||
@@ -237,100 +234,100 @@ void Ending2::updateCounters()
|
||||
void Ending2::iniSpriteList()
|
||||
{
|
||||
// Reinicia el vector
|
||||
spriteList.clear();
|
||||
sprite_list_.clear();
|
||||
|
||||
// Añade los valores
|
||||
spriteList.push_back("bin");
|
||||
spriteList.push_back("floppy");
|
||||
spriteList.push_back("bird");
|
||||
spriteList.push_back("chip");
|
||||
spriteList.push_back("jeannine");
|
||||
spriteList.push_back("spark");
|
||||
spriteList.push_back("code");
|
||||
spriteList.push_back("paco");
|
||||
spriteList.push_back("elsa");
|
||||
spriteList.push_back("z80");
|
||||
sprite_list_.push_back("bin");
|
||||
sprite_list_.push_back("floppy");
|
||||
sprite_list_.push_back("bird");
|
||||
sprite_list_.push_back("chip");
|
||||
sprite_list_.push_back("jeannine");
|
||||
sprite_list_.push_back("spark");
|
||||
sprite_list_.push_back("code");
|
||||
sprite_list_.push_back("paco");
|
||||
sprite_list_.push_back("elsa");
|
||||
sprite_list_.push_back("z80");
|
||||
|
||||
spriteList.push_back("bell");
|
||||
spriteList.push_back("dong");
|
||||
sprite_list_.push_back("bell");
|
||||
sprite_list_.push_back("dong");
|
||||
|
||||
spriteList.push_back("amstrad_cs");
|
||||
spriteList.push_back("breakout");
|
||||
sprite_list_.push_back("amstrad_cs");
|
||||
sprite_list_.push_back("breakout");
|
||||
|
||||
spriteList.push_back("flying_arounder");
|
||||
spriteList.push_back("stopped_arounder");
|
||||
spriteList.push_back("walking_arounder");
|
||||
spriteList.push_back("arounders_door");
|
||||
spriteList.push_back("arounders_machine");
|
||||
sprite_list_.push_back("flying_arounder");
|
||||
sprite_list_.push_back("stopped_arounder");
|
||||
sprite_list_.push_back("walking_arounder");
|
||||
sprite_list_.push_back("arounders_door");
|
||||
sprite_list_.push_back("arounders_machine");
|
||||
|
||||
spriteList.push_back("abad");
|
||||
spriteList.push_back("abad_bell");
|
||||
spriteList.push_back("lord_abad");
|
||||
sprite_list_.push_back("abad");
|
||||
sprite_list_.push_back("abad_bell");
|
||||
sprite_list_.push_back("lord_abad");
|
||||
|
||||
spriteList.push_back("bat");
|
||||
spriteList.push_back("batman_bell");
|
||||
spriteList.push_back("batman_fire");
|
||||
spriteList.push_back("batman");
|
||||
sprite_list_.push_back("bat");
|
||||
sprite_list_.push_back("batman_bell");
|
||||
sprite_list_.push_back("batman_fire");
|
||||
sprite_list_.push_back("batman");
|
||||
|
||||
spriteList.push_back("demon");
|
||||
spriteList.push_back("heavy");
|
||||
spriteList.push_back("dimallas");
|
||||
spriteList.push_back("guitar");
|
||||
sprite_list_.push_back("demon");
|
||||
sprite_list_.push_back("heavy");
|
||||
sprite_list_.push_back("dimallas");
|
||||
sprite_list_.push_back("guitar");
|
||||
|
||||
spriteList.push_back("jailbattle_alien");
|
||||
spriteList.push_back("jailbattle_human");
|
||||
sprite_list_.push_back("jailbattle_alien");
|
||||
sprite_list_.push_back("jailbattle_human");
|
||||
|
||||
spriteList.push_back("jailer_#1");
|
||||
spriteList.push_back("jailer_#2");
|
||||
spriteList.push_back("jailer_#3");
|
||||
spriteList.push_back("bry");
|
||||
spriteList.push_back("upv_student");
|
||||
sprite_list_.push_back("jailer_#1");
|
||||
sprite_list_.push_back("jailer_#2");
|
||||
sprite_list_.push_back("jailer_#3");
|
||||
sprite_list_.push_back("bry");
|
||||
sprite_list_.push_back("upv_student");
|
||||
|
||||
spriteList.push_back("lamp");
|
||||
spriteList.push_back("robot");
|
||||
spriteList.push_back("congo");
|
||||
spriteList.push_back("crosshair");
|
||||
spriteList.push_back("tree_thing");
|
||||
sprite_list_.push_back("lamp");
|
||||
sprite_list_.push_back("robot");
|
||||
sprite_list_.push_back("congo");
|
||||
sprite_list_.push_back("crosshair");
|
||||
sprite_list_.push_back("tree_thing");
|
||||
|
||||
spriteList.push_back("matatunos");
|
||||
spriteList.push_back("tuno");
|
||||
sprite_list_.push_back("matatunos");
|
||||
sprite_list_.push_back("tuno");
|
||||
|
||||
spriteList.push_back("mummy");
|
||||
spriteList.push_back("sam");
|
||||
sprite_list_.push_back("mummy");
|
||||
sprite_list_.push_back("sam");
|
||||
|
||||
spriteList.push_back("qvoid");
|
||||
spriteList.push_back("sigmasua");
|
||||
sprite_list_.push_back("qvoid");
|
||||
sprite_list_.push_back("sigmasua");
|
||||
|
||||
spriteList.push_back("tv_panel");
|
||||
spriteList.push_back("tv");
|
||||
sprite_list_.push_back("tv_panel");
|
||||
sprite_list_.push_back("tv");
|
||||
|
||||
spriteList.push_back("spider");
|
||||
spriteList.push_back("shock");
|
||||
spriteList.push_back("wave");
|
||||
sprite_list_.push_back("spider");
|
||||
sprite_list_.push_back("shock");
|
||||
sprite_list_.push_back("wave");
|
||||
|
||||
spriteList.push_back("player");
|
||||
sprite_list_.push_back("player");
|
||||
}
|
||||
|
||||
// Carga todos los sprites desde una lista
|
||||
void Ending2::loadSprites()
|
||||
{
|
||||
// Inicializa variables
|
||||
maxSpriteWidth = 0;
|
||||
maxSpriteHeight = 0;
|
||||
sprite_max_width_ = 0;
|
||||
sprite_max_height_ = 0;
|
||||
|
||||
// Carga los sprites
|
||||
for (auto sl : spriteList)
|
||||
for (auto sl : sprite_list_)
|
||||
{
|
||||
sprites.emplace_back(std::make_shared<AnimatedSprite>(resource->getTexture(sl + ".png"), resource->getAnimation(sl + ".ani")));
|
||||
maxSpriteWidth = std::max(sprites.back()->getWidth(), maxSpriteWidth);
|
||||
maxSpriteHeight = std::max(sprites.back()->getHeight(), maxSpriteHeight);
|
||||
sprites_.emplace_back(std::make_shared<AnimatedSprite>(resource_->getTexture(sl + ".png"), resource_->getAnimations(sl + ".ani")));
|
||||
sprite_max_width_ = std::max(sprites_.back()->getWidth(), sprite_max_width_);
|
||||
sprite_max_height_ = std::max(sprites_.back()->getHeight(), sprite_max_height_);
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza los sprites
|
||||
void Ending2::updateSprites()
|
||||
{
|
||||
for (auto sprite : sprites)
|
||||
for (auto sprite : sprites_)
|
||||
{
|
||||
sprite->update();
|
||||
}
|
||||
@@ -339,7 +336,7 @@ void Ending2::updateSprites()
|
||||
// Actualiza los sprites de texto
|
||||
void Ending2::updateTextSprites()
|
||||
{
|
||||
for (auto sprite : spriteTexts)
|
||||
for (auto sprite : sprite_texts_)
|
||||
{
|
||||
sprite->update();
|
||||
}
|
||||
@@ -348,16 +345,16 @@ void Ending2::updateTextSprites()
|
||||
// Actualiza los sprites de texto del final
|
||||
void Ending2::updateTexts()
|
||||
{
|
||||
if (texts.back()->getPosY() > GAMECANVAS_CENTER_Y)
|
||||
if (texts_.back()->getPosY() > GAMECANVAS_CENTER_Y)
|
||||
{
|
||||
for (auto sprite : texts)
|
||||
for (auto sprite : texts_)
|
||||
{
|
||||
sprite->update();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
postCounterEnabled = true;
|
||||
post_counter_enabled_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,7 +362,7 @@ void Ending2::updateTexts()
|
||||
void Ending2::renderSprites()
|
||||
{
|
||||
const Color color = stringToColor(options.video.palette, "red");
|
||||
for (auto sprite : sprites)
|
||||
for (auto sprite : sprites_)
|
||||
{
|
||||
const bool a = sprite->getRect().y + sprite->getRect().h > 0;
|
||||
const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT;
|
||||
@@ -378,15 +375,15 @@ void Ending2::renderSprites()
|
||||
|
||||
// Pinta el ultimo elemento de otro color
|
||||
const Color c = stringToColor(options.video.palette, "white");
|
||||
sprites.back()->getTexture()->setColor(c.r, c.g, c.b);
|
||||
sprites.back()->render();
|
||||
sprites_.back()->getTexture()->setColor(c.r, c.g, c.b);
|
||||
sprites_.back()->render();
|
||||
}
|
||||
|
||||
// Dibuja los sprites con el texto
|
||||
void Ending2::renderSpriteTexts()
|
||||
{
|
||||
const Color color = stringToColor(options.video.palette, "white");
|
||||
for (auto sprite : spriteTexts)
|
||||
for (auto sprite : sprite_texts_)
|
||||
{
|
||||
const bool a = sprite->getRect().y + sprite->getRect().h > 0;
|
||||
const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT;
|
||||
@@ -401,7 +398,7 @@ void Ending2::renderSpriteTexts()
|
||||
// Dibuja los sprites con el texto del final
|
||||
void Ending2::renderTexts()
|
||||
{
|
||||
for (auto sprite : texts)
|
||||
for (auto sprite : texts_)
|
||||
{
|
||||
const bool a = sprite->getRect().y + sprite->getRect().h > 0;
|
||||
const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT;
|
||||
@@ -415,58 +412,58 @@ void Ending2::renderTexts()
|
||||
// Coloca los sprites en su sito
|
||||
void Ending2::placeSprites()
|
||||
{
|
||||
for (int i = 0; i < (int)sprites.size(); ++i)
|
||||
for (int i = 0; i < (int)sprites_.size(); ++i)
|
||||
{
|
||||
const int x = i % 2 == 0 ? firstCol : secondCol;
|
||||
const int y = (i / 1) * (maxSpriteHeight + distSpriteText + text->getCharacterSize() + distSpriteSprite) + GAMECANVAS_HEIGHT + 40;
|
||||
const int w = sprites[i]->getWidth();
|
||||
const int h = sprites[i]->getHeight();
|
||||
const int x = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_;
|
||||
const int y = (i / 1) * (sprite_max_height_ + dist_sprite_text_ + text_->getCharacterSize() + dist_sprite_sprite_) + GAMECANVAS_HEIGHT + 40;
|
||||
const int w = sprites_[i]->getWidth();
|
||||
const int h = sprites_[i]->getHeight();
|
||||
const int dx = -(w / 2);
|
||||
const int dy = i % 1 == 0 ? maxSpriteHeight - h : (int)(maxSpriteHeight * 1.5f) - h;
|
||||
const int dy = i % 1 == 0 ? sprite_max_height_ - h : (int)(sprite_max_height_ * 1.5f) - h;
|
||||
|
||||
sprites[i]->setPosition({x + dx, y + dy, w, h});
|
||||
sprites[i]->setVelY(despSpeed);
|
||||
sprites_[i]->setPosition({x + dx, y + dy, w, h});
|
||||
sprites_[i]->setVelY(sprite_desp_speed_);
|
||||
}
|
||||
|
||||
// Recoloca el último sprite, que es el del jugador
|
||||
const int w = sprites.back()->getWidth();
|
||||
const int w = sprites_.back()->getWidth();
|
||||
const int x = GAMECANVAS_CENTER_X - (w / 2);
|
||||
const int y = sprites.back()->getPosY() + maxSpriteHeight * 2;
|
||||
sprites.back()->setPosX(x);
|
||||
sprites.back()->setPosY(y);
|
||||
sprites.back()->setCurrentAnimation("walk");
|
||||
const int y = sprites_.back()->getPosY() + sprite_max_height_ * 2;
|
||||
sprites_.back()->setPosX(x);
|
||||
sprites_.back()->setPosY(y);
|
||||
sprites_.back()->setCurrentAnimation("walk");
|
||||
}
|
||||
|
||||
// Crea los sprites con las texturas con los textos
|
||||
void Ending2::createSpriteTexts()
|
||||
{
|
||||
// Crea los sprites de texto a partir de la lista
|
||||
for (int i = 0; i < (int)spriteList.size(); ++i)
|
||||
for (int i = 0; i < (int)sprite_list_.size(); ++i)
|
||||
{
|
||||
// Calcula constantes
|
||||
std::string txt = spriteList[i];
|
||||
std::string txt = sprite_list_[i];
|
||||
std::replace(txt.begin(), txt.end(), '_', ' ');
|
||||
txt = txt == "player" ? "JAILDOCTOR" : txt; // Reemplaza el texto
|
||||
const int w = text->lenght(txt, 1);
|
||||
const int h = text->getCharacterSize();
|
||||
const int x = i % 2 == 0 ? firstCol : secondCol;
|
||||
const int w = text_->lenght(txt, 1);
|
||||
const int h = text_->getCharacterSize();
|
||||
const int x = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_;
|
||||
const int dx = -(w / 2);
|
||||
const int y = sprites[i]->getPosY() + sprites[i]->getHeight() + distSpriteText;
|
||||
const int y = sprites_[i]->getPosY() + sprites_[i]->getHeight() + dist_sprite_text_;
|
||||
|
||||
// Cambia la posición del último sprite
|
||||
const int X = (i == (int)spriteList.size() - 1) ? GAMECANVAS_CENTER_X - (w / 2) : x + dx;
|
||||
const int X = (i == (int)sprite_list_.size() - 1) ? GAMECANVAS_CENTER_X - (w / 2) : x + dx;
|
||||
|
||||
// Crea la textura
|
||||
auto texture = std::make_shared<Texture>(renderer);
|
||||
auto texture = std::make_shared<Texture>(renderer_);
|
||||
texture->createBlank(w, h);
|
||||
texture->setAsRenderTarget(renderer);
|
||||
texture->setAsRenderTarget(renderer_);
|
||||
texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||
text->write(0, 0, txt);
|
||||
text_->write(0, 0, txt);
|
||||
|
||||
// Crea el sprite
|
||||
SDL_Rect pos = {X, y, w, h};
|
||||
spriteTexts.emplace_back(std::make_shared<MovingSprite>(texture, pos));
|
||||
spriteTexts.back()->setVelY(despSpeed);
|
||||
sprite_texts_.emplace_back(std::make_shared<MovingSprite>(texture, pos));
|
||||
sprite_texts_.back()->setVelY(sprite_desp_speed_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,28 +478,28 @@ void Ending2::createTexts()
|
||||
for (int i = 0; i < (int)list.size(); ++i)
|
||||
{
|
||||
// Calcula constantes
|
||||
const int w = text->lenght(list[i], 1);
|
||||
const int h = text->getCharacterSize();
|
||||
const int w = text_->lenght(list[i], 1);
|
||||
const int h = text_->getCharacterSize();
|
||||
const int x = GAMECANVAS_CENTER_X;
|
||||
const int dx = -(w / 2);
|
||||
const int y = GAMECANVAS_HEIGHT + (text->getCharacterSize() * (i * 2));
|
||||
const int y = GAMECANVAS_HEIGHT + (text_->getCharacterSize() * (i * 2));
|
||||
|
||||
// Crea la textura
|
||||
auto texture = std::make_shared<Texture>(renderer);
|
||||
auto texture = std::make_shared<Texture>(renderer_);
|
||||
texture->createBlank(w, h);
|
||||
texture->setAsRenderTarget(renderer);
|
||||
texture->setAsRenderTarget(renderer_);
|
||||
texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||
text->write(0, 0, list[i]);
|
||||
text_->write(0, 0, list[i]);
|
||||
|
||||
// Crea el sprite
|
||||
SDL_Rect pos = {x + dx, y, w, h};
|
||||
texts.emplace_back(std::make_shared<MovingSprite>(texture, pos));
|
||||
texts.back()->setVelY(despSpeed);
|
||||
texts_.emplace_back(std::make_shared<MovingSprite>(texture, pos));
|
||||
texts_.back()->setVelY(sprite_desp_speed_);
|
||||
}
|
||||
|
||||
// Crea los últimos textos
|
||||
// El primer texto va a continuación del ultimo spriteText
|
||||
const int start = spriteTexts.back()->getPosY() + text->getCharacterSize() * 15;
|
||||
const int start = sprite_texts_.back()->getPosY() + text_->getCharacterSize() * 15;
|
||||
list.clear();
|
||||
list.push_back("THANK YOU");
|
||||
list.push_back("FOR PLAYING!");
|
||||
@@ -511,23 +508,23 @@ void Ending2::createTexts()
|
||||
for (int i = 0; i < (int)list.size(); ++i)
|
||||
{
|
||||
// Calcula constantes
|
||||
const int w = text->lenght(list[i], 1);
|
||||
const int h = text->getCharacterSize();
|
||||
const int w = text_->lenght(list[i], 1);
|
||||
const int h = text_->getCharacterSize();
|
||||
const int x = GAMECANVAS_CENTER_X;
|
||||
const int dx = -(w / 2);
|
||||
const int y = start + (text->getCharacterSize() * (i * 2));
|
||||
const int y = start + (text_->getCharacterSize() * (i * 2));
|
||||
|
||||
// Crea la textura
|
||||
auto texture = std::make_shared<Texture>(renderer);
|
||||
auto texture = std::make_shared<Texture>(renderer_);
|
||||
texture->createBlank(w, h);
|
||||
texture->setAsRenderTarget(renderer);
|
||||
texture->setAsRenderTarget(renderer_);
|
||||
texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||
text->write(0, 0, list[i]);
|
||||
text_->write(0, 0, list[i]);
|
||||
|
||||
// Crea el sprite
|
||||
SDL_Rect pos = {x + dx, y, w, h};
|
||||
texts.emplace_back(std::make_shared<MovingSprite>(texture, pos));
|
||||
texts.back()->setVelY(despSpeed);
|
||||
texts_.emplace_back(std::make_shared<MovingSprite>(texture, pos));
|
||||
texts_.back()->setVelY(sprite_desp_speed_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,21 +532,21 @@ void Ending2::createTexts()
|
||||
void Ending2::updateFinalFade()
|
||||
{
|
||||
// La variable step va de 0 a 40 en el tramo de postCounter que va de 500 a 540. Al dividirlo por 40, va de 0.0f a 1.0f
|
||||
const float step = std::min(std::max(postCounter, 500) - 500, 40) / 40.0f;
|
||||
const int index = (colors.size() - 1) * step;
|
||||
const float step = std::min(std::max(post_counter_, 500) - 500, 40) / 40.0f;
|
||||
const int index = (colors_.size() - 1) * step;
|
||||
|
||||
for (auto t : texts)
|
||||
for (auto t : texts_)
|
||||
{
|
||||
t->getTexture()->setColor(colors[index].r, colors[index].g, colors[index].b);
|
||||
t->getTexture()->setColor(colors_[index].r, colors_[index].g, colors_[index].b);
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza el volumen de la musica
|
||||
void Ending2::updateMusicVolume()
|
||||
{
|
||||
if (postCounter > 0)
|
||||
if (post_counter_ > 0)
|
||||
{
|
||||
const float step = (600.0f - postCounter) / 600.0f;
|
||||
const float step = (600.0f - post_counter_) / 600.0f;
|
||||
const int volume = 128 * step;
|
||||
JA_SetVolume(volume);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <string> // for string
|
||||
#include <vector> // for vector
|
||||
#include "utils.h" // for Color
|
||||
#include "defines.h" // for GAMECANVAS_FIRST_QUARTER_X, GAMECANVAS_THIRD_QUARTER_X, GAMECANVAS_WIDTH
|
||||
class AnimatedSprite; // lines 9-9
|
||||
class Asset; // lines 10-10
|
||||
class Input; // lines 11-11
|
||||
@@ -18,34 +19,35 @@ struct JA_Music_t; // lines 16-16
|
||||
class Ending2
|
||||
{
|
||||
private:
|
||||
// Constantes
|
||||
static constexpr int FIRST_COL_ = GAMECANVAS_FIRST_QUARTER_X + (GAMECANVAS_WIDTH / 16); // Primera columna por donde desfilan los sprites
|
||||
static constexpr int SECOND_COL_ = GAMECANVAS_THIRD_QUARTER_X - (GAMECANVAS_WIDTH / 16); // Segunda columna por donde desfilan los sprites
|
||||
|
||||
// Objetos y punteros
|
||||
Screen *screen; // Objeto encargado de dibujar en pantalla
|
||||
SDL_Renderer *renderer; // El renderizador de la ventana
|
||||
Resource *resource; // Objeto con los recursos
|
||||
Asset *asset; // Objeto con los ficheros de recursos
|
||||
Input *input; // Objeto pata gestionar la entrada
|
||||
std::shared_ptr<Text> text; // Objeto para escribir texto en pantalla
|
||||
std::vector<std::shared_ptr<AnimatedSprite>> sprites; // Vector con todos los sprites a dibujar
|
||||
std::vector<std::shared_ptr<MovingSprite>> spriteTexts; // Vector con los sprites de texto de los sprites
|
||||
std::vector<std::shared_ptr<MovingSprite>> texts; // Vector con los sprites de texto
|
||||
Screen *screen_; // Objeto encargado de dibujar en pantalla
|
||||
SDL_Renderer *renderer_; // El renderizador de la ventana
|
||||
Resource *resource_; // Objeto con los recursos
|
||||
Asset *asset_; // Objeto con los ficheros de recursos
|
||||
Input *input_; // Objeto pata gestionar la entrada
|
||||
std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
|
||||
std::vector<std::shared_ptr<AnimatedSprite>> sprites_; // Vector con todos los sprites a dibujar
|
||||
std::vector<std::shared_ptr<MovingSprite>> sprite_texts_; // Vector con los sprites de texto de los sprites
|
||||
std::vector<std::shared_ptr<MovingSprite>> texts_; // Vector con los sprites de texto
|
||||
|
||||
// Variables
|
||||
bool counterEnabled; // Indica si está el contador habilitado
|
||||
int preCounter; // Contador previo
|
||||
int postCounter; // Contador posterior
|
||||
bool postCounterEnabled; // Indica si está habilitado el contador
|
||||
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
|
||||
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
|
||||
JA_Music_t *music; // Musica que suena durante el final
|
||||
std::vector<std::string> spriteList; // Lista con todos los sprites a dibujar
|
||||
std::vector<Color> colors; // Vector con los colores para el fade
|
||||
int maxSpriteWidth; // El valor de ancho del sprite mas ancho
|
||||
int maxSpriteHeight; // El valor de alto del sprite mas alto
|
||||
int distSpriteText; // Distancia entre el sprite y el texto que lo acompaña
|
||||
int distSpriteSprite; // Distancia entre dos sprites de la misma columna
|
||||
float despSpeed; // Velocidad de desplazamiento de los sprites
|
||||
int firstCol; // Primera columna por donde desfilan los sprites
|
||||
int secondCol; // Segunda columna por donde desfilan los sprites
|
||||
bool counter_enabled_; // Indica si está el contador habilitado
|
||||
int pre_counter_; // Contador previo
|
||||
int post_counter_; // Contador posterior
|
||||
bool post_counter_enabled_; // Indica si está habilitado el contador
|
||||
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
|
||||
JA_Music_t *music_; // Musica que suena durante el final
|
||||
std::vector<std::string> sprite_list_; // Lista con todos los sprites a dibujar
|
||||
std::vector<Color> colors_; // Vector con los colores para el fade
|
||||
int sprite_max_width_; // El valor de ancho del sprite mas ancho
|
||||
int sprite_max_height_; // El valor de alto del sprite mas alto
|
||||
int dist_sprite_text_; // Distancia entre el sprite y el texto que lo acompaña
|
||||
int dist_sprite_sprite_; // Distancia entre dos sprites de la misma columna
|
||||
float sprite_desp_speed_; // Velocidad de desplazamiento de los sprites
|
||||
|
||||
// Actualiza el objeto
|
||||
void update();
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
Enemy::Enemy(EnemyData enemy)
|
||||
{
|
||||
// Crea objetos
|
||||
sprite_ = std::make_shared<AnimatedSprite>(Resource::get()->getTexture(enemy.texture_path), Resource::get()->getAnimation(enemy.animation_path));
|
||||
sprite_ = std::make_shared<AnimatedSprite>(Resource::get()->getTexture(enemy.texture_path), Resource::get()->getAnimations(enemy.animation_path));
|
||||
|
||||
// Obten el resto de valores
|
||||
x1_ = enemy.x1;
|
||||
|
||||
117
source/game.cpp
117
source/game.cpp
@@ -24,6 +24,7 @@
|
||||
#include "notifier.h"
|
||||
#include "global_inputs.h"
|
||||
#include "global_events.h"
|
||||
//#include "surface.h"
|
||||
|
||||
// Constructor
|
||||
Game::Game()
|
||||
@@ -36,32 +37,34 @@ Game::Game()
|
||||
cheevos_(Cheevos::get())
|
||||
{
|
||||
// Inicia algunas variables
|
||||
board_.iniClock = SDL_GetTicks();
|
||||
//test_surface_ = std::make_shared<Surface>(Screen::get()->getSurface(), "test.gif");
|
||||
board_ = std::make_shared<ScoreboardData>();
|
||||
board_->ini_clock = SDL_GetTicks();
|
||||
#ifdef DEBUG
|
||||
current_room_ = "03.room";
|
||||
const int x = 25;
|
||||
const int y = 13;
|
||||
spawn_point_ = {x * 8, y * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL};
|
||||
constexpr int X = 25;
|
||||
constexpr int Y = 13;
|
||||
spawn_point_ = PlayerSpawn(X * 8, Y * 8, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL);
|
||||
debug_->setEnabled(false);
|
||||
#else
|
||||
current_room_ = "03.room";
|
||||
const int x = 25;
|
||||
const int y = 13;
|
||||
spawn_point_ = {x * 8, y * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL};
|
||||
constexpr int X = 25;
|
||||
constexpr int Y = 13;
|
||||
spawn_point_ = PlayerSpawn(X * 8, Y * 8, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL);
|
||||
#endif
|
||||
|
||||
// Crea los objetos
|
||||
scoreboard_ = std::make_shared<Scoreboard>(&board_);
|
||||
item_tracker_ = std::make_shared<ItemTracker>();
|
||||
ItemTracker::init();
|
||||
scoreboard_ = std::make_shared<Scoreboard>(board_);
|
||||
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_};
|
||||
room_ = std::make_shared<Room>(resource_->getRoom(current_room_), board_);
|
||||
std::string player_texture = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png";
|
||||
std::string player_animations = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani";
|
||||
const PlayerData player(spawn_point_, player_texture, player_animations, room_);
|
||||
player_ = std::make_shared<Player>(player);
|
||||
text_ = resource_->getText("smb2");
|
||||
music_ = resource_->getMusic("game.ogg");
|
||||
death_sound_ = JA_LoadSound(asset_->get("death.wav").c_str());
|
||||
death_sound_ = resource_->getSound("death.wav");
|
||||
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
|
||||
@@ -85,15 +88,14 @@ Game::Game()
|
||||
|
||||
// Inicializa el resto de variables
|
||||
ticks_ = 0;
|
||||
ticks_speed_ = 15;
|
||||
board_.lives = 9;
|
||||
board_->lives = 9;
|
||||
#ifdef DEBUG
|
||||
board_.lives = 9;
|
||||
board_->lives = 9;
|
||||
#endif
|
||||
board_.items = 0;
|
||||
board_.rooms = 1;
|
||||
board_.music = true;
|
||||
board_.jail_is_open = options.cheats.jail_is_open == Cheat::CheatState::ENABLED;
|
||||
board_->items = 0;
|
||||
board_->rooms = 1;
|
||||
board_->music = true;
|
||||
board_->jail_is_open = options.cheats.jail_is_open == Cheat::CheatState::ENABLED;
|
||||
setScoreBoardColor();
|
||||
room_tracker_->addRoom(current_room_);
|
||||
paused_ = false;
|
||||
@@ -110,7 +112,7 @@ Game::Game()
|
||||
|
||||
Game::~Game()
|
||||
{
|
||||
// Libera la memoria de los objetos
|
||||
ItemTracker::destroy();
|
||||
SDL_DestroyTexture(room_name_texture_);
|
||||
}
|
||||
|
||||
@@ -130,8 +132,8 @@ void Game::checkEvents()
|
||||
case SDL_SCANCODE_G:
|
||||
debug_->switchEnabled();
|
||||
options.cheats.invincible = static_cast<Cheat::CheatState>(debug_->getEnabled());
|
||||
board_.music = !debug_->getEnabled();
|
||||
board_.music ? JA_ResumeMusic() : JA_PauseMusic();
|
||||
board_->music = !debug_->getEnabled();
|
||||
board_->music ? JA_ResumeMusic() : JA_PauseMusic();
|
||||
break;
|
||||
|
||||
case SDL_SCANCODE_R:
|
||||
@@ -155,19 +157,19 @@ void Game::checkEvents()
|
||||
break;
|
||||
|
||||
case SDL_SCANCODE_F6:
|
||||
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS"}, 2);
|
||||
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS"}, NotificationText::LEFT, 2, false, "F6");
|
||||
break;
|
||||
|
||||
case SDL_SCANCODE_F7:
|
||||
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS"}, 3);
|
||||
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS"}, NotificationText::LEFT, 3, false, "F7");
|
||||
break;
|
||||
|
||||
case SDL_SCANCODE_F8:
|
||||
Notifier::get()->show({"JAILDESIGNER IS LOGGED IN", ""}, 4);
|
||||
Notifier::get()->show({"JAILDESIGNER", "IS LOGGED IN"}, NotificationText::LEFT, 4, false);
|
||||
break;
|
||||
|
||||
case SDL_SCANCODE_F9:
|
||||
Notifier::get()->show({"JAILDESIGNER IS LOGGED IN", ""}, 5);
|
||||
Notifier::get()->show({"JAILDESIGNER", "IS LOGGED IN"}, NotificationText::LEFT, 5, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -182,13 +184,15 @@ void Game::checkInput()
|
||||
{
|
||||
if (input_->checkInput(input_toggle_music, REPEAT_FALSE))
|
||||
{
|
||||
board_.music = !board_.music;
|
||||
board_.music ? JA_ResumeMusic() : JA_PauseMusic();
|
||||
board_->music = !board_->music;
|
||||
board_->music ? JA_ResumeMusic() : JA_PauseMusic();
|
||||
Notifier::get()->show({"MUSIC " + std::string(board_->music ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
|
||||
}
|
||||
|
||||
else if (input_->checkInput(input_pause, REPEAT_FALSE))
|
||||
{
|
||||
switchPause();
|
||||
Notifier::get()->show({std::string(paused_ ? "GAME PAUSED" : "GAME RUNNING")}, NotificationText::CENTER);
|
||||
}
|
||||
|
||||
globalInputs::check();
|
||||
@@ -198,7 +202,7 @@ void Game::checkInput()
|
||||
void Game::run()
|
||||
{
|
||||
JA_PlayMusic(music_);
|
||||
if (!board_.music)
|
||||
if (!board_->music)
|
||||
{
|
||||
JA_PauseMusic();
|
||||
}
|
||||
@@ -217,7 +221,7 @@ void Game::run()
|
||||
void Game::update()
|
||||
{
|
||||
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
|
||||
if (SDL_GetTicks() - ticks_ > ticks_speed_)
|
||||
if (SDL_GetTicks() - ticks_ > GAME_SPEED)
|
||||
{
|
||||
// Actualiza el contador de ticks
|
||||
ticks_ = SDL_GetTicks();
|
||||
@@ -258,6 +262,7 @@ void Game::render()
|
||||
{
|
||||
// Prepara para dibujar el frame
|
||||
screen_->start();
|
||||
//test_surface_->render(0, 0, 10, 10, 64, 64);
|
||||
|
||||
// Dibuja los elementos del juego en orden
|
||||
room_->renderMap();
|
||||
@@ -283,7 +288,7 @@ 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("STATE = " + std::to_string(static_cast<int>(player_->state_)));
|
||||
}
|
||||
|
||||
// Pone la información de debug en pantalla
|
||||
@@ -336,7 +341,7 @@ bool Game::changeRoom(std::string file)
|
||||
if (asset_->get(file) != "")
|
||||
{
|
||||
// Crea un objeto habitación nuevo a partir del fichero
|
||||
room_ = std::make_shared<Room>(resource_->getRoom(file), item_tracker_, &board_.items, board_.jail_is_open);
|
||||
room_ = std::make_shared<Room>(resource_->getRoom(file), board_);
|
||||
|
||||
// Pone el nombre de la habitación en la textura
|
||||
fillRoomNameTexture();
|
||||
@@ -347,8 +352,8 @@ bool Game::changeRoom(std::string file)
|
||||
if (room_tracker_->addRoom(file))
|
||||
{
|
||||
// Incrementa el contador de habitaciones visitadas
|
||||
board_.rooms++;
|
||||
options.stats.rooms = board_.rooms;
|
||||
board_->rooms++;
|
||||
options.stats.rooms = board_->rooms;
|
||||
|
||||
// Actualiza las estadisticas
|
||||
stats_->addVisit(room_->getName());
|
||||
@@ -407,7 +412,7 @@ void Game::checkIfPlayerIsAlive()
|
||||
// Comprueba si ha terminado la partida
|
||||
void Game::checkGameOver()
|
||||
{
|
||||
if (board_.lives < 0 && black_screen_counter_ > 17)
|
||||
if (board_->lives < 0 && black_screen_counter_ > 17)
|
||||
{
|
||||
options.section.section = Section::GAME_OVER;
|
||||
}
|
||||
@@ -424,7 +429,7 @@ void Game::killPlayer()
|
||||
// Resta una vida al jugador
|
||||
if (options.cheats.infinite_lives == Cheat::CheatState::DISABLED)
|
||||
{
|
||||
--board_.lives;
|
||||
--board_->lives;
|
||||
}
|
||||
|
||||
// Actualiza las estadisticas
|
||||
@@ -440,10 +445,10 @@ void Game::killPlayer()
|
||||
setBlackScreen();
|
||||
|
||||
// Crea la nueva habitación y el nuevo jugador
|
||||
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_};
|
||||
room_ = std::make_shared<Room>(resource_->getRoom(current_room_), board_);
|
||||
std::string player_texture = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png";
|
||||
std::string player_animations = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani";
|
||||
const PlayerData player(spawn_point_, player_texture, player_animations, room_);
|
||||
player_ = std::make_shared<Player>(player);
|
||||
|
||||
// Pone los objetos en pausa mientras esta la habitación en negro
|
||||
@@ -508,19 +513,19 @@ void Game::setScoreBoardColor()
|
||||
const bool isBrightBlack = colorAreEqual(colorBorder, stringToColor(options.video.palette, "bright_black"));
|
||||
|
||||
// Si el color del borde es negro o negro brillante cambia el texto del marcador a blanco
|
||||
board_.color = isBlack || isBrightBlack ? stringToColor(options.video.palette, "white") : colorBorder;
|
||||
board_->color = isBlack || isBrightBlack ? stringToColor(options.video.palette, "white") : colorBorder;
|
||||
}
|
||||
|
||||
// Comprueba si ha finalizado el juego
|
||||
bool Game::checkEndGame()
|
||||
{
|
||||
const bool isOnTheRoom = room_->getName() == "THE JAIL"; // Estar en la habitación que toca
|
||||
const bool haveTheItems = board_.items >= int(total_items_ * 0.9f) || options.cheats.jail_is_open == Cheat::CheatState::ENABLED; // Con mas del 90% de los items recogidos
|
||||
const bool haveTheItems = board_->items >= int(total_items_ * 0.9f) || options.cheats.jail_is_open == Cheat::CheatState::ENABLED; // Con mas del 90% de los items recogidos
|
||||
const bool isOnTheDoor = player_->getRect().x <= 128; // Y en la ubicación que toca (En la puerta)
|
||||
|
||||
if (haveTheItems)
|
||||
{
|
||||
board_.jail_is_open = true;
|
||||
board_->jail_is_open = true;
|
||||
}
|
||||
|
||||
if (haveTheItems && isOnTheRoom && isOnTheDoor)
|
||||
@@ -581,7 +586,7 @@ void Game::switchPause()
|
||||
// Da vidas al jugador cuando está en la Jail
|
||||
void Game::checkRestoringJail()
|
||||
{
|
||||
if (room_->getName() != "THE JAIL" || board_.lives == 9)
|
||||
if (room_->getName() != "THE JAIL" || board_->lives == 9)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -597,11 +602,11 @@ void Game::checkRestoringJail()
|
||||
if (counter == 100)
|
||||
{
|
||||
counter = 0;
|
||||
board_.lives++;
|
||||
board_->lives++;
|
||||
JA_PlaySound(death_sound_);
|
||||
|
||||
// Invalida el logro de completar el juego sin entrar a la jail
|
||||
const bool haveTheItems = board_.items >= int(total_items_ * 0.9f);
|
||||
const bool haveTheItems = board_->items >= int(total_items_ * 0.9f);
|
||||
if (!haveTheItems)
|
||||
{
|
||||
cheevos_->invalidate(9);
|
||||
@@ -644,42 +649,42 @@ void Game::fillRoomNameTexture()
|
||||
void Game::checkSomeCheevos()
|
||||
{
|
||||
// Logros sobre la cantidad de items
|
||||
if (board_.items == total_items_)
|
||||
if (board_->items == total_items_)
|
||||
{
|
||||
cheevos_->unlock(4);
|
||||
cheevos_->unlock(3);
|
||||
cheevos_->unlock(2);
|
||||
cheevos_->unlock(1);
|
||||
}
|
||||
else if (board_.items >= total_items_ * 0.75f)
|
||||
else if (board_->items >= total_items_ * 0.75f)
|
||||
{
|
||||
cheevos_->unlock(3);
|
||||
cheevos_->unlock(2);
|
||||
cheevos_->unlock(1);
|
||||
}
|
||||
else if (board_.items >= total_items_ * 0.5f)
|
||||
else if (board_->items >= total_items_ * 0.5f)
|
||||
{
|
||||
cheevos_->unlock(2);
|
||||
cheevos_->unlock(1);
|
||||
}
|
||||
else if (board_.items >= total_items_ * 0.25f)
|
||||
else if (board_->items >= total_items_ * 0.25f)
|
||||
{
|
||||
cheevos_->unlock(1);
|
||||
}
|
||||
|
||||
// Logros sobre las habitaciones visitadas
|
||||
if (board_.rooms >= 60)
|
||||
if (board_->rooms >= 60)
|
||||
{
|
||||
cheevos_->unlock(7);
|
||||
cheevos_->unlock(6);
|
||||
cheevos_->unlock(5);
|
||||
}
|
||||
else if (board_.rooms >= 40)
|
||||
else if (board_->rooms >= 40)
|
||||
{
|
||||
cheevos_->unlock(6);
|
||||
cheevos_->unlock(5);
|
||||
}
|
||||
else if (board_.rooms >= 20)
|
||||
else if (board_->rooms >= 20)
|
||||
{
|
||||
cheevos_->unlock(5);
|
||||
}
|
||||
@@ -695,7 +700,7 @@ void Game::checkEndGameCheevos()
|
||||
cheevos_->unlock(9);
|
||||
|
||||
// "Complete the game with all items"
|
||||
if (board_.items == total_items_)
|
||||
if (board_->items == total_items_)
|
||||
{
|
||||
cheevos_->unlock(10);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "player.h" // Para playerSpawn_t
|
||||
#include "scoreboard.h" // Para board_t
|
||||
#include "room.h"
|
||||
//#include "surface.h"
|
||||
class Asset;
|
||||
class Cheevos;
|
||||
class Debug;
|
||||
@@ -37,21 +38,20 @@ private:
|
||||
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
|
||||
//std::shared_ptr<Surface> test_surface_;
|
||||
|
||||
// Variables
|
||||
JA_Music_t *music_; // Musica que suena durante el juego
|
||||
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
|
||||
Uint32 ticks_speed_; // Velocidad a la que se repiten los bucles del programa
|
||||
std::string current_room_; // Fichero de la habitación actual
|
||||
playerSpawn_t spawn_point_; // Lugar de la habitación donde aparece el jugador
|
||||
PlayerSpawn spawn_point_; // Lugar de la habitación donde aparece el jugador
|
||||
JA_Sound_t *death_sound_; // Sonido a reproducir cuando muere el jugador
|
||||
board_t board_; // Estructura con los datos del marcador
|
||||
std::shared_ptr<ScoreboardData> board_; // Estructura con los datos del marcador
|
||||
bool paused_; // Indica si el juego se encuentra en pausa
|
||||
bool black_screen_; // Indica si la pantalla está en negro. Se utiliza para la muerte del jugador
|
||||
int black_screen_counter_; // Contador para temporizar la pantalla en negro
|
||||
|
||||
@@ -18,50 +18,46 @@
|
||||
|
||||
// Constructor
|
||||
GameOver::GameOver()
|
||||
: screen(Screen::get()),
|
||||
renderer(Screen::get()->getRenderer()),
|
||||
resource(Resource::get()),
|
||||
asset(Asset::get()),
|
||||
input(Input::get())
|
||||
: screen_(Screen::get()),
|
||||
renderer_(Screen::get()->getRenderer()),
|
||||
resource_(Resource::get()),
|
||||
asset_(Asset::get()),
|
||||
input_(Input::get())
|
||||
{
|
||||
// Reserva memoria para los punteros a objetos
|
||||
text = resource->getText("smb2");
|
||||
playerSprite = std::make_shared<AnimatedSprite>(resource->getTexture("player_game_over.png"), resource->getAnimation("player_game_over.ani"));
|
||||
tvSprite = std::make_shared<AnimatedSprite>(resource->getTexture("tv.png"), resource->getAnimation("tv.ani"));
|
||||
music = resource->getMusic("game_over.ogg");
|
||||
text_ = resource_->getText("smb2");
|
||||
player_sprite_ = std::make_shared<AnimatedSprite>(resource_->getTexture("player_game_over.png"), resource_->getAnimations("player_game_over.ani"));
|
||||
tv_sprite_ = std::make_shared<AnimatedSprite>(resource_->getTexture("tv.png"), resource_->getAnimations("tv.ani"));
|
||||
music_ = resource_->getMusic("game_over.ogg");
|
||||
|
||||
// Inicializa variables
|
||||
preCounter = 0;
|
||||
counter = 0;
|
||||
pre_counter_ = 0;
|
||||
counter_ = 0;
|
||||
options.section.section = Section::GAME_OVER;
|
||||
options.section.subsection = Subsection::NONE;
|
||||
ticks = 0;
|
||||
ticksSpeed = 15;
|
||||
endSection = 400;
|
||||
iniFade = 310;
|
||||
fadeLenght = 20;
|
||||
playerSprite->setPosX(GAMECANVAS_CENTER_X + 10);
|
||||
playerSprite->setPosY(30);
|
||||
tvSprite->setPosX(GAMECANVAS_CENTER_X - tvSprite->getWidth() - 10);
|
||||
tvSprite->setPosY(30);
|
||||
ticks_ = 0;
|
||||
player_sprite_->setPosX(GAMECANVAS_CENTER_X + 10);
|
||||
player_sprite_->setPosY(30);
|
||||
tv_sprite_->setPosX(GAMECANVAS_CENTER_X - tv_sprite_->getWidth() - 10);
|
||||
tv_sprite_->setPosY(30);
|
||||
|
||||
// Inicializa el vector de colores
|
||||
const std::vector<std::string> colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
|
||||
for (auto cl : colorList)
|
||||
{
|
||||
colors.push_back(stringToColor(options.video.palette, cl));
|
||||
colors_.push_back(stringToColor(options.video.palette, cl));
|
||||
}
|
||||
color = colors.back();
|
||||
color_ = colors_.back();
|
||||
}
|
||||
|
||||
// Actualiza el objeto
|
||||
void GameOver::update()
|
||||
{
|
||||
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
|
||||
if (SDL_GetTicks() - ticks > ticksSpeed)
|
||||
if (SDL_GetTicks() - ticks_ > GAME_SPEED)
|
||||
{
|
||||
// Actualiza el contador de ticks
|
||||
ticks = SDL_GetTicks();
|
||||
ticks_ = SDL_GetTicks();
|
||||
|
||||
// Comprueba las entradas
|
||||
checkInput();
|
||||
@@ -73,44 +69,41 @@ void GameOver::update()
|
||||
updateCounters();
|
||||
|
||||
// Actualiza los dos sprites
|
||||
playerSprite->update();
|
||||
tvSprite->update();
|
||||
player_sprite_->update();
|
||||
tv_sprite_->update();
|
||||
|
||||
screen->update();
|
||||
screen_->update();
|
||||
}
|
||||
}
|
||||
|
||||
// Dibuja el final en pantalla
|
||||
void GameOver::render()
|
||||
{
|
||||
const int y = 32;
|
||||
constexpr int Y = 32;
|
||||
|
||||
// Prepara para empezar a dibujar en la textura de juego
|
||||
screen->start();
|
||||
|
||||
// Limpia la pantalla
|
||||
screen->clean();
|
||||
screen_->start();
|
||||
screen_->clean();
|
||||
|
||||
// Escribe el texto de GAME OVER
|
||||
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, y, "G A M E O V E R", 1, color);
|
||||
text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y, "G A M E O V E R", 1, color_);
|
||||
|
||||
// Dibuja los sprites
|
||||
playerSprite->setPosY(y + 30);
|
||||
tvSprite->setPosY(y + 30);
|
||||
player_sprite_->setPosY(Y + 30);
|
||||
tv_sprite_->setPosY(Y + 30);
|
||||
renderSprites();
|
||||
|
||||
// Escribe el texto con las habitaciones y los items
|
||||
const std::string itemsTxt = std::to_string(options.stats.items / 100) + std::to_string((options.stats.items % 100) / 10) + std::to_string(options.stats.items % 10);
|
||||
const std::string roomsTxt = std::to_string(options.stats.rooms / 100) + std::to_string((options.stats.rooms % 100) / 10) + std::to_string(options.stats.rooms % 10);
|
||||
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, y + 80, "ITEMS: " + itemsTxt, 1, color);
|
||||
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, y + 90, "ROOMS: " + roomsTxt, 1, color);
|
||||
text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 80, "ITEMS: " + itemsTxt, 1, color_);
|
||||
text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 90, "ROOMS: " + roomsTxt, 1, color_);
|
||||
|
||||
// Escribe el texto con "Tu peor pesadilla"
|
||||
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, y + 110, "YOUR WORST NIGHTMARE IS", 1, color);
|
||||
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, y + 120, options.stats.worst_nightmare, 1, color);
|
||||
text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 110, "YOUR WORST NIGHTMARE IS", 1, color_);
|
||||
text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 120, options.stats.worst_nightmare, 1, color_);
|
||||
|
||||
// Vuelca el contenido del renderizador en pantalla
|
||||
screen->render();
|
||||
screen_->render();
|
||||
}
|
||||
|
||||
// Comprueba el manejador de eventos
|
||||
@@ -143,53 +136,53 @@ void GameOver::run()
|
||||
// Actualiza el color usado para renderizar los textos e imagenes
|
||||
void GameOver::updateColor()
|
||||
{
|
||||
const int half = endSection / 2;
|
||||
const int half = COUNTER_SECTION_END_ / 2;
|
||||
|
||||
if (counter < half)
|
||||
if (counter_ < half)
|
||||
{
|
||||
const float step = std::min(counter, fadeLenght) / (float)fadeLenght;
|
||||
const int index = (colors.size() - 1) - int((colors.size() - 1) * step);
|
||||
color = colors[index];
|
||||
const float step = std::min(counter_, COUNTER_FADE_LENGHT_) / (float)COUNTER_FADE_LENGHT_;
|
||||
const int index = (colors_.size() - 1) - int((colors_.size() - 1) * step);
|
||||
color_ = colors_[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
const float step = std::min(std::max(counter, iniFade) - iniFade, fadeLenght) / (float)fadeLenght;
|
||||
const int index = (colors.size() - 1) * step;
|
||||
color = colors[index];
|
||||
const float step = std::min(std::max(counter_, COUNTER_INIT_FADE_) - COUNTER_INIT_FADE_, COUNTER_FADE_LENGHT_) / (float)COUNTER_FADE_LENGHT_;
|
||||
const int index = (colors_.size() - 1) * step;
|
||||
color_ = colors_[index];
|
||||
}
|
||||
}
|
||||
|
||||
// Dibuja los sprites
|
||||
void GameOver::renderSprites()
|
||||
{
|
||||
playerSprite->getTexture()->setColor(color.r, color.g, color.b);
|
||||
playerSprite->render();
|
||||
player_sprite_->getTexture()->setColor(color_.r, color_.g, color_.b);
|
||||
player_sprite_->render();
|
||||
|
||||
tvSprite->getTexture()->setColor(color.r, color.g, color.b);
|
||||
tvSprite->render();
|
||||
tv_sprite_->getTexture()->setColor(color_.r, color_.g, color_.b);
|
||||
tv_sprite_->render();
|
||||
}
|
||||
|
||||
// Actualiza los contadores
|
||||
void GameOver::updateCounters()
|
||||
{
|
||||
// Actualiza el contador
|
||||
if (preCounter < 50)
|
||||
if (pre_counter_ < 50)
|
||||
{
|
||||
preCounter++;
|
||||
pre_counter_++;
|
||||
}
|
||||
else
|
||||
{
|
||||
counter++;
|
||||
counter_++;
|
||||
}
|
||||
|
||||
// Hace sonar la música
|
||||
if (counter == 1)
|
||||
if (counter_ == 1)
|
||||
{
|
||||
JA_PlayMusic(music, 0);
|
||||
JA_PlayMusic(music_, 0);
|
||||
}
|
||||
|
||||
// Comprueba si ha terminado la sección
|
||||
else if (counter == endSection)
|
||||
else if (counter_ == COUNTER_SECTION_END_)
|
||||
{
|
||||
options.section.section = Section::LOGO;
|
||||
options.section.subsection = Subsection::LOGO_TO_TITLE;
|
||||
|
||||
@@ -16,27 +16,28 @@ struct JA_Music_t; // lines 15-15
|
||||
class GameOver
|
||||
{
|
||||
private:
|
||||
// Constantes
|
||||
static constexpr int COUNTER_SECTION_END_ = 400; // Contador: cuando acaba la sección
|
||||
static constexpr int COUNTER_INIT_FADE_ = 310; // Contador: cuando emiepza el fade
|
||||
static constexpr int COUNTER_FADE_LENGHT_ = 20; // Contador: duración del fade
|
||||
|
||||
// Objetos y punteros
|
||||
Screen *screen; // Objeto encargado de dibujar en pantalla
|
||||
SDL_Renderer *renderer; // El renderizador de la ventana
|
||||
Resource *resource; // Objeto con los recursos
|
||||
Asset *asset; // Objeto con los ficheros de recursos
|
||||
Input *input; // Objeto pata gestionar la entrada
|
||||
std::shared_ptr<Text> text; // Objeto para escribir texto en pantalla
|
||||
std::shared_ptr<AnimatedSprite> playerSprite; // Sprite con el jugador
|
||||
std::shared_ptr<AnimatedSprite> tvSprite; // Sprite con el televisor
|
||||
Screen *screen_; // Objeto encargado de dibujar en pantalla
|
||||
SDL_Renderer *renderer_; // El renderizador de la ventana
|
||||
Resource *resource_; // Objeto con los recursos
|
||||
Asset *asset_; // Objeto con los ficheros de recursos
|
||||
Input *input_; // Objeto pata gestionar la entrada
|
||||
std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
|
||||
std::shared_ptr<AnimatedSprite> player_sprite_; // Sprite con el jugador
|
||||
std::shared_ptr<AnimatedSprite> tv_sprite_; // Sprite con el televisor
|
||||
|
||||
// Variables
|
||||
int preCounter; // Contador previo
|
||||
int counter; // Contador
|
||||
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
|
||||
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
|
||||
std::vector<Color> colors; // Vector con los colores para el fade
|
||||
Color color; // Color usado para el texto y los sprites
|
||||
int endSection; // Contador: cuando acaba la sección
|
||||
int iniFade; // Contador: cuando emiepza el fade
|
||||
int fadeLenght; // Contador: duración del fade
|
||||
JA_Music_t *music; // Musica que suena durante el juego
|
||||
int pre_counter_ = 0; // Contador previo
|
||||
int counter_ = 0; // Contador
|
||||
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
||||
std::vector<Color> colors_; // Vector con los colores para el fade
|
||||
Color color_; // Color usado para el texto y los sprites
|
||||
JA_Music_t *music_; // Musica que suena durante el juego
|
||||
|
||||
// Actualiza el objeto
|
||||
void update();
|
||||
|
||||
@@ -1,94 +1,9 @@
|
||||
#include "gif.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define EXTENSION_INTRODUCER 0x21
|
||||
#define IMAGE_DESCRIPTOR 0x2C
|
||||
#define TRAILER 0x3B
|
||||
|
||||
#define GRAPHIC_CONTROL 0xF9
|
||||
#define APPLICATION_EXTENSION 0xFF
|
||||
#define COMMENT_EXTENSION 0xFE
|
||||
#define PLAINTEXT_EXTENSION 0x01
|
||||
|
||||
#define READ(dst, size) memcpy(dst, buffer, size); buffer += size
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
unsigned char fields;
|
||||
unsigned char background_color_index;
|
||||
unsigned char pixel_aspect_ratio;
|
||||
}
|
||||
screen_descriptor_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
}
|
||||
rgb;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short image_left_position;
|
||||
unsigned short image_top_position;
|
||||
unsigned short image_width;
|
||||
unsigned short image_height;
|
||||
unsigned char fields;
|
||||
}
|
||||
image_descriptor_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char byte;
|
||||
int prev;
|
||||
int len;
|
||||
}
|
||||
dictionary_entry_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char extension_code;
|
||||
unsigned char block_size;
|
||||
}
|
||||
extension_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char fields;
|
||||
unsigned short delay_time;
|
||||
unsigned char transparent_color_index;
|
||||
}
|
||||
graphic_control_extension_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char application_id[ 8 ];
|
||||
unsigned char version[ 3 ];
|
||||
}
|
||||
application_extension_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short left;
|
||||
unsigned short top;
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
unsigned char cell_width;
|
||||
unsigned char cell_height;
|
||||
unsigned char foreground_color;
|
||||
unsigned char background_color;
|
||||
}
|
||||
plaintext_extension_t;
|
||||
|
||||
//static unsigned short width = 0;
|
||||
//static unsigned short height = 0;
|
||||
//static unsigned char* uncompressed_data = NULL;
|
||||
|
||||
void uncompress( int code_length,
|
||||
const unsigned char *input,
|
||||
int input_length,
|
||||
65
source/gif.h
Normal file
65
source/gif.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define EXTENSION_INTRODUCER 0x21
|
||||
#define IMAGE_DESCRIPTOR 0x2C
|
||||
#define TRAILER 0x3B
|
||||
#define GRAPHIC_CONTROL 0xF9
|
||||
#define APPLICATION_EXTENSION 0xFF
|
||||
#define COMMENT_EXTENSION 0xFE
|
||||
#define PLAINTEXT_EXTENSION 0x01
|
||||
|
||||
#define READ(dst, size) memcpy(dst, buffer, size); buffer += size
|
||||
|
||||
typedef struct {
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
unsigned char fields;
|
||||
unsigned char background_color_index;
|
||||
unsigned char pixel_aspect_ratio;
|
||||
} screen_descriptor_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char r, g, b;
|
||||
} rgb;
|
||||
|
||||
typedef struct {
|
||||
unsigned short image_left_position;
|
||||
unsigned short image_top_position;
|
||||
unsigned short image_width;
|
||||
unsigned short image_height;
|
||||
unsigned char fields;
|
||||
} image_descriptor_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char byte;
|
||||
int prev;
|
||||
int len;
|
||||
} dictionary_entry_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char extension_code;
|
||||
unsigned char block_size;
|
||||
} extension_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char fields;
|
||||
unsigned short delay_time;
|
||||
unsigned char transparent_color_index;
|
||||
} graphic_control_extension_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char application_id[8];
|
||||
unsigned char version[3];
|
||||
} application_extension_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned short left, top, width, height;
|
||||
unsigned char cell_width, cell_height;
|
||||
unsigned char foreground_color, background_color;
|
||||
} plaintext_extension_t;
|
||||
|
||||
void uncompress(int code_length, const unsigned char *input, int input_length, unsigned char *out);
|
||||
uint32_t* LoadPalette(unsigned char *buffer);
|
||||
unsigned char* LoadGif(unsigned char *buffer, unsigned short* w, unsigned short* h);
|
||||
@@ -9,7 +9,22 @@
|
||||
|
||||
namespace globalInputs
|
||||
{
|
||||
// Cambia la paleta
|
||||
void quit()
|
||||
{
|
||||
const std::string code = options.section.section == Section::GAME ? "PRESS AGAIN TO RETURN TO MENU" : "PRESS AGAIN TO EXIT";
|
||||
auto code_found = stringInVector(Notifier::get()->getCodes(), code);
|
||||
if (code_found)
|
||||
{
|
||||
// Si la notificación de salir está activa, cambia de sección
|
||||
options.section.section = options.section.section == Section::GAME ? Section::TITLE : Section::QUIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Si la notificación de salir no está activa, muestra la notificación
|
||||
Notifier::get()->show({code}, NotificationText::CENTER, -1, true, code);
|
||||
}
|
||||
}
|
||||
// Cambia la paleta de colores
|
||||
void switchPalette()
|
||||
{
|
||||
options.video.palette = options.video.palette == Palette::ZXSPECTRUM ? Palette::ZXARNE : Palette::ZXSPECTRUM;
|
||||
@@ -41,7 +56,7 @@ namespace globalInputs
|
||||
{
|
||||
if (Input::get()->checkInput(input_exit, REPEAT_FALSE))
|
||||
{
|
||||
options.section.section = Section::QUIT;
|
||||
quit();
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(input_accept, REPEAT_FALSE))
|
||||
@@ -52,32 +67,41 @@ namespace globalInputs
|
||||
else if (Input::get()->checkInput(input_toggle_border, REPEAT_FALSE))
|
||||
{
|
||||
Screen::get()->toggleBorder();
|
||||
Notifier::get()->show({"BORDER " + std::string(options.video.border.enabled ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(input_toggle_videomode, REPEAT_FALSE))
|
||||
{
|
||||
Screen::get()->toggleVideoMode();
|
||||
Notifier::get()->show({"FULLSCREEN " + std::string(options.video.mode == 0 ? "DISABLED" : "ENABLED")}, NotificationText::CENTER);
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(input_window_dec_size, REPEAT_FALSE))
|
||||
{
|
||||
Screen::get()->decWindowZoom();
|
||||
if (Screen::get()->decWindowZoom())
|
||||
{
|
||||
Notifier::get()->show({"WINDOW ZOOM x" + std::to_string(options.window.zoom)}, NotificationText::CENTER);
|
||||
}
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(input_window_inc_size, REPEAT_FALSE))
|
||||
{
|
||||
Screen::get()->incWindowZoom();
|
||||
if (Screen::get()->incWindowZoom())
|
||||
{
|
||||
Notifier::get()->show({"WINDOW ZOOM x" + std::to_string(options.window.zoom)}, NotificationText::CENTER);
|
||||
}
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(input_toggle_shaders, REPEAT_FALSE))
|
||||
{
|
||||
Screen::get()->toggleShaders();
|
||||
Notifier::get()->show({"HOLA"});
|
||||
Notifier::get()->show({"SHADERS " + std::string(options.video.shaders ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(input_toggle_palette, REPEAT_FALSE))
|
||||
{
|
||||
switchPalette();
|
||||
Notifier::get()->show({"PALETTE " + std::string(options.video.palette == Palette::ZXSPECTRUM ? "ZX SPECTRUM" : "ZX ARNE")}, NotificationText::CENTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,59 +1,57 @@
|
||||
#include "item.h"
|
||||
#include "resource.h"
|
||||
#include "sprite.h" // Para Sprite
|
||||
#include "texture.h" // Para Texture
|
||||
|
||||
// Constructor
|
||||
Item::Item(item_t item)
|
||||
Item::Item(ItemData item)
|
||||
{
|
||||
constexpr int ITEMSIZE = 8;
|
||||
|
||||
// Crea objetos;
|
||||
sprite = std::make_shared<Sprite>(item.texture, item.x, item.y, ITEMSIZE, ITEMSIZE);
|
||||
sprite_ = std::make_shared<Sprite>(Resource::get()->getTexture(item.tile_set_file), item.x, item.y, ITEMSIZE, ITEMSIZE);
|
||||
|
||||
// Inicia variables
|
||||
sprite->setClip((item.tile % 10) * ITEMSIZE, (item.tile / 10) * ITEMSIZE, ITEMSIZE, ITEMSIZE);
|
||||
collider = sprite->getRect();
|
||||
colorChangeSpeed = 4;
|
||||
counter = item.counter * colorChangeSpeed;
|
||||
sprite_->setClip((item.tile % 10) * ITEMSIZE, (item.tile / 10) * ITEMSIZE, ITEMSIZE, ITEMSIZE);
|
||||
collider_ = sprite_->getRect();
|
||||
change_color_speed = 4;
|
||||
counter_ = item.counter * change_color_speed;
|
||||
|
||||
// Inicializa los colores
|
||||
Color c = item.color1;
|
||||
color.push_back(c);
|
||||
color.push_back(c);
|
||||
color_.push_back(item.color1);
|
||||
color_.push_back(item.color1);
|
||||
|
||||
c = item.color2;
|
||||
color.push_back(c);
|
||||
color.push_back(c);
|
||||
color_.push_back(item.color2);
|
||||
color_.push_back(item.color2);
|
||||
}
|
||||
|
||||
// Pinta el objeto en pantalla
|
||||
void Item::render()
|
||||
{
|
||||
const int index = (counter / colorChangeSpeed) % color.size();
|
||||
sprite->getTexture()->setColor(color[index].r, color[index].g, color[index].b);
|
||||
sprite->render();
|
||||
sprite->getTexture()->setColor(255, 255, 255);
|
||||
const int index = (counter_ / change_color_speed) % color_.size();
|
||||
sprite_->getTexture()->setColor(color_[index].r, color_[index].g, color_[index].b);
|
||||
sprite_->render();
|
||||
sprite_->getTexture()->setColor(255, 255, 255);
|
||||
}
|
||||
|
||||
// Obtiene su ubicación
|
||||
SDL_Point Item::getPos()
|
||||
{
|
||||
const SDL_Point p = {sprite->getX(), sprite->getY()};
|
||||
const SDL_Point p = {sprite_->getX(), sprite_->getY()};
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
// Asigna los colores del objeto
|
||||
void Item::setColors(Color col1, Color col2)
|
||||
{
|
||||
// Reinicializa el vector de colores
|
||||
color.clear();
|
||||
color_.clear();
|
||||
|
||||
// Añade el primer color
|
||||
color.push_back(col1);
|
||||
color.push_back(col1);
|
||||
color_.push_back(col1);
|
||||
color_.push_back(col1);
|
||||
|
||||
// Añade el segundo color
|
||||
color.push_back(col2);
|
||||
color.push_back(col2);
|
||||
color_.push_back(col2);
|
||||
color_.push_back(col2);
|
||||
}
|
||||
@@ -9,11 +9,9 @@
|
||||
#include "texture.h" // for Texture
|
||||
#include "utils.h" // for Color
|
||||
|
||||
struct item_t
|
||||
struct ItemData
|
||||
{
|
||||
SDL_Renderer *renderer; // El renderizador de la ventana
|
||||
std::shared_ptr<Texture> texture; // Textura con los gráficos del item
|
||||
std::string tileSetFile; // Ruta al fichero con los gráficos del item
|
||||
std::string tile_set_file; // 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
|
||||
int tile; // Número de tile dentro de la textura
|
||||
@@ -21,25 +19,25 @@ struct item_t
|
||||
Color color1; // Uno de los dos colores que se utiliza para el item
|
||||
Color color2; // Uno de los dos colores que se utiliza para el item
|
||||
|
||||
// Constructor por defecto
|
||||
item_t() : renderer(nullptr), texture(nullptr), x(0), y(0), tile(0), counter(0), color1(), color2() {}
|
||||
// Constructor
|
||||
ItemData() : x(0), y(0), tile(0), counter(0), color1(), color2() {}
|
||||
};
|
||||
|
||||
class Item
|
||||
{
|
||||
private:
|
||||
// Objetos y punteros
|
||||
std::shared_ptr<Sprite> sprite; // Sprite del objeto
|
||||
std::shared_ptr<Sprite> sprite_; // Sprite del objeto
|
||||
|
||||
// Variables
|
||||
std::vector<Color> color; // Vector con los colores del objeto
|
||||
int counter; // Contador interno
|
||||
SDL_Rect collider; // Rectangulo de colisión
|
||||
int colorChangeSpeed; // Cuanto mas alto, mas tarda en cambiar de color
|
||||
std::vector<Color> color_; // Vector con los colores del objeto
|
||||
int counter_; // Contador interno
|
||||
SDL_Rect collider_; // Rectangulo de colisión
|
||||
int change_color_speed; // Cuanto mas alto, mas tarda en cambiar de color
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
Item(item_t item);
|
||||
Item(ItemData item);
|
||||
|
||||
// Destructor
|
||||
~Item() = default;
|
||||
@@ -48,18 +46,17 @@ public:
|
||||
void render();
|
||||
|
||||
// Actualiza las variables del objeto
|
||||
void update() { counter++; }
|
||||
void update() { counter_++; }
|
||||
|
||||
// Obtiene el rectangulo de colision del objeto
|
||||
SDL_Rect &getCollider() { return collider; }
|
||||
SDL_Rect &getCollider() { return collider_; }
|
||||
|
||||
// Obtiene su ubicación
|
||||
SDL_Point getPos();
|
||||
|
||||
// Recarga la textura
|
||||
void reLoadTexture() { sprite->getTexture()->reLoad(); }
|
||||
void reLoadTexture() { sprite_->getTexture()->reLoad(); }
|
||||
|
||||
// Asigna los colores del objeto
|
||||
void setColors(Color col1, Color col2);
|
||||
|
||||
};
|
||||
@@ -1,50 +1,57 @@
|
||||
#include "item_tracker.h"
|
||||
|
||||
// Destructor
|
||||
ItemTracker::~ItemTracker()
|
||||
// [SINGLETON]
|
||||
ItemTracker *ItemTracker::item_tracker_ = nullptr;
|
||||
|
||||
// [SINGLETON] Crearemos el objeto con esta función estática
|
||||
void ItemTracker::init()
|
||||
{
|
||||
list.clear();
|
||||
ItemTracker::item_tracker_ = new ItemTracker();
|
||||
}
|
||||
|
||||
// [SINGLETON] Destruiremos el objeto con esta función estática
|
||||
void ItemTracker::destroy()
|
||||
{
|
||||
delete ItemTracker::item_tracker_;
|
||||
}
|
||||
|
||||
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
|
||||
ItemTracker *ItemTracker::get()
|
||||
{
|
||||
return ItemTracker::item_tracker_;
|
||||
}
|
||||
|
||||
// Comprueba si el objeto ya ha sido cogido
|
||||
bool ItemTracker::hasBeenPicked(std::string name, SDL_Point pos)
|
||||
bool ItemTracker::hasBeenPicked(const std::string &name, SDL_Point pos)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
// Primero busca si ya hay una entrada con ese nombre
|
||||
const int index = findByName(name);
|
||||
if (index != -1)
|
||||
if (const int index = findByName(name); index != -1)
|
||||
{
|
||||
// Luego busca si existe ya una entrada con esa posición
|
||||
if (findByPos(index, pos) != -1)
|
||||
{
|
||||
success = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Añade el objeto a la lista de objetos cogidos
|
||||
void ItemTracker::addItem(std::string name, SDL_Point pos)
|
||||
void ItemTracker::addItem(const std::string &name, SDL_Point pos)
|
||||
{
|
||||
// Comprueba si el objeto no ha sido recogido con anterioridad
|
||||
if (!hasBeenPicked(name, pos))
|
||||
{
|
||||
// Primero busca si ya hay una entrada con ese nombre
|
||||
const int index = findByName(name);
|
||||
if (index != -1)
|
||||
if (const int index = findByName(name); index != -1)
|
||||
{
|
||||
list[index].pos.push_back(pos);
|
||||
item_list_.at(index).pos.push_back(pos);
|
||||
}
|
||||
|
||||
// En caso contrario crea la entrada
|
||||
else
|
||||
{
|
||||
item_tracker_t item;
|
||||
item.name = name;
|
||||
item.pos.push_back(pos);
|
||||
list.push_back(item);
|
||||
item_list_.emplace_back(name, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,7 +61,7 @@ int ItemTracker::findByName(std::string name)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (auto l : list)
|
||||
for (const auto &l : item_list_)
|
||||
{
|
||||
if (l.name == name)
|
||||
{
|
||||
@@ -71,7 +78,7 @@ int ItemTracker::findByPos(int index, SDL_Point pos)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (auto l : list[index].pos)
|
||||
for (const auto &l : item_list_[index].pos)
|
||||
{
|
||||
if ((l.x == pos.x) && (l.y == pos.y))
|
||||
{
|
||||
|
||||
@@ -4,17 +4,27 @@
|
||||
#include <string> // Para string, basic_string
|
||||
#include <vector> // Para vector
|
||||
|
||||
struct item_tracker_t
|
||||
struct ItemTrackerData
|
||||
{
|
||||
std::string name; // Nombre de la habitación donde se encuentra el objeto
|
||||
std::vector<SDL_Point> pos; // Lista de objetos cogidos de la habitación
|
||||
|
||||
// Constructor
|
||||
ItemTrackerData(const std::string &name, const SDL_Point &position)
|
||||
: name(name)
|
||||
{
|
||||
pos.push_back(position);
|
||||
}
|
||||
};
|
||||
|
||||
class ItemTracker
|
||||
{
|
||||
private:
|
||||
// [SINGLETON] Objeto privado
|
||||
static ItemTracker *item_tracker_;
|
||||
|
||||
// Variables
|
||||
std::vector<item_tracker_t> list; // Lista con todos los objetos recogidos
|
||||
std::vector<ItemTrackerData> item_list_; // Lista con todos los objetos recogidos
|
||||
|
||||
// Busca una entrada en la lista por nombre
|
||||
int findByName(std::string name);
|
||||
@@ -22,13 +32,25 @@ private:
|
||||
// Busca una entrada en la lista por posición
|
||||
int findByPos(int index, SDL_Point pos);
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
ItemTracker() = default;
|
||||
|
||||
// Destructor
|
||||
~ItemTracker();
|
||||
~ItemTracker() = default;
|
||||
|
||||
public:
|
||||
// [SINGLETON] Crearemos el objeto con esta función estática
|
||||
static void init();
|
||||
|
||||
// [SINGLETON] Destruiremos el objeto con esta función estática
|
||||
static void destroy();
|
||||
|
||||
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
|
||||
static ItemTracker *get();
|
||||
|
||||
// Comprueba si el objeto ya ha sido cogido
|
||||
bool hasBeenPicked(std::string name, SDL_Point pos);
|
||||
bool hasBeenPicked(const std::string &name, SDL_Point pos);
|
||||
|
||||
// Añade el objeto a la lista de objetos cogidos
|
||||
void addItem(std::string name, SDL_Point pos);
|
||||
void addItem(const std::string &name, SDL_Point pos);
|
||||
};
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "sprite.h" // for Sprite
|
||||
#include "texture.h" // for Texture
|
||||
#include "utils.h" // for Color, stringToColor, Palette
|
||||
#include <iostream>
|
||||
|
||||
// Constructor
|
||||
LoadingScreen::LoadingScreen()
|
||||
@@ -40,6 +41,16 @@ LoadingScreen::LoadingScreen()
|
||||
loading_sound2_ = resource_->getMusic("loading_sound2.ogg");
|
||||
loading_sound3_ = resource_->getMusic("loading_sound3.ogg");
|
||||
|
||||
texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width, options.game.height);
|
||||
if (texture_ == nullptr)
|
||||
{
|
||||
if (options.console)
|
||||
{
|
||||
std::cout << "LoadingScreen::texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
}
|
||||
clearTexture();
|
||||
|
||||
// Inicializa variables
|
||||
options.section.section = Section::LOADING_SCREEN;
|
||||
options.section.subsection = Subsection::NONE;
|
||||
@@ -71,6 +82,7 @@ LoadingScreen::LoadingScreen()
|
||||
LoadingScreen::~LoadingScreen()
|
||||
{
|
||||
JA_StopMusic();
|
||||
SDL_DestroyTexture(texture_);
|
||||
}
|
||||
|
||||
// Comprueba el manejador de eventos
|
||||
@@ -165,8 +177,8 @@ void LoadingScreen::renderBorder()
|
||||
// Añade lineas amarillas
|
||||
color = stringToColor(options.video.palette, "yellow");
|
||||
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
|
||||
const int width = GAMECANVAS_WIDTH + (options.video.border.width * 2);
|
||||
const int height = GAMECANVAS_HEIGHT + (options.video.border.height * 2);
|
||||
const int width = options.game.width + (options.video.border.width * 2);
|
||||
const int height = options.game.height + (options.video.border.height * 2);
|
||||
bool drawEnabled = rand() % 2 == 0 ? true : false;
|
||||
int row = 0;
|
||||
int rowSize = 1;
|
||||
@@ -187,12 +199,13 @@ void LoadingScreen::renderBorder()
|
||||
void LoadingScreen::update()
|
||||
{
|
||||
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
|
||||
if (SDL_GetTicks() - ticks_ > ticks_speed_)
|
||||
if (SDL_GetTicks() - ticks_ > GAME_SPEED)
|
||||
{
|
||||
ticks_ = SDL_GetTicks();
|
||||
checkInput();
|
||||
updateCounter();
|
||||
updateLoad();
|
||||
fillTexture();
|
||||
screen_->update();
|
||||
}
|
||||
}
|
||||
@@ -212,8 +225,8 @@ void LoadingScreen::render()
|
||||
// Prepara para empezar a dibujar en la textura de juego
|
||||
screen_->start();
|
||||
|
||||
// Dibuja la pantalla de carga
|
||||
renderLoad();
|
||||
// Copila la textura a la pantalla
|
||||
SDL_RenderCopy(renderer_, texture_, nullptr, nullptr);
|
||||
|
||||
// Vuelca el contenido del renderizador en pantalla
|
||||
screen_->render();
|
||||
@@ -279,3 +292,32 @@ void LoadingScreen::recreateLoadingScreen()
|
||||
// Vuelca el contenido del renderizador en pantalla
|
||||
screen_->render();
|
||||
}
|
||||
|
||||
// Dibuja sobre la textura
|
||||
void LoadingScreen::fillTexture()
|
||||
{
|
||||
// Empieza a dibujar en la textura
|
||||
auto temp = SDL_GetRenderTarget(renderer_);
|
||||
SDL_SetRenderTarget(renderer_, texture_);
|
||||
|
||||
// Dibuja la pantalla de carga
|
||||
renderLoad();
|
||||
|
||||
// Deja el renderizador como estaba
|
||||
SDL_SetRenderTarget(renderer_, temp);
|
||||
}
|
||||
|
||||
// Limpia la textura
|
||||
void LoadingScreen::clearTexture()
|
||||
{
|
||||
// Empieza a dibujar en la textura
|
||||
auto temp = SDL_GetRenderTarget(renderer_);
|
||||
SDL_SetRenderTarget(renderer_, texture_);
|
||||
|
||||
// Limpia
|
||||
SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF);
|
||||
SDL_RenderClear(renderer_);
|
||||
|
||||
// Deja el renderizador como estaba
|
||||
SDL_SetRenderTarget(renderer_, temp);
|
||||
}
|
||||
@@ -30,7 +30,6 @@ private:
|
||||
int pre_counter_ = 0; // Contador previo para realizar una pausa inicial
|
||||
int counter_ = 0; // Contador
|
||||
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
||||
Uint32 ticks_speed_ = 15; // Velocidad a la que se repiten los bucles del programa
|
||||
int load_counter_ = 0; // Contador para controlar las cargas
|
||||
bool loading_first_part_ = true; // Para saber en que parte de la carga se encuentra
|
||||
JA_Music_t *loading_sound1_; // Sonidos para imitar la carga tipo spectrum
|
||||
@@ -38,6 +37,7 @@ private:
|
||||
JA_Music_t *loading_sound3_; // Sonidos para imitar la carga tipo spectrum
|
||||
int line_index_[192]; // El orden en el que se procesan las 192 lineas de la pantalla de carga
|
||||
SDL_Rect load_rect_ = {0, 0, 51, 1}; // Rectangulo para dibujar la pantalla de carga
|
||||
SDL_Texture *texture_; // Textura para dibujar la pantalla de carga
|
||||
|
||||
// Actualiza las variables
|
||||
void update();
|
||||
@@ -66,6 +66,12 @@ private:
|
||||
// Reconstruye la pantalla de carga
|
||||
void recreateLoadingScreen();
|
||||
|
||||
// Dibuja sobre la textura
|
||||
void fillTexture();
|
||||
|
||||
// Limpia la textura
|
||||
void clearTexture();
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
LoadingScreen();
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "sprite.h" // for Sprite
|
||||
#include "texture.h" // for Texture
|
||||
#include "utils.h" // for Color, stringToColor
|
||||
#include "defines.h"
|
||||
|
||||
// Constructor
|
||||
Logo::Logo()
|
||||
@@ -153,43 +154,43 @@ void Logo::updateTextureColors()
|
||||
since_1998_texture_->setColor(color_[7].r, color_[7].g, color_[7].b);
|
||||
}
|
||||
|
||||
else if (counter_ == init_fade_ + inc * 0)
|
||||
else if (counter_ == INIT_FADE_ + inc * 0)
|
||||
{
|
||||
jailgames_texture_->setColor(color_[6].r, color_[6].g, color_[6].b);
|
||||
since_1998_texture_->setColor(color_[6].r, color_[6].g, color_[6].b);
|
||||
}
|
||||
|
||||
else if (counter_ == init_fade_ + inc * 1)
|
||||
else if (counter_ == INIT_FADE_ + inc * 1)
|
||||
{
|
||||
jailgames_texture_->setColor(color_[5].r, color_[5].g, color_[5].b);
|
||||
since_1998_texture_->setColor(color_[5].r, color_[5].g, color_[5].b);
|
||||
}
|
||||
|
||||
else if (counter_ == init_fade_ + inc * 2)
|
||||
else if (counter_ == INIT_FADE_ + inc * 2)
|
||||
{
|
||||
jailgames_texture_->setColor(color_[4].r, color_[4].g, color_[4].b);
|
||||
since_1998_texture_->setColor(color_[4].r, color_[4].g, color_[4].b);
|
||||
}
|
||||
|
||||
else if (counter_ == init_fade_ + inc * 3)
|
||||
else if (counter_ == INIT_FADE_ + inc * 3)
|
||||
{
|
||||
jailgames_texture_->setColor(color_[3].r, color_[3].g, color_[3].b);
|
||||
since_1998_texture_->setColor(color_[3].r, color_[3].g, color_[3].b);
|
||||
}
|
||||
|
||||
else if (counter_ == init_fade_ + inc * 4)
|
||||
else if (counter_ == INIT_FADE_ + inc * 4)
|
||||
{
|
||||
jailgames_texture_->setColor(color_[2].r, color_[2].g, color_[2].b);
|
||||
since_1998_texture_->setColor(color_[2].r, color_[2].g, color_[2].b);
|
||||
}
|
||||
|
||||
else if (counter_ == init_fade_ + inc * 5)
|
||||
else if (counter_ == INIT_FADE_ + inc * 5)
|
||||
{
|
||||
jailgames_texture_->setColor(color_[1].r, color_[1].g, color_[1].b);
|
||||
since_1998_texture_->setColor(color_[1].r, color_[1].g, color_[1].b);
|
||||
}
|
||||
|
||||
else if (counter_ == init_fade_ + inc * 6)
|
||||
else if (counter_ == INIT_FADE_ + inc * 6)
|
||||
{
|
||||
jailgames_texture_->setColor(color_[0].r, color_[0].g, color_[0].b);
|
||||
since_1998_texture_->setColor(color_[0].r, color_[0].g, color_[0].b);
|
||||
@@ -200,7 +201,7 @@ void Logo::updateTextureColors()
|
||||
void Logo::update()
|
||||
{
|
||||
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
|
||||
if (SDL_GetTicks() - ticks_ > ticks_speed_)
|
||||
if (SDL_GetTicks() - ticks_ > GAME_SPEED)
|
||||
{
|
||||
// Actualiza el contador de ticks
|
||||
ticks_ = SDL_GetTicks();
|
||||
@@ -220,7 +221,7 @@ void Logo::update()
|
||||
screen_->update();
|
||||
|
||||
// Comprueba si ha terminado el logo
|
||||
if (counter_ == end_logo_ + post_logo_)
|
||||
if (counter_ == END_LOGO_ + POST_LOGO_)
|
||||
{
|
||||
endSection();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,11 @@ class Texture; // lines 13-13
|
||||
class Logo
|
||||
{
|
||||
private:
|
||||
// Constantes
|
||||
static constexpr int INIT_FADE_ = 300; // Tiempo del contador cuando inicia el fade a negro
|
||||
static constexpr int END_LOGO_ = 400; // Tiempo del contador para terminar el logo
|
||||
static constexpr int POST_LOGO_ = 20; // Tiempo que dura el logo con el fade al maximo
|
||||
|
||||
// Objetos y punteros
|
||||
Screen *screen_; // Objeto encargado de dibujar en pantalla
|
||||
SDL_Renderer *renderer_; // El renderizador de la ventana
|
||||
@@ -30,10 +35,6 @@ private:
|
||||
std::vector<Color> color_; // Vector con los colores para el fade
|
||||
int counter_ = 0; // Contador
|
||||
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
||||
Uint32 ticks_speed_ = 15; // Velocidad a la que se repiten los bucles del programa
|
||||
int init_fade_ = 300; // Tiempo del contador cuando inicia el fade a negro
|
||||
int end_logo_ = 400; // Tiempo del contador para terminar el logo
|
||||
int post_logo_ = 20; // Tiempo que dura el logo con el fade al maximo
|
||||
|
||||
// Actualiza las variables
|
||||
void update();
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
Notifier *Notifier::notifier_ = nullptr;
|
||||
|
||||
// [SINGLETON] Crearemos el objeto con esta función estática
|
||||
void Notifier::init(const std::string &icon_file, std::shared_ptr<Text> text)
|
||||
void Notifier::init(const std::string &icon_file, const std::string &text)
|
||||
{
|
||||
Notifier::notifier_ = new Notifier(icon_file, text);
|
||||
}
|
||||
@@ -34,10 +34,10 @@ Notifier *Notifier::get()
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Notifier::Notifier(std::string icon_file, std::shared_ptr<Text> text)
|
||||
Notifier::Notifier(const std::string &icon_file, const std::string &text)
|
||||
: renderer_(Screen::get()->getRenderer()),
|
||||
icon_texture_(!icon_file.empty() ? std::make_unique<Texture>(renderer_, icon_file) : nullptr),
|
||||
text_(text),
|
||||
icon_texture_(!icon_file.empty() ? Resource::get()->getTexture(icon_file) : nullptr),
|
||||
text_(Resource::get()->getText(text)),
|
||||
bg_color_(options.notifications.color),
|
||||
wait_time_(150),
|
||||
stack_(false),
|
||||
@@ -84,18 +84,19 @@ void Notifier::update()
|
||||
// Comprueba los estados
|
||||
if (notifications_[i].state == NotificationStatus::RISING)
|
||||
{
|
||||
const float step = ((float)notifications_[i].counter / notifications_[i].travel_dist);
|
||||
const int alpha = 255 * step;
|
||||
//const float step = ((float)notifications_[i].counter / notifications_[i].travel_dist);
|
||||
//const int alpha = 255 * step;
|
||||
constexpr int ALPHA = 255;
|
||||
|
||||
if (options.notifications.getVerticalPosition() == "TOP")
|
||||
if (options.notifications.getVerticalPosition() == NotificationPosition::TOP)
|
||||
{
|
||||
notifications_[i].rect.y++;
|
||||
}
|
||||
else
|
||||
else if (options.notifications.getVerticalPosition() == NotificationPosition::BOTTOM)
|
||||
{
|
||||
notifications_[i].rect.y--;
|
||||
}
|
||||
notifications_[i].texture->setAlpha(alpha);
|
||||
notifications_[i].texture->setAlpha(ALPHA);
|
||||
|
||||
if (notifications_[i].rect.y == notifications_[i].y)
|
||||
{
|
||||
@@ -116,18 +117,20 @@ void Notifier::update()
|
||||
else if (notifications_[i].state == NotificationStatus::VANISHING)
|
||||
{
|
||||
|
||||
const float step = (notifications_[i].counter / (float)notifications_[i].travel_dist);
|
||||
const int alpha = 255 * (1 - step);
|
||||
//const float step = (notifications_[i].counter / (float)notifications_[i].travel_dist);
|
||||
//const int ALPHA = 255 * (1 - step);
|
||||
constexpr int ALPHA = 255;
|
||||
|
||||
if (options.notifications.getVerticalPosition() == "TOP")
|
||||
|
||||
if (options.notifications.getVerticalPosition() == NotificationPosition::TOP)
|
||||
{
|
||||
notifications_[i].rect.y--;
|
||||
}
|
||||
else
|
||||
else if (options.notifications.getVerticalPosition() == NotificationPosition::BOTTOM)
|
||||
{
|
||||
notifications_[i].rect.y++;
|
||||
}
|
||||
notifications_[i].texture->setAlpha(alpha);
|
||||
notifications_[i].texture->setAlpha(ALPHA);
|
||||
|
||||
if (notifications_[i].rect.y == notifications_[i].y - notifications_[i].travel_dist)
|
||||
{
|
||||
@@ -153,7 +156,7 @@ void Notifier::clearFinishedNotifications()
|
||||
}
|
||||
}
|
||||
|
||||
void Notifier::show(std::vector<std::string> texts, int icon, const std::string &code)
|
||||
void Notifier::show(std::vector<std::string> texts, NotificationText text_is, int icon, bool can_be_removed, const std::string &code)
|
||||
{
|
||||
// Si no hay texto, acaba
|
||||
if (texts.empty())
|
||||
@@ -181,43 +184,41 @@ void Notifier::show(std::vector<std::string> texts, int icon, const std::string
|
||||
}
|
||||
|
||||
// Inicializa variables
|
||||
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 icon_space = icon >= 0 ? ICON_SIZE_ + padding_in_h : 0;
|
||||
text_is = icon_space > 0 ? NotificationText::LEFT : text_is;
|
||||
const int width = options.game.width - (PADDING_OUT_ * 2);
|
||||
const int height = (text_->getCharacterSize() * texts.size()) + (padding_in_v * 2);
|
||||
const auto shape = NotificationShape::SQUARED;
|
||||
|
||||
// Posición horizontal
|
||||
auto desp_h = 0;
|
||||
if (options.notifications.getHorizontalPosition() == "LEFT")
|
||||
if (options.notifications.getHorizontalPosition() == NotificationPosition::LEFT)
|
||||
{
|
||||
desp_h = padding_out;
|
||||
desp_h = PADDING_OUT_;
|
||||
}
|
||||
else if (options.notifications.getHorizontalPosition() == "CENTER")
|
||||
else if (options.notifications.getHorizontalPosition() == NotificationPosition::CENTER)
|
||||
{
|
||||
desp_h = ((options.game.width / 2) - (width / 2));
|
||||
}
|
||||
else
|
||||
else if (options.notifications.getHorizontalPosition() == NotificationPosition::RIGHT)
|
||||
{
|
||||
desp_h = options.game.width - width - padding_out;
|
||||
desp_h = options.game.width - width - PADDING_OUT_;
|
||||
}
|
||||
|
||||
// Posición vertical
|
||||
const int desp_v = (options.notifications.getVerticalPosition() == "TOP") ? padding_out : (options.game.height - height - padding_out);
|
||||
|
||||
const int desp_v = (options.notifications.getVerticalPosition() == NotificationPosition::TOP) ? PADDING_OUT_ : options.game.height - height - PADDING_OUT_;
|
||||
// Offset
|
||||
const auto travel_dist = height + padding_out;
|
||||
const auto travel_dist = height + PADDING_OUT_;
|
||||
auto offset = 0;
|
||||
if (options.notifications.getVerticalPosition() == "TOP")
|
||||
if (options.notifications.getVerticalPosition() == NotificationPosition::TOP)
|
||||
{
|
||||
offset = !notifications_.empty() ? notifications_.back().y + travel_dist : desp_v;
|
||||
offset = !notifications_.empty() ? notifications_.back().y + notifications_.back().travel_dist : desp_v;
|
||||
}
|
||||
else
|
||||
else if (options.notifications.getVerticalPosition() == NotificationPosition::BOTTOM)
|
||||
{
|
||||
offset = !notifications_.empty() ? notifications_.back().y - travel_dist : desp_v;
|
||||
offset = !notifications_.empty() ? notifications_.back().y - notifications_.back().travel_dist : desp_v;
|
||||
}
|
||||
|
||||
// Crea la notificacion
|
||||
@@ -225,11 +226,12 @@ void Notifier::show(std::vector<std::string> texts, int icon, const std::string
|
||||
|
||||
// Inicializa variables
|
||||
n.code = code;
|
||||
n.can_be_removed = can_be_removed;
|
||||
n.y = offset;
|
||||
n.travel_dist = travel_dist;
|
||||
n.texts = texts;
|
||||
n.shape = shape;
|
||||
int y_pos = offset + ((options.notifications.getVerticalPosition() == "TOP") ? -travel_dist : travel_dist);
|
||||
int y_pos = offset + ((options.notifications.getVerticalPosition() == NotificationPosition::TOP) ? -travel_dist : travel_dist);
|
||||
n.rect = {desp_h, y_pos, width, height};
|
||||
|
||||
// Crea la textura
|
||||
@@ -266,9 +268,9 @@ void Notifier::show(std::vector<std::string> texts, int icon, const std::string
|
||||
// Dibuja el icono de la notificación
|
||||
if (has_icons_ && icon >= 0 && texts.size() >= 2)
|
||||
{
|
||||
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->setClip({icon_size * (icon % 10), icon_size * (icon / 10), icon_size, icon_size});
|
||||
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->setClip({ICON_SIZE_ * (icon % 10), ICON_SIZE_ * (icon / 10), ICON_SIZE_, ICON_SIZE_});
|
||||
sp->render();
|
||||
}
|
||||
|
||||
@@ -276,8 +278,15 @@ void Notifier::show(std::vector<std::string> texts, int icon, const std::string
|
||||
const Color color{255, 255, 255};
|
||||
int iterator = 0;
|
||||
for (const auto &text : texts)
|
||||
{
|
||||
if (text_is == NotificationText::LEFT)
|
||||
{
|
||||
text_->writeColored(padding_in_h + icon_space, padding_in_v + iterator * (text_->getCharacterSize() + 1), text, color);
|
||||
}
|
||||
else if (text_is == NotificationText::CENTER)
|
||||
{
|
||||
text_->writeDX(TEXT_CENTER | TEXT_COLOR, width / 2, padding_in_v + iterator * (text_->getCharacterSize() + 1), text, 1, color);
|
||||
}
|
||||
++iterator;
|
||||
}
|
||||
|
||||
@@ -301,9 +310,12 @@ bool Notifier::isActive() { return !notifications_.empty(); }
|
||||
void Notifier::clearNotifications()
|
||||
{
|
||||
for (auto ¬ification : notifications_)
|
||||
{
|
||||
if (notification.can_be_removed)
|
||||
{
|
||||
notification.state = NotificationStatus::FINISHED;
|
||||
}
|
||||
}
|
||||
|
||||
clearFinishedNotifications();
|
||||
}
|
||||
|
||||
@@ -10,9 +10,19 @@ class Sprite; // lines 9-9
|
||||
class Text; // lines 10-10
|
||||
class Texture; // lines 11-11
|
||||
|
||||
enum class NotificationText
|
||||
{
|
||||
LEFT,
|
||||
CENTER,
|
||||
};
|
||||
|
||||
class Notifier
|
||||
{
|
||||
private:
|
||||
// Constantes
|
||||
static constexpr int ICON_SIZE_ = 16;
|
||||
static constexpr int PADDING_OUT_ = 0;
|
||||
|
||||
// [SINGLETON] Objeto notifier
|
||||
static Notifier *notifier_;
|
||||
|
||||
@@ -42,11 +52,14 @@ private:
|
||||
int y;
|
||||
int travel_dist;
|
||||
std::string code; // Permite asignar un código a la notificación
|
||||
bool can_be_removed;
|
||||
int height;
|
||||
|
||||
// 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("") {}
|
||||
shape(NotificationShape::SQUARED), rect{0, 0, 0, 0}, y(0), travel_dist(0), code(""),
|
||||
can_be_removed(true), height(0) {}
|
||||
};
|
||||
|
||||
// Objetos y punteros
|
||||
@@ -71,14 +84,14 @@ private:
|
||||
// [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos notifier desde fuera
|
||||
|
||||
// Constructor
|
||||
Notifier(std::string icon_file, std::shared_ptr<Text> text);
|
||||
Notifier(const std::string &icon_file, const std::string &text);
|
||||
|
||||
// Destructor
|
||||
~Notifier() = default;
|
||||
|
||||
public:
|
||||
// [SINGLETON] Crearemos el objeto con esta función estática
|
||||
static void init(const std::string &icon_file, std::shared_ptr<Text> text);
|
||||
static void init(const std::string &icon_file, const std::string &text);
|
||||
|
||||
// [SINGLETON] Destruiremos el objeto con esta función estática
|
||||
static void destroy();
|
||||
@@ -93,7 +106,7 @@ public:
|
||||
void update();
|
||||
|
||||
// Muestra una notificación de texto por pantalla
|
||||
void show(std::vector<std::string> texts, int icon = -1, const std::string &code = std::string());
|
||||
void show(std::vector<std::string> texts, NotificationText text_is = NotificationText::LEFT, int icon = -1, bool can_be_removed = true, const std::string &code = std::string());
|
||||
|
||||
// Indica si hay notificaciones activas
|
||||
bool isActive();
|
||||
|
||||
@@ -53,8 +53,13 @@ bool loadOptionsFromFile(const std::string &file_path)
|
||||
while (std::getline(file, line))
|
||||
{
|
||||
// Elimina espacios en blanco iniciales y finales
|
||||
line = std::string(std::find_if(line.begin(), line.end(), [](int ch) { return !std::isspace(ch); }), line.end());
|
||||
line.erase(std::find_if(line.rbegin(), line.rend(), [](int ch) { return !std::isspace(ch); }).base(), line.end());
|
||||
line = std::string(std::find_if(line.begin(), line.end(), [](int ch)
|
||||
{ return !std::isspace(ch); }),
|
||||
line.end());
|
||||
line.erase(std::find_if(line.rbegin(), line.rend(), [](int ch)
|
||||
{ return !std::isspace(ch); })
|
||||
.base(),
|
||||
line.end());
|
||||
|
||||
// Ignora líneas vacías o comentarios
|
||||
if (line.empty() || line[0] == '#')
|
||||
@@ -107,7 +112,6 @@ bool loadOptionsFromFile(const std::string &file_path)
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
// Guarda las opciones en un fichero
|
||||
bool saveOptionsToFile(const std::string &file_path)
|
||||
{
|
||||
@@ -169,36 +173,105 @@ bool saveOptionsToFile(const std::string &file_path)
|
||||
return success;
|
||||
}
|
||||
|
||||
// Establece las opciones
|
||||
bool setOptions(const std::string &var, const std::string &value)
|
||||
{
|
||||
static const std::unordered_map<std::string, std::function<void(std::string)>> optionHandlers = {
|
||||
{"version", [](std::string v)
|
||||
static const std::unordered_map<std::string, std::function<void(const std::string &)>> optionHandlers = {
|
||||
{"version", [](const std::string &v)
|
||||
{ options.version = v; }},
|
||||
{"keys", [](std::string v)
|
||||
{ options.keys = static_cast<ControlScheme>(safeStoi(v, static_cast<int>(ControlScheme::CURSOR))); }},
|
||||
{"window.zoom", [](std::string v)
|
||||
{ options.window.zoom = safeStoi(v, 1); }},
|
||||
{"video.mode", [](std::string v)
|
||||
{ options.video.mode = safeStoi(v, 0); }},
|
||||
{"video.filter", [](std::string v)
|
||||
{ options.video.filter = static_cast<ScreenFilter>(safeStoi(v, static_cast<int>(DEFAULT_VIDEO_FILTER))); }},
|
||||
{"video.shaders", [](std::string v)
|
||||
{"keys", [](const std::string &v)
|
||||
{
|
||||
int val = safeStoi(v, static_cast<int>(DEFAULT_CONTROL_SCHEME));
|
||||
if (val == static_cast<int>(ControlScheme::CURSOR) || val == static_cast<int>(ControlScheme::OPQA) || val == static_cast<int>(ControlScheme::WASD))
|
||||
{
|
||||
options.keys = static_cast<ControlScheme>(val);
|
||||
}
|
||||
else
|
||||
{
|
||||
options.keys = DEFAULT_CONTROL_SCHEME;
|
||||
}
|
||||
}},
|
||||
{"window.zoom", [](const std::string &v)
|
||||
{
|
||||
int val = safeStoi(v, DEFAULT_WINDOW_ZOOM);
|
||||
if (val > 0)
|
||||
{
|
||||
options.window.zoom = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
options.window.zoom = DEFAULT_WINDOW_ZOOM;
|
||||
}
|
||||
}},
|
||||
{"video.mode", [](const std::string &v)
|
||||
{
|
||||
int val = safeStoi(v, 0);
|
||||
if (val == 0 || val == SDL_WINDOW_FULLSCREEN_DESKTOP)
|
||||
{
|
||||
options.video.mode = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
options.video.mode = 0;
|
||||
}
|
||||
}},
|
||||
{"video.filter", [](const std::string &v)
|
||||
{
|
||||
int val = safeStoi(v, static_cast<int>(DEFAULT_VIDEO_FILTER));
|
||||
if (val == static_cast<int>(ScreenFilter::NEAREST) || val == static_cast<int>(ScreenFilter::LINEAR))
|
||||
{
|
||||
options.video.filter = static_cast<ScreenFilter>(val);
|
||||
}
|
||||
else
|
||||
{
|
||||
options.video.filter = DEFAULT_VIDEO_FILTER;
|
||||
}
|
||||
}},
|
||||
{"video.shaders", [](const std::string &v)
|
||||
{ options.video.shaders = stringToBool(v); }},
|
||||
{"video.vertical_sync", [](std::string v)
|
||||
{"video.vertical_sync", [](const std::string &v)
|
||||
{ options.video.vertical_sync = stringToBool(v); }},
|
||||
{"video.integer_scale", [](std::string v)
|
||||
{"video.integer_scale", [](const std::string &v)
|
||||
{ options.video.integer_scale = stringToBool(v); }},
|
||||
{"video.keep_aspect", [](std::string v)
|
||||
{"video.keep_aspect", [](const std::string &v)
|
||||
{ options.video.keep_aspect = stringToBool(v); }},
|
||||
{"video.border.enabled", [](std::string v)
|
||||
{"video.border.enabled", [](const std::string &v)
|
||||
{ options.video.border.enabled = stringToBool(v); }},
|
||||
{"video.border.width", [](std::string v)
|
||||
{ options.video.border.width = safeStoi(v, 32); }},
|
||||
{"video.border.height", [](std::string v)
|
||||
{ options.video.border.height = safeStoi(v, 24); }},
|
||||
{"video.palette", [](std::string v)
|
||||
{ options.video.palette = static_cast<Palette>(safeStoi(v, static_cast<int>(DEFAULT_PALETTE))); }}};
|
||||
{"video.border.width", [](const std::string &v)
|
||||
{
|
||||
int val = safeStoi(v, DEFAULT_BORDER_WIDTH);
|
||||
if (val > 0)
|
||||
{
|
||||
options.video.border.width = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
options.video.border.width = DEFAULT_BORDER_WIDTH;
|
||||
}
|
||||
}},
|
||||
{"video.border.height", [](const std::string &v)
|
||||
{
|
||||
int val = safeStoi(v, DEFAULT_BORDER_HEIGHT);
|
||||
if (val > 0)
|
||||
{
|
||||
options.video.border.height = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
options.video.border.height = DEFAULT_BORDER_HEIGHT;
|
||||
}
|
||||
}},
|
||||
{"video.palette", [](const std::string &v)
|
||||
{
|
||||
int val = safeStoi(v, static_cast<int>(DEFAULT_PALETTE));
|
||||
if (val == static_cast<int>(Palette::ZXSPECTRUM) || val == static_cast<int>(Palette::ZXARNE))
|
||||
{
|
||||
options.video.palette = static_cast<Palette>(val);
|
||||
}
|
||||
else
|
||||
{
|
||||
options.video.palette = DEFAULT_PALETTE;
|
||||
}
|
||||
}}};
|
||||
|
||||
auto it = optionHandlers.find(var);
|
||||
if (it != optionHandlers.end())
|
||||
|
||||
143
source/options.h
143
source/options.h
@@ -4,6 +4,7 @@
|
||||
#include <string> // for string, basic_string
|
||||
#include "screen.h" // for ScreenFilter
|
||||
#include "utils.h" // for Color, Palette
|
||||
#include <algorithm>
|
||||
|
||||
// Secciones del programa
|
||||
enum class Section
|
||||
@@ -36,11 +37,15 @@ enum class NotificationPosition
|
||||
UPPER_LEFT,
|
||||
UPPER_CENTER,
|
||||
UPPER_RIGHT,
|
||||
MIDDLE_LEFT,
|
||||
MIDDLE_RIGHT,
|
||||
BOTTOM_LEFT,
|
||||
BOTTOM_CENTER,
|
||||
BOTTOM_RIGHT
|
||||
BOTTOM_RIGHT,
|
||||
TOP,
|
||||
BOTTOM,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
CENTER,
|
||||
UNKNOWN,
|
||||
};
|
||||
|
||||
// Tipos de control de teclado
|
||||
@@ -64,6 +69,12 @@ constexpr bool DEFAULT_VIDEO_KEEP_ASPECT = true;
|
||||
constexpr bool DEFAULT_BORDER_ENABLED = true; // Borde activado por defecto
|
||||
constexpr int DEFAULT_BORDER_WIDTH = 32; // Ancho del borde por defecto
|
||||
constexpr int DEFAULT_BORDER_HEIGHT = 24; // Alto del borde por defecto
|
||||
constexpr int DEFAULT_SOUND_VOLUME = 100; // Volumen por defecto de los efectos de sonido
|
||||
constexpr bool DEFAULT_SOUND_ENABLED = true; // Sonido habilitado por defecto
|
||||
constexpr int DEFAULT_MUSIC_VOLUME = 80; // Volumen por defecto de la musica
|
||||
constexpr bool DEFAULT_MUSIC_ENABLED = true; // Musica habilitada por defecto
|
||||
constexpr int DEFAULT_AUDIO_VOLUME = 100; // Volumen por defecto
|
||||
constexpr bool DEFAULT_AUDIO_ENABLED = true; // Audio por defecto
|
||||
constexpr Palette DEFAULT_PALETTE = Palette::ZXSPECTRUM; // Paleta por defecto
|
||||
constexpr Section DEFAULT_SECTION = Section::LOGO; // Sección por defecto
|
||||
constexpr Subsection DEFAULT_SUBSECTION = Subsection::LOGO_TO_INTRO; // Subsección por defecto
|
||||
@@ -72,7 +83,7 @@ constexpr NotificationPosition DEFAULT_NOTIFICATION_POSITION = NotificationPosit
|
||||
constexpr bool DEFAULT_NOTIFICATION_SOUND = true; // Sonido de las notificaciones por defecto
|
||||
const Color DEFAULT_NOTIFICATION_COLOR = Color(48, 48, 48); // Color de las notificaciones por defecto
|
||||
constexpr bool DEFAULT_CONSOLE = false; // Consola desactivada por defecto
|
||||
constexpr std::string DEFAULT_VERSION = "1.09"; // Versión por defecto
|
||||
constexpr const char *DEFAULT_VERSION = "1.09"; // Versión por defecto
|
||||
|
||||
// Estructura para las opciones de las notificaciones
|
||||
struct OptionsNotification
|
||||
@@ -94,43 +105,42 @@ struct OptionsNotification
|
||||
color(c) {}
|
||||
|
||||
// Método que devuelve la posición horizontal
|
||||
std::string getHorizontalPosition() const
|
||||
NotificationPosition getHorizontalPosition() const
|
||||
{
|
||||
switch (pos)
|
||||
{
|
||||
case NotificationPosition::UPPER_LEFT:
|
||||
case NotificationPosition::MIDDLE_LEFT:
|
||||
case NotificationPosition::BOTTOM_LEFT:
|
||||
return "LEFT";
|
||||
return NotificationPosition::LEFT;
|
||||
case NotificationPosition::UPPER_CENTER:
|
||||
case NotificationPosition::BOTTOM_CENTER:
|
||||
return "CENTER";
|
||||
return NotificationPosition::CENTER;
|
||||
case NotificationPosition::UPPER_RIGHT:
|
||||
case NotificationPosition::MIDDLE_RIGHT:
|
||||
case NotificationPosition::BOTTOM_RIGHT:
|
||||
return "RIGHT";
|
||||
return NotificationPosition::RIGHT;
|
||||
default:
|
||||
return NotificationPosition::UNKNOWN;
|
||||
}
|
||||
return "UNKNOWN";
|
||||
return NotificationPosition::UNKNOWN;
|
||||
}
|
||||
|
||||
// Método que devuelve la posición vertical
|
||||
std::string getVerticalPosition() const
|
||||
NotificationPosition getVerticalPosition() const
|
||||
{
|
||||
switch (pos)
|
||||
{
|
||||
case NotificationPosition::UPPER_LEFT:
|
||||
case NotificationPosition::UPPER_CENTER:
|
||||
case NotificationPosition::UPPER_RIGHT:
|
||||
return "UPPER";
|
||||
case NotificationPosition::MIDDLE_LEFT:
|
||||
case NotificationPosition::MIDDLE_RIGHT:
|
||||
return "MIDDLE";
|
||||
return NotificationPosition::TOP;
|
||||
case NotificationPosition::BOTTOM_LEFT:
|
||||
case NotificationPosition::BOTTOM_CENTER:
|
||||
case NotificationPosition::BOTTOM_RIGHT:
|
||||
return "BOTTOM";
|
||||
return NotificationPosition::BOTTOM;
|
||||
default:
|
||||
return NotificationPosition::UNKNOWN;
|
||||
}
|
||||
return "UNKNOWN";
|
||||
return NotificationPosition::UNKNOWN;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -212,14 +222,17 @@ struct OptionsStats
|
||||
struct OptionsWindow
|
||||
{
|
||||
int zoom; // Zoom de la ventana
|
||||
int max_zoom; // Máximo tamaño de zoom para la ventana
|
||||
|
||||
// Constructor por defecto
|
||||
OptionsWindow()
|
||||
: zoom(DEFAULT_WINDOW_ZOOM) {}
|
||||
: zoom(DEFAULT_WINDOW_ZOOM),
|
||||
max_zoom(DEFAULT_WINDOW_ZOOM) {}
|
||||
|
||||
// Constructor
|
||||
OptionsWindow(int z)
|
||||
: zoom(z) {}
|
||||
OptionsWindow(int z, int mz)
|
||||
: zoom(z),
|
||||
max_zoom(mz) {}
|
||||
};
|
||||
|
||||
// Estructura para gestionar el borde de la pantalla
|
||||
@@ -277,6 +290,89 @@ struct OptionsVideo
|
||||
palette(p) {}
|
||||
};
|
||||
|
||||
// Estructura para las opciones de musica
|
||||
struct OptionsMusic
|
||||
{
|
||||
bool enabled; // Indica si la música suena o no
|
||||
int volume; // Volumen al que suena la música (0 a 128 internamente)
|
||||
|
||||
// Constructor por defecto
|
||||
OptionsMusic()
|
||||
: enabled(DEFAULT_MUSIC_ENABLED),
|
||||
volume(convertVolume(DEFAULT_MUSIC_VOLUME)) {} // Usa el método estático para la conversión
|
||||
|
||||
// Constructor con parámetros
|
||||
OptionsMusic(bool e, int v)
|
||||
: enabled(e),
|
||||
volume(convertVolume(v)) {} // Convierte el volumen usando el método estático
|
||||
|
||||
// Método para establecer el volumen
|
||||
void setVolume(int v)
|
||||
{
|
||||
v = std::clamp(v, 0, 100); // Ajusta v al rango [0, 100]
|
||||
volume = convertVolume(v); // Convierte al rango interno
|
||||
}
|
||||
|
||||
// Método estático para convertir de 0-100 a 0-128
|
||||
static int convertVolume(int v)
|
||||
{
|
||||
return (v * 128) / 100;
|
||||
}
|
||||
};
|
||||
|
||||
// Estructura para las opciones de sonido
|
||||
struct OptionsSound
|
||||
{
|
||||
bool enabled; // Indica si los sonidos suenan o no
|
||||
int volume; // Volumen al que suenan los sonidos (0 a 128 internamente)
|
||||
|
||||
// Constructor por defecto
|
||||
OptionsSound()
|
||||
: enabled(DEFAULT_SOUND_ENABLED),
|
||||
volume(convertVolume(DEFAULT_SOUND_VOLUME)) {} // Usa el método estático para la conversión
|
||||
|
||||
// Constructor con parámetros
|
||||
OptionsSound(bool e, int v)
|
||||
: enabled(e),
|
||||
volume(convertVolume(v)) {} // También lo integra aquí
|
||||
|
||||
// Método para establecer el volumen
|
||||
void setVolume(int v)
|
||||
{
|
||||
v = std::clamp(v, 0, 100); // Ajusta v al rango [0, 100]
|
||||
volume = convertVolume(v); // Convierte al rango interno
|
||||
}
|
||||
|
||||
// Método estático para convertir de 0-100 a 0-128
|
||||
static int convertVolume(int v)
|
||||
{
|
||||
return (v * 128) / 100;
|
||||
}
|
||||
};
|
||||
|
||||
// Estructura para las opciones de audio
|
||||
struct OptionsAudio
|
||||
{
|
||||
OptionsMusic music; // Opciones para la música
|
||||
OptionsSound sound; // Opciones para los efectos de sonido
|
||||
bool enabled; // Indica si el audio está activo o no
|
||||
int volume; // Volumen al que suenan el audio
|
||||
|
||||
// Constructor por defecto
|
||||
OptionsAudio()
|
||||
: music(OptionsMusic()),
|
||||
sound(OptionsSound()),
|
||||
enabled(DEFAULT_AUDIO_ENABLED),
|
||||
volume(DEFAULT_AUDIO_VOLUME) {}
|
||||
|
||||
// Constructor
|
||||
OptionsAudio(OptionsMusic m, OptionsSound s, bool e, int v)
|
||||
: music(m),
|
||||
sound(s),
|
||||
enabled(e),
|
||||
volume(v) {}
|
||||
};
|
||||
|
||||
// Estructura para las opciones de juego
|
||||
struct OptionsGame
|
||||
{
|
||||
@@ -305,6 +401,7 @@ struct Options
|
||||
OptionsStats stats; // Datos con las estadisticas de juego
|
||||
OptionsNotification notifications; // Opciones relativas a las notificaciones;
|
||||
OptionsWindow window; // Opciones relativas a la ventana
|
||||
OptionsAudio audio; // Opciones relativas al audio
|
||||
ControlScheme keys; // Teclas usadas para jugar
|
||||
SectionState section; // Sección actual del programa
|
||||
|
||||
@@ -318,11 +415,12 @@ struct Options
|
||||
stats(OptionsStats()),
|
||||
notifications(OptionsNotification()),
|
||||
window(OptionsWindow()),
|
||||
audio(OptionsAudio()),
|
||||
keys(DEFAULT_CONTROL_SCHEME),
|
||||
section(SectionState()) {}
|
||||
|
||||
// Constructor
|
||||
Options(std::string cv, bool c, Cheat ch, OptionsGame g, OptionsVideo v, OptionsStats s, OptionsNotification n, OptionsWindow sw, ControlScheme k, SectionState sec)
|
||||
Options(std::string cv, bool c, Cheat ch, OptionsGame g, OptionsVideo v, OptionsStats s, OptionsNotification n, OptionsWindow sw, OptionsAudio a, ControlScheme k, SectionState sec)
|
||||
: version(cv),
|
||||
console(c),
|
||||
cheats(ch),
|
||||
@@ -331,6 +429,7 @@ struct Options
|
||||
stats(s),
|
||||
notifications(n),
|
||||
window(sw),
|
||||
audio(a),
|
||||
keys(k),
|
||||
section(sec) {}
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <fcntl.h> // Para SEEK_END, SEEK_SET
|
||||
#include <stdio.h> // Para NULL, fseek, fclose, fopen, fread, ftell
|
||||
#include <stdlib.h> // Para malloc, free
|
||||
#include "gif.c" // Para LoadGif, LoadPalette
|
||||
#include "gif.h" // Para LoadGif, LoadPalette
|
||||
|
||||
struct jSurface_s
|
||||
{
|
||||
|
||||
@@ -16,99 +16,32 @@
|
||||
#include "screen.h"
|
||||
|
||||
// Constructor
|
||||
Player::Player(player_t player)
|
||||
Player::Player(PlayerData player)
|
||||
: renderer_(Screen::get()->getRenderer()),
|
||||
input_(Input::get()),
|
||||
resource_(Resource::get()),
|
||||
asset_(Asset::get()),
|
||||
debug_(Debug::get()),
|
||||
room_(player.room)
|
||||
{
|
||||
// Crea objetos
|
||||
sprite_ = std::make_shared<AnimatedSprite>(resource_->getTexture(player.png), resource_->getAnimation(player.animation));
|
||||
// Inicializa algunas variables
|
||||
initSprite(player.texture_path, player.animations_path);
|
||||
setColor();
|
||||
applySpawnValues(player.spawn);
|
||||
placeSprite();
|
||||
initSounds();
|
||||
|
||||
// Inicializa variables
|
||||
reLoadPalette();
|
||||
is_on_border_ = false;
|
||||
border_ = BORDER_TOP;
|
||||
auto_movement_ = false;
|
||||
is_alive_ = true;
|
||||
is_paused_ = false;
|
||||
|
||||
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;
|
||||
|
||||
sprite_->setPosX(player.spawn.x);
|
||||
sprite_->setPosY(player.spawn.y);
|
||||
sprite_->setWidth(8);
|
||||
sprite_->setHeight(16);
|
||||
|
||||
sprite_->setFlip(player.spawn.flip);
|
||||
sprite_->setCurrentAnimation("walk");
|
||||
sprite_->update();
|
||||
|
||||
last_position_ = getRect();
|
||||
collider_box_ = getRect();
|
||||
const SDL_Point p = {0, 0};
|
||||
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()));
|
||||
|
||||
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()));
|
||||
|
||||
jumping_counter_ = 0;
|
||||
falling_counter_ = 0;
|
||||
collider_points_.resize(collider_points_.size() + 8, {0, 0});
|
||||
under_feet_.resize(under_feet_.size() + 2, {0, 0});
|
||||
feet_.resize(feet_.size() + 2, {0, 0});
|
||||
|
||||
#ifdef DEBUG
|
||||
rx = {0, 0, 0, 0};
|
||||
ry = {0, 0, 0, 0};
|
||||
debugColor = {0, 255, 0};
|
||||
debugPoint = {0, 0};
|
||||
debug_rect_x_ = {0, 0, 0, 0};
|
||||
debug_rect_y_ = {0, 0, 0, 0};
|
||||
debug_color_ = {0, 255, 0};
|
||||
debug_point_ = {0, 0};
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -119,59 +52,29 @@ void Player::render()
|
||||
sprite_->render();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debug_->getEnabled())
|
||||
{
|
||||
// Pinta los underfeet
|
||||
SDL_SetRenderDrawColor(renderer_, 255, 0, 255, 255);
|
||||
SDL_RenderDrawPoint(renderer_, under_feet_[0].x, under_feet_[0].y);
|
||||
SDL_RenderDrawPoint(renderer_, under_feet_[1].x, under_feet_[1].y);
|
||||
|
||||
// Pinta rectangulo del jugador
|
||||
SDL_SetRenderDrawColor(renderer_, debugColor.r, debugColor.g, debugColor.b, 192);
|
||||
SDL_Rect rect = getRect();
|
||||
SDL_RenderFillRect(renderer_, &rect);
|
||||
SDL_SetRenderDrawColor(renderer_, 0, 255, 255, 255);
|
||||
SDL_RenderDrawRect(renderer_, &rect);
|
||||
|
||||
// Pinta el rectangulo de movimiento
|
||||
SDL_SetRenderDrawColor(renderer_, 255, 0, 0, 255);
|
||||
if (vx_ != 0.0f)
|
||||
{
|
||||
SDL_RenderFillRect(renderer_, &rx);
|
||||
}
|
||||
if (vy_ != 0.0f)
|
||||
{
|
||||
SDL_RenderFillRect(renderer_, &ry);
|
||||
}
|
||||
|
||||
// Pinta el punto de debug
|
||||
SDL_SetRenderDrawColor(renderer_, rand() % 256, rand() % 256, rand() % 256, 255);
|
||||
SDL_RenderDrawPoint(renderer_, debugPoint.x, debugPoint.y);
|
||||
}
|
||||
renderDebugInfo();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Actualiza las variables del objeto
|
||||
void Player::update()
|
||||
{
|
||||
if (is_paused_)
|
||||
{ // Si está en modo pausa no se actualiza nada
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_paused_)
|
||||
{
|
||||
checkInput(); // Comprueba las entradas y modifica variables
|
||||
move(); // Recalcula la posición del jugador
|
||||
animate(); // Establece la animación del jugador
|
||||
checkBorders(); // Comprueba si está situado en alguno de los cuatro bordes de la habitación
|
||||
checkJumpEnd(); // Comprueba si ha finalizado el salto al alcanzar la altura de inicio
|
||||
checkKillingTiles(); // Comprueba que el jugador no toque ningun tile de los que matan
|
||||
checkKillingTiles(); // Comprueba que el jugador no toque ningun tile de los que matan}
|
||||
}
|
||||
}
|
||||
|
||||
// Comprueba las entradas y modifica variables
|
||||
void Player::checkInput()
|
||||
{
|
||||
// Solo comprueba las entradas de dirección cuando está sobre una superficie
|
||||
if (state_ != s_standing)
|
||||
if (state_ != PlayerState::STANDING)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -192,10 +95,12 @@ void Player::checkInput()
|
||||
}
|
||||
|
||||
else
|
||||
{ // No se pulsa ninguna dirección
|
||||
{
|
||||
// No se pulsa ninguna dirección
|
||||
vx_ = 0.0f;
|
||||
if (isOnAutoSurface())
|
||||
{ // Si deja de moverse sobre una superficie se engancha
|
||||
{
|
||||
// Si deja de moverse sobre una superficie se engancha
|
||||
auto_movement_ = true;
|
||||
}
|
||||
}
|
||||
@@ -223,7 +128,7 @@ void Player::checkInput()
|
||||
|
||||
if (isOnFloor() || isOnAutoSurface())
|
||||
{
|
||||
setState(s_jumping);
|
||||
setState(PlayerState::JUMPING);
|
||||
vy_ = -MAX_VY_;
|
||||
jump_init_pos_ = y_;
|
||||
jumping_counter_ = 0;
|
||||
@@ -231,18 +136,6 @@ void Player::checkInput()
|
||||
}
|
||||
}
|
||||
|
||||
// Indica si el jugador esta en uno de los cuatro bordes de la pantalla
|
||||
bool Player::getOnBorder()
|
||||
{
|
||||
return is_on_border_;
|
||||
}
|
||||
|
||||
// Indica en cual de los cuatro bordes se encuentra
|
||||
int Player::getBorder()
|
||||
{
|
||||
return border_;
|
||||
}
|
||||
|
||||
// Comprueba si está situado en alguno de los cuatro bordes de la habitación
|
||||
void Player::checkBorders()
|
||||
{
|
||||
@@ -252,7 +145,7 @@ void Player::checkBorders()
|
||||
is_on_border_ = true;
|
||||
}
|
||||
|
||||
else if (x_ + w_ > PLAY_AREA_RIGHT)
|
||||
else if (x_ + WIDTH_ > PLAY_AREA_RIGHT)
|
||||
{
|
||||
border_ = BORDER_RIGHT;
|
||||
is_on_border_ = true;
|
||||
@@ -264,7 +157,7 @@ void Player::checkBorders()
|
||||
is_on_border_ = true;
|
||||
}
|
||||
|
||||
else if (y_ + h_ > PLAY_AREA_BOTTOM)
|
||||
else if (y_ + HEIGHT_ > PLAY_AREA_BOTTOM)
|
||||
{
|
||||
border_ = BORDER_BOTTOM;
|
||||
is_on_border_ = true;
|
||||
@@ -280,7 +173,7 @@ void Player::checkBorders()
|
||||
void Player::checkState()
|
||||
{
|
||||
// Actualiza las variables en función del estado
|
||||
if (state_ == s_falling)
|
||||
if (state_ == PlayerState::FALLING)
|
||||
{
|
||||
vx_ = 0.0f;
|
||||
vy_ = MAX_VY_;
|
||||
@@ -288,9 +181,9 @@ void Player::checkState()
|
||||
playFallSound();
|
||||
}
|
||||
|
||||
else if (state_ == s_standing)
|
||||
else if (state_ == PlayerState::STANDING)
|
||||
{
|
||||
if (previous_state_ == s_falling && falling_counter_ > MAX_FALLING_HEIGHT_)
|
||||
if (previous_state_ == PlayerState::FALLING && falling_counter_ > MAX_FALLING_HEIGHT_)
|
||||
{ // Si cae de muy alto, el jugador muere
|
||||
is_alive_ = false;
|
||||
}
|
||||
@@ -299,7 +192,7 @@ void Player::checkState()
|
||||
falling_counter_ = 0;
|
||||
if (!isOnFloor() && !isOnAutoSurface() && !isOnDownSlope())
|
||||
{
|
||||
setState(s_falling);
|
||||
setState(PlayerState::FALLING);
|
||||
vx_ = 0.0f;
|
||||
vy_ = MAX_VY_;
|
||||
falling_counter_++;
|
||||
@@ -307,7 +200,7 @@ void Player::checkState()
|
||||
}
|
||||
}
|
||||
|
||||
else if (state_ == s_jumping)
|
||||
else if (state_ == PlayerState::JUMPING)
|
||||
{
|
||||
falling_counter_ = 0;
|
||||
jumping_counter_++;
|
||||
@@ -320,13 +213,13 @@ void Player::switchBorders()
|
||||
{
|
||||
if (border_ == BORDER_TOP)
|
||||
{
|
||||
y_ = PLAY_AREA_BOTTOM - h_ - 0 - BLOCK;
|
||||
setState(s_standing);
|
||||
y_ = PLAY_AREA_BOTTOM - HEIGHT_ - 0 - BLOCK;
|
||||
setState(PlayerState::STANDING);
|
||||
}
|
||||
else if (border_ == BORDER_BOTTOM)
|
||||
{
|
||||
y_ = PLAY_AREA_TOP + 0;
|
||||
setState(s_standing);
|
||||
setState(PlayerState::STANDING);
|
||||
}
|
||||
else if (border_ == BORDER_RIGHT)
|
||||
{
|
||||
@@ -334,7 +227,7 @@ void Player::switchBorders()
|
||||
}
|
||||
if (border_ == BORDER_LEFT)
|
||||
{
|
||||
x_ = PLAY_AREA_RIGHT - w_ - 0;
|
||||
x_ = PLAY_AREA_RIGHT - WIDTH_ - 0;
|
||||
}
|
||||
|
||||
is_on_border_ = false;
|
||||
@@ -347,7 +240,7 @@ void Player::applyGravity()
|
||||
|
||||
// La gravedad solo se aplica cuando el jugador esta saltando
|
||||
// Nunca mientras cae o esta de pie
|
||||
if (state_ == s_jumping)
|
||||
if (state_ == PlayerState::JUMPING)
|
||||
{
|
||||
vy_ += GF;
|
||||
if (vy_ > MAX_VY_)
|
||||
@@ -357,19 +250,6 @@ void Player::applyGravity()
|
||||
}
|
||||
}
|
||||
|
||||
// Obtiene el rectangulo que delimita al jugador
|
||||
SDL_Rect Player::getRect()
|
||||
{
|
||||
return {static_cast<int>(x_), static_cast<int>(y_), w_, h_};
|
||||
}
|
||||
|
||||
// Obtiene el rectangulo de colision del jugador
|
||||
SDL_Rect &Player::getCollider()
|
||||
{
|
||||
collider_box_ = getRect();
|
||||
return collider_box_;
|
||||
}
|
||||
|
||||
// Recalcula la posición del jugador y su animación
|
||||
void Player::move()
|
||||
{
|
||||
@@ -378,7 +258,7 @@ void Player::move()
|
||||
checkState(); // Comprueba el estado del jugador
|
||||
|
||||
#ifdef DEBUG
|
||||
debugColor = {0, 255, 0};
|
||||
debug_color_ = {0, 255, 0};
|
||||
#endif
|
||||
|
||||
// Se mueve hacia la izquierda
|
||||
@@ -388,11 +268,11 @@ void Player::move()
|
||||
SDL_Rect proj;
|
||||
proj.x = static_cast<int>(x_ + vx_);
|
||||
proj.y = static_cast<int>(y_);
|
||||
proj.h = h_;
|
||||
proj.h = HEIGHT_;
|
||||
proj.w = ceil(abs(vx_)); // Para evitar que tenga un ancho de 0 pixels
|
||||
|
||||
#ifdef DEBUG
|
||||
rx = proj;
|
||||
debug_rect_x_ = proj;
|
||||
#endif
|
||||
|
||||
// Comprueba la colisión con las superficies
|
||||
@@ -411,18 +291,18 @@ void Player::move()
|
||||
}
|
||||
|
||||
// Si ha tocado alguna rampa mientras camina (sin saltar), asciende
|
||||
if (state_ != s_jumping)
|
||||
if (state_ != PlayerState::JUMPING)
|
||||
{
|
||||
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
|
||||
v_line_t leftSide = {static_cast<int>(x_), static_cast<int>(y_) + HEIGHT_ - 2, static_cast<int>(y_) + HEIGHT_ - 1}; // Comprueba solo los dos pixels de abajo
|
||||
const int ly = room_->checkLeftSlopes(&leftSide);
|
||||
if (ly > -1)
|
||||
{
|
||||
y_ = ly - h_;
|
||||
y_ = ly - HEIGHT_;
|
||||
}
|
||||
}
|
||||
|
||||
// Si está bajando la rampa, recoloca al jugador
|
||||
if (isOnDownSlope() && state_ != s_jumping)
|
||||
if (isOnDownSlope() && state_ != PlayerState::JUMPING)
|
||||
{
|
||||
y_ += 1;
|
||||
}
|
||||
@@ -433,13 +313,13 @@ void Player::move()
|
||||
{
|
||||
// Crea el rectangulo de proyección en el eje X para ver si colisiona
|
||||
SDL_Rect proj;
|
||||
proj.x = static_cast<int>(x_) + w_;
|
||||
proj.x = static_cast<int>(x_) + WIDTH_;
|
||||
proj.y = static_cast<int>(y_);
|
||||
proj.h = h_;
|
||||
proj.h = HEIGHT_;
|
||||
proj.w = ceil(vx_); // Para evitar que tenga un ancho de 0 pixels
|
||||
|
||||
#ifdef DEBUG
|
||||
rx = proj;
|
||||
debug_rect_x_ = proj;
|
||||
#endif
|
||||
|
||||
// Comprueba la colisión
|
||||
@@ -454,38 +334,38 @@ void Player::move()
|
||||
else
|
||||
{
|
||||
// Si hay colisión lo mueve hasta donde no colisiona
|
||||
x_ = pos - w_;
|
||||
x_ = pos - WIDTH_;
|
||||
}
|
||||
|
||||
// Si ha tocado alguna rampa mientras camina (sin saltar), asciende
|
||||
if (state_ != s_jumping)
|
||||
if (state_ != PlayerState::JUMPING)
|
||||
{
|
||||
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
|
||||
v_line_t rightSide = {static_cast<int>(x_) + WIDTH_ - 1, static_cast<int>(y_) + HEIGHT_ - 2, static_cast<int>(y_) + HEIGHT_ - 1}; // Comprueba solo los dos pixels de abajo
|
||||
const int ry = room_->checkRightSlopes(&rightSide);
|
||||
if (ry > -1)
|
||||
{
|
||||
y_ = ry - h_;
|
||||
y_ = ry - HEIGHT_;
|
||||
}
|
||||
}
|
||||
|
||||
// Si está bajando la rampa, recoloca al jugador
|
||||
if (isOnDownSlope() && state_ != s_jumping)
|
||||
if (isOnDownSlope() && state_ != PlayerState::JUMPING)
|
||||
{
|
||||
y_ += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Si ha salido del suelo, el jugador cae
|
||||
if (state_ == s_standing && !isOnFloor())
|
||||
if (state_ == PlayerState::STANDING && !isOnFloor())
|
||||
{
|
||||
setState(s_falling);
|
||||
setState(PlayerState::FALLING);
|
||||
|
||||
// Deja de estar enganchado a la superficie automatica
|
||||
auto_movement_ = false;
|
||||
}
|
||||
|
||||
// Si ha salido de una superficie automatica, detiene el movimiento automatico
|
||||
if (state_ == s_standing && isOnFloor() && !isOnAutoSurface())
|
||||
if (state_ == PlayerState::STANDING && isOnFloor() && !isOnAutoSurface())
|
||||
{
|
||||
// Deja de estar enganchado a la superficie automatica
|
||||
auto_movement_ = false;
|
||||
@@ -499,10 +379,10 @@ void Player::move()
|
||||
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_;
|
||||
proj.w = WIDTH_;
|
||||
|
||||
#ifdef DEBUG
|
||||
ry = proj;
|
||||
debug_rect_y_ = proj;
|
||||
#endif
|
||||
|
||||
// Comprueba la colisión
|
||||
@@ -518,7 +398,7 @@ void Player::move()
|
||||
{
|
||||
// Si hay colisión lo mueve hasta donde no colisiona y entra en caída
|
||||
y_ = pos + 1;
|
||||
setState(s_falling);
|
||||
setState(PlayerState::FALLING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -528,12 +408,12 @@ void Player::move()
|
||||
// Crea el rectangulo de proyección en el eje Y para ver si colisiona
|
||||
SDL_Rect proj;
|
||||
proj.x = static_cast<int>(x_);
|
||||
proj.y = static_cast<int>(y_) + h_;
|
||||
proj.y = static_cast<int>(y_) + HEIGHT_;
|
||||
proj.h = ceil(vy_); // Para evitar que tenga una altura de 0 pixels
|
||||
proj.w = w_;
|
||||
proj.w = WIDTH_;
|
||||
|
||||
#ifdef DEBUG
|
||||
ry = proj;
|
||||
debug_rect_y_ = proj;
|
||||
#endif
|
||||
|
||||
// Comprueba la colisión con las superficies normales y las automáticas
|
||||
@@ -541,8 +421,8 @@ void Player::move()
|
||||
if (pos > -1)
|
||||
{
|
||||
// Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre la superficie
|
||||
y_ = pos - h_;
|
||||
setState(s_standing);
|
||||
y_ = pos - HEIGHT_;
|
||||
setState(PlayerState::STANDING);
|
||||
|
||||
// Deja de estar enganchado a la superficie automatica
|
||||
auto_movement_ = false;
|
||||
@@ -550,7 +430,7 @@ void Player::move()
|
||||
else
|
||||
{
|
||||
// Si no hay colisión con los muros, comprueba la colisión con las rampas
|
||||
if (state_ != s_jumping)
|
||||
if (state_ != PlayerState::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};
|
||||
@@ -559,11 +439,11 @@ void Player::move()
|
||||
{
|
||||
// No está saltando y hay colisión con una rampa
|
||||
// Calcula la nueva posición
|
||||
y_ = p - h_;
|
||||
setState(s_standing);
|
||||
y_ = p - HEIGHT_;
|
||||
setState(PlayerState::STANDING);
|
||||
#ifdef DEBUG
|
||||
debugColor = {255, 255, 0};
|
||||
debugPoint = {(int)x_ + (w_ / 2), p};
|
||||
debug_color_ = {255, 255, 0};
|
||||
debug_point_ = {(int)x_ + (WIDTH_ / 2), p};
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -572,7 +452,7 @@ void Player::move()
|
||||
// Calcula la nueva posición
|
||||
y_ += vy_;
|
||||
#ifdef DEBUG
|
||||
debugColor = {255, 0, 0};
|
||||
debug_color_ = {255, 0, 0};
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -585,13 +465,12 @@ void Player::move()
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza la posición del sprite
|
||||
sprite_->setPosX(x_);
|
||||
sprite_->setPosY(y_);
|
||||
placeSprite(); // Coloca el sprite en la nueva posición
|
||||
collider_box_ = getRect(); // Actualiza el rectangulo de colisión
|
||||
|
||||
#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));
|
||||
debug_->add("RECT_Y: " + std::to_string(ry.x) + "," + std::to_string(ry.y) + "," + std::to_string(ry.w) + "," + std::to_string(ry.h));
|
||||
debug_->add("RECT_X: " + std::to_string(debug_rect_x_.x) + "," + std::to_string(debug_rect_x_.y) + "," + std::to_string(debug_rect_x_.w) + "," + std::to_string(debug_rect_x_.h));
|
||||
debug_->add("RECT_Y: " + std::to_string(debug_rect_y_.x) + "," + std::to_string(debug_rect_y_.y) + "," + std::to_string(debug_rect_y_.w) + "," + std::to_string(debug_rect_y_.h));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -607,14 +486,14 @@ void Player::animate()
|
||||
// Comprueba si ha finalizado el salto al alcanzar la altura de inicio
|
||||
void Player::checkJumpEnd()
|
||||
{
|
||||
if (state_ == s_jumping)
|
||||
if (state_ == PlayerState::JUMPING)
|
||||
{
|
||||
if (vy_ > 0)
|
||||
{
|
||||
if (y_ >= jump_init_pos_)
|
||||
{
|
||||
// Si alcanza la altura de salto inicial, pasa al estado de caída
|
||||
setState(s_falling);
|
||||
setState(PlayerState::FALLING);
|
||||
vy_ = MAX_VY_;
|
||||
jumping_counter_ = 0;
|
||||
}
|
||||
@@ -760,46 +639,21 @@ bool Player::checkKillingTiles()
|
||||
return check;
|
||||
}
|
||||
|
||||
// Obtiene algunos parametros del jugador
|
||||
playerSpawn_t Player::getSpawnParams()
|
||||
// Establece el color del jugador
|
||||
void Player::setColor()
|
||||
{
|
||||
playerSpawn_t params;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Recarga la textura
|
||||
void Player::reLoadTexture()
|
||||
{
|
||||
sprite_->getTexture()->reLoad();
|
||||
}
|
||||
|
||||
// Recarga la paleta
|
||||
void Player::reLoadPalette()
|
||||
{
|
||||
color_ = stringToColor(options.video.palette, "white");
|
||||
if (options.cheats.infinite_lives == Cheat::CheatState::ENABLED)
|
||||
{
|
||||
color_ = stringToColor(options.video.palette, "yellow");
|
||||
}
|
||||
if (options.cheats.invincible == Cheat::CheatState::ENABLED)
|
||||
{
|
||||
color_ = stringToColor(options.video.palette, "cyan");
|
||||
}
|
||||
}
|
||||
|
||||
// Establece el valor de la variable
|
||||
void Player::setRoom(std::shared_ptr<Room> room)
|
||||
else if (options.cheats.infinite_lives == Cheat::CheatState::ENABLED)
|
||||
{
|
||||
room_ = room;
|
||||
color_ = stringToColor(options.video.palette, "yellow");
|
||||
}
|
||||
else
|
||||
{
|
||||
color_ = stringToColor(options.video.palette, "white");
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza los puntos de colisión
|
||||
@@ -821,15 +675,15 @@ void Player::updateFeet()
|
||||
{
|
||||
const SDL_Point p = {static_cast<int>(x_), static_cast<int>(y_)};
|
||||
|
||||
under_feet_[0] = {p.x, p.y + h_};
|
||||
under_feet_[1] = {p.x + 7, p.y + h_};
|
||||
under_feet_[0] = {p.x, p.y + HEIGHT_};
|
||||
under_feet_[1] = {p.x + 7, p.y + HEIGHT_};
|
||||
|
||||
feet_[0] = {p.x, p.y + h_ - 1};
|
||||
feet_[1] = {p.x + 7, p.y + h_ - 1};
|
||||
feet_[0] = {p.x, p.y + HEIGHT_ - 1};
|
||||
feet_[1] = {p.x + 7, p.y + HEIGHT_ - 1};
|
||||
}
|
||||
|
||||
// Cambia el estado del jugador
|
||||
void Player::setState(state_e value)
|
||||
void Player::setState(PlayerState value)
|
||||
{
|
||||
previous_state_ = state_;
|
||||
state_ = value;
|
||||
@@ -837,20 +691,87 @@ void Player::setState(state_e value)
|
||||
checkState();
|
||||
}
|
||||
|
||||
// Comprueba si el jugador esta vivo
|
||||
bool Player::isAlive()
|
||||
// Inicializa los sonidos de salto y caida
|
||||
void Player::initSounds()
|
||||
{
|
||||
return is_alive_;
|
||||
jumping_sound_.clear();
|
||||
falling_sound_.clear();
|
||||
|
||||
for (int i = 1; i <= 24; ++i)
|
||||
{
|
||||
std::string soundFile = "jump" + std::to_string(i) + ".wav";
|
||||
jumping_sound_.push_back(Resource::get()->getSound(soundFile));
|
||||
|
||||
if (i >= 11)
|
||||
{
|
||||
falling_sound_.push_back(Resource::get()->getSound(soundFile));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pone el jugador en modo pausa
|
||||
void Player::pause()
|
||||
// Coloca el sprite en la posición del jugador
|
||||
void Player::placeSprite()
|
||||
{
|
||||
is_paused_ = true;
|
||||
sprite_->setPosX(x_);
|
||||
sprite_->setPosY(y_);
|
||||
}
|
||||
|
||||
// Quita el modo pausa del jugador
|
||||
void Player::resume()
|
||||
// Aplica los valores de spawn al jugador
|
||||
void Player::applySpawnValues(const PlayerSpawn &spawn)
|
||||
{
|
||||
is_paused_ = false;
|
||||
x_ = spawn.x;
|
||||
y_ = spawn.y;
|
||||
vx_ = spawn.vx;
|
||||
vy_ = spawn.vy;
|
||||
jump_init_pos_ = spawn.jump_init_pos;
|
||||
state_ = spawn.state;
|
||||
sprite_->setFlip(spawn.flip);
|
||||
}
|
||||
|
||||
// Inicializa el sprite del jugador
|
||||
void Player::initSprite(const std::string &texture_path, const std::string &animations_path)
|
||||
{
|
||||
auto texture = Resource::get()->getTexture(texture_path);
|
||||
auto animations = Resource::get()->getAnimations(animations_path);
|
||||
|
||||
sprite_ = std::make_shared<AnimatedSprite>(texture, animations);
|
||||
sprite_->setWidth(WIDTH_);
|
||||
sprite_->setHeight(HEIGHT_);
|
||||
sprite_->setCurrentAnimation("walk");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Pinta la información de debug del jugador
|
||||
void Player::renderDebugInfo()
|
||||
{
|
||||
if (debug_->getEnabled())
|
||||
{
|
||||
// Pinta los underfeet
|
||||
SDL_SetRenderDrawColor(renderer_, 255, 0, 255, 255);
|
||||
SDL_RenderDrawPoint(renderer_, under_feet_[0].x, under_feet_[0].y);
|
||||
SDL_RenderDrawPoint(renderer_, under_feet_[1].x, under_feet_[1].y);
|
||||
|
||||
// Pinta rectangulo del jugador
|
||||
SDL_SetRenderDrawColor(renderer_, debug_color_.r, debug_color_.g, debug_color_.b, 192);
|
||||
SDL_Rect rect = getRect();
|
||||
SDL_RenderFillRect(renderer_, &rect);
|
||||
SDL_SetRenderDrawColor(renderer_, 0, 255, 255, 255);
|
||||
SDL_RenderDrawRect(renderer_, &rect);
|
||||
|
||||
// Pinta el rectangulo de movimiento
|
||||
SDL_SetRenderDrawColor(renderer_, 255, 0, 0, 255);
|
||||
if (vx_ != 0.0f)
|
||||
{
|
||||
SDL_RenderFillRect(renderer_, &debug_rect_x_);
|
||||
}
|
||||
if (vy_ != 0.0f)
|
||||
{
|
||||
SDL_RenderFillRect(renderer_, &debug_rect_y_);
|
||||
}
|
||||
|
||||
// Pinta el punto de debug
|
||||
SDL_SetRenderDrawColor(renderer_, rand() % 256, rand() % 256, rand() % 256, 255);
|
||||
SDL_RenderDrawPoint(renderer_, debug_point_.x, debug_point_.y);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
116
source/player.h
116
source/player.h
@@ -8,7 +8,7 @@
|
||||
#include "utils.h" // Para color_t
|
||||
#include "defines.h" // Para BLOCK
|
||||
#include "room.h"
|
||||
class AnimatedSprite;
|
||||
#include "animated_sprite.h"
|
||||
class Asset;
|
||||
class Debug;
|
||||
class Input;
|
||||
@@ -16,43 +16,55 @@ class Resource;
|
||||
class Room;
|
||||
struct JA_Sound_t;
|
||||
|
||||
enum state_e
|
||||
enum class PlayerState
|
||||
{
|
||||
s_standing,
|
||||
s_jumping,
|
||||
s_falling
|
||||
STANDING,
|
||||
JUMPING,
|
||||
FALLING,
|
||||
};
|
||||
|
||||
struct playerSpawn_t
|
||||
struct PlayerSpawn
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float vx;
|
||||
float vy;
|
||||
int jump_init_pos;
|
||||
state_e state;
|
||||
PlayerState state;
|
||||
SDL_RendererFlip flip;
|
||||
|
||||
// Constructor por defecto
|
||||
PlayerSpawn() : x(0), y(0), vx(0), vy(0), jump_init_pos(0), state(PlayerState::STANDING), flip(SDL_FLIP_NONE) {}
|
||||
|
||||
// Constructor
|
||||
PlayerSpawn(float x, float y, float vx, float vy, int jump_init_pos, PlayerState state, SDL_RendererFlip flip)
|
||||
: x(x), y(y), vx(vx), vy(vy), jump_init_pos(jump_init_pos), state(state), flip(flip) {}
|
||||
};
|
||||
|
||||
struct player_t
|
||||
struct PlayerData
|
||||
{
|
||||
playerSpawn_t spawn;
|
||||
std::string png;
|
||||
std::string animation;
|
||||
PlayerSpawn spawn;
|
||||
std::string texture_path;
|
||||
std::string animations_path;
|
||||
std::shared_ptr<Room> room;
|
||||
|
||||
// Constructor
|
||||
PlayerData(PlayerSpawn spawn, std::string texture_path, std::string animations_path, std::shared_ptr<Room> room)
|
||||
: spawn(spawn), texture_path(texture_path), animations_path(animations_path), room(room) {}
|
||||
};
|
||||
|
||||
class Player
|
||||
{
|
||||
public:
|
||||
// Constantes
|
||||
static constexpr int WIDTH_ = 8; // Ancho del jugador
|
||||
static constexpr int HEIGHT_ = 16; // ALto del jugador
|
||||
static constexpr int MAX_FALLING_HEIGHT_ = BLOCK * 4; // Altura maxima permitida de caída.
|
||||
static constexpr 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
|
||||
Debug *debug_; // Objeto para gestionar la información de debug
|
||||
std::shared_ptr<Room> room_; // Objeto encargado de gestionar cada habitación del juego
|
||||
@@ -63,32 +75,30 @@ public:
|
||||
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
|
||||
PlayerState state_; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo
|
||||
PlayerState previous_state_; // Estado previo en el que se encontraba el jugador
|
||||
bool is_on_border_ = false; // Indica si el jugador esta en uno de los cuatro bordes de la pantalla
|
||||
bool is_alive_ = true; // Indica si el jugador esta vivo o no
|
||||
bool is_paused_ = false; // Indica si el jugador esta en modo pausa
|
||||
bool auto_movement_ = false; // Indica si esta siendo arrastrado por una superficie automatica
|
||||
int border_ = BORDER_TOP; // Indica en cual de los cuatro bordes se encuentra
|
||||
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
|
||||
int jumping_counter_ = 0; // Cuenta el tiempo de salto
|
||||
int falling_counter_ = 0; // Cuenta el tiempo de caida
|
||||
|
||||
#ifdef DEBUG
|
||||
SDL_Rect rx; // Rectangulo de desplazamiento para el modo debug
|
||||
SDL_Rect ry; // Rectangulo de desplazamiento para el modo debug
|
||||
Color debugColor; // Color del recuadro de debug del jugador
|
||||
SDL_Point debugPoint; // Punto para debug
|
||||
SDL_Rect debug_rect_x_; // Rectangulo de desplazamiento para el modo debug
|
||||
SDL_Rect debug_rect_y_; // Rectangulo de desplazamiento para el modo debug
|
||||
Color debug_color_; // Color del recuadro de debug del jugador
|
||||
SDL_Point debug_point_; // Punto para debug
|
||||
#endif
|
||||
|
||||
// Comprueba las entradas y modifica variables
|
||||
@@ -100,9 +110,6 @@ public:
|
||||
// Comprueba el estado del jugador
|
||||
void checkState();
|
||||
|
||||
// Asigna velocidad negativa en el eje Y al jugador
|
||||
void jump();
|
||||
|
||||
// Aplica gravedad al jugador
|
||||
void applyGravity();
|
||||
|
||||
@@ -140,11 +147,28 @@ public:
|
||||
void updateFeet();
|
||||
|
||||
// Cambia el estado del jugador
|
||||
void setState(state_e value);
|
||||
void setState(PlayerState value);
|
||||
|
||||
// Inicializa los sonidos de salto y caida
|
||||
void initSounds();
|
||||
|
||||
// Coloca el sprite en la posición del jugador
|
||||
void placeSprite();
|
||||
|
||||
// Aplica los valores de spawn al jugador
|
||||
void applySpawnValues(const PlayerSpawn &spawn);
|
||||
|
||||
// Inicializa el sprite del jugador
|
||||
void initSprite(const std::string &texture_path, const std::string &animations_path);
|
||||
|
||||
#ifdef DEBUG
|
||||
// Pinta la información de debug del jugador
|
||||
void renderDebugInfo();
|
||||
#endif
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
Player(player_t player);
|
||||
Player(PlayerData player);
|
||||
|
||||
// Destructor
|
||||
~Player() = default;
|
||||
@@ -156,38 +180,38 @@ public:
|
||||
void update();
|
||||
|
||||
// Indica si el jugador esta en uno de los cuatro bordes de la pantalla
|
||||
bool getOnBorder();
|
||||
bool getOnBorder() { return is_on_border_; }
|
||||
|
||||
// Indica en cual de los cuatro bordes se encuentra
|
||||
int getBorder();
|
||||
int getBorder() { return border_; }
|
||||
|
||||
// Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla
|
||||
void switchBorders();
|
||||
|
||||
// Obtiene el rectangulo que delimita al jugador
|
||||
SDL_Rect getRect();
|
||||
SDL_Rect getRect() { return {static_cast<int>(x_), static_cast<int>(y_), WIDTH_, HEIGHT_}; }
|
||||
|
||||
// Obtiene el rectangulo de colision del jugador
|
||||
SDL_Rect &getCollider();
|
||||
SDL_Rect &getCollider() { return collider_box_; }
|
||||
|
||||
// Obtiene algunos parametros del jugador
|
||||
playerSpawn_t getSpawnParams();
|
||||
// Obtiene el estado de reaparición del jugador
|
||||
PlayerSpawn getSpawnParams() { return {x_, y_, vx_, vy_, jump_init_pos_, state_, sprite_->getFlip()}; }
|
||||
|
||||
// Recarga la textura
|
||||
void reLoadTexture();
|
||||
void reLoadTexture() { sprite_->getTexture()->reLoad(); }
|
||||
|
||||
// Recarga la paleta
|
||||
void reLoadPalette();
|
||||
// Establece el color del jugador
|
||||
void setColor();
|
||||
|
||||
// Establece el valor de la variable
|
||||
void setRoom(std::shared_ptr<Room> room);
|
||||
// Establece la habitación en la que se encuentra el jugador
|
||||
void setRoom(std::shared_ptr<Room> room) { room_ = room; }
|
||||
|
||||
// Comprueba si el jugador esta vivo
|
||||
bool isAlive();
|
||||
bool isAlive() { return is_alive_; }
|
||||
|
||||
// Pone el jugador en modo pausa
|
||||
void pause();
|
||||
void pause() { is_paused_ = true; }
|
||||
|
||||
// Quita el modo pausa del jugador
|
||||
void resume();
|
||||
void resume() { is_paused_ = false; }
|
||||
};
|
||||
@@ -151,7 +151,7 @@ std::shared_ptr<Text> Resource::getText(const std::string &name)
|
||||
}
|
||||
|
||||
// Obtiene la animación a partir de un nombre
|
||||
AnimationsFileBuffer &Resource::getAnimation(const std::string &name)
|
||||
Animations &Resource::getAnimations(const std::string &name)
|
||||
{
|
||||
auto it = std::find_if(animations_.begin(), animations_.end(), [&name](const auto &a)
|
||||
{ return a.name == name; });
|
||||
@@ -181,7 +181,7 @@ std::vector<int> &Resource::getTileMap(const std::string &name)
|
||||
}
|
||||
|
||||
// Obtiene la habitación a partir de un nombre
|
||||
std::shared_ptr<room_t> Resource::getRoom(const std::string &name)
|
||||
std::shared_ptr<RoomData> Resource::getRoom(const std::string &name)
|
||||
{
|
||||
auto it = std::find_if(rooms_.begin(), rooms_.end(), [&name](const auto &r)
|
||||
{ return r.name == name; });
|
||||
@@ -304,7 +304,7 @@ void Resource::loadRooms()
|
||||
for (const auto &l : list)
|
||||
{
|
||||
auto name = getFileName(l);
|
||||
rooms_.emplace_back(ResourceRoom(name, std::make_shared<room_t>(loadRoomFile(l))));
|
||||
rooms_.emplace_back(ResourceRoom(name, std::make_shared<RoomData>(loadRoomFile(l))));
|
||||
printWithDots("Room : ", name, "[ LOADED ]");
|
||||
updateLoadingProgress();
|
||||
}
|
||||
@@ -440,6 +440,9 @@ void Resource::checkEvents()
|
||||
void Resource::updateLoadingProgress()
|
||||
{
|
||||
count_.add(1);
|
||||
if (count_.loaded % 5 == 0 || count_.loaded == count_.total)
|
||||
{
|
||||
renderProgress();
|
||||
}
|
||||
checkEvents();
|
||||
}
|
||||
@@ -69,10 +69,10 @@ struct ResourceText
|
||||
struct ResourceAnimation
|
||||
{
|
||||
std::string name; // Nombre del fichero
|
||||
AnimationsFileBuffer animation; // Objeto con las animaciones
|
||||
Animations animation; // Objeto con las animaciones
|
||||
|
||||
// Constructor
|
||||
ResourceAnimation(const std::string &name, const AnimationsFileBuffer &animation)
|
||||
ResourceAnimation(const std::string &name, const Animations &animation)
|
||||
: name(name), animation(animation) {}
|
||||
};
|
||||
|
||||
@@ -91,10 +91,10 @@ struct ResourceTileMap
|
||||
struct ResourceRoom
|
||||
{
|
||||
std::string name; // Nombre de la habitación
|
||||
std::shared_ptr<room_t> room; // Habitación
|
||||
std::shared_ptr<RoomData> room; // Habitación
|
||||
|
||||
// Constructor
|
||||
ResourceRoom(const std::string &name, std::shared_ptr<room_t> room)
|
||||
ResourceRoom(const std::string &name, std::shared_ptr<RoomData> room)
|
||||
: name(name), room(room) {}
|
||||
};
|
||||
|
||||
@@ -232,13 +232,13 @@ public:
|
||||
std::shared_ptr<Text> getText(const std::string &name);
|
||||
|
||||
// Obtiene la animación a partir de un nombre
|
||||
AnimationsFileBuffer &getAnimation(const std::string &name);
|
||||
Animations &getAnimations(const std::string &name);
|
||||
|
||||
// Obtiene el mapa de tiles a partir de un nombre
|
||||
std::vector<int> &getTileMap(const std::string &name);
|
||||
|
||||
// Obtiene la habitación a partir de un nombre
|
||||
std::shared_ptr<room_t> getRoom(const std::string &name);
|
||||
std::shared_ptr<RoomData> getRoom(const std::string &name);
|
||||
|
||||
// Obtiene todas las habitaciones
|
||||
std::vector<ResourceRoom> &getRooms();
|
||||
|
||||
654
source/room.cpp
654
source/room.cpp
File diff suppressed because it is too large
Load Diff
133
source/room.h
133
source/room.h
@@ -8,6 +8,7 @@
|
||||
#include "enemy.h" // for EnemyData
|
||||
#include "item.h" // for item_t
|
||||
#include "utils.h" // for Color
|
||||
#include "scoreboard.h"
|
||||
class Asset; // lines 12-12
|
||||
class Debug; // lines 13-13
|
||||
class ItemTracker;
|
||||
@@ -30,94 +31,90 @@ enum tile_e
|
||||
struct aTile_t
|
||||
{
|
||||
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
|
||||
int x_orig; // Poicion X donde se encuentra el primer tile de la animacion en la tilesheet
|
||||
};
|
||||
|
||||
struct room_t
|
||||
struct RoomData
|
||||
{
|
||||
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::string bg_color; // Color de fondo de la habitación
|
||||
std::string border_color; // Color del borde de la pantalla
|
||||
std::string item_color1; // Color 1 para los items de la habitación
|
||||
std::string item_color2; // Color 2 para los items de la habitación
|
||||
std::string room_top; // Identificador de la habitación que se encuentra arriba
|
||||
std::string room_bottom; // Identificador de la habitación que se encuentra abajp
|
||||
std::string room_left; // Identificador de la habitación que se encuentra a la izquierda
|
||||
std::string room_right; // Identificador de la habitación que se encuentra a la derecha
|
||||
std::string tile_set_file; // Imagen con los graficos para la habitación
|
||||
std::string tile_map_file; // Fichero con el mapa de indices de tile
|
||||
std::vector<int> tile_map; // Indice de los tiles a dibujar en la habitación
|
||||
int auto_surface_direction; // Sentido en el que arrastran las superficies automáticas de la habitación
|
||||
std::vector<EnemyData> 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
|
||||
std::vector<ItemData> items; // Listado con los items que hay en la habitación
|
||||
};
|
||||
|
||||
// Carga las variables desde un fichero de mapa
|
||||
room_t loadRoomFile(std::string file, bool verbose = false);
|
||||
RoomData loadRoomFile(const std::string &file_path, bool verbose = false);
|
||||
|
||||
// Carga las variables y texturas desde un fichero de mapa de tiles
|
||||
std::vector<int> loadRoomTileFile(std::string file_path, bool verbose = false);
|
||||
std::vector<int> loadRoomTileFile(const std::string &file_path, bool verbose = false);
|
||||
|
||||
// Asigna variables a partir de dos cadenas
|
||||
bool setVars(room_t *room, std::string var, std::string value);
|
||||
// Asigna variables a una estructura RoomData
|
||||
bool setRoom(RoomData *room, const std::string &key, const std::string &value);
|
||||
|
||||
// Asigna variables a una estructura enemy_t
|
||||
bool setEnemy(EnemyData *enemy, std::string var, std::string value);
|
||||
// Asigna variables a una estructura EnemyData
|
||||
bool setEnemy(EnemyData *enemy, const std::string &key, const std::string &value);
|
||||
|
||||
// Asigna variables a una estructura item_t
|
||||
bool setItem(item_t *item, std::string var, std::string value);
|
||||
// Asigna variables a una estructura ItemData
|
||||
bool setItem(ItemData *item, const std::string &key, const std::string &value);
|
||||
|
||||
class Room
|
||||
{
|
||||
private:
|
||||
// Constantes
|
||||
static constexpr int TILE_SIZE_ = 8; // Ancho del tile en pixels
|
||||
static constexpr int MAP_WIDTH_ = 32; // Ancho del mapa en tiles
|
||||
static constexpr int MAP_HEIGHT_ = 16; // Alto del mapa en tiles
|
||||
|
||||
// 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<std::shared_ptr<Enemy>> enemies; // Listado con los enemigos de la habitación
|
||||
std::vector<std::shared_ptr<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
|
||||
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<std::shared_ptr<Enemy>> enemies_; // Listado con los enemigos de la habitación
|
||||
std::vector<std::shared_ptr<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
|
||||
SDL_Texture *map_texture_; // Textura para dibujar el mapa de la habitación
|
||||
std::shared_ptr<ScoreboardData> data_; // Puntero a los datos del marcador
|
||||
|
||||
// Variables
|
||||
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
|
||||
JA_Sound_t *itemSound; // Sonido producido al coger un objeto
|
||||
std::vector<h_line_t> bottomSurfaces; // Lista con las superficies inferiores de la habitación
|
||||
std::vector<h_line_t> topSurfaces; // Lista con las superficies superiores de la habitación
|
||||
std::vector<v_line_t> leftSurfaces; // Lista con las superficies laterales de la parte izquierda de la habitación
|
||||
std::vector<v_line_t> rightSurfaces; // Lista con las superficies laterales de la parte derecha de la habitación
|
||||
std::vector<d_line_t> leftSlopes; // Lista con todas las rampas que suben hacia la izquierda
|
||||
std::vector<d_line_t> rightSlopes; // Lista con todas las rampas que suben hacia la derecha
|
||||
int counter; // Contador para lo que haga falta
|
||||
bool paused; // Indica si el mapa esta en modo pausa
|
||||
std::vector<aTile_t> aTile; // Vector con los indices de tiles animados
|
||||
std::vector<h_line_t> autoSurfaces; // Lista con las superficies automaticas de la habitación
|
||||
int tileSize; // Ancho del tile en pixels
|
||||
int mapWidth; // Ancho del mapa en tiles
|
||||
int mapHeight; // Alto del mapa en tiles
|
||||
int tileSetWidth; // Ancho del tileset en tiles
|
||||
bool jailEnabled; // Indica si hay acceso a la Jail
|
||||
std::string number_; // Numero de la habitación
|
||||
std::string name_; // Nombre de la habitación
|
||||
std::string bg_color_; // Color de fondo de la habitación
|
||||
std::string border_color_; // Color del borde de la pantalla
|
||||
std::string item_color1_; // Color 1 para los items de la habitación
|
||||
std::string item_color2_; // Color 2 para los items de la habitación
|
||||
std::string room_top_; // Identificador de la habitación que se encuentra arriba
|
||||
std::string room_bottom_; // Identificador de la habitación que se encuentra abajp
|
||||
std::string room_left_; // Identificador de la habitación que se encuentra a la izquierda
|
||||
std::string room_right_; // Identificador de la habitación que se encuentra a la derecha
|
||||
std::string tile_set_file_; // Imagen con los graficos para la habitación
|
||||
std::string tile_map_file_; // Fichero con el mapa de indices de tile
|
||||
std::vector<int> tile_map_; // Indice de los tiles a dibujar en la habitación
|
||||
int auto_surface_direction_; // Sentido en el que arrastran las superficies automáticas de la habitación
|
||||
JA_Sound_t *item_sound_; // Sonido producido al coger un objeto
|
||||
std::vector<h_line_t> bottom_surfaces_; // Lista con las superficies inferiores de la habitación
|
||||
std::vector<h_line_t> top_surfaces_; // Lista con las superficies superiores de la habitación
|
||||
std::vector<v_line_t> left_surfaces_; // Lista con las superficies laterales de la parte izquierda de la habitación
|
||||
std::vector<v_line_t> right_surfaces_; // Lista con las superficies laterales de la parte derecha de la habitación
|
||||
std::vector<d_line_t> left_slopes_; // Lista con todas las rampas que suben hacia la izquierda
|
||||
std::vector<d_line_t> right_slopes_; // Lista con todas las rampas que suben hacia la derecha
|
||||
int counter_; // Contador para lo que haga falta
|
||||
bool paused_; // Indica si el mapa esta en modo pausa
|
||||
std::vector<aTile_t> animated_tiles_; // Vector con los indices de tiles animados
|
||||
std::vector<h_line_t> auto_surfaces_; // Lista con las superficies automaticas de la habitación
|
||||
int tile_set_width_; // Ancho del tileset en tiles
|
||||
|
||||
// Pinta el mapa de la habitación en la textura
|
||||
void fillMapTexture();
|
||||
@@ -160,7 +157,7 @@ private:
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
Room(std::shared_ptr<room_t> room, std::shared_ptr<ItemTracker> itemTracker, int *itemsPicked, bool jailEnabled);
|
||||
Room(std::shared_ptr<RoomData> room, std::shared_ptr<ScoreboardData> data);
|
||||
|
||||
// Destructor
|
||||
~Room();
|
||||
|
||||
@@ -9,107 +9,89 @@
|
||||
#include "screen.h" // for Screen
|
||||
#include "text.h" // for Text
|
||||
#include "texture.h" // for Texture
|
||||
#include <iostream>
|
||||
|
||||
// Constructor
|
||||
Scoreboard::Scoreboard(board_t *board)
|
||||
: renderer(Screen::get()->getRenderer()),
|
||||
resource(Resource::get()),
|
||||
asset(Asset::get()),
|
||||
board(board)
|
||||
Scoreboard::Scoreboard(std::shared_ptr<ScoreboardData> data)
|
||||
: renderer_(Screen::get()->getRenderer()),
|
||||
resource_(Resource::get()),
|
||||
asset_(Asset::get()),
|
||||
data_(data)
|
||||
{
|
||||
const int TEXTURE_WIDTH_ = options.game.width;
|
||||
constexpr int TEXTURE_HEIGHT_ = 6 * BLOCK;
|
||||
|
||||
// Reserva memoria para los objetos
|
||||
itemTexture = resource->getTexture("items.png");
|
||||
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";
|
||||
sprite = std::make_shared<AnimatedSprite>(resource->getTexture(playerPNG), resource->getAnimation(playerANI));
|
||||
sprite->setCurrentAnimation("walk_menu");
|
||||
text = resource->getText("smb2");
|
||||
item_texture_ = resource_->getTexture("items.png");
|
||||
auto player_texture = resource_->getTexture(options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png");
|
||||
auto player_animations = resource_->getAnimations(options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani");
|
||||
player_sprite_ = std::make_shared<AnimatedSprite>(player_texture, player_animations);
|
||||
player_sprite_->setCurrentAnimation("walk_menu");
|
||||
text_ = resource_->getText("smb2");
|
||||
|
||||
texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, TEXTURE_WIDTH_, TEXTURE_HEIGHT_);
|
||||
if (texture_ == nullptr)
|
||||
{
|
||||
if (options.console)
|
||||
{
|
||||
std::cout << "Scorebard::texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
}
|
||||
texture_dest_ = {0, options.game.height - TEXTURE_HEIGHT_, TEXTURE_WIDTH_, TEXTURE_HEIGHT_};
|
||||
|
||||
// Inicializa las variables
|
||||
counter = 0;
|
||||
colorChangeSpeed = 4;
|
||||
paused = false;
|
||||
timePaused = 0;
|
||||
totalTimePaused = 0;
|
||||
itemsColor = stringToColor(options.video.palette, "white");
|
||||
counter_ = 0;
|
||||
change_color_speed_ = 4;
|
||||
is_paused_ = false;
|
||||
paused_time_ = 0;
|
||||
paused_time_elapsed_ = 0;
|
||||
items_color_ = stringToColor(options.video.palette, "white");
|
||||
|
||||
// Inicializa el vector de colores
|
||||
const std::vector<std::string> vColors = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"};
|
||||
for (auto v : vColors)
|
||||
{
|
||||
color.push_back(stringToColor(options.video.palette, v));
|
||||
color_.push_back(stringToColor(options.video.palette, v));
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Scoreboard::~Scoreboard()
|
||||
{
|
||||
SDL_DestroyTexture(texture_);
|
||||
}
|
||||
|
||||
// Pinta el objeto en pantalla
|
||||
void Scoreboard::render()
|
||||
{
|
||||
// Anclas
|
||||
const int line1 = 19 * BLOCK;
|
||||
const int line2 = line1 + (2 * BLOCK);
|
||||
|
||||
// Dibuja el fondo del marcador
|
||||
const SDL_Rect rect = {0, 18 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT};
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
|
||||
// Dibuja las vidas
|
||||
const int desp = (counter / 40) % 8;
|
||||
const int frame = desp % 4;
|
||||
sprite->setCurrentAnimationFrame(frame);
|
||||
sprite->setPosY(line2);
|
||||
for (int i = 0; i < board->lives; ++i)
|
||||
{
|
||||
sprite->setPosX(8 + (16 * i) + desp);
|
||||
const int index = i % color.size();
|
||||
sprite->getTexture()->setColor(color[index].r, color[index].g, color[index].b);
|
||||
sprite->render();
|
||||
}
|
||||
|
||||
// Muestra si suena la música
|
||||
if (board->music)
|
||||
{
|
||||
const Color c = board->color;
|
||||
SDL_Rect clip = {0, 8, 8, 8};
|
||||
itemTexture->setColor(c.r, c.g, c.b);
|
||||
itemTexture->render(20 * BLOCK, line2, &clip);
|
||||
}
|
||||
|
||||
// Escribe los textos
|
||||
const std::string timeTxt = std::to_string((clock.minutes % 100) / 10) + std::to_string(clock.minutes % 10) + clock.separator + std::to_string((clock.seconds % 60) / 10) + std::to_string(clock.seconds % 10);
|
||||
const std::string itemsTxt = std::to_string(board->items / 100) + std::to_string((board->items % 100) / 10) + std::to_string(board->items % 10);
|
||||
this->text->writeColored(BLOCK, line1, "Items collected ", board->color);
|
||||
this->text->writeColored(17 * BLOCK, line1, itemsTxt, itemsColor);
|
||||
this->text->writeColored(20 * BLOCK, line1, " Time ", board->color);
|
||||
this->text->writeColored(26 * BLOCK, line1, timeTxt, stringToColor(options.video.palette, "white"));
|
||||
|
||||
const std::string roomsTxt = std::to_string(board->rooms / 100) + std::to_string((board->rooms % 100) / 10) + std::to_string(board->rooms % 10);
|
||||
this->text->writeColored(22 * BLOCK, line2, "Rooms", stringToColor(options.video.palette, "white"));
|
||||
this->text->writeColored(28 * BLOCK, line2, roomsTxt, stringToColor(options.video.palette, "white"));
|
||||
SDL_RenderCopy(renderer_, texture_, nullptr, &texture_dest_);
|
||||
}
|
||||
|
||||
// Actualiza las variables del objeto
|
||||
void Scoreboard::update()
|
||||
{
|
||||
counter++;
|
||||
sprite->update();
|
||||
counter_++;
|
||||
player_sprite_->update();
|
||||
|
||||
// Actualiza el color de la cantidad de items recogidos
|
||||
updateItemsColor();
|
||||
|
||||
if (!paused)
|
||||
// Dibuja la textura
|
||||
fillTexture();
|
||||
|
||||
if (!is_paused_)
|
||||
{
|
||||
// Si está en pausa no se actualiza el reloj
|
||||
clock = getTime();
|
||||
clock_ = getTime();
|
||||
}
|
||||
}
|
||||
|
||||
// Obtiene el tiempo transcurrido de partida
|
||||
Scoreboard::clock_t Scoreboard::getTime()
|
||||
Scoreboard::ClockData Scoreboard::getTime()
|
||||
{
|
||||
const Uint32 timeElapsed = SDL_GetTicks() - board->iniClock - totalTimePaused;
|
||||
const Uint32 timeElapsed = SDL_GetTicks() - data_->ini_clock - paused_time_elapsed_;
|
||||
|
||||
clock_t time;
|
||||
ClockData time;
|
||||
time.hours = timeElapsed / 3600000;
|
||||
time.minutes = timeElapsed / 60000;
|
||||
time.seconds = timeElapsed / 1000;
|
||||
@@ -121,10 +103,10 @@ Scoreboard::clock_t Scoreboard::getTime()
|
||||
// Recarga la textura
|
||||
void Scoreboard::reLoadTexture()
|
||||
{
|
||||
sprite->getTexture()->reLoad();
|
||||
player_sprite_->getTexture()->reLoad();
|
||||
// playerTexture->reLoad();
|
||||
itemTexture->reLoad();
|
||||
text->reLoadTexture();
|
||||
item_texture_->reLoad();
|
||||
text_->reLoadTexture();
|
||||
}
|
||||
|
||||
// Recarga la paleta
|
||||
@@ -132,42 +114,42 @@ void Scoreboard::reLoadPalette()
|
||||
{
|
||||
// Reinicia el vector de colores
|
||||
const std::vector<std::string> vColors = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"};
|
||||
color.clear();
|
||||
color_.clear();
|
||||
for (auto v : vColors)
|
||||
{
|
||||
color.push_back(stringToColor(options.video.palette, v));
|
||||
color_.push_back(stringToColor(options.video.palette, v));
|
||||
}
|
||||
}
|
||||
|
||||
// Pone el marcador en modo pausa
|
||||
void Scoreboard::pause()
|
||||
{
|
||||
paused = true;
|
||||
timePaused = SDL_GetTicks();
|
||||
is_paused_ = true;
|
||||
paused_time_ = SDL_GetTicks();
|
||||
}
|
||||
|
||||
// Quita el modo pausa del marcador
|
||||
void Scoreboard::resume()
|
||||
{
|
||||
paused = false;
|
||||
totalTimePaused += SDL_GetTicks() - timePaused;
|
||||
is_paused_ = false;
|
||||
paused_time_elapsed_ += SDL_GetTicks() - paused_time_;
|
||||
}
|
||||
|
||||
// Actualiza el color de la cantidad de items recogidos
|
||||
void Scoreboard::updateItemsColor()
|
||||
{
|
||||
if (!board->jail_is_open)
|
||||
if (!data_->jail_is_open)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (counter % 20 < 10)
|
||||
if (counter_ % 20 < 10)
|
||||
{
|
||||
itemsColor = stringToColor(options.video.palette, "white");
|
||||
items_color_ = stringToColor(options.video.palette, "white");
|
||||
}
|
||||
else
|
||||
{
|
||||
itemsColor = stringToColor(options.video.palette, "magenta");
|
||||
items_color_ = stringToColor(options.video.palette, "magenta");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,3 +158,56 @@ int Scoreboard::getMinutes()
|
||||
{
|
||||
return getTime().minutes;
|
||||
}
|
||||
|
||||
// Dibuja los elementos del marcador en la textura
|
||||
void Scoreboard::fillTexture()
|
||||
{
|
||||
// Empieza a dibujar en la textura
|
||||
auto temp = SDL_GetRenderTarget(renderer_);
|
||||
SDL_SetRenderTarget(renderer_, texture_);
|
||||
|
||||
// Limpia la textura
|
||||
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 255);
|
||||
SDL_RenderFillRect(renderer_, nullptr);
|
||||
|
||||
// Anclas
|
||||
constexpr int LINE1 = BLOCK;
|
||||
constexpr int LINE2 = 3 * BLOCK;
|
||||
|
||||
// Dibuja las vidas
|
||||
const int desp = (counter_ / 40) % 8;
|
||||
const int frame = desp % 4;
|
||||
player_sprite_->setCurrentAnimationFrame(frame);
|
||||
player_sprite_->setPosY(LINE2);
|
||||
for (int i = 0; i < data_->lives; ++i)
|
||||
{
|
||||
player_sprite_->setPosX(8 + (16 * i) + desp);
|
||||
const int index = i % color_.size();
|
||||
player_sprite_->getTexture()->setColor(color_[index].r, color_[index].g, color_[index].b);
|
||||
player_sprite_->render();
|
||||
}
|
||||
|
||||
// Muestra si suena la música
|
||||
if (data_->music)
|
||||
{
|
||||
const Color c = data_->color;
|
||||
SDL_Rect clip = {0, 8, 8, 8};
|
||||
item_texture_->setColor(c.r, c.g, c.b);
|
||||
item_texture_->render(20 * BLOCK, LINE2, &clip);
|
||||
}
|
||||
|
||||
// Escribe los textos
|
||||
const std::string timeTxt = std::to_string((clock_.minutes % 100) / 10) + std::to_string(clock_.minutes % 10) + clock_.separator + std::to_string((clock_.seconds % 60) / 10) + std::to_string(clock_.seconds % 10);
|
||||
const std::string itemsTxt = std::to_string(data_->items / 100) + std::to_string((data_->items % 100) / 10) + std::to_string(data_->items % 10);
|
||||
text_->writeColored(BLOCK, LINE1, "Items collected ", data_->color);
|
||||
text_->writeColored(17 * BLOCK, LINE1, itemsTxt, items_color_);
|
||||
text_->writeColored(20 * BLOCK, LINE1, " Time ", data_->color);
|
||||
text_->writeColored(26 * BLOCK, LINE1, timeTxt, stringToColor(options.video.palette, "white"));
|
||||
|
||||
const std::string roomsTxt = std::to_string(data_->rooms / 100) + std::to_string((data_->rooms % 100) / 10) + std::to_string(data_->rooms % 10);
|
||||
text_->writeColored(22 * BLOCK, LINE2, "Rooms", stringToColor(options.video.palette, "white"));
|
||||
text_->writeColored(28 * BLOCK, LINE2, roomsTxt, stringToColor(options.video.palette, "white"));
|
||||
|
||||
// Deja el renderizador como estaba
|
||||
SDL_SetRenderTarget(renderer_, temp);
|
||||
}
|
||||
@@ -12,21 +12,25 @@ class Resource;
|
||||
class Text;
|
||||
class Texture;
|
||||
|
||||
struct board_t
|
||||
struct ScoreboardData
|
||||
{
|
||||
int items; // Lleva la cuenta de los objetos recogidos
|
||||
int lives; // Lleva la cuenta de ls vidas restantes del jugador
|
||||
int rooms; // Lleva la cuenta de las habitaciones visitadas
|
||||
bool music; // Indica si ha de sonar la musica durante el juego
|
||||
Color color; // Color para escribir el texto del marcador
|
||||
Uint32 iniClock; // Tiempo inicial para calcular el tiempo transcurrido
|
||||
Uint32 ini_clock; // Tiempo inicial para calcular el tiempo transcurrido
|
||||
bool jail_is_open; // Indica si se puede entrar a la Jail
|
||||
|
||||
// Constructor
|
||||
ScoreboardData()
|
||||
: items(0), lives(3), rooms(0), music(true), color({0, 0, 0}), ini_clock(0), jail_is_open(false) {}
|
||||
};
|
||||
|
||||
class Scoreboard
|
||||
{
|
||||
private:
|
||||
struct clock_t
|
||||
struct ClockData
|
||||
{
|
||||
int hours;
|
||||
int minutes;
|
||||
@@ -35,36 +39,41 @@ private:
|
||||
};
|
||||
|
||||
// Objetos y punteros
|
||||
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
|
||||
std::shared_ptr<Text> text; // Objeto para escribir texto
|
||||
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
|
||||
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
|
||||
std::shared_ptr<Text> text_; // Objeto para escribir texto
|
||||
std::shared_ptr<AnimatedSprite> player_sprite_; // Sprite para mostrar las vidas en el marcador
|
||||
std::shared_ptr<Texture> item_texture_; // Textura con los graficos para las vidas
|
||||
std::shared_ptr<ScoreboardData> data_; // Contiene las variables a mostrar en el marcador
|
||||
SDL_Texture *texture_; // Textura donde dibujar el marcador;
|
||||
|
||||
// Variables
|
||||
std::vector<Color> color; // Vector con los colores del objeto
|
||||
int counter; // Contador interno
|
||||
int colorChangeSpeed; // Cuanto mas alto, mas tarda en cambiar de color
|
||||
bool paused; // Indica si el marcador esta en modo pausa
|
||||
Uint32 timePaused; // Milisegundos que ha estado el marcador en pausa
|
||||
Uint32 totalTimePaused; // Tiempo acumulado en pausa
|
||||
clock_t clock; // Contiene las horas, minutos y segundos transcurridos desde el inicio de la partida
|
||||
Color itemsColor; // Color de la cantidad de items recogidos
|
||||
std::vector<Color> color_; // Vector con los colores del objeto
|
||||
int counter_; // Contador interno
|
||||
int change_color_speed_; // Cuanto mas alto, mas tarda en cambiar de color
|
||||
bool is_paused_; // Indica si el marcador esta en modo pausa
|
||||
Uint32 paused_time_; // Milisegundos que ha estado el marcador en pausa
|
||||
Uint32 paused_time_elapsed_; // Tiempo acumulado en pausa
|
||||
ClockData clock_; // Contiene las horas, minutos y segundos transcurridos desde el inicio de la partida
|
||||
Color items_color_; // Color de la cantidad de items recogidos
|
||||
SDL_Rect texture_dest_; // Rectangulo donde dibujar la textura del marcador
|
||||
|
||||
// Obtiene el tiempo transcurrido de partida
|
||||
clock_t getTime();
|
||||
ClockData getTime();
|
||||
|
||||
// Actualiza el color de la cantidad de items recogidos
|
||||
void updateItemsColor();
|
||||
|
||||
// Dibuja los elementos del marcador en la textura
|
||||
void fillTexture();
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
Scoreboard(board_t *board);
|
||||
Scoreboard(std::shared_ptr<ScoreboardData> data);
|
||||
|
||||
// Destructor
|
||||
~Scoreboard() = default;
|
||||
~Scoreboard();
|
||||
|
||||
// Pinta el objeto en pantalla
|
||||
void render();
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "notifier.h" // Para Notify
|
||||
#include "options.h"
|
||||
#include "mouse.h"
|
||||
//#include "surface.h"
|
||||
|
||||
// [SINGLETON]
|
||||
Screen *Screen::screen_ = nullptr;
|
||||
@@ -40,50 +41,66 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
|
||||
: window_(window),
|
||||
renderer_(renderer)
|
||||
{
|
||||
game_canvas_width_ = options.game.width;
|
||||
game_canvas_height_ = options.game.height;
|
||||
notification_logical_width_ = game_canvas_width_;
|
||||
notification_logical_height_ = game_canvas_height_;
|
||||
|
||||
iniFade();
|
||||
iniSpectrumFade();
|
||||
// Ajusta los tamaños
|
||||
adjustGameCanvasRect();
|
||||
adjustWindowSize();
|
||||
|
||||
// Define el color del borde para el modo de pantalla completa
|
||||
border_color_ = {0x00, 0x00, 0x00};
|
||||
|
||||
// Crea la textura donde se dibujan los graficos del juego
|
||||
game_canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, game_canvas_width_, game_canvas_height_);
|
||||
if (game_canvas_ == nullptr)
|
||||
// Establece el modo de escalado
|
||||
SDL_RenderSetIntegerScale(renderer_, options.video.integer_scale ? SDL_TRUE : SDL_FALSE);
|
||||
|
||||
// Crea la textura donde se vuelcan las surfaces
|
||||
surface_texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, options.game.width, options.game.height);
|
||||
if (surface_texture_ == nullptr)
|
||||
{
|
||||
if (options.console)
|
||||
{
|
||||
std::cout << "gameCanvas could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
std::cout << "surface_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
}
|
||||
//SDL_SetTextureBlendMode(surface_texture_, SDL_BLENDMODE_BLEND);
|
||||
|
||||
// Crea la textura donde se dibujan los graficos del juego
|
||||
game_texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width, options.game.height);
|
||||
if (game_texture_ == nullptr)
|
||||
{
|
||||
if (options.console)
|
||||
{
|
||||
std::cout << "game_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Crea la textura donde se dibuja el borde que rodea el area de juego
|
||||
border_canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, game_canvas_width_ + options.video.border.width * 2, game_canvas_height_ + options.video.border.height * 2);
|
||||
if (border_canvas_ == nullptr)
|
||||
border_texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width + options.video.border.width * 2, options.game.height + options.video.border.height * 2);
|
||||
if (border_texture_ == nullptr)
|
||||
{
|
||||
if (options.console)
|
||||
{
|
||||
std::cout << "borderCanvas could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
std::cout << "border_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
}
|
||||
setBorderColor(border_color_);
|
||||
|
||||
// Crea la surface donde se pinta el juego
|
||||
//surface_ = std::make_shared<Surface>(nullptr, options.game.width, options.game.height);
|
||||
//surface_->loadPalette(Asset::get()->get("test.gif"));
|
||||
|
||||
// Establece el modo de video
|
||||
setVideoMode(options.video.mode);
|
||||
|
||||
// Muestra la ventana
|
||||
SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
show();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Screen::~Screen()
|
||||
{
|
||||
SDL_DestroyTexture(game_canvas_);
|
||||
SDL_DestroyTexture(border_canvas_);
|
||||
SDL_DestroyTexture(surface_texture_);
|
||||
SDL_DestroyTexture(game_texture_);
|
||||
SDL_DestroyTexture(border_texture_);
|
||||
}
|
||||
|
||||
// Limpia la pantalla
|
||||
@@ -96,13 +113,14 @@ void Screen::clean(Color color)
|
||||
// Prepara para empezar a dibujar en la textura de juego
|
||||
void Screen::start()
|
||||
{
|
||||
SDL_SetRenderTarget(renderer_, game_canvas_);
|
||||
//surface_->clear(surface_->getSurface(), surface_->getTransparentColor());
|
||||
SDL_SetRenderTarget(renderer_, game_texture_);
|
||||
}
|
||||
|
||||
// Prepara para empezar a dibujar en la textura del borde
|
||||
void Screen::startDrawOnBorder()
|
||||
{
|
||||
SDL_SetRenderTarget(renderer_, border_canvas_);
|
||||
SDL_SetRenderTarget(renderer_, border_texture_);
|
||||
}
|
||||
|
||||
// Vuelca el contenido del renderizador en pantalla
|
||||
@@ -111,6 +129,10 @@ void Screen::render()
|
||||
// Renderiza sobre gameCanvas los overlays
|
||||
renderNotifications();
|
||||
|
||||
//fillTextureWithColor(renderer_, surface_texture_, 0xFF, 0x00, 0xFF, 0xFF);
|
||||
//surface_->copyToTexture(renderer_, surface_texture_);
|
||||
//SDL_RenderCopy(renderer_, surface_texture_, nullptr, nullptr);
|
||||
|
||||
// Si está el borde activo, vuelca gameCanvas sobre borderCanvas
|
||||
if (options.video.border.enabled)
|
||||
{
|
||||
@@ -121,7 +143,6 @@ void Screen::render()
|
||||
renderPresent();
|
||||
}
|
||||
|
||||
|
||||
// Vuelca el contenido del renderizador en pantalla
|
||||
void Screen::renderWithoutNotifier()
|
||||
{
|
||||
@@ -139,7 +160,6 @@ void Screen::renderWithoutNotifier()
|
||||
void Screen::setVideoMode(int videoMode)
|
||||
{
|
||||
// Aplica el modo de video
|
||||
SDL_SetWindowFullscreen(window_, videoMode);
|
||||
|
||||
// Modo ventana
|
||||
if (videoMode == 0)
|
||||
@@ -147,79 +167,23 @@ void Screen::setVideoMode(int videoMode)
|
||||
// Muestra el puntero
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
|
||||
// Modifica el tamaño de la ventana en función del borde
|
||||
if (options.video.border.enabled)
|
||||
{
|
||||
window_width_ = game_canvas_width_ + options.video.border.width * 2;
|
||||
window_height_ = game_canvas_height_ + options.video.border.height * 2;
|
||||
dest_ = {options.video.border.width, options.video.border.height, game_canvas_width_, game_canvas_height_};
|
||||
SDL_SetWindowFullscreen(window_, videoMode);
|
||||
adjustWindowSize();
|
||||
adjustGameCanvasRect();
|
||||
adjustRenderLogicalSize();
|
||||
}
|
||||
|
||||
// Modo pantalla completa
|
||||
else
|
||||
{
|
||||
window_width_ = game_canvas_width_;
|
||||
window_height_ = game_canvas_height_;
|
||||
dest_ = {0, 0, game_canvas_width_, game_canvas_height_};
|
||||
}
|
||||
|
||||
// Modifica el tamaño de la ventana
|
||||
SDL_SetWindowSize(window_, window_width_ * options.window.zoom, window_height_ * options.window.zoom);
|
||||
SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
}
|
||||
|
||||
// Si está activo el modo de pantalla completa añade el borde
|
||||
else if (videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP)
|
||||
{
|
||||
// Oculta el puntero
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
adjustWindowSize();
|
||||
|
||||
// Obten el alto y el ancho de la ventana
|
||||
SDL_GetWindowSize(window_, &window_width_, &window_height_);
|
||||
|
||||
// Aplica el escalado al rectangulo donde se pinta la textura del juego
|
||||
if (options.video.integer_scale)
|
||||
{
|
||||
// Calcula el tamaño de la escala máxima
|
||||
int scale = 0;
|
||||
while (((game_canvas_width_ * (scale + 1)) <= window_width_) && ((game_canvas_height_ * (scale + 1)) <= window_height_))
|
||||
{
|
||||
scale++;
|
||||
adjustGameCanvasRect();
|
||||
SDL_SetWindowFullscreen(window_, videoMode);
|
||||
}
|
||||
|
||||
dest_.w = game_canvas_width_ * scale;
|
||||
dest_.h = game_canvas_height_ * scale;
|
||||
dest_.x = (window_width_ - dest_.w) / 2;
|
||||
dest_.y = (window_height_ - dest_.h) / 2;
|
||||
}
|
||||
else if (options.video.keep_aspect)
|
||||
{
|
||||
float ratio = (float)game_canvas_width_ / (float)game_canvas_height_;
|
||||
if ((window_width_ - game_canvas_width_) >= (window_height_ - game_canvas_height_))
|
||||
{
|
||||
dest_.h = window_height_;
|
||||
dest_.w = (int)((window_height_ * ratio) + 0.5f);
|
||||
dest_.x = (window_width_ - dest_.w) / 2;
|
||||
dest_.y = (window_height_ - dest_.h) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
dest_.w = window_width_;
|
||||
dest_.h = (int)((window_width_ / ratio) + 0.5f);
|
||||
dest_.x = (window_width_ - dest_.w) / 2;
|
||||
dest_.y = (window_height_ - dest_.h) / 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dest_.w = window_width_;
|
||||
dest_.h = window_height_;
|
||||
dest_.x = dest_.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Modifica el tamaño del renderizador
|
||||
SDL_RenderSetLogicalSize(renderer_, window_width_, window_height_);
|
||||
|
||||
// Actualiza las opciones
|
||||
options.video.mode = videoMode;
|
||||
|
||||
@@ -232,11 +196,11 @@ void Screen::setVideoMode(int videoMode)
|
||||
|
||||
if (options.video.border.enabled)
|
||||
{
|
||||
shader::init(window_, border_canvas_, source.c_str());
|
||||
shader::init(window_, border_texture_, source.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
shader::init(window_, game_canvas_, source.c_str());
|
||||
shader::init(window_, game_texture_, source.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -248,27 +212,42 @@ void Screen::toggleVideoMode()
|
||||
setVideoMode(options.video.mode);
|
||||
}
|
||||
|
||||
// Cambia el tamaño de la ventana
|
||||
void Screen::setWindowZoom(int size)
|
||||
{
|
||||
options.window.zoom = size;
|
||||
setVideoMode(0);
|
||||
}
|
||||
|
||||
// Reduce el tamaño de la ventana
|
||||
void Screen::decWindowZoom()
|
||||
bool Screen::decWindowZoom()
|
||||
{
|
||||
if (options.video.mode == 0)
|
||||
{
|
||||
int previous_zoom = options.window.zoom;
|
||||
--options.window.zoom;
|
||||
options.window.zoom = std::max(options.window.zoom, 1);
|
||||
setVideoMode(0);
|
||||
|
||||
if (options.window.zoom != previous_zoom)
|
||||
{
|
||||
adjustWindowSize();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Aumenta el tamaño de la ventana
|
||||
void Screen::incWindowZoom()
|
||||
bool Screen::incWindowZoom()
|
||||
{
|
||||
if (options.video.mode == 0)
|
||||
{
|
||||
int previous_zoom = options.window.zoom;
|
||||
++options.window.zoom;
|
||||
options.window.zoom = std::min(options.window.zoom, 4);
|
||||
setVideoMode(0);
|
||||
options.window.zoom = std::min(options.window.zoom, options.window.max_zoom);
|
||||
|
||||
if (options.window.zoom != previous_zoom)
|
||||
{
|
||||
adjustWindowSize();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cambia el color del borde
|
||||
@@ -276,7 +255,7 @@ void Screen::setBorderColor(Color color)
|
||||
{
|
||||
border_color_ = color;
|
||||
auto temp = SDL_GetRenderTarget(renderer_);
|
||||
SDL_SetRenderTarget(renderer_, border_canvas_);
|
||||
SDL_SetRenderTarget(renderer_, border_texture_);
|
||||
SDL_SetRenderDrawColor(renderer_, border_color_.r, border_color_.g, border_color_.b, 0xFF);
|
||||
SDL_RenderClear(renderer_);
|
||||
SDL_SetRenderTarget(renderer_, temp);
|
||||
@@ -307,139 +286,9 @@ void Screen::setBorderEnabled(bool value) { options.video.border.enabled = value
|
||||
void Screen::toggleBorder()
|
||||
{
|
||||
options.video.border.enabled = !options.video.border.enabled;
|
||||
setVideoMode(0);
|
||||
}
|
||||
|
||||
// Activa el fade
|
||||
void Screen::setFade() { fade_ = true; }
|
||||
|
||||
// Comprueba si ha terminado el fade
|
||||
bool Screen::fadeEnded()
|
||||
{
|
||||
if (fade_ || fade_counter_ > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Activa el spectrum fade
|
||||
void Screen::setspectrumFade()
|
||||
{
|
||||
spectrum_fade_ = true;
|
||||
}
|
||||
|
||||
// Comprueba si ha terminado el spectrum fade
|
||||
bool Screen::spectrumFadeEnded()
|
||||
{
|
||||
if (spectrum_fade_ || spectrum_fade_counter_ > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Inicializa las variables para el fade
|
||||
void Screen::iniFade()
|
||||
{
|
||||
fade_ = false;
|
||||
fade_counter_ = 0;
|
||||
fade_lenght_ = 200;
|
||||
}
|
||||
|
||||
// Actualiza el fade
|
||||
void Screen::updateFade()
|
||||
{
|
||||
if (!fade_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fade_counter_++;
|
||||
if (fade_counter_ > fade_lenght_)
|
||||
{
|
||||
iniFade();
|
||||
}
|
||||
}
|
||||
|
||||
// Dibuja el fade
|
||||
void Screen::renderFade()
|
||||
{
|
||||
if (!fade_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const SDL_Rect rect = {0, 0, game_canvas_width_, game_canvas_height_};
|
||||
Color color = {0, 0, 0};
|
||||
const float step = (float)fade_counter_ / (float)fade_lenght_;
|
||||
const int alpha = 0 + (255 - 0) * step;
|
||||
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, alpha);
|
||||
SDL_RenderFillRect(renderer_, &rect);
|
||||
}
|
||||
|
||||
// Inicializa las variables para el fade spectrum
|
||||
void Screen::iniSpectrumFade()
|
||||
{
|
||||
spectrum_fade_ = false;
|
||||
spectrum_fade_counter_ = 0;
|
||||
spectrum_fade_lenght_ = 50;
|
||||
|
||||
spectrum_color_.clear();
|
||||
|
||||
// Inicializa el vector de colores
|
||||
const std::vector<std::string> vColors = {"black", "blue", "red", "magenta", "green", "cyan", "yellow", "bright_white"};
|
||||
for (auto v : vColors)
|
||||
{
|
||||
spectrum_color_.push_back(stringToColor(options.video.palette, v));
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza el spectrum fade
|
||||
void Screen::updateSpectrumFade()
|
||||
{
|
||||
if (!spectrum_fade_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
spectrum_fade_counter_++;
|
||||
if (spectrum_fade_counter_ > spectrum_fade_lenght_)
|
||||
{
|
||||
iniSpectrumFade();
|
||||
SDL_SetTextureColorMod(game_canvas_, 255, 255, 255);
|
||||
}
|
||||
}
|
||||
|
||||
// Dibuja el spectrum fade
|
||||
void Screen::renderSpectrumFade()
|
||||
{
|
||||
if (!spectrum_fade_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const float step = (float)spectrum_fade_counter_ / (float)spectrum_fade_lenght_;
|
||||
const int max = spectrum_color_.size() - 1;
|
||||
const int index = max + (0 - max) * step;
|
||||
const Color c = spectrum_color_[index];
|
||||
SDL_SetTextureColorMod(game_canvas_, c.r, c.g, c.b);
|
||||
}
|
||||
|
||||
// Actualiza los efectos
|
||||
void Screen::updateFX()
|
||||
{
|
||||
updateFade();
|
||||
updateSpectrumFade();
|
||||
}
|
||||
|
||||
// Dibuja los efectos
|
||||
void Screen::renderFX()
|
||||
{
|
||||
renderFade();
|
||||
renderSpectrumFade();
|
||||
adjustWindowSize();
|
||||
adjustGameCanvasRect();
|
||||
adjustRenderLogicalSize();
|
||||
}
|
||||
|
||||
// Dibuja las notificaciones
|
||||
@@ -452,10 +301,8 @@ void Screen::renderNotifications()
|
||||
void Screen::gameCanvasToBorderCanvas()
|
||||
{
|
||||
auto temp = SDL_GetRenderTarget(renderer_);
|
||||
SDL_SetRenderTarget(renderer_, border_canvas_);
|
||||
SDL_SetRenderDrawColor(renderer_, border_color_.r, border_color_.g, border_color_.b, 0xFF);
|
||||
SDL_RenderClear(renderer_);
|
||||
SDL_RenderCopy(renderer_, game_canvas_, nullptr, &dest_);
|
||||
SDL_SetRenderTarget(renderer_, border_texture_);
|
||||
SDL_RenderCopy(renderer_, game_texture_, nullptr, &game_texture_rect_);
|
||||
SDL_SetRenderTarget(renderer_, temp);
|
||||
}
|
||||
|
||||
@@ -463,7 +310,7 @@ void Screen::gameCanvasToBorderCanvas()
|
||||
void Screen::renderPresent()
|
||||
{
|
||||
SDL_SetRenderTarget(renderer_, nullptr);
|
||||
SDL_SetRenderDrawColor(renderer_, border_color_.r, border_color_.g, border_color_.b, 0xFF);
|
||||
SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF);
|
||||
SDL_RenderClear(renderer_);
|
||||
|
||||
if (options.video.shaders)
|
||||
@@ -475,11 +322,11 @@ void Screen::renderPresent()
|
||||
{
|
||||
if (options.video.border.enabled)
|
||||
{
|
||||
SDL_RenderCopy(renderer_, border_canvas_, nullptr, nullptr);
|
||||
SDL_RenderCopy(renderer_, border_texture_, nullptr, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_RenderCopy(renderer_, game_canvas_, nullptr, &dest_);
|
||||
SDL_RenderCopy(renderer_, game_texture_, nullptr, &game_texture_rect_);
|
||||
}
|
||||
SDL_RenderPresent(renderer_);
|
||||
}
|
||||
@@ -510,3 +357,71 @@ void Screen::hide()
|
||||
{
|
||||
SDL_HideWindow(window_);
|
||||
}
|
||||
|
||||
// Calcula el tamaño de la ventana
|
||||
void Screen::adjustWindowSize()
|
||||
{
|
||||
window_width_ = options.game.width + (options.video.border.enabled ? options.video.border.width * 2 : 0);
|
||||
window_height_ = options.game.height + (options.video.border.enabled ? options.video.border.height * 2 : 0);
|
||||
|
||||
options.window.max_zoom = getMaxZoom();
|
||||
|
||||
// Establece el nuevo tamaño
|
||||
if (options.video.mode == 0)
|
||||
{
|
||||
int old_width, old_height;
|
||||
SDL_GetWindowSize(window_, &old_width, &old_height);
|
||||
|
||||
int old_pos_x, old_pos_y;
|
||||
SDL_GetWindowPosition(window_, &old_pos_x, &old_pos_y);
|
||||
|
||||
int new_pos_x = old_pos_x + (old_width - (window_width_ * options.window.zoom)) / 2;
|
||||
int new_pos_y = old_pos_y + (old_height - (window_height_ * options.window.zoom)) / 2;
|
||||
|
||||
SDL_SetWindowSize(window_, window_width_ * options.window.zoom, window_height_ * options.window.zoom);
|
||||
SDL_SetWindowPosition(window_, std::max(new_pos_x, WINDOWS_DECORATIONS_), std::max(new_pos_y, 0));
|
||||
}
|
||||
}
|
||||
|
||||
// Ajusta game_canvas_rect_
|
||||
void Screen::adjustGameCanvasRect()
|
||||
{
|
||||
game_texture_rect_ = {
|
||||
options.video.border.enabled ? options.video.border.width : 0,
|
||||
options.video.border.enabled ? options.video.border.height : 0,
|
||||
options.game.width,
|
||||
options.game.height};
|
||||
}
|
||||
|
||||
// Ajusta el tamaño lógico del renderizador
|
||||
void Screen::adjustRenderLogicalSize()
|
||||
{
|
||||
const int extra_width = options.video.border.enabled ? options.video.border.width * 2 : 0;
|
||||
const int extra_height = options.video.border.enabled ? options.video.border.height * 2 : 0;
|
||||
SDL_RenderSetLogicalSize(renderer_, options.game.width + extra_width, options.game.height + extra_height);
|
||||
}
|
||||
|
||||
// Obtiene el tamaño máximo de zoom posible para la ventana
|
||||
int Screen::getMaxZoom()
|
||||
{
|
||||
// Obtiene información sobre la pantalla
|
||||
SDL_DisplayMode DM;
|
||||
SDL_GetCurrentDisplayMode(0, &DM);
|
||||
|
||||
// Calcula el máximo factor de zoom que se puede aplicar a la pantalla
|
||||
const int max_zoom = std::min(DM.w / window_width_, (DM.h - WINDOWS_DECORATIONS_) / window_height_);
|
||||
|
||||
// Normaliza los valores de zoom
|
||||
options.window.zoom = std::min(options.window.zoom, max_zoom);
|
||||
|
||||
return max_zoom;
|
||||
}
|
||||
|
||||
// Renderiza un frame negro
|
||||
void Screen::renderBlackFrame()
|
||||
{
|
||||
SDL_SetRenderTarget(renderer_, nullptr);
|
||||
SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF);
|
||||
SDL_RenderClear(renderer_);
|
||||
SDL_RenderPresent(renderer_);
|
||||
}
|
||||
@@ -6,7 +6,9 @@
|
||||
#include <SDL2/SDL_stdinc.h> // for Uint32
|
||||
#include <SDL2/SDL_video.h> // for SDL_Window
|
||||
#include <vector> // for vector
|
||||
#include <memory> // for shared_ptr
|
||||
#include "utils.h" // for Color
|
||||
//#include "surface.h"
|
||||
|
||||
// Tipos de filtro
|
||||
enum class ScreenFilter : Uint32
|
||||
@@ -18,51 +20,25 @@ enum class ScreenFilter : Uint32
|
||||
class Screen
|
||||
{
|
||||
private:
|
||||
// Constantes
|
||||
static constexpr int WINDOWS_DECORATIONS_ = 35;
|
||||
|
||||
// [SINGLETON] Objeto privado
|
||||
static Screen *screen_;
|
||||
|
||||
// Objetos y punteros
|
||||
SDL_Window *window_; // Ventana de la aplicación
|
||||
SDL_Renderer *renderer_; // El renderizador de la ventana
|
||||
SDL_Texture *game_canvas_; // Textura donde se dibuja el juego
|
||||
SDL_Texture *border_canvas_; // Textura donde se dibuja el borde del juego
|
||||
SDL_Texture *surface_texture_; // Textura donde se dibuja el juego
|
||||
SDL_Texture *game_texture_; // Textura donde se dibuja el juego
|
||||
SDL_Texture *border_texture_; // Textura donde se dibuja el borde del juego
|
||||
//std::shared_ptr<Surface> surface_; // Objeto para trabajar con surfaces
|
||||
|
||||
// Variables
|
||||
int window_width_; // Ancho de la pantalla o ventana
|
||||
int window_height_; // Alto de la pantalla o ventana
|
||||
int game_canvas_width_; // Resolución interna del juego. Es el ancho de la textura donde se dibuja el juego
|
||||
int game_canvas_height_; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego
|
||||
SDL_Rect dest_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
|
||||
SDL_Rect game_texture_rect_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
|
||||
Color border_color_; // Color del borde añadido a la textura de juego para rellenar la pantalla
|
||||
int notification_logical_width_; // Ancho lógico de las notificaciones en relación al tamaño de pantalla
|
||||
int notification_logical_height_; // Alto lógico de las notificaciones en relación al tamaño de pantalla
|
||||
|
||||
// Variables - Efectos
|
||||
bool fade_; // Indica si esta activo el efecto de fade
|
||||
int fade_counter_; // Temporizador para el efecto de fade
|
||||
int fade_lenght_; // Duración del fade
|
||||
bool spectrum_fade_; // Indica si esta activo el efecto de fade spectrum
|
||||
int spectrum_fade_counter_; // Temporizador para el efecto de fade spectrum
|
||||
int spectrum_fade_lenght_; // Duración del fade spectrum
|
||||
std::vector<Color> spectrum_color_; // Colores para el fade spectrum
|
||||
|
||||
// Inicializa las variables para el fade
|
||||
void iniFade();
|
||||
|
||||
// Actualiza el fade
|
||||
void updateFade();
|
||||
|
||||
// Dibuja el fade
|
||||
void renderFade();
|
||||
|
||||
// Inicializa las variables para el fade spectrum
|
||||
void iniSpectrumFade();
|
||||
|
||||
// Actualiza el spectrum fade
|
||||
void updateSpectrumFade();
|
||||
|
||||
// Dibuja el spectrum fade
|
||||
void renderSpectrumFade();
|
||||
|
||||
// Dibuja las notificaciones
|
||||
void renderNotifications();
|
||||
@@ -73,6 +49,18 @@ private:
|
||||
// Muestra el contenido de Screen por pantalla
|
||||
void renderPresent();
|
||||
|
||||
// Calcula el tamaño de la ventana
|
||||
void adjustWindowSize();
|
||||
|
||||
// Ajusta game_canvas_rect_
|
||||
void adjustGameCanvasRect();
|
||||
|
||||
// Ajusta el tamaño lógico del renderizador
|
||||
void adjustRenderLogicalSize();
|
||||
|
||||
// Renderiza un frame negro
|
||||
void renderBlackFrame();
|
||||
|
||||
// Constructor
|
||||
Screen(SDL_Window *window, SDL_Renderer *renderer);
|
||||
|
||||
@@ -111,14 +99,11 @@ public:
|
||||
// Camibia entre pantalla completa y ventana
|
||||
void toggleVideoMode();
|
||||
|
||||
// Cambia el tamaño de la ventana
|
||||
void setWindowZoom(int size);
|
||||
|
||||
// Reduce el tamaño de la ventana
|
||||
void decWindowZoom();
|
||||
bool decWindowZoom();
|
||||
|
||||
// Aumenta el tamaño de la ventana
|
||||
void incWindowZoom();
|
||||
bool incWindowZoom();
|
||||
|
||||
// Cambia el color del borde
|
||||
void setBorderColor(Color color);
|
||||
@@ -136,24 +121,6 @@ public:
|
||||
// Cambia entre borde visible y no visible
|
||||
void toggleBorder();
|
||||
|
||||
// Activa el fade
|
||||
void setFade();
|
||||
|
||||
// Comprueba si ha terminado el fade
|
||||
bool fadeEnded();
|
||||
|
||||
// Activa el spectrum fade
|
||||
void setspectrumFade();
|
||||
|
||||
// Comprueba si ha terminado el spectrum fade
|
||||
bool spectrumFadeEnded();
|
||||
|
||||
// Actualiza los efectos
|
||||
void updateFX();
|
||||
|
||||
// Dibuja los efectos
|
||||
void renderFX();
|
||||
|
||||
// Cambia el estado de los shaders
|
||||
void toggleShaders();
|
||||
|
||||
@@ -163,6 +130,12 @@ public:
|
||||
// Oculta la ventana
|
||||
void hide();
|
||||
|
||||
// Obtiene el tamaño máximo de zoom posible para la ventana
|
||||
int getMaxZoom();
|
||||
|
||||
// Getters
|
||||
SDL_Renderer *getRenderer() { return renderer_; }
|
||||
//std::shared_ptr<SurfaceData> getSurface() { return surface_->getSurface(); }
|
||||
SDL_Texture *getGameTexture() { return game_texture_; };
|
||||
SDL_Texture *getBorderTexture() { return border_texture_; }
|
||||
};
|
||||
243
source/surface.cpp
Normal file
243
source/surface.cpp
Normal file
@@ -0,0 +1,243 @@
|
||||
#include "surface.h"
|
||||
#include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_ARGB8888
|
||||
#include <SDL2/SDL_rect.h> // Para SDL_Rect
|
||||
#include <fstream> // Para std::ifstream
|
||||
#include <iostream> // Para std::cerr
|
||||
#include <vector> // Para std::vector
|
||||
#include <stdexcept> // For exceptions
|
||||
#include "gif.h" // Para LoadGif, LoadPalette
|
||||
#include <memory> // Para std::shared_ptr
|
||||
#include <algorithm> // Para std::copy
|
||||
#include "asset.h"
|
||||
|
||||
Surface::Surface(std::shared_ptr<SurfaceData> surface_dest, int w, int h)
|
||||
: surface_dest_(surface_dest),
|
||||
surface_(std::make_shared<SurfaceData>(w, h)),
|
||||
transparent_color_(0) {}
|
||||
|
||||
Surface::Surface(std::shared_ptr<SurfaceData> surface_dest, std::string file_path)
|
||||
: surface_dest_(surface_dest),
|
||||
surface_(std::make_shared<SurfaceData>(loadSurface(Asset::get()->get(file_path)))),
|
||||
transparent_color_(0) {
|
||||
std::cout << "surface loaded: "<< surface_->width << "x" << surface_->height << std::endl;
|
||||
}
|
||||
|
||||
Surface::~Surface() {}
|
||||
|
||||
// Carga una superficie desde un archivo
|
||||
SurfaceData Surface::loadSurface(const std::string &file_path)
|
||||
{
|
||||
std::ifstream file(file_path, std::ios::binary | std::ios::ate);
|
||||
|
||||
if (!file.is_open())
|
||||
{
|
||||
std::cerr << "Error opening file: " << file_path << std::endl;
|
||||
throw std::runtime_error("Error opening file");
|
||||
}
|
||||
|
||||
std::streamsize size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
std::vector<Uint8> buffer(size);
|
||||
if (!file.read((char *)buffer.data(), size))
|
||||
{
|
||||
std::cerr << "Error reading file: " << file_path << std::endl;
|
||||
throw std::runtime_error("Error reading file");
|
||||
}
|
||||
|
||||
Uint16 w, h;
|
||||
Uint8 *pixels = LoadGif(buffer.data(), &w, &h);
|
||||
if (pixels == nullptr)
|
||||
{
|
||||
std::cerr << "Error loading GIF from file: " << file_path << std::endl;
|
||||
throw std::runtime_error("Error loading GIF");
|
||||
}
|
||||
|
||||
// Crear y devolver directamente el objeto SurfaceData
|
||||
return SurfaceData(w, h, pixels);
|
||||
}
|
||||
|
||||
// Carga una paleta desde un archivo
|
||||
void Surface::loadPalette(const std::string &file_path)
|
||||
{
|
||||
// Abrir el archivo en modo binario
|
||||
std::ifstream file(file_path, std::ios::binary | std::ios::ate);
|
||||
if (!file.is_open())
|
||||
{
|
||||
throw std::runtime_error("Error opening file: " + file_path);
|
||||
}
|
||||
|
||||
// Leer el contenido del archivo en un buffer
|
||||
std::streamsize size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
std::vector<Uint8> buffer(size);
|
||||
if (!file.read(reinterpret_cast<char *>(buffer.data()), size))
|
||||
{
|
||||
throw std::runtime_error("Error reading file: " + file_path);
|
||||
}
|
||||
|
||||
// Cargar la paleta usando los datos del buffer
|
||||
std::unique_ptr<Uint32[]> pal(LoadPalette(buffer.data()));
|
||||
if (pal == nullptr)
|
||||
{
|
||||
throw std::runtime_error("Error loading palette from file: " + file_path);
|
||||
}
|
||||
|
||||
// Copiar los datos de la paleta al std::array
|
||||
std::copy(pal.get(), pal.get() + palette_.size(), palette_.begin());
|
||||
|
||||
for (auto p : palette_)
|
||||
{
|
||||
std::cout << std::hex << p << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
// Establece un color en la paleta
|
||||
void Surface::setColor(int index, Uint32 color)
|
||||
{
|
||||
palette_.at(index) = color;
|
||||
}
|
||||
|
||||
// Limpia la superficie de destino con un color
|
||||
void Surface::clear(std::shared_ptr<SurfaceData> surface, Uint8 color)
|
||||
{
|
||||
const size_t total_pixels = surface->width * surface->height;
|
||||
std::fill(surface->data, surface->data + total_pixels, color);
|
||||
}
|
||||
|
||||
// Pone un pixel en la superficie de destino
|
||||
void Surface::putPixel(int x, int y, Uint8 color)
|
||||
{
|
||||
if (color == transparent_color_)
|
||||
{
|
||||
return; // Color transparente, no dibujar
|
||||
}
|
||||
|
||||
if (x < 0 || y < 0 || x >= surface_dest_->width || y >= surface_dest_->height)
|
||||
{
|
||||
return; // Coordenadas fuera de rango
|
||||
}
|
||||
|
||||
const int index = x + y * surface_dest_->width;
|
||||
surface_dest_->data[index] = color;
|
||||
}
|
||||
|
||||
// Obtiene el color de un pixel de la superficie de origen
|
||||
Uint8 Surface::getPixel(int x, int y)
|
||||
{
|
||||
return surface_->data[x + y * surface_->width];
|
||||
}
|
||||
|
||||
// Copia una región de la superficie de origen a la de destino
|
||||
void Surface::render(int dx, int dy, int sx, int sy, int w, int h)
|
||||
{
|
||||
if (!surface_ || !surface_dest_)
|
||||
{
|
||||
throw std::runtime_error("Surface source or destination is null.");
|
||||
}
|
||||
|
||||
// Limitar la región para evitar accesos fuera de rango
|
||||
w = std::min(w, surface_->width - sx);
|
||||
h = std::min(h, surface_->height - sy);
|
||||
w = std::min(w, surface_dest_->width - dx);
|
||||
h = std::min(h, surface_dest_->height - dy);
|
||||
|
||||
for (int iy = 0; iy < h; ++iy)
|
||||
{
|
||||
for (int ix = 0; ix < w; ++ix)
|
||||
{
|
||||
Uint8 color = surface_->data[(sx + ix) + (sy + iy) * surface_->width];
|
||||
if (color != transparent_color_) // Opcional: Ignorar píxeles transparentes
|
||||
{
|
||||
surface_dest_->data[(dx + ix) + (dy + iy) * surface_dest_->width] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Vuelca la superficie a una textura
|
||||
void Surface::flip(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
{
|
||||
Uint32 *pixels;
|
||||
int pitch;
|
||||
SDL_LockTexture(texture, nullptr, (void **)&pixels, &pitch);
|
||||
for (int i = 0; i < surface_.width * surface_.height; ++i)
|
||||
{
|
||||
pixels[i] = palette_[surface_.data[i]];
|
||||
}
|
||||
SDL_UnlockTexture(texture);
|
||||
SDL_RenderCopy(renderer, texture, nullptr, nullptr);
|
||||
}
|
||||
*/
|
||||
|
||||
// Vuelca la superficie a una textura
|
||||
void Surface::copyToTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
{
|
||||
if (!renderer || !texture)
|
||||
{
|
||||
throw std::runtime_error("Renderer or texture is null.");
|
||||
}
|
||||
|
||||
if (surface_->width <= 0 || surface_->height <= 0 || !surface_->data)
|
||||
{
|
||||
throw std::runtime_error("Invalid surface dimensions or data.");
|
||||
}
|
||||
|
||||
Uint32 *pixels = nullptr;
|
||||
int pitch = 0;
|
||||
|
||||
// Bloquea la textura para modificar los píxeles directamente
|
||||
if (SDL_LockTexture(texture, nullptr, (void **)&pixels, &pitch) != 0)
|
||||
{
|
||||
throw std::runtime_error("Failed to lock texture: " + std::string(SDL_GetError()));
|
||||
}
|
||||
|
||||
// Convertir `pitch` de bytes a Uint32 (asegurando alineación correcta en hardware)
|
||||
int row_stride = pitch / sizeof(Uint32);
|
||||
|
||||
for (int y = 0; y < surface_->height; ++y)
|
||||
{
|
||||
for (int x = 0; x < surface_->width; ++x)
|
||||
{
|
||||
// Calcular la posición correcta en la textura teniendo en cuenta el stride
|
||||
int texture_index = y * row_stride + x;
|
||||
int surface_index = y * surface_->width + x;
|
||||
|
||||
pixels[texture_index] = palette_[surface_->data[surface_index]];
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockTexture(texture); // Desbloquea la textura
|
||||
|
||||
// Renderiza la textura en la pantalla completa
|
||||
if (SDL_RenderCopy(renderer, texture, nullptr, nullptr) != 0)
|
||||
{
|
||||
throw std::runtime_error("Failed to copy texture to renderer: " + std::string(SDL_GetError()));
|
||||
}
|
||||
}
|
||||
|
||||
// Realiza un efecto de fundido en la paleta
|
||||
bool Surface::fadePalette()
|
||||
{
|
||||
// Verificar que el tamaño mínimo de palette_ sea adecuado
|
||||
static constexpr int palette_size = 19;
|
||||
if (sizeof(palette_) / sizeof(palette_[0]) < palette_size)
|
||||
{
|
||||
throw std::runtime_error("Palette size is insufficient for fadePalette operation.");
|
||||
}
|
||||
|
||||
// Desplazar colores (pares e impares)
|
||||
for (int i = 18; i > 1; --i)
|
||||
{
|
||||
palette_[i] = palette_[i - 2];
|
||||
}
|
||||
|
||||
// Ajustar el primer color
|
||||
palette_[1] = palette_[0];
|
||||
|
||||
// Devolver si el índice 15 coincide con el índice 0
|
||||
return palette_[15] == palette_[0];
|
||||
}
|
||||
108
source/surface.h
Normal file
108
source/surface.h
Normal file
@@ -0,0 +1,108 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL2/SDL_render.h> // Para SDL_Renderer
|
||||
#include <SDL2/SDL_stdinc.h> // Para Uint8, Uint32
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
struct SurfaceData
|
||||
{
|
||||
Uint8 *data;
|
||||
Uint16 width;
|
||||
Uint16 height;
|
||||
|
||||
// Constructor por defecto
|
||||
SurfaceData() : data(nullptr), width(0), height(0) {}
|
||||
|
||||
// Constructor que inicializa dimensiones y asigna memoria
|
||||
SurfaceData(Uint16 w, Uint16 h)
|
||||
: data(new Uint8[w * h]()), width(w), height(h) {}
|
||||
|
||||
// Constructor para inicializar directamente con datos
|
||||
SurfaceData(Uint16 w, Uint16 h, Uint8 *pixels)
|
||||
: data(pixels), width(w), height(h) {}
|
||||
|
||||
// Destructor para liberar memoria
|
||||
~SurfaceData() { delete[] data; }
|
||||
|
||||
// Evita copias accidentales (opcional para mayor seguridad)
|
||||
SurfaceData(const SurfaceData &) = delete;
|
||||
SurfaceData &operator=(const SurfaceData &) = delete;
|
||||
|
||||
// Permite movimiento para evitar copias costosas
|
||||
SurfaceData(SurfaceData &&other) noexcept
|
||||
: data(other.data), width(other.width), height(other.height)
|
||||
{
|
||||
other.data = nullptr;
|
||||
other.width = 0;
|
||||
other.height = 0;
|
||||
}
|
||||
|
||||
SurfaceData &operator=(SurfaceData &&other) noexcept
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
delete[] data;
|
||||
|
||||
data = other.data;
|
||||
width = other.width;
|
||||
height = other.height;
|
||||
|
||||
other.data = nullptr;
|
||||
other.width = 0;
|
||||
other.height = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class Surface
|
||||
{
|
||||
private:
|
||||
std::shared_ptr<SurfaceData> surface_dest_;
|
||||
std::shared_ptr<SurfaceData> surface_;
|
||||
std::array<Uint32, 256> palette_;
|
||||
int transparent_color_;
|
||||
|
||||
// Pone un pixel en la superficie de destino
|
||||
void putPixel(int x, int y, Uint8 color);
|
||||
|
||||
// Obtiene el color de un pixel de la superficie de origen
|
||||
Uint8 getPixel(int x, int y);
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
Surface(std::shared_ptr<SurfaceData> surface_dest, int w, int h);
|
||||
Surface(std::shared_ptr<SurfaceData> surface_dest, std::string file_path);
|
||||
|
||||
// Destructor
|
||||
~Surface();
|
||||
|
||||
// Carga una superficie desde un archivo
|
||||
SurfaceData loadSurface(const std::string &file_path);
|
||||
|
||||
// Carga una paleta desde un archivo
|
||||
void loadPalette(const std::string &file_path);
|
||||
|
||||
// Copia una región de la superficie de origen a la de destino
|
||||
void render(int dx, int dy, int sx, int sy, int w, int h);
|
||||
|
||||
// Establece un color en la paleta
|
||||
void setColor(int index, Uint32 color);
|
||||
|
||||
// Limpia la superficie de destino con un color
|
||||
void clear(std::shared_ptr<SurfaceData> surface, Uint8 color);
|
||||
|
||||
// Vuelca la superficie a una textura
|
||||
void copyToTexture(SDL_Renderer *renderer, SDL_Texture *texture);
|
||||
|
||||
// Realiza un efecto de fundido en la paleta
|
||||
bool fadePalette();
|
||||
|
||||
// Getters
|
||||
std::shared_ptr<SurfaceData> getSurface() const { return surface_; }
|
||||
// std::shared_ptr<SurfaceData> getSurfaceDest() const { return surface_dest_; }
|
||||
// std::array<Uint32, 256> getPalette() const { return palette_; }
|
||||
int getTransparentColor() const { return transparent_color_; }
|
||||
};
|
||||
@@ -11,7 +11,7 @@
|
||||
struct Color;
|
||||
|
||||
// Definiciones de tipos
|
||||
struct Surface
|
||||
/*struct Surface
|
||||
{
|
||||
std::shared_ptr<Uint8[]> data;
|
||||
Uint16 w, h;
|
||||
@@ -19,7 +19,7 @@ struct Surface
|
||||
// Constructor
|
||||
Surface(Uint16 width, Uint16 height, std::shared_ptr<Uint8[]> pixels)
|
||||
: data(pixels), w(width), h(height) {}
|
||||
};
|
||||
};*/
|
||||
|
||||
class Texture
|
||||
{
|
||||
@@ -27,7 +27,7 @@ private:
|
||||
// Objetos y punteros
|
||||
SDL_Renderer *renderer_; // Renderizador donde dibujar la textura
|
||||
SDL_Texture *texture_ = nullptr; // La textura
|
||||
std::shared_ptr<Surface> surface_ = nullptr; // Surface para usar imagenes en formato gif con paleta
|
||||
//std::shared_ptr<Surface> surface_ = nullptr; // Surface para usar imagenes en formato gif con paleta
|
||||
|
||||
// Variables
|
||||
std::string path_; // Ruta de la imagen de la textura
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR
|
||||
#include "texture.h" // for Texture
|
||||
#include "utils.h" // for Color, stringToColor, Palette
|
||||
#include "paleta.h"
|
||||
|
||||
// Constructor
|
||||
Title::Title()
|
||||
@@ -71,6 +72,9 @@ Title::Title()
|
||||
|
||||
// Rellena la textura de fondo con todos los gráficos
|
||||
fillTexture();
|
||||
|
||||
// Inicia la musica
|
||||
playMusic("title.ogg");
|
||||
}
|
||||
|
||||
// Destructor
|
||||
@@ -213,7 +217,7 @@ void Title::renderInfo()
|
||||
void Title::update()
|
||||
{
|
||||
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
|
||||
if (SDL_GetTicks() - ticks_ > ticks_speed_)
|
||||
if (SDL_GetTicks() - ticks_ > GAME_SPEED)
|
||||
{
|
||||
// Actualiza el contador de ticks
|
||||
ticks_ = SDL_GetTicks();
|
||||
|
||||
@@ -48,7 +48,6 @@ private:
|
||||
int counter_ = 0; // Contador
|
||||
std::string long_text_; // Texto que aparece en la parte inferior del titulo
|
||||
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
||||
Uint32 ticks_speed_ = 15; // Velocidad a la que se repiten los bucles del programa
|
||||
std::vector<letter_t> letters_; // Vector con las letras de la marquesina
|
||||
int marquee_speed_ = 3; // Velocidad de desplazamiento de la marquesina
|
||||
bool show_cheevos_ = false; // Indica si se muestra por pantalla el listado de logros
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <iostream> // for basic_ostream, cout, basic_ios, ios, endl
|
||||
#include <unordered_map> // for unordered_map
|
||||
#include <string> // for string
|
||||
#include "jail_audio.h"
|
||||
#include "resource.h"
|
||||
|
||||
// Calcula el cuadrado de la distancia entre dos puntos
|
||||
double distanceSquared(int x1, int y1, int x2, int y2)
|
||||
@@ -519,3 +521,38 @@ void printWithDots(const std::string &text1, const std::string &text2, const std
|
||||
|
||||
std::cout << text3 << std::endl;
|
||||
}
|
||||
|
||||
// Comprueba si una vector contiene una cadena
|
||||
bool stringInVector(const std::vector<std::string> &vec, const std::string &str)
|
||||
{
|
||||
return std::find(vec.begin(), vec.end(), str) != vec.end();
|
||||
}
|
||||
|
||||
// Hace sonar la música
|
||||
void playMusic(const std::string &music_path)
|
||||
{
|
||||
// Si la música no está sonando
|
||||
if (JA_GetMusicState() == JA_MUSIC_INVALID || JA_GetMusicState() == JA_MUSIC_STOPPED)
|
||||
{
|
||||
JA_PlayMusic(Resource::get()->getMusic(music_path));
|
||||
}
|
||||
}
|
||||
|
||||
// Rellena una textura de un color
|
||||
void fillTextureWithColor(SDL_Renderer* renderer, SDL_Texture* texture, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
||||
{
|
||||
// Guardar el render target actual
|
||||
SDL_Texture* previous_target = SDL_GetRenderTarget(renderer);
|
||||
|
||||
// Establecer la textura como el render target
|
||||
SDL_SetRenderTarget(renderer, texture);
|
||||
|
||||
// Establecer el color deseado
|
||||
SDL_SetRenderDrawColor(renderer, r, g, b, a);
|
||||
|
||||
// Pintar toda el área
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
// Restaurar el render target previo
|
||||
SDL_SetRenderTarget(renderer, previous_target);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
#include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point
|
||||
#include <SDL2/SDL_stdinc.h> // for Uint8
|
||||
#include <string> // for string
|
||||
#include <vector>
|
||||
#include <SDL2/SDL_render.h> // for SDL_Renderer
|
||||
#include <SDL2/SDL.h> // for SDL_Texture
|
||||
|
||||
|
||||
// Tipos de paleta
|
||||
enum class Palette : int
|
||||
@@ -123,3 +127,12 @@ std::string getPath(const std::string &full_path);
|
||||
|
||||
// Imprime por pantalla una linea de texto de tamaño fijo rellena con puntos
|
||||
void printWithDots(const std::string &text1, const std::string &text2, const std::string &text3);
|
||||
|
||||
// Comprueba si una vector contiene una cadena
|
||||
bool stringInVector(const std::vector<std::string> &vec, const std::string &str);
|
||||
|
||||
// Hace sonar la música
|
||||
void playMusic(const std::string &music_path);
|
||||
|
||||
// Rellena una textura de un color
|
||||
void fillTextureWithColor(SDL_Renderer* renderer, SDL_Texture* texture, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
||||
Reference in New Issue
Block a user