19 Commits

Author SHA1 Message Date
4e525642a0 v1.09 2025-03-01 09:15:08 +01:00
c7db6aeaa3 canvi de pc 2025-03-01 08:11:00 +01:00
5ff04daf20 gonna fer un commit per si reventa algo: estic a meitat implementar surfaces 2025-02-28 22:58:01 +01:00
5bb2b5e7c4 fix: les notificacions ja no embruten la pantalla de càrrega 2025-02-28 14:00:59 +01:00
7a685c0cc8 fix: no pintava el efecte de carrega del borde en LoadingScreen 2025-02-28 13:40:30 +01:00
07e83fc811 Tornada a posar la musica de Title i el attract mode 2025-02-28 13:25:21 +01:00
3167251eae Eliminat el alpha de les notificacions 2025-02-28 13:13:36 +01:00
4efbb61fbc Arreglat aixina sense massa ganes Scoreboard::render() 2025-02-28 13:11:02 +01:00
3992fc08bf Afegides comprobacions de valors per al fitxer de configuració 2025-02-28 11:34:51 +01:00
366fe404ca Modes de video aclarits (sembla)
La finestra manté la posició al canviar de tamany o activar el borde
La finestra ja pot creixer mentres donde de si el escriptori
2025-02-28 09:46:55 +01:00
217781c621 lo mateix 2025-02-27 23:18:16 +01:00
212b2b481c Treballant en els modes de video 2025-02-27 21:05:01 +01:00
59e766f5c3 Nou engine de notificacions 2025-02-27 19:03:57 +01:00
2e11fec2cb canvi de pc 2025-02-27 16:51:20 +01:00
0d7ab830c9 Modificada la barra de progres de carrega de recursos per a que s'actualitze cada 5 items. Aixina ja va rapidet encara que estiga el vsync 2025-02-27 14:21:53 +01:00
0cec9f8556 Solventat bug amb el punter a ScoreboardData 2025-02-27 14:17:00 +01:00
c6474cb2da canvi de pc 2025-02-27 07:37:39 +01:00
e6fd4225a2 Ja torna a deixar jugar
Encara queden bugs per corregir
Trencat el sistema de triar la paleta, de moment
2025-02-26 20:37:29 +01:00
85ab5ea03f Singleton de ItemTracker
Arreglos menors
2025-02-26 13:07:41 +01:00
55 changed files with 2965 additions and 2422 deletions

BIN
data/test.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

View File

@@ -8,7 +8,7 @@
#include "utils.h" // Para printWithDots #include "utils.h" // Para printWithDots
// Carga las animaciones en un vector(Animations) desde un fichero // 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); std::ifstream file(file_path);
if (!file) if (!file)
@@ -37,18 +37,18 @@ AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const std::stri
// Carga las animaciones // Carga las animaciones
if (!file_path.empty()) if (!file_path.empty())
{ {
AnimationsFileBuffer v = loadAnimationsFromFile(file_path); Animations v = loadAnimationsFromFile(file_path);
loadFromAnimationsFileBuffer(v); setAnimations(v);
} }
} }
// Constructor // Constructor
AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const AnimationsFileBuffer &animations) AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const Animations &animations)
: MovingSprite(texture) : MovingSprite(texture)
{ {
if (!animations.empty()) 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_].current_frame = 0;
animations_[current_animation_].counter = 0; animations_[current_animation_].counter = 0;
animations_[current_animation_].completed = false; 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_].current_frame = 0;
animations_[current_animation_].counter = 0; animations_[current_animation_].counter = 0;
animations_[current_animation_].completed = false; 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 // 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_width = 1;
int frame_height = 1; int frame_height = 1;
@@ -162,9 +164,9 @@ void AnimatedSprite::loadFromAnimationsFileBuffer(const AnimationsFileBuffer &so
int max_tiles = 1; int max_tiles = 1;
size_t index = 0; 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 // Parsea el fichero para buscar variables y valores
if (line != "[animation]") 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 // Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación
if (line == "[animation]") if (line == "[animation]")
{ {
Animation animation; AnimationData animation;
do do
{ {
index++; index++;
line = source.at(index); line = animations.at(index);
size_t pos = line.find("="); size_t pos = line.find("=");
if (pos != std::string::npos) if (pos != std::string::npos)

View File

@@ -7,7 +7,7 @@
#include "moving_sprite.h" // Para MovingSprite #include "moving_sprite.h" // Para MovingSprite
class Texture; // lines 9-9 class Texture; // lines 9-9
struct Animation struct AnimationData
{ {
std::string name; // Nombre de la animacion std::string name; // Nombre de la animacion
std::vector<SDL_Rect> frames; // Cada uno de los frames que componen la animación 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 current_frame; // Frame actual
int counter; // Contador para las animaciones 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 // 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 class AnimatedSprite : public MovingSprite
{ {
protected: protected:
// Variables // 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 int current_animation_ = 0; // Animacion activa
// Calcula el frame correspondiente a la animación actual // Calcula el frame correspondiente a la animación actual
void animate(); void animate();
// Carga la animación desde un vector de cadenas // Carga la animación desde un vector de cadenas
void loadFromAnimationsFileBuffer(const AnimationsFileBuffer &source); void setAnimations(const Animations &animations);
public: public:
// Constructor // Constructor
AnimatedSprite(std::shared_ptr<Texture> texture, const std::string &file_path); 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) explicit AnimatedSprite(std::shared_ptr<Texture> texture)
: MovingSprite(texture) {} : MovingSprite(texture) {}

View File

@@ -88,7 +88,7 @@ void Cheevos::unlock(int id)
// Marcar el logro como completado // Marcar el logro como completado
cheevos_list_.at(index).completed = true; cheevos_list_.at(index).completed = true;
// Mostrar notificación en la pantalla // 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 // Guardar el estado de los logros
saveToFile(); saveToFile();
} }

View File

@@ -1,22 +1,22 @@
#include "credits.h" #include "credits.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_error.h> // for SDL_GetError #include <SDL2/SDL_error.h> // for SDL_GetError
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <algorithm> // for min #include <algorithm> // for min
#include <iostream> // for basic_ostream, operator<<, cout, endl #include <iostream> // for basic_ostream, operator<<, cout, endl
#include "animated_sprite.h" // for AnimatedSprite #include "animated_sprite.h" // for AnimatedSprite
#include "asset.h" // for Asset #include "asset.h" // for Asset
#include "defines.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_WIDTH #include "defines.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_WIDTH
#include "global_events.h" // for check #include "global_events.h" // for check
#include "global_inputs.h" // for check #include "global_inputs.h" // for check
#include "input.h" // for Input #include "input.h" // for Input
#include "options.h" // for Options, options, OptionsVideo, Sect... #include "options.h" // for Options, options, OptionsVideo, Sect...
#include "resource.h" // for Resource #include "resource.h" // for Resource
#include "screen.h" // for Screen #include "screen.h" // for Screen
#include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR #include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR
// Constructor // Constructor
Credits::Credits() Credits::Credits()
@@ -28,7 +28,7 @@ Credits::Credits()
{ {
// Reserva memoria para los punteros // Reserva memoria para los punteros
text_ = resource_->getText("smb2"); 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 // Inicializa variables
options.section.section = Section::CREDITS; options.section.section = Section::CREDITS;
@@ -255,7 +255,7 @@ void Credits::updateCounter()
void Credits::update() void Credits::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // 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 // Actualiza el contador de ticks
ticks_ = SDL_GetTicks(); ticks_ = SDL_GetTicks();

View File

@@ -38,7 +38,6 @@ private:
bool counter_enabled_ = true; // Indica si esta activo el contador bool counter_enabled_ = true; // Indica si esta activo el contador
int sub_counter_ = 0; // Contador secundario int sub_counter_ = 0; // Contador secundario
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa 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 std::vector<captions_t> texts_; // Vector con los textos
// Actualiza las variables // Actualiza las variables

View File

@@ -7,7 +7,10 @@
// Textos // Textos
constexpr const char *WINDOW_CAPTION = "JailDoctor's Dilemma"; constexpr const char *WINDOW_CAPTION = "JailDoctor's Dilemma";
constexpr const char *TEXT_COPYRIGHT = "@2022 JailDesigner"; 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 // Tamaño de bloque
constexpr int BLOCK = 8; constexpr int BLOCK = 8;

View File

@@ -1,67 +1,73 @@
#include "demo.h" #include "demo.h"
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <iostream> // for basic_ostream, operator<<, cout, endl #include <iostream> // for basic_ostream, operator<<, cout, endl
#include "asset.h" // for Asset #include "asset.h" // for Asset
#include "debug.h" // for Debug #include "debug.h" // for Debug
#include "defines.h" // for BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_CENT... #include "defines.h" // for BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_CENT...
#include "global_events.h" // for check #include "global_events.h" // for check
#include "global_inputs.h" // for check #include "global_inputs.h" // for check
#include "input.h" // for Input #include "input.h" // for Input
#include "item_tracker.h" // for ItemTracker #include "item_tracker.h" // for ItemTracker
#include "options.h" // for Options, options, OptionsVideo, Section... #include "options.h" // for Options, options, OptionsVideo, Section...
#include "resource.h" // for Resource #include "resource.h" // for Resource
#include "room.h" // for Room #include "room.h" // for Room
#include "screen.h" // for Screen #include "screen.h" // for Screen
#include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR #include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR
#include "utils.h" // for Color, stringToColor, colorAreEqual #include "utils.h" // for Color, stringToColor, colorAreEqual
// Constructor // Constructor
Demo::Demo() Demo::Demo()
: screen(Screen::get()), : screen_(Screen::get()),
renderer(Screen::get()->getRenderer()), renderer_(Screen::get()->getRenderer()),
resource(Resource::get()), resource_(Resource::get()),
asset(Asset::get()), asset_(Asset::get()),
input(Input::get()), input_(Input::get()),
debug(Debug::get()) debug_(Debug::get())
{ {
// Inicia algunas variables // Inicia algunas variables
board.iniClock = SDL_GetTicks(); board_ = std::make_shared<ScoreboardData>();
rooms.push_back("04.room"); board_->ini_clock = SDL_GetTicks();
rooms.push_back("54.room"); rooms_.push_back("04.room");
rooms.push_back("20.room"); rooms_.push_back("54.room");
rooms.push_back("09.room"); rooms_.push_back("20.room");
rooms.push_back("05.room"); rooms_.push_back("09.room");
rooms.push_back("11.room"); rooms_.push_back("05.room");
rooms.push_back("31.room"); rooms_.push_back("11.room");
rooms.push_back("44.room"); rooms_.push_back("31.room");
rooms_.push_back("44.room");
roomIndex = 0; room_index_ = 0;
currentRoom = rooms[roomIndex]; current_room_ = rooms_[room_index_];
// Crea los objetos // Crea los objetos
itemTracker = std::make_shared<ItemTracker>(); ItemTracker::init();
scoreboard = std::make_shared<Scoreboard>(&board); scoreboard_ = std::make_shared<Scoreboard>(board_);
room = std::make_shared<Room>(resource->getRoom(currentRoom), itemTracker, &board.items, false); room_ = std::make_shared<Room>(resource_->getRoom(current_room_), board_);
text = resource->getText("smb2"); text_ = resource_->getText("smb2");
// Inicializa el resto de variables // Inicializa el resto de variables
counter = 0; counter_ = 0;
roomTime = 400; room_time_ = 400;
ticks = 0; ticks_ = 0;
ticksSpeed = 15; board_->lives = 9;
board.lives = 9; board_->items = 0;
board.items = 0; board_->rooms = 1;
board.rooms = 1; board_->jail_is_open = false;
board.jail_is_open = false; board_->music = true;
board.music = true;
setScoreBoardColor(); setScoreBoardColor();
options.section.section = Section::DEMO; options.section.section = Section::DEMO;
options.section.subsection = Subsection::NONE; options.section.subsection = Subsection::NONE;
} }
// Destructor
Demo::~Demo()
{
ItemTracker::destroy();
}
// Comprueba los eventos de la cola // Comprueba los eventos de la cola
void Demo::checkEvents() void Demo::checkEvents()
{ {
@@ -93,21 +99,20 @@ void Demo::run()
void Demo::update() void Demo::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // 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 // Actualiza el contador de ticks
ticks = SDL_GetTicks(); ticks_ = SDL_GetTicks();
// Comprueba las entradas // Comprueba las entradas
checkInput(); checkInput();
// Actualiza los objetos // Actualiza los objetos
room->update(); room_->update();
scoreboard->update(); scoreboard_->update();
screen->updateFX();
checkRoomChange(); checkRoomChange();
screen->update(); screen_->update();
} }
} }
@@ -115,18 +120,17 @@ void Demo::update()
void Demo::render() void Demo::render()
{ {
// Prepara para dibujar el frame // Prepara para dibujar el frame
screen->start(); screen_->start();
// Dibuja los elementos del juego en orden // Dibuja los elementos del juego en orden
room->renderMap(); room_->renderMap();
room->renderEnemies(); room_->renderEnemies();
room->renderItems(); room_->renderItems();
renderRoomName(); renderRoomName();
scoreboard->render(); scoreboard_->render();
screen->renderFX();
// Actualiza la pantalla // Actualiza la pantalla
screen->render(); screen_->render();
} }
// Escribe el nombre de la pantalla // Escribe el nombre de la pantalla
@@ -135,10 +139,10 @@ void Demo::renderRoomName()
// Texto en el centro de la pantalla // Texto en el centro de la pantalla
SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK * 2}; SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK * 2};
Color color = stringToColor(options.video.palette, "white"); Color color = stringToColor(options.video.palette, "white");
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF); SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
SDL_RenderFillRect(renderer, &rect); 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 // Recarga todas las texturas
@@ -148,9 +152,9 @@ void Demo::reLoadTextures()
{ {
std::cout << "** RELOAD REQUESTED" << std::endl; std::cout << "** RELOAD REQUESTED" << std::endl;
} }
room->reLoadTexture(); room_->reLoadTexture();
scoreboard->reLoadTexture(); scoreboard_->reLoadTexture();
text->reLoadTexture(); text_->reLoadTexture();
} }
// Cambia la paleta // Cambia la paleta
@@ -166,8 +170,8 @@ void Demo::switchPalette()
options.video.palette = Palette::ZXSPECTRUM; options.video.palette = Palette::ZXSPECTRUM;
} }
room->reLoadPalette(); room_->reLoadPalette();
scoreboard->reLoadPalette(); scoreboard_->reLoadPalette();
// Pone el color del marcador en función del color del borde de la habitación // Pone el color del marcador en función del color del borde de la habitación
setScoreBoardColor(); setScoreBoardColor();
@@ -180,10 +184,10 @@ bool Demo::changeRoom(std::string file)
if (file != "0") if (file != "0")
{ {
// Verifica que exista el fichero que se va a cargar // 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 // 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 // Pone el color del marcador en función del color del borde de la habitación
setScoreBoardColor(); setScoreBoardColor();
@@ -198,19 +202,19 @@ bool Demo::changeRoom(std::string file)
// Comprueba si se ha de cambiar de habitación // Comprueba si se ha de cambiar de habitación
void Demo::checkRoomChange() void Demo::checkRoomChange()
{ {
counter++; counter_++;
if (counter == roomTime) if (counter_ == room_time_)
{ {
counter = 0; counter_ = 0;
roomIndex++; room_index_++;
if (roomIndex == (int)rooms.size()) if (room_index_ == (int)rooms_.size())
{ {
options.section.section = Section::LOGO; options.section.section = Section::LOGO;
options.section.subsection = Subsection::LOGO_TO_TITLE; options.section.subsection = Subsection::LOGO_TO_TITLE;
} }
else else
{ {
changeRoom(rooms[roomIndex]); changeRoom(rooms_[room_index_]);
} }
} }
} }
@@ -219,13 +223,13 @@ void Demo::checkRoomChange()
void Demo::setScoreBoardColor() void Demo::setScoreBoardColor()
{ {
// Obtiene el color del borde // Obtiene el color del borde
const Color color = room->getBorderColor(); const Color color = room_->getBorderColor();
// Si el color es negro lo cambia a blanco // Si el color es negro lo cambia a blanco
const Color black_color = stringToColor(options.video.palette, "black"); 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 // Si el color es negro brillante lo cambia a blanco
const Color bright_blac_color = stringToColor(options.video.palette, "bright_black"); 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;
} }

View File

@@ -1,44 +1,42 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr #include <memory> // for shared_ptr
#include <string> // for string #include <string> // for string
#include <vector> // for vector #include <vector> // for vector
#include "scoreboard.h" // for board_t #include "scoreboard.h" // for board_t
class Asset; // lines 11-11 class Asset; // lines 11-11
class Debug; // lines 12-12 class Debug; // lines 12-12
class Input; // lines 13-13 class Input; // lines 13-13
class ItemTracker; // lines 14-14 class ItemTracker; // lines 14-14
class Resource; // lines 15-15 class Resource; // lines 15-15
class Room; // lines 16-16 class Room; // lines 16-16
class Screen; // lines 17-17 class Screen; // lines 17-17
class Text; // lines 18-18 class Text; // lines 18-18
class Demo class Demo
{ {
private: private:
// Objetos y punteros // Objetos y punteros
Screen *screen; // Objeto encargado de manejar el renderizador Screen *screen_; // Objeto encargado de manejar el renderizador
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
Resource *resource; // Objeto con los recursos Resource *resource_; // Objeto con los recursos
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos
Input *input; // Objeto pata gestionar la entrada Input *input_; // Objeto pata gestionar la entrada
Debug *debug; // Objeto para gestionar la información de debug 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<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<Text> text_; // Objeto para los textos del juego
std::shared_ptr<Scoreboard> scoreboard; // Objeto encargado de gestionar el marcador std::shared_ptr<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador
std::shared_ptr<ItemTracker> itemTracker; // Lleva el control de los objetos recogidos
// Variables // Variables
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa 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 current_room_; // Fichero de la habitación actual
std::string currentRoom; // Fichero de la habitación actual std::shared_ptr<ScoreboardData> board_; // Estructura con los datos del marcador
board_t board; // Estructura con los datos del marcador int counter_; // Contador para el modo demo
int counter; // Contador para el modo demo int room_time_; // Tiempo que se muestra cada habitacion
int roomTime; // Tiempo que se muestra cada habitacion int room_index_; // Indice para el vector de habitaciones
int roomIndex; // Indice para el vector de habitaciones std::vector<std::string> rooms_; // Listado con los mapas de la demo
std::vector<std::string> rooms; // Listado con los mapas de la demo
// Actualiza el juego, las variables, comprueba la entrada, etc. // Actualiza el juego, las variables, comprueba la entrada, etc.
void update(); void update();
@@ -75,7 +73,7 @@ public:
Demo(); Demo();
// Destructor // Destructor
~Demo() = default; ~Demo();
// Bucle para el juego // Bucle para el juego
void run(); void run();

View File

@@ -79,11 +79,10 @@ Director::Director(int argc, const char *argv[])
Screen::init(window_, renderer_); Screen::init(window_, renderer_);
Screen::get()->setBorderColor(borderColor); Screen::get()->setBorderColor(borderColor);
Resource::init(); 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")); Input::init(Asset::get()->get("gamecontrollerdb.txt"));
initInput(); initInput();
Debug::init(); Debug::init();
title_music_ = JA_LoadMusic(Asset::get()->get("title.ogg").c_str());
Cheevos::init(Asset::get()->get("cheevos.bin")); Cheevos::init(Asset::get()->get("cheevos.bin"));
} }
@@ -101,8 +100,6 @@ Director::~Director()
Resource::destroy(); Resource::destroy();
Cheevos::destroy(); Cheevos::destroy();
JA_DeleteMusic(title_music_);
SDL_DestroyRenderer(renderer_); SDL_DestroyRenderer(renderer_);
SDL_DestroyWindow(window_); SDL_DestroyWindow(window_);
SDL_Quit(); SDL_Quit();
@@ -280,6 +277,16 @@ void Director::initInput()
void Director::initJailAudio() void Director::initJailAudio()
{ {
JA_Init(48000, AUDIO_S16, 2); 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 // Arranca SDL y crea la ventana
@@ -353,8 +360,10 @@ bool Director::initSDL()
// Inicializa el color de renderizado // Inicializa el color de renderizado
SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF); SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF);
// Establece el tamaño del buffer de renderizado // Modifica el tamaño del renderizador
SDL_RenderSetLogicalSize(renderer_, options.game.width, options.game.height); 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 // Establece el modo de mezcla
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND);
@@ -396,6 +405,9 @@ bool Director::setFileList()
// Datos // Datos
Asset::get()->add(prefix + "/data/input/gamecontrollerdb.txt", AssetType::DATA); Asset::get()->add(prefix + "/data/input/gamecontrollerdb.txt", AssetType::DATA);
// Test
Asset::get()->add(prefix + "/data/test.gif", AssetType::DATA);
// Ficheros de sistema // Ficheros de sistema
Asset::get()->add(system_folder_ + "/config.txt", AssetType::DATA, false, true); Asset::get()->add(system_folder_ + "/config.txt", AssetType::DATA, false, true);
@@ -748,10 +760,6 @@ void Director::runLoadingScreen()
// Ejecuta la seccion de juego con el titulo y los menus // Ejecuta la seccion de juego con el titulo y los menus
void Director::runTitle() void Director::runTitle()
{ {
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
{
JA_PlayMusic(title_music_);
}
auto title = std::make_unique<Title>(); auto title = std::make_unique<Title>();
title->run(); title->run();
} }

View File

@@ -13,7 +13,6 @@ private:
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
// Variables // Variables
JA_Music_t *title_music_; // Musica del titulo
std::string executable_path_; // Path del ejecutable std::string executable_path_; // Path del ejecutable
std::string system_folder_; // Carpeta del sistema donde guardar datos std::string system_folder_; // Carpeta del sistema donde guardar datos

View File

@@ -1,47 +1,46 @@
#include "ending.h" #include "ending.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_error.h> // for SDL_GetError #include <SDL2/SDL_error.h> // for SDL_GetError
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <algorithm> // for min #include <algorithm> // for min
#include <iostream> // for basic_ostream, operator<<, cout, endl #include <iostream> // for basic_ostream, operator<<, cout, endl
#include "asset.h" // for Asset #include "asset.h" // for Asset
#include "defines.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_WIDTH #include "defines.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_WIDTH
#include "global_events.h" // for check #include "global_events.h" // for check
#include "global_inputs.h" // for check #include "global_inputs.h" // for check
#include "input.h" // for Input #include "input.h" // for Input
#include "jail_audio.h" // for JA_SetVolume, JA_PlayMusic, JA_StopM... #include "jail_audio.h" // for JA_SetVolume, JA_PlayMusic, JA_StopM...
#include "options.h" // for Options, options, OptionsVideo, Sect... #include "options.h" // for Options, options, OptionsVideo, Sect...
#include "resource.h" // for Resource #include "resource.h" // for Resource
#include "screen.h" // for Screen #include "screen.h" // for Screen
#include "sprite.h" // for Sprite #include "sprite.h" // for Sprite
#include "text.h" // for Text, TEXT_STROKE #include "text.h" // for Text, TEXT_STROKE
#include "texture.h" // for Texture #include "texture.h" // for Texture
#include "utils.h" // for Color, stringToColor, Palette #include "utils.h" // for Color, stringToColor, Palette
// Constructor // Constructor
Ending::Ending() Ending::Ending()
: screen(Screen::get()), : screen_(Screen::get()),
renderer(Screen::get()->getRenderer()), renderer_(Screen::get()->getRenderer()),
resource(Resource::get()), resource_(Resource::get()),
asset(Asset::get()), asset_(Asset::get()),
input(Input::get()) input_(Input::get())
{ {
// Reserva memoria para los punteros a objetos // Reserva memoria para los punteros a objetos
text = resource->getText("smb2"); text_ = resource_->getText("smb2");
music = resource->getMusic("ending1.ogg"); music = resource_->getMusic("ending1.ogg");
// Inicializa variables // Inicializa variables
counter = -1; counter_ = -1;
preCounter = 0; pre_counter_ = 0;
coverCounter = 0; cover_counter_ = 0;
options.section.section = Section::ENDING; options.section.section = Section::ENDING;
options.section.subsection = Subsection::NONE; options.section.subsection = Subsection::NONE;
ticks = 0; ticks_ = 0;
ticksSpeed = 15; current_scene_ = 0;
scene = 0;
// Inicializa los textos // Inicializa los textos
iniTexts(); iniTexts();
@@ -53,18 +52,18 @@ Ending::Ending()
iniScenes(); iniScenes();
// Cambia el color del borde // 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 // Crea la textura para cubrir el rexto
coverTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT + 8); cover_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT + 8);
if (coverTexture == nullptr) if (cover_texture_ == nullptr)
{ {
if (options.console) if (options.console)
{ {
std::cout << "Error: canvasTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl; 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 // Rellena la textura para la cortinilla
fillCoverTexture(); fillCoverTexture();
@@ -74,17 +73,17 @@ Ending::Ending()
Ending::~Ending() Ending::~Ending()
{ {
// Libera la memoria de los objetos // Libera la memoria de los objetos
SDL_DestroyTexture(coverTexture); SDL_DestroyTexture(cover_texture_);
} }
// Actualiza el objeto // Actualiza el objeto
void Ending::update() void Ending::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // 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 // Actualiza el contador de ticks
ticks = SDL_GetTicks(); ticks_ = SDL_GetTicks();
// Comprueba las entradas // Comprueba las entradas
checkInput(); checkInput();
@@ -101,7 +100,7 @@ void Ending::update()
// Actualiza el volumen de la musica // Actualiza el volumen de la musica
updateMusicVolume(); updateMusicVolume();
screen->update(); screen_->update();
} }
} }
@@ -109,22 +108,22 @@ void Ending::update()
void Ending::render() void Ending::render()
{ {
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
screen->start(); screen_->start();
// Limpia la pantalla // Limpia la pantalla
screen->clean(stringToColor(options.video.palette, "black")); screen_->clean(stringToColor(options.video.palette, "black"));
// Dibuja las imagenes de la escena // Dibuja las imagenes de la escena
spritePics[scene].sprite->render(); sprite_pics_[current_scene_].sprite->render();
spritePics[scene].coverSprite->render(); sprite_pics_[current_scene_].cover_sprite->render();
// Dibuja los textos de la escena // 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(); sprite_texts_[ti.index].sprite->render();
spriteTexts[ti.index].coverSprite->render(); sprite_texts_[ti.index].cover_sprite->render();
} }
} }
@@ -132,7 +131,7 @@ void Ending::render()
renderCoverTexture(); renderCoverTexture();
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen->render(); screen_->render();
} }
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
@@ -155,7 +154,7 @@ void Ending::checkInput()
void Ending::iniTexts() void Ending::iniTexts()
{ {
// Vector con los textos // Vector con los textos
std::vector<textAndPos_t> texts; std::vector<TextAndPosition> texts;
// Escena #0 // Escena #0
texts.push_back({"HE FINALLY MANAGED", 32}); texts.push_back({"HE FINALLY MANAGED", 32});
@@ -187,66 +186,66 @@ void Ending::iniTexts()
texts.push_back({"WERE BORN...", 158}); texts.push_back({"WERE BORN...", 158});
// Crea los sprites // Crea los sprites
spriteTexts.clear(); sprite_texts_.clear();
for (auto t : texts) for (auto t : texts)
{ {
endingTexture_t st; EndingTexture st;
const int width = text->lenght(t.caption, 1) + 2 + 2; const int width = text_->lenght(t.caption, 1) + 2 + 2;
const int height = text->getCharacterSize() + 2 + 2; const int height = text_->getCharacterSize() + 2 + 2;
Color c = stringToColor(options.video.palette, "black"); Color c = stringToColor(options.video.palette, "black");
// Crea la texture // Crea la texture
st.texture = std::make_shared<Texture>(renderer); st.texture = std::make_shared<Texture>(renderer_);
st.texture->createBlank(width, height); st.texture->createBlank(width, height);
st.texture->setAsRenderTarget(renderer); st.texture->setAsRenderTarget(renderer_);
st.texture->setBlendMode(SDL_BLENDMODE_BLEND); 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 // Crea el sprite
st.sprite = std::make_shared<Sprite>(st.texture, 0, 0, st.texture->getWidth(), st.texture->getHeight()); 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); st.sprite->setPosition((GAMECANVAS_WIDTH - st.texture->getWidth()) / 2, t.pos);
// Crea la coverTexture // Crea la coverTexture
st.coverTexture = std::make_shared<Texture>(renderer); st.cover_texture = std::make_shared<Texture>(renderer_);
st.coverTexture->createBlank(width, height + 8); st.cover_texture->createBlank(width, height + 8);
st.coverTexture->setAsRenderTarget(renderer); st.cover_texture->setAsRenderTarget(renderer_);
st.coverTexture->setBlendMode(SDL_BLENDMODE_BLEND); st.cover_texture->setBlendMode(SDL_BLENDMODE_BLEND);
// Rellena la coverTexture con color transparente // Rellena la coverTexture con color transparente
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
SDL_RenderClear(renderer); SDL_RenderClear(renderer_);
// Los primeros 8 pixels crea una malla // Los primeros 8 pixels crea una malla
c = stringToColor(options.video.palette, "black"); 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) for (int i = 0; i < width; i += 2)
{ {
SDL_RenderDrawPoint(renderer, i, 0); SDL_RenderDrawPoint(renderer_, i, 0);
SDL_RenderDrawPoint(renderer, i, 2); SDL_RenderDrawPoint(renderer_, i, 2);
SDL_RenderDrawPoint(renderer, i, 4); SDL_RenderDrawPoint(renderer_, i, 4);
SDL_RenderDrawPoint(renderer, i, 6); SDL_RenderDrawPoint(renderer_, i, 6);
SDL_RenderDrawPoint(renderer, i + 1, 5); SDL_RenderDrawPoint(renderer_, i + 1, 5);
SDL_RenderDrawPoint(renderer, i + 1, 7); SDL_RenderDrawPoint(renderer_, i + 1, 7);
} }
// El resto se rellena de color sólido // El resto se rellena de color sólido
SDL_Rect rect = {0, 8, width, height}; SDL_Rect rect = {0, 8, width, height};
c = stringToColor(options.video.palette, "black"); 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);
SDL_RenderFillRect(renderer, &rect); SDL_RenderFillRect(renderer_, &rect);
// Crea el sprite // Crea el sprite
st.coverSprite = std::make_shared<Sprite>(st.coverTexture, 0, 0, st.coverTexture->getWidth(), st.coverTexture->getHeight() - 8); st.cover_sprite = std::make_shared<Sprite>(st.cover_texture, 0, 0, st.cover_texture->getWidth(), st.cover_texture->getHeight() - 8);
st.coverSprite->setPosition((GAMECANVAS_WIDTH - st.coverTexture->getWidth()) / 2, t.pos); st.cover_sprite->setPosition((GAMECANVAS_WIDTH - st.cover_texture->getWidth()) / 2, t.pos);
st.coverSprite->setClip(0, 8, -1, -1); st.cover_sprite->setClip(0, 8, -1, -1);
// Inicializa variables // Inicializa variables
st.clipDesp = 8; st.clip_desp = 8;
st.clipHeight = height; st.clip_height = height;
spriteTexts.push_back(st); sprite_texts_.push_back(st);
} }
} }
@@ -254,7 +253,7 @@ void Ending::iniTexts()
void Ending::iniPics() void Ending::iniPics()
{ {
// Vector con las rutas y la posición // Vector con las rutas y la posición
std::vector<textAndPos_t> pics; std::vector<TextAndPosition> pics;
if (options.video.palette == Palette::ZXSPECTRUM) if (options.video.palette == Palette::ZXSPECTRUM)
{ {
@@ -274,14 +273,14 @@ void Ending::iniPics()
} }
// Crea los sprites // Crea los sprites
spritePics.clear(); sprite_pics_.clear();
for (auto p : pics) for (auto p : pics)
{ {
endingTexture_t sp; EndingTexture sp;
// Crea la texture // Crea la texture
sp.texture = resource->getTexture(p.caption); sp.texture = resource_->getTexture(p.caption);
const int width = sp.texture->getWidth(); const int width = sp.texture->getWidth();
const int height = sp.texture->getHeight(); const int height = sp.texture->getHeight();
@@ -290,45 +289,45 @@ void Ending::iniPics()
sp.sprite->setPosition((GAMECANVAS_WIDTH - width) / 2, p.pos); sp.sprite->setPosition((GAMECANVAS_WIDTH - width) / 2, p.pos);
// Crea la coverTexture // Crea la coverTexture
sp.coverTexture = std::make_shared<Texture>(renderer); sp.cover_texture = std::make_shared<Texture>(renderer_);
sp.coverTexture->createBlank(width, height + 8); sp.cover_texture->createBlank(width, height + 8);
sp.coverTexture->setAsRenderTarget(renderer); sp.cover_texture->setAsRenderTarget(renderer_);
sp.coverTexture->setBlendMode(SDL_BLENDMODE_BLEND); sp.cover_texture->setBlendMode(SDL_BLENDMODE_BLEND);
// Rellena la coverTexture con color transparente // Rellena la coverTexture con color transparente
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
SDL_RenderClear(renderer); SDL_RenderClear(renderer_);
// Los primeros 8 pixels crea una malla // Los primeros 8 pixels crea una malla
Color c = stringToColor(options.video.palette, "black"); 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) for (int i = 0; i < width; i += 2)
{ {
SDL_RenderDrawPoint(renderer, i, 0); SDL_RenderDrawPoint(renderer_, i, 0);
SDL_RenderDrawPoint(renderer, i, 2); SDL_RenderDrawPoint(renderer_, i, 2);
SDL_RenderDrawPoint(renderer, i, 4); SDL_RenderDrawPoint(renderer_, i, 4);
SDL_RenderDrawPoint(renderer, i, 6); SDL_RenderDrawPoint(renderer_, i, 6);
SDL_RenderDrawPoint(renderer, i + 1, 5); SDL_RenderDrawPoint(renderer_, i + 1, 5);
SDL_RenderDrawPoint(renderer, i + 1, 7); SDL_RenderDrawPoint(renderer_, i + 1, 7);
} }
// El resto se rellena de color sólido // El resto se rellena de color sólido
SDL_Rect rect = {0, 8, width, height}; SDL_Rect rect = {0, 8, width, height};
c = stringToColor(options.video.palette, "black"); 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);
SDL_RenderFillRect(renderer, &rect); SDL_RenderFillRect(renderer_, &rect);
// Crea el sprite // Crea el sprite
sp.coverSprite = std::make_shared<Sprite>(sp.coverTexture, 0, 0, sp.coverTexture->getWidth(), sp.coverTexture->getHeight() - 8); sp.cover_sprite = std::make_shared<Sprite>(sp.cover_texture, 0, 0, sp.cover_texture->getWidth(), sp.cover_texture->getHeight() - 8);
sp.coverSprite->setPosition((GAMECANVAS_WIDTH - sp.coverTexture->getWidth()) / 2, p.pos); sp.cover_sprite->setPosition((GAMECANVAS_WIDTH - sp.cover_texture->getWidth()) / 2, p.pos);
sp.coverSprite->setClip(0, 8, -1, -1); sp.cover_sprite->setClip(0, 8, -1, -1);
// Inicializa variables // Inicializa variables
sp.clipDesp = 8; sp.clip_desp = 8;
sp.clipHeight = height; sp.clip_height = height;
spritePics.push_back(sp); sprite_pics_.push_back(sp);
} }
} }
@@ -340,79 +339,79 @@ void Ending::iniScenes()
const int lapse = 80; const int lapse = 80;
// Crea el contenedor // Crea el contenedor
scene_t sc; SceneData sc;
// Inicializa el vector // Inicializa el vector
scenes.clear(); scenes_.clear();
// Crea la escena #0 // Crea la escena #0
sc.counterEnd = 1000; sc.counter_end = 1000;
sc.pictureIndex = 0; sc.picture_index = 0;
sc.textIndex.clear(); sc.text_index.clear();
trigger = 85 * 2; trigger = 85 * 2;
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({0, trigger}); sc.text_index.push_back({0, trigger});
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({1, trigger}); sc.text_index.push_back({1, trigger});
trigger += lapse * 3; trigger += lapse * 3;
sc.textIndex.push_back({2, trigger}); sc.text_index.push_back({2, trigger});
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({3, trigger}); sc.text_index.push_back({3, trigger});
scenes.push_back(sc); scenes_.push_back(sc);
// Crea la escena #1 // Crea la escena #1
sc.counterEnd = 1400; sc.counter_end = 1400;
sc.pictureIndex = 1; sc.picture_index = 1;
sc.textIndex.clear(); sc.text_index.clear();
trigger = 140 * 2; trigger = 140 * 2;
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({4, trigger}); sc.text_index.push_back({4, trigger});
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({5, trigger}); sc.text_index.push_back({5, trigger});
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({6, trigger}); sc.text_index.push_back({6, trigger});
trigger += lapse * 3; trigger += lapse * 3;
sc.textIndex.push_back({7, trigger}); sc.text_index.push_back({7, trigger});
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({8, trigger}); sc.text_index.push_back({8, trigger});
trigger += lapse * 3; trigger += lapse * 3;
sc.textIndex.push_back({9, trigger}); sc.text_index.push_back({9, trigger});
scenes.push_back(sc); scenes_.push_back(sc);
// Crea la escena #2 // Crea la escena #2
sc.counterEnd = 1000; sc.counter_end = 1000;
sc.pictureIndex = 2; sc.picture_index = 2;
sc.textIndex.clear(); sc.text_index.clear();
trigger = 148 / 2; trigger = 148 / 2;
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({10, trigger}); sc.text_index.push_back({10, trigger});
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({11, trigger}); sc.text_index.push_back({11, trigger});
scenes.push_back(sc); scenes_.push_back(sc);
// Crea la escena #3 // Crea la escena #3
sc.counterEnd = 800; sc.counter_end = 800;
sc.pictureIndex = 3; sc.picture_index = 3;
sc.textIndex.clear(); sc.text_index.clear();
trigger = 87 / 2; trigger = 87 / 2;
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({12, trigger}); sc.text_index.push_back({12, trigger});
trigger += lapse / 2; trigger += lapse / 2;
sc.textIndex.push_back({13, trigger}); sc.text_index.push_back({13, trigger});
scenes.push_back(sc); scenes_.push_back(sc);
// Crea la escena #4 // Crea la escena #4
sc.counterEnd = 1000; sc.counter_end = 1000;
sc.pictureIndex = 4; sc.picture_index = 4;
sc.textIndex.clear(); sc.text_index.clear();
trigger = 91 * 2; trigger = 91 * 2;
trigger += lapse; trigger += lapse;
sc.textIndex.push_back({14, trigger}); sc.text_index.push_back({14, trigger});
trigger += lapse * 2; trigger += lapse * 2;
sc.textIndex.push_back({15, trigger}); sc.text_index.push_back({15, trigger});
trigger += lapse * 3; trigger += lapse * 3;
sc.textIndex.push_back({16, trigger}); sc.text_index.push_back({16, trigger});
scenes.push_back(sc); scenes_.push_back(sc);
} }
// Bucle principal // Bucle principal
@@ -435,80 +434,80 @@ void Ending::run()
void Ending::updateCounters() void Ending::updateCounters()
{ {
// Incrementa el contador // Incrementa el contador
if (preCounter < 200) if (pre_counter_ < 200)
{ {
preCounter++; pre_counter_++;
} }
else 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 // Actualiza las cortinillas de los elementos
void Ending::updateSpriteCovers() void Ending::updateSpriteCovers()
{ // Actualiza la cortinilla de los textos { // 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; sprite_texts_[ti.index].clip_height -= 2;
spriteTexts[ti.index].coverSprite->setY(spriteTexts[ti.index].coverSprite->getY() + 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 // 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; sprite_pics_[current_scene_].clip_height -= 2;
if (spritePics[scene].clipHeight < 0) 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 // Comprueba si se ha de cambiar de escena
void Ending::checkChangeScene() void Ending::checkChangeScene()
{ {
if (counter > scenes[scene].counterEnd) if (counter_ > scenes_[current_scene_].counter_end)
{ {
scene++; current_scene_++;
counter = 0; counter_ = 0;
coverCounter = 0; cover_counter_ = 0;
if (scene == 5) if (current_scene_ == 5)
{ {
// Termina el bucle // Termina el bucle
options.section.section = Section::ENDING2; options.section.section = Section::ENDING2;
// Mantiene los valores anteriores // Mantiene los valores anteriores
scene = 4; current_scene_ = 4;
coverCounter = 100; cover_counter_ = 100;
} }
} }
} }
@@ -517,49 +516,49 @@ void Ending::checkChangeScene()
void Ending::fillCoverTexture() void Ending::fillCoverTexture()
{ {
// Rellena la textura que cubre el texto con color transparente // Rellena la textura que cubre el texto con color transparente
SDL_SetRenderTarget(renderer, coverTexture); SDL_SetRenderTarget(renderer_, cover_texture_);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
SDL_RenderClear(renderer); SDL_RenderClear(renderer_);
// Los primeros 8 pixels crea una malla // Los primeros 8 pixels crea una malla
const Color color = stringToColor(options.video.palette, "black"); 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) for (int i = 0; i < 256; i += 2)
{ {
SDL_RenderDrawPoint(renderer, i + 0, GAMECANVAS_HEIGHT + 0); SDL_RenderDrawPoint(renderer_, i + 0, GAMECANVAS_HEIGHT + 0);
SDL_RenderDrawPoint(renderer, i + 1, GAMECANVAS_HEIGHT + 1); SDL_RenderDrawPoint(renderer_, i + 1, GAMECANVAS_HEIGHT + 1);
SDL_RenderDrawPoint(renderer, i + 0, GAMECANVAS_HEIGHT + 2); SDL_RenderDrawPoint(renderer_, i + 0, GAMECANVAS_HEIGHT + 2);
SDL_RenderDrawPoint(renderer, i + 1, GAMECANVAS_HEIGHT + 3); SDL_RenderDrawPoint(renderer_, i + 1, GAMECANVAS_HEIGHT + 3);
SDL_RenderDrawPoint(renderer, i, GAMECANVAS_HEIGHT + 4); SDL_RenderDrawPoint(renderer_, i, GAMECANVAS_HEIGHT + 4);
SDL_RenderDrawPoint(renderer, i, GAMECANVAS_HEIGHT + 6); SDL_RenderDrawPoint(renderer_, i, GAMECANVAS_HEIGHT + 6);
} }
// El resto se rellena de color sólido // El resto se rellena de color sólido
SDL_Rect rect = {0, 0, 256, GAMECANVAS_HEIGHT}; 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 // Dibuja la cortinilla de cambio de escena
void Ending::renderCoverTexture() void Ending::renderCoverTexture()
{ {
if (coverCounter > 0) if (cover_counter_ > 0)
{ // Dibuja la textura que cubre el texto { // Dibuja la textura que cubre el texto
const int offset = std::min(coverCounter, 100); const int offset = std::min(cover_counter_, 100);
SDL_Rect srcRect = {0, 200 - (coverCounter * 2), 256, offset * 2}; SDL_Rect srcRect = {0, 200 - (cover_counter_ * 2), 256, offset * 2};
SDL_Rect dstRect = {0, 0, 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 // Actualiza el volumen de la musica
void Ending::updateMusicVolume() 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; const int volume = 128 * step;
JA_SetVolume(volume); JA_SetVolume(volume);
} }

View File

@@ -1,34 +1,34 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture #include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr #include <memory> // for shared_ptr
#include <string> // for string #include <string> // for string
#include <vector> // for vector #include <vector> // for vector
class Asset; // lines 9-9 class Asset; // lines 9-9
class Input; // lines 10-10 class Input; // lines 10-10
class Resource; // lines 11-11 class Resource; // lines 11-11
class Screen; // lines 12-12 class Screen; // lines 12-12
class Sprite; // lines 13-13 class Sprite; // lines 13-13
class Text; // lines 14-14 class Text; // lines 14-14
class Texture; // lines 15-15 class Texture; // lines 15-15
struct JA_Music_t; // lines 16-16 struct JA_Music_t; // lines 16-16
class Ending class Ending
{ {
private: private:
// Estructuras // 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<Texture> texture; // Textura a mostrar
std::shared_ptr<Sprite> sprite; // Sprite para mostrar la textura 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<Texture> cover_texture; // Textura que cubre a la otra textura
std::shared_ptr<Sprite> coverSprite; // Sprite para mostrar la 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 clipDesp; // Desplazamiento del spriteClip de la textura de cobertura int clip_desp; // Desplazamiento del spriteClip de la textura de cobertura
int clipHeight; // Altura 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 std::string caption; // Texto
int pos; // Posición int pos; // Posición
@@ -40,32 +40,31 @@ private:
int trigger; 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 std::vector<asdhk> text_index; // Indices del vector de textos a mostrar y su disparador
int pictureIndex; // Indice del vector de imagenes a mostrar int picture_index; // Indice del vector de imagenes a mostrar
int counterEnd; // Valor del contador en el que finaliza la escena int counter_end; // Valor del contador en el que finaliza la escena
}; };
// Objetos y punteros // Objetos y punteros
Screen *screen; // Objeto encargado de dibujar en pantalla Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
Resource *resource; // Objeto con los recursos Resource *resource_; // Objeto con los recursos
Asset *asset; // Objeto con los ficheros de recursos Asset *asset_; // Objeto con los ficheros de recursos
Input *input; // Objeto pata gestionar la entrada Input *input_; // Objeto pata gestionar la entrada
std::shared_ptr<Text> text; // Objeto para escribir texto en pantalla std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
SDL_Texture *coverTexture; // Textura para cubrir el texto SDL_Texture *cover_texture_; // Textura para cubrir el texto
// Variables // Variables
int counter; // Contador int counter_; // Contador
int preCounter; // Contador previo int pre_counter_; // Contador previo
int coverCounter; // Contador para la cortinilla int cover_counter_; // Contador para la cortinilla
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa 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> sprite_texts_; // Vector con los sprites de texto con su cortinilla
std::vector<endingTexture_t> spriteTexts; // Vector con los sprites de texto con su cortinilla std::vector<EndingTexture> sprite_pics_; // Vector con los sprites de texto con su cortinilla
std::vector<endingTexture_t> spritePics; // Vector con los sprites de texto con su cortinilla int current_scene_; // Escena actual
int scene; // Escena actual std::vector<SceneData> scenes_; // Vector con los textos e imagenes de cada escena
std::vector<scene_t> scenes; // Vector con los textos e imagenes de cada escena
JA_Music_t *music; // Musica que suena durante el final JA_Music_t *music; // Musica que suena durante el final
// Actualiza el objeto // Actualiza el objeto

View File

@@ -1,60 +1,57 @@
#include "ending2.h" #include "ending2.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <algorithm> // for max, min, replace #include <algorithm> // for max, min, replace
#include "animated_sprite.h" // for AnimatedSprite #include "animated_sprite.h" // for AnimatedSprite
#include "asset.h" // for Asset #include "asset.h" // for Asset
#include "defines.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_CENTER_X #include "defines.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_CENTER_X
#include "global_events.h" // for check #include "global_events.h" // for check
#include "global_inputs.h" // for check #include "global_inputs.h" // for check
#include "input.h" // for Input #include "input.h" // for Input
#include "jail_audio.h" // for JA_SetVolume, JA_PlayMusic, JA_StopM... #include "jail_audio.h" // for JA_SetVolume, JA_PlayMusic, JA_StopM...
#include "moving_sprite.h" // for MovingSprite #include "moving_sprite.h" // for MovingSprite
#include "options.h" // for Options, options, OptionsVideo, Sect... #include "options.h" // for Options, options, OptionsVideo, Sect...
#include "resource.h" // for Resource #include "resource.h" // for Resource
#include "screen.h" // for Screen #include "screen.h" // for Screen
#include "text.h" // for Text #include "text.h" // for Text
#include "texture.h" // for Texture #include "texture.h" // for Texture
#include "utils.h" // for Color, stringToColor #include "utils.h" // for Color, stringToColor
// Constructor // Constructor
Ending2::Ending2() Ending2::Ending2()
: screen(Screen::get()), : screen_(Screen::get()),
renderer(Screen::get()->getRenderer()), renderer_(Screen::get()->getRenderer()),
resource(Resource::get()), resource_(Resource::get()),
asset(Asset::get()), asset_(Asset::get()),
input(Input::get()) input_(Input::get())
{ {
// Reserva memoria para los punteros a objetos // Reserva memoria para los punteros a objetos
text = resource->getText("smb2"); text_ = resource_->getText("smb2");
music = resource->getMusic("ending2.ogg"); music_ = resource_->getMusic("ending2.ogg");
// Inicializa variables // Inicializa variables
counterEnabled = false; counter_enabled_ = false;
preCounter = 0; pre_counter_ = 0;
postCounter = 0; post_counter_ = 0;
postCounterEnabled = false; post_counter_enabled_ = false;
options.section.section = Section::ENDING2; options.section.section = Section::ENDING2;
options.section.subsection = Subsection::NONE; options.section.subsection = Subsection::NONE;
ticks = 0; ticks_ = 0;
ticksSpeed = 15; dist_sprite_text_ = 8;
distSpriteText = 8; dist_sprite_sprite_ = 0;
distSpriteSprite = 0; sprite_desp_speed_ = -0.2f;
despSpeed = -0.2f;
firstCol = GAMECANVAS_FIRST_QUARTER_X + (GAMECANVAS_WIDTH / 16);
secondCol = GAMECANVAS_THIRD_QUARTER_X - (GAMECANVAS_WIDTH / 16);
// Inicializa el vector de colores // Inicializa el vector de colores
const std::vector<std::string> color_list = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"}; const std::vector<std::string> color_list = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
for (auto color : color_list) 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 // Cambia el color del borde
screen->setBorderColor(stringToColor(options.video.palette, "black")); screen_->setBorderColor(stringToColor(options.video.palette, "black"));
// Inicializa la lista de sprites // Inicializa la lista de sprites
iniSpriteList(); iniSpriteList();
@@ -76,10 +73,10 @@ Ending2::Ending2()
void Ending2::update() void Ending2::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // 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 // Actualiza el contador de ticks
ticks = SDL_GetTicks(); ticks_ = SDL_GetTicks();
// Comprueba las entradas // Comprueba las entradas
checkInput(); checkInput();
@@ -87,7 +84,7 @@ void Ending2::update()
// Actualiza los contadores // Actualiza los contadores
updateCounters(); updateCounters();
if (counterEnabled) if (counter_enabled_)
{ {
// Actualiza los sprites // Actualiza los sprites
updateSprites(); updateSprites();
@@ -105,7 +102,7 @@ void Ending2::update()
// Actualiza el volumen de la musica // Actualiza el volumen de la musica
updateMusicVolume(); updateMusicVolume();
screen->update(); screen_->update();
} }
} }
@@ -113,10 +110,10 @@ void Ending2::update()
void Ending2::render() void Ending2::render()
{ {
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
screen->start(); screen_->start();
// Limpia la pantalla // Limpia la pantalla
screen->clean(stringToColor(options.video.palette, "black")); screen_->clean(stringToColor(options.video.palette, "black"));
// Dibuja los sprites // Dibuja los sprites
renderSprites(); renderSprites();
@@ -127,7 +124,7 @@ void Ending2::render()
// Dibuja los sprites con el texto del final // Dibuja los sprites con el texto del final
renderTexts(); renderTexts();
const std::string txt = std::to_string(postCounter); const std::string txt = std::to_string(post_counter_);
// text->write(0, 192 - 8, txt); // text->write(0, 192 - 8, txt);
// Dibuja la cuadricula // Dibuja la cuadricula
@@ -147,24 +144,24 @@ void Ending2::render()
{ {
// Dibuja una trama arriba y abajo // 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) for (int i = 0; i < 256; i += 2)
{ {
SDL_RenderDrawPoint(renderer, i + 0, 0); SDL_RenderDrawPoint(renderer_, i + 0, 0);
SDL_RenderDrawPoint(renderer, i + 1, 1); SDL_RenderDrawPoint(renderer_, i + 1, 1);
SDL_RenderDrawPoint(renderer, i + 0, 2); SDL_RenderDrawPoint(renderer_, i + 0, 2);
SDL_RenderDrawPoint(renderer, i + 1, 3); SDL_RenderDrawPoint(renderer_, i + 1, 3);
SDL_RenderDrawPoint(renderer, i, 4); SDL_RenderDrawPoint(renderer_, i, 4);
SDL_RenderDrawPoint(renderer, i, 6); SDL_RenderDrawPoint(renderer_, i, 6);
SDL_RenderDrawPoint(renderer, i + 0, 191); SDL_RenderDrawPoint(renderer_, i + 0, 191);
SDL_RenderDrawPoint(renderer, i + 1, 190); SDL_RenderDrawPoint(renderer_, i + 1, 190);
SDL_RenderDrawPoint(renderer, i + 0, 189); SDL_RenderDrawPoint(renderer_, i + 0, 189);
SDL_RenderDrawPoint(renderer, i + 1, 188); SDL_RenderDrawPoint(renderer_, i + 1, 188);
SDL_RenderDrawPoint(renderer, i, 187); SDL_RenderDrawPoint(renderer_, i, 187);
SDL_RenderDrawPoint(renderer, i, 185); SDL_RenderDrawPoint(renderer_, i, 185);
} }
// SDL_RenderDrawLine(renderer, 0, 1, 255, 1); // SDL_RenderDrawLine(renderer, 0, 1, 255, 1);
// SDL_RenderDrawLine(renderer, 0, 3, 255, 3); // SDL_RenderDrawLine(renderer, 0, 3, 255, 3);
@@ -173,7 +170,7 @@ void Ending2::render()
} }
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen->render(); screen_->render();
} }
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
@@ -195,7 +192,7 @@ void Ending2::checkInput()
// Bucle principal // Bucle principal
void Ending2::run() void Ending2::run()
{ {
JA_PlayMusic(music); JA_PlayMusic(music_);
while (options.section.section == Section::ENDING2) while (options.section.section == Section::ENDING2)
{ {
@@ -212,21 +209,21 @@ void Ending2::run()
void Ending2::updateCounters() void Ending2::updateCounters()
{ {
// Incrementa el contador // Incrementa el contador
if (preCounter < 200) if (pre_counter_ < 200)
{ {
preCounter++; pre_counter_++;
} }
else 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.section = Section::LOGO;
options.section.subsection = Subsection::LOGO_TO_INTRO; options.section.subsection = Subsection::LOGO_TO_INTRO;
@@ -237,100 +234,100 @@ void Ending2::updateCounters()
void Ending2::iniSpriteList() void Ending2::iniSpriteList()
{ {
// Reinicia el vector // Reinicia el vector
spriteList.clear(); sprite_list_.clear();
// Añade los valores // Añade los valores
spriteList.push_back("bin"); sprite_list_.push_back("bin");
spriteList.push_back("floppy"); sprite_list_.push_back("floppy");
spriteList.push_back("bird"); sprite_list_.push_back("bird");
spriteList.push_back("chip"); sprite_list_.push_back("chip");
spriteList.push_back("jeannine"); sprite_list_.push_back("jeannine");
spriteList.push_back("spark"); sprite_list_.push_back("spark");
spriteList.push_back("code"); sprite_list_.push_back("code");
spriteList.push_back("paco"); sprite_list_.push_back("paco");
spriteList.push_back("elsa"); sprite_list_.push_back("elsa");
spriteList.push_back("z80"); sprite_list_.push_back("z80");
spriteList.push_back("bell"); sprite_list_.push_back("bell");
spriteList.push_back("dong"); sprite_list_.push_back("dong");
spriteList.push_back("amstrad_cs"); sprite_list_.push_back("amstrad_cs");
spriteList.push_back("breakout"); sprite_list_.push_back("breakout");
spriteList.push_back("flying_arounder"); sprite_list_.push_back("flying_arounder");
spriteList.push_back("stopped_arounder"); sprite_list_.push_back("stopped_arounder");
spriteList.push_back("walking_arounder"); sprite_list_.push_back("walking_arounder");
spriteList.push_back("arounders_door"); sprite_list_.push_back("arounders_door");
spriteList.push_back("arounders_machine"); sprite_list_.push_back("arounders_machine");
spriteList.push_back("abad"); sprite_list_.push_back("abad");
spriteList.push_back("abad_bell"); sprite_list_.push_back("abad_bell");
spriteList.push_back("lord_abad"); sprite_list_.push_back("lord_abad");
spriteList.push_back("bat"); sprite_list_.push_back("bat");
spriteList.push_back("batman_bell"); sprite_list_.push_back("batman_bell");
spriteList.push_back("batman_fire"); sprite_list_.push_back("batman_fire");
spriteList.push_back("batman"); sprite_list_.push_back("batman");
spriteList.push_back("demon"); sprite_list_.push_back("demon");
spriteList.push_back("heavy"); sprite_list_.push_back("heavy");
spriteList.push_back("dimallas"); sprite_list_.push_back("dimallas");
spriteList.push_back("guitar"); sprite_list_.push_back("guitar");
spriteList.push_back("jailbattle_alien"); sprite_list_.push_back("jailbattle_alien");
spriteList.push_back("jailbattle_human"); sprite_list_.push_back("jailbattle_human");
spriteList.push_back("jailer_#1"); sprite_list_.push_back("jailer_#1");
spriteList.push_back("jailer_#2"); sprite_list_.push_back("jailer_#2");
spriteList.push_back("jailer_#3"); sprite_list_.push_back("jailer_#3");
spriteList.push_back("bry"); sprite_list_.push_back("bry");
spriteList.push_back("upv_student"); sprite_list_.push_back("upv_student");
spriteList.push_back("lamp"); sprite_list_.push_back("lamp");
spriteList.push_back("robot"); sprite_list_.push_back("robot");
spriteList.push_back("congo"); sprite_list_.push_back("congo");
spriteList.push_back("crosshair"); sprite_list_.push_back("crosshair");
spriteList.push_back("tree_thing"); sprite_list_.push_back("tree_thing");
spriteList.push_back("matatunos"); sprite_list_.push_back("matatunos");
spriteList.push_back("tuno"); sprite_list_.push_back("tuno");
spriteList.push_back("mummy"); sprite_list_.push_back("mummy");
spriteList.push_back("sam"); sprite_list_.push_back("sam");
spriteList.push_back("qvoid"); sprite_list_.push_back("qvoid");
spriteList.push_back("sigmasua"); sprite_list_.push_back("sigmasua");
spriteList.push_back("tv_panel"); sprite_list_.push_back("tv_panel");
spriteList.push_back("tv"); sprite_list_.push_back("tv");
spriteList.push_back("spider"); sprite_list_.push_back("spider");
spriteList.push_back("shock"); sprite_list_.push_back("shock");
spriteList.push_back("wave"); sprite_list_.push_back("wave");
spriteList.push_back("player"); sprite_list_.push_back("player");
} }
// Carga todos los sprites desde una lista // Carga todos los sprites desde una lista
void Ending2::loadSprites() void Ending2::loadSprites()
{ {
// Inicializa variables // Inicializa variables
maxSpriteWidth = 0; sprite_max_width_ = 0;
maxSpriteHeight = 0; sprite_max_height_ = 0;
// Carga los sprites // 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"))); sprites_.emplace_back(std::make_shared<AnimatedSprite>(resource_->getTexture(sl + ".png"), resource_->getAnimations(sl + ".ani")));
maxSpriteWidth = std::max(sprites.back()->getWidth(), maxSpriteWidth); sprite_max_width_ = std::max(sprites_.back()->getWidth(), sprite_max_width_);
maxSpriteHeight = std::max(sprites.back()->getHeight(), maxSpriteHeight); sprite_max_height_ = std::max(sprites_.back()->getHeight(), sprite_max_height_);
} }
} }
// Actualiza los sprites // Actualiza los sprites
void Ending2::updateSprites() void Ending2::updateSprites()
{ {
for (auto sprite : sprites) for (auto sprite : sprites_)
{ {
sprite->update(); sprite->update();
} }
@@ -339,7 +336,7 @@ void Ending2::updateSprites()
// Actualiza los sprites de texto // Actualiza los sprites de texto
void Ending2::updateTextSprites() void Ending2::updateTextSprites()
{ {
for (auto sprite : spriteTexts) for (auto sprite : sprite_texts_)
{ {
sprite->update(); sprite->update();
} }
@@ -348,16 +345,16 @@ void Ending2::updateTextSprites()
// Actualiza los sprites de texto del final // Actualiza los sprites de texto del final
void Ending2::updateTexts() 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(); sprite->update();
} }
} }
else else
{ {
postCounterEnabled = true; post_counter_enabled_ = true;
} }
} }
@@ -365,7 +362,7 @@ void Ending2::updateTexts()
void Ending2::renderSprites() void Ending2::renderSprites()
{ {
const Color color = stringToColor(options.video.palette, "red"); 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 a = sprite->getRect().y + sprite->getRect().h > 0;
const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT; const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT;
@@ -378,15 +375,15 @@ void Ending2::renderSprites()
// Pinta el ultimo elemento de otro color // Pinta el ultimo elemento de otro color
const Color c = stringToColor(options.video.palette, "white"); const Color c = stringToColor(options.video.palette, "white");
sprites.back()->getTexture()->setColor(c.r, c.g, c.b); sprites_.back()->getTexture()->setColor(c.r, c.g, c.b);
sprites.back()->render(); sprites_.back()->render();
} }
// Dibuja los sprites con el texto // Dibuja los sprites con el texto
void Ending2::renderSpriteTexts() void Ending2::renderSpriteTexts()
{ {
const Color color = stringToColor(options.video.palette, "white"); 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 a = sprite->getRect().y + sprite->getRect().h > 0;
const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT; const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT;
@@ -401,7 +398,7 @@ void Ending2::renderSpriteTexts()
// Dibuja los sprites con el texto del final // Dibuja los sprites con el texto del final
void Ending2::renderTexts() void Ending2::renderTexts()
{ {
for (auto sprite : texts) for (auto sprite : texts_)
{ {
const bool a = sprite->getRect().y + sprite->getRect().h > 0; const bool a = sprite->getRect().y + sprite->getRect().h > 0;
const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT; const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT;
@@ -415,58 +412,58 @@ void Ending2::renderTexts()
// Coloca los sprites en su sito // Coloca los sprites en su sito
void Ending2::placeSprites() 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 x = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_;
const int y = (i / 1) * (maxSpriteHeight + distSpriteText + text->getCharacterSize() + distSpriteSprite) + GAMECANVAS_HEIGHT + 40; 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 w = sprites_[i]->getWidth();
const int h = sprites[i]->getHeight(); const int h = sprites_[i]->getHeight();
const int dx = -(w / 2); 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]->setPosition({x + dx, y + dy, w, h});
sprites[i]->setVelY(despSpeed); sprites_[i]->setVelY(sprite_desp_speed_);
} }
// Recoloca el último sprite, que es el del jugador // 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 x = GAMECANVAS_CENTER_X - (w / 2);
const int y = sprites.back()->getPosY() + maxSpriteHeight * 2; const int y = sprites_.back()->getPosY() + sprite_max_height_ * 2;
sprites.back()->setPosX(x); sprites_.back()->setPosX(x);
sprites.back()->setPosY(y); sprites_.back()->setPosY(y);
sprites.back()->setCurrentAnimation("walk"); sprites_.back()->setCurrentAnimation("walk");
} }
// Crea los sprites con las texturas con los textos // Crea los sprites con las texturas con los textos
void Ending2::createSpriteTexts() void Ending2::createSpriteTexts()
{ {
// Crea los sprites de texto a partir de la lista // 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 // Calcula constantes
std::string txt = spriteList[i]; std::string txt = sprite_list_[i];
std::replace(txt.begin(), txt.end(), '_', ' '); std::replace(txt.begin(), txt.end(), '_', ' ');
txt = txt == "player" ? "JAILDOCTOR" : txt; // Reemplaza el texto txt = txt == "player" ? "JAILDOCTOR" : txt; // Reemplaza el texto
const int w = text->lenght(txt, 1); const int w = text_->lenght(txt, 1);
const int h = text->getCharacterSize(); const int h = text_->getCharacterSize();
const int x = i % 2 == 0 ? firstCol : secondCol; const int x = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_;
const int dx = -(w / 2); 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 // 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 // Crea la textura
auto texture = std::make_shared<Texture>(renderer); auto texture = std::make_shared<Texture>(renderer_);
texture->createBlank(w, h); texture->createBlank(w, h);
texture->setAsRenderTarget(renderer); texture->setAsRenderTarget(renderer_);
texture->setBlendMode(SDL_BLENDMODE_BLEND); texture->setBlendMode(SDL_BLENDMODE_BLEND);
text->write(0, 0, txt); text_->write(0, 0, txt);
// Crea el sprite // Crea el sprite
SDL_Rect pos = {X, y, w, h}; SDL_Rect pos = {X, y, w, h};
spriteTexts.emplace_back(std::make_shared<MovingSprite>(texture, pos)); sprite_texts_.emplace_back(std::make_shared<MovingSprite>(texture, pos));
spriteTexts.back()->setVelY(despSpeed); sprite_texts_.back()->setVelY(sprite_desp_speed_);
} }
} }
@@ -481,28 +478,28 @@ void Ending2::createTexts()
for (int i = 0; i < (int)list.size(); ++i) for (int i = 0; i < (int)list.size(); ++i)
{ {
// Calcula constantes // Calcula constantes
const int w = text->lenght(list[i], 1); const int w = text_->lenght(list[i], 1);
const int h = text->getCharacterSize(); const int h = text_->getCharacterSize();
const int x = GAMECANVAS_CENTER_X; const int x = GAMECANVAS_CENTER_X;
const int dx = -(w / 2); 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 // Crea la textura
auto texture = std::make_shared<Texture>(renderer); auto texture = std::make_shared<Texture>(renderer_);
texture->createBlank(w, h); texture->createBlank(w, h);
texture->setAsRenderTarget(renderer); texture->setAsRenderTarget(renderer_);
texture->setBlendMode(SDL_BLENDMODE_BLEND); texture->setBlendMode(SDL_BLENDMODE_BLEND);
text->write(0, 0, list[i]); text_->write(0, 0, list[i]);
// Crea el sprite // Crea el sprite
SDL_Rect pos = {x + dx, y, w, h}; SDL_Rect pos = {x + dx, y, w, h};
texts.emplace_back(std::make_shared<MovingSprite>(texture, pos)); texts_.emplace_back(std::make_shared<MovingSprite>(texture, pos));
texts.back()->setVelY(despSpeed); texts_.back()->setVelY(sprite_desp_speed_);
} }
// Crea los últimos textos // Crea los últimos textos
// El primer texto va a continuación del ultimo spriteText // 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.clear();
list.push_back("THANK YOU"); list.push_back("THANK YOU");
list.push_back("FOR PLAYING!"); list.push_back("FOR PLAYING!");
@@ -511,23 +508,23 @@ void Ending2::createTexts()
for (int i = 0; i < (int)list.size(); ++i) for (int i = 0; i < (int)list.size(); ++i)
{ {
// Calcula constantes // Calcula constantes
const int w = text->lenght(list[i], 1); const int w = text_->lenght(list[i], 1);
const int h = text->getCharacterSize(); const int h = text_->getCharacterSize();
const int x = GAMECANVAS_CENTER_X; const int x = GAMECANVAS_CENTER_X;
const int dx = -(w / 2); const int dx = -(w / 2);
const int y = start + (text->getCharacterSize() * (i * 2)); const int y = start + (text_->getCharacterSize() * (i * 2));
// Crea la textura // Crea la textura
auto texture = std::make_shared<Texture>(renderer); auto texture = std::make_shared<Texture>(renderer_);
texture->createBlank(w, h); texture->createBlank(w, h);
texture->setAsRenderTarget(renderer); texture->setAsRenderTarget(renderer_);
texture->setBlendMode(SDL_BLENDMODE_BLEND); texture->setBlendMode(SDL_BLENDMODE_BLEND);
text->write(0, 0, list[i]); text_->write(0, 0, list[i]);
// Crea el sprite // Crea el sprite
SDL_Rect pos = {x + dx, y, w, h}; SDL_Rect pos = {x + dx, y, w, h};
texts.emplace_back(std::make_shared<MovingSprite>(texture, pos)); texts_.emplace_back(std::make_shared<MovingSprite>(texture, pos));
texts.back()->setVelY(despSpeed); texts_.back()->setVelY(sprite_desp_speed_);
} }
} }
@@ -535,21 +532,21 @@ void Ending2::createTexts()
void Ending2::updateFinalFade() 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 // 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 float step = std::min(std::max(post_counter_, 500) - 500, 40) / 40.0f;
const int index = (colors.size() - 1) * step; 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 // Actualiza el volumen de la musica
void Ending2::updateMusicVolume() 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; const int volume = 128 * step;
JA_SetVolume(volume); JA_SetVolume(volume);
} }

View File

@@ -1,51 +1,53 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr #include <memory> // for shared_ptr
#include <string> // for string #include <string> // for string
#include <vector> // for vector #include <vector> // for vector
#include "utils.h" // for Color #include "utils.h" // for Color
class AnimatedSprite; // lines 9-9 #include "defines.h" // for GAMECANVAS_FIRST_QUARTER_X, GAMECANVAS_THIRD_QUARTER_X, GAMECANVAS_WIDTH
class Asset; // lines 10-10 class AnimatedSprite; // lines 9-9
class Input; // lines 11-11 class Asset; // lines 10-10
class MovingSprite; // lines 12-12 class Input; // lines 11-11
class Resource; // lines 13-13 class MovingSprite; // lines 12-12
class Screen; // lines 14-14 class Resource; // lines 13-13
class Text; // lines 15-15 class Screen; // lines 14-14
struct JA_Music_t; // lines 16-16 class Text; // lines 15-15
struct JA_Music_t; // lines 16-16
class Ending2 class Ending2
{ {
private: 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 // Objetos y punteros
Screen *screen; // Objeto encargado de dibujar en pantalla Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
Resource *resource; // Objeto con los recursos Resource *resource_; // Objeto con los recursos
Asset *asset; // Objeto con los ficheros de recursos Asset *asset_; // Objeto con los ficheros de recursos
Input *input; // Objeto pata gestionar la entrada Input *input_; // Objeto pata gestionar la entrada
std::shared_ptr<Text> text; // Objeto para escribir texto en pantalla 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<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>> sprite_texts_; // Vector con los sprites de texto de los sprites
std::vector<std::shared_ptr<MovingSprite>> texts; // Vector con los sprites de texto std::vector<std::shared_ptr<MovingSprite>> texts_; // Vector con los sprites de texto
// Variables // Variables
bool counterEnabled; // Indica si está el contador habilitado bool counter_enabled_; // Indica si está el contador habilitado
int preCounter; // Contador previo int pre_counter_; // Contador previo
int postCounter; // Contador posterior int post_counter_; // Contador posterior
bool postCounterEnabled; // Indica si está habilitado el contador bool post_counter_enabled_; // Indica si está habilitado el contador
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa 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
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<std::string> spriteList; // Lista con todos los sprites a dibujar std::vector<Color> colors_; // Vector con los colores para el fade
std::vector<Color> colors; // Vector con los colores para el fade int sprite_max_width_; // El valor de ancho del sprite mas ancho
int maxSpriteWidth; // El valor de ancho del sprite mas ancho int sprite_max_height_; // El valor de alto del sprite mas alto
int maxSpriteHeight; // El valor de alto del sprite mas alto int dist_sprite_text_; // Distancia entre el sprite y el texto que lo acompaña
int distSpriteText; // Distancia entre el sprite y el texto que lo acompaña int dist_sprite_sprite_; // Distancia entre dos sprites de la misma columna
int distSpriteSprite; // Distancia entre dos sprites de la misma columna float sprite_desp_speed_; // Velocidad de desplazamiento de los sprites
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
// Actualiza el objeto // Actualiza el objeto
void update(); void update();

View File

@@ -1,16 +1,16 @@
#include "enemy.h" #include "enemy.h"
#include <SDL2/SDL_render.h> // for SDL_RendererFlip, SDL_FLIP_NONE, SDL_FL... #include <SDL2/SDL_render.h> // for SDL_RendererFlip, SDL_FLIP_NONE, SDL_FL...
#include <stdlib.h> // for rand #include <stdlib.h> // for rand
#include "animated_sprite.h" // for AnimatedSprite #include "animated_sprite.h" // for AnimatedSprite
#include "options.h" // for Options, OptionsVideo, options #include "options.h" // for Options, OptionsVideo, options
#include "resource.h" // for Resource #include "resource.h" // for Resource
#include "texture.h" // for Texture #include "texture.h" // for Texture
// Constructor // Constructor
Enemy::Enemy(EnemyData enemy) Enemy::Enemy(EnemyData enemy)
{ {
// Crea objetos // 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 // Obten el resto de valores
x1_ = enemy.x1; x1_ = enemy.x1;

View File

@@ -24,6 +24,7 @@
#include "notifier.h" #include "notifier.h"
#include "global_inputs.h" #include "global_inputs.h"
#include "global_events.h" #include "global_events.h"
//#include "surface.h"
// Constructor // Constructor
Game::Game() Game::Game()
@@ -36,32 +37,34 @@ Game::Game()
cheevos_(Cheevos::get()) cheevos_(Cheevos::get())
{ {
// Inicia algunas variables // 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 #ifdef DEBUG
current_room_ = "03.room"; current_room_ = "03.room";
const int x = 25; constexpr int X = 25;
const int y = 13; constexpr int Y = 13;
spawn_point_ = {x * 8, y * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL}; spawn_point_ = PlayerSpawn(X * 8, Y * 8, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL);
debug_->setEnabled(false); debug_->setEnabled(false);
#else #else
current_room_ = "03.room"; current_room_ = "03.room";
const int x = 25; constexpr int X = 25;
const int y = 13; constexpr int Y = 13;
spawn_point_ = {x * 8, y * 8, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL}; spawn_point_ = PlayerSpawn(X * 8, Y * 8, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL);
#endif #endif
// Crea los objetos // Crea los objetos
scoreboard_ = std::make_shared<Scoreboard>(&board_); ItemTracker::init();
item_tracker_ = std::make_shared<ItemTracker>(); scoreboard_ = std::make_shared<Scoreboard>(board_);
room_tracker_ = std::make_shared<RoomTracker>(); room_tracker_ = std::make_shared<RoomTracker>();
room_ = std::make_shared<Room>(resource_->getRoom(current_room_), item_tracker_, &board_.items, false); room_ = std::make_shared<Room>(resource_->getRoom(current_room_), board_);
const std::string playerPNG = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png"; std::string player_texture = 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"; std::string player_animations = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani";
const player_t player = {spawn_point_, playerPNG, playerANI, room_}; const PlayerData player(spawn_point_, player_texture, player_animations, room_);
player_ = std::make_shared<Player>(player); player_ = std::make_shared<Player>(player);
text_ = resource_->getText("smb2"); text_ = resource_->getText("smb2");
music_ = resource_->getMusic("game.ogg"); 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")); 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 // Crea la textura para poner el nombre de la habitación
@@ -85,15 +88,14 @@ Game::Game()
// Inicializa el resto de variables // Inicializa el resto de variables
ticks_ = 0; ticks_ = 0;
ticks_speed_ = 15; board_->lives = 9;
board_.lives = 9;
#ifdef DEBUG #ifdef DEBUG
board_.lives = 9; board_->lives = 9;
#endif #endif
board_.items = 0; board_->items = 0;
board_.rooms = 1; board_->rooms = 1;
board_.music = true; board_->music = true;
board_.jail_is_open = options.cheats.jail_is_open == Cheat::CheatState::ENABLED; board_->jail_is_open = options.cheats.jail_is_open == Cheat::CheatState::ENABLED;
setScoreBoardColor(); setScoreBoardColor();
room_tracker_->addRoom(current_room_); room_tracker_->addRoom(current_room_);
paused_ = false; paused_ = false;
@@ -110,7 +112,7 @@ Game::Game()
Game::~Game() Game::~Game()
{ {
// Libera la memoria de los objetos ItemTracker::destroy();
SDL_DestroyTexture(room_name_texture_); SDL_DestroyTexture(room_name_texture_);
} }
@@ -130,8 +132,8 @@ void Game::checkEvents()
case SDL_SCANCODE_G: case SDL_SCANCODE_G:
debug_->switchEnabled(); debug_->switchEnabled();
options.cheats.invincible = static_cast<Cheat::CheatState>(debug_->getEnabled()); options.cheats.invincible = static_cast<Cheat::CheatState>(debug_->getEnabled());
board_.music = !debug_->getEnabled(); board_->music = !debug_->getEnabled();
board_.music ? JA_ResumeMusic() : JA_PauseMusic(); board_->music ? JA_ResumeMusic() : JA_PauseMusic();
break; break;
case SDL_SCANCODE_R: case SDL_SCANCODE_R:
@@ -155,19 +157,19 @@ void Game::checkEvents()
break; break;
case SDL_SCANCODE_F6: 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; break;
case SDL_SCANCODE_F7: 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; break;
case SDL_SCANCODE_F8: case SDL_SCANCODE_F8:
Notifier::get()->show({"JAILDESIGNER IS LOGGED IN", ""}, 4); Notifier::get()->show({"JAILDESIGNER", "IS LOGGED IN"}, NotificationText::LEFT, 4, false);
break; break;
case SDL_SCANCODE_F9: case SDL_SCANCODE_F9:
Notifier::get()->show({"JAILDESIGNER IS LOGGED IN", ""}, 5); Notifier::get()->show({"JAILDESIGNER", "IS LOGGED IN"}, NotificationText::LEFT, 5, false);
break; break;
default: default:
break; break;
@@ -182,13 +184,15 @@ void Game::checkInput()
{ {
if (input_->checkInput(input_toggle_music, REPEAT_FALSE)) if (input_->checkInput(input_toggle_music, REPEAT_FALSE))
{ {
board_.music = !board_.music; board_->music = !board_->music;
board_.music ? JA_ResumeMusic() : JA_PauseMusic(); 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)) else if (input_->checkInput(input_pause, REPEAT_FALSE))
{ {
switchPause(); switchPause();
Notifier::get()->show({std::string(paused_ ? "GAME PAUSED" : "GAME RUNNING")}, NotificationText::CENTER);
} }
globalInputs::check(); globalInputs::check();
@@ -198,7 +202,7 @@ void Game::checkInput()
void Game::run() void Game::run()
{ {
JA_PlayMusic(music_); JA_PlayMusic(music_);
if (!board_.music) if (!board_->music)
{ {
JA_PauseMusic(); JA_PauseMusic();
} }
@@ -217,7 +221,7 @@ void Game::run()
void Game::update() void Game::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // 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 // Actualiza el contador de ticks
ticks_ = SDL_GetTicks(); ticks_ = SDL_GetTicks();
@@ -258,6 +262,7 @@ void Game::render()
{ {
// Prepara para dibujar el frame // Prepara para dibujar el frame
screen_->start(); screen_->start();
//test_surface_->render(0, 0, 10, 10, 64, 64);
// Dibuja los elementos del juego en orden // Dibuja los elementos del juego en orden
room_->renderMap(); 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("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("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 // Pone la información de debug en pantalla
@@ -336,7 +341,7 @@ bool Game::changeRoom(std::string file)
if (asset_->get(file) != "") if (asset_->get(file) != "")
{ {
// Crea un objeto habitación nuevo a partir del fichero // 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 // Pone el nombre de la habitación en la textura
fillRoomNameTexture(); fillRoomNameTexture();
@@ -347,8 +352,8 @@ bool Game::changeRoom(std::string file)
if (room_tracker_->addRoom(file)) if (room_tracker_->addRoom(file))
{ {
// Incrementa el contador de habitaciones visitadas // Incrementa el contador de habitaciones visitadas
board_.rooms++; board_->rooms++;
options.stats.rooms = board_.rooms; options.stats.rooms = board_->rooms;
// Actualiza las estadisticas // Actualiza las estadisticas
stats_->addVisit(room_->getName()); stats_->addVisit(room_->getName());
@@ -407,7 +412,7 @@ void Game::checkIfPlayerIsAlive()
// Comprueba si ha terminado la partida // Comprueba si ha terminado la partida
void Game::checkGameOver() 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; options.section.section = Section::GAME_OVER;
} }
@@ -424,7 +429,7 @@ void Game::killPlayer()
// Resta una vida al jugador // Resta una vida al jugador
if (options.cheats.infinite_lives == Cheat::CheatState::DISABLED) if (options.cheats.infinite_lives == Cheat::CheatState::DISABLED)
{ {
--board_.lives; --board_->lives;
} }
// Actualiza las estadisticas // Actualiza las estadisticas
@@ -440,10 +445,10 @@ void Game::killPlayer()
setBlackScreen(); setBlackScreen();
// Crea la nueva habitación y el nuevo jugador // 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); room_ = std::make_shared<Room>(resource_->getRoom(current_room_), board_);
const std::string playerPNG = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png"; std::string player_texture = 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"; std::string player_animations = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani";
const player_t player = {spawn_point_, playerPNG, playerANI, room_}; const PlayerData player(spawn_point_, player_texture, player_animations, room_);
player_ = std::make_shared<Player>(player); player_ = std::make_shared<Player>(player);
// Pone los objetos en pausa mientras esta la habitación en negro // 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")); 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 // 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 // Comprueba si ha finalizado el juego
bool Game::checkEndGame() bool Game::checkEndGame()
{ {
const bool isOnTheRoom = room_->getName() == "THE JAIL"; // Estar en la habitación que toca 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) const bool isOnTheDoor = player_->getRect().x <= 128; // Y en la ubicación que toca (En la puerta)
if (haveTheItems) if (haveTheItems)
{ {
board_.jail_is_open = true; board_->jail_is_open = true;
} }
if (haveTheItems && isOnTheRoom && isOnTheDoor) if (haveTheItems && isOnTheRoom && isOnTheDoor)
@@ -581,7 +586,7 @@ void Game::switchPause()
// Da vidas al jugador cuando está en la Jail // Da vidas al jugador cuando está en la Jail
void Game::checkRestoringJail() void Game::checkRestoringJail()
{ {
if (room_->getName() != "THE JAIL" || board_.lives == 9) if (room_->getName() != "THE JAIL" || board_->lives == 9)
{ {
return; return;
} }
@@ -597,11 +602,11 @@ void Game::checkRestoringJail()
if (counter == 100) if (counter == 100)
{ {
counter = 0; counter = 0;
board_.lives++; board_->lives++;
JA_PlaySound(death_sound_); JA_PlaySound(death_sound_);
// Invalida el logro de completar el juego sin entrar a la jail // 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) if (!haveTheItems)
{ {
cheevos_->invalidate(9); cheevos_->invalidate(9);
@@ -644,42 +649,42 @@ void Game::fillRoomNameTexture()
void Game::checkSomeCheevos() void Game::checkSomeCheevos()
{ {
// Logros sobre la cantidad de items // Logros sobre la cantidad de items
if (board_.items == total_items_) if (board_->items == total_items_)
{ {
cheevos_->unlock(4); cheevos_->unlock(4);
cheevos_->unlock(3); cheevos_->unlock(3);
cheevos_->unlock(2); cheevos_->unlock(2);
cheevos_->unlock(1); cheevos_->unlock(1);
} }
else if (board_.items >= total_items_ * 0.75f) else if (board_->items >= total_items_ * 0.75f)
{ {
cheevos_->unlock(3); cheevos_->unlock(3);
cheevos_->unlock(2); cheevos_->unlock(2);
cheevos_->unlock(1); cheevos_->unlock(1);
} }
else if (board_.items >= total_items_ * 0.5f) else if (board_->items >= total_items_ * 0.5f)
{ {
cheevos_->unlock(2); cheevos_->unlock(2);
cheevos_->unlock(1); cheevos_->unlock(1);
} }
else if (board_.items >= total_items_ * 0.25f) else if (board_->items >= total_items_ * 0.25f)
{ {
cheevos_->unlock(1); cheevos_->unlock(1);
} }
// Logros sobre las habitaciones visitadas // Logros sobre las habitaciones visitadas
if (board_.rooms >= 60) if (board_->rooms >= 60)
{ {
cheevos_->unlock(7); cheevos_->unlock(7);
cheevos_->unlock(6); cheevos_->unlock(6);
cheevos_->unlock(5); cheevos_->unlock(5);
} }
else if (board_.rooms >= 40) else if (board_->rooms >= 40)
{ {
cheevos_->unlock(6); cheevos_->unlock(6);
cheevos_->unlock(5); cheevos_->unlock(5);
} }
else if (board_.rooms >= 20) else if (board_->rooms >= 20)
{ {
cheevos_->unlock(5); cheevos_->unlock(5);
} }
@@ -695,7 +700,7 @@ void Game::checkEndGameCheevos()
cheevos_->unlock(9); cheevos_->unlock(9);
// "Complete the game with all items" // "Complete the game with all items"
if (board_.items == total_items_) if (board_->items == total_items_)
{ {
cheevos_->unlock(10); cheevos_->unlock(10);
} }

View File

@@ -8,6 +8,7 @@
#include "player.h" // Para playerSpawn_t #include "player.h" // Para playerSpawn_t
#include "scoreboard.h" // Para board_t #include "scoreboard.h" // Para board_t
#include "room.h" #include "room.h"
//#include "surface.h"
class Asset; class Asset;
class Cheevos; class Cheevos;
class Debug; class Debug;
@@ -37,26 +38,25 @@ private:
Cheevos *cheevos_; // Objeto encargado de gestionar los logros del juego 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<Room> room_; // Objeto encargado de gestionar cada habitación del juego
std::shared_ptr<Player> player_; // Objeto con el jugador 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<RoomTracker> room_tracker_; // Lleva el control de las habitaciones visitadas
std::shared_ptr<Text> text_; // Objeto para los textos 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<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador
std::shared_ptr<Stats> stats_; // Objeto encargado de gestionar las estadísticas 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 SDL_Texture *room_name_texture_; // Textura para escribir el nombre de la habitación
//std::shared_ptr<Surface> test_surface_;
// Variables // Variables
JA_Music_t *music_; // Musica que suena durante el juego JA_Music_t *music_; // Musica que suena durante el juego
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa 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
std::string current_room_; // Fichero de la habitación actual PlayerSpawn spawn_point_; // Lugar de la habitación donde aparece el jugador
playerSpawn_t spawn_point_; // Lugar de la habitación donde aparece el jugador JA_Sound_t *death_sound_; // Sonido a reproducir cuando muere el jugador
JA_Sound_t *death_sound_; // Sonido a reproducir cuando muere el jugador std::shared_ptr<ScoreboardData> board_; // Estructura con los datos del marcador
board_t board_; // Estructura con los datos del marcador bool paused_; // Indica si el juego se encuentra en pausa
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
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
int black_screen_counter_; // Contador para temporizar la pantalla en negro int total_items_; // Cantidad total de items que hay en el mapeado del juego
int total_items_; // Cantidad total de items que hay en el mapeado del juego SDL_Rect room_name_rect_; // Rectangulo donde pintar la textura con el nombre de la habitación
SDL_Rect room_name_rect_; // Rectangulo donde pintar la textura con el nombre de la habitación
// Actualiza el juego, las variables, comprueba la entrada, etc. // Actualiza el juego, las variables, comprueba la entrada, etc.
void update(); void update();

View File

@@ -1,67 +1,63 @@
#include "game_over.h" #include "game_over.h"
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <algorithm> // for min, max #include <algorithm> // for min, max
#include <string> // for basic_string, operator+, to_string, cha... #include <string> // for basic_string, operator+, to_string, cha...
#include "animated_sprite.h" // for AnimatedSprite #include "animated_sprite.h" // for AnimatedSprite
#include "asset.h" // for Asset #include "asset.h" // for Asset
#include "defines.h" // for GAMECANVAS_CENTER_X #include "defines.h" // for GAMECANVAS_CENTER_X
#include "global_events.h" // for check #include "global_events.h" // for check
#include "global_inputs.h" // for check #include "global_inputs.h" // for check
#include "input.h" // for Input #include "input.h" // for Input
#include "jail_audio.h" // for JA_PlayMusic #include "jail_audio.h" // for JA_PlayMusic
#include "options.h" // for Options, options, OptionsStats, Section... #include "options.h" // for Options, options, OptionsStats, Section...
#include "resource.h" // for Resource #include "resource.h" // for Resource
#include "screen.h" // for Screen #include "screen.h" // for Screen
#include "text.h" // for TEXT_CENTER, TEXT_COLOR, Text #include "text.h" // for TEXT_CENTER, TEXT_COLOR, Text
#include "texture.h" // for Texture #include "texture.h" // for Texture
// Constructor // Constructor
GameOver::GameOver() GameOver::GameOver()
: screen(Screen::get()), : screen_(Screen::get()),
renderer(Screen::get()->getRenderer()), renderer_(Screen::get()->getRenderer()),
resource(Resource::get()), resource_(Resource::get()),
asset(Asset::get()), asset_(Asset::get()),
input(Input::get()) input_(Input::get())
{ {
// Reserva memoria para los punteros a objetos // Reserva memoria para los punteros a objetos
text = resource->getText("smb2"); text_ = resource_->getText("smb2");
playerSprite = std::make_shared<AnimatedSprite>(resource->getTexture("player_game_over.png"), resource->getAnimation("player_game_over.ani")); player_sprite_ = std::make_shared<AnimatedSprite>(resource_->getTexture("player_game_over.png"), resource_->getAnimations("player_game_over.ani"));
tvSprite = std::make_shared<AnimatedSprite>(resource->getTexture("tv.png"), resource->getAnimation("tv.ani")); tv_sprite_ = std::make_shared<AnimatedSprite>(resource_->getTexture("tv.png"), resource_->getAnimations("tv.ani"));
music = resource->getMusic("game_over.ogg"); music_ = resource_->getMusic("game_over.ogg");
// Inicializa variables // Inicializa variables
preCounter = 0; pre_counter_ = 0;
counter = 0; counter_ = 0;
options.section.section = Section::GAME_OVER; options.section.section = Section::GAME_OVER;
options.section.subsection = Subsection::NONE; options.section.subsection = Subsection::NONE;
ticks = 0; ticks_ = 0;
ticksSpeed = 15; player_sprite_->setPosX(GAMECANVAS_CENTER_X + 10);
endSection = 400; player_sprite_->setPosY(30);
iniFade = 310; tv_sprite_->setPosX(GAMECANVAS_CENTER_X - tv_sprite_->getWidth() - 10);
fadeLenght = 20; tv_sprite_->setPosY(30);
playerSprite->setPosX(GAMECANVAS_CENTER_X + 10);
playerSprite->setPosY(30);
tvSprite->setPosX(GAMECANVAS_CENTER_X - tvSprite->getWidth() - 10);
tvSprite->setPosY(30);
// Inicializa el vector de colores // Inicializa el vector de colores
const std::vector<std::string> colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"}; const std::vector<std::string> colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
for (auto cl : colorList) 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 // Actualiza el objeto
void GameOver::update() void GameOver::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // 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 // Actualiza el contador de ticks
ticks = SDL_GetTicks(); ticks_ = SDL_GetTicks();
// Comprueba las entradas // Comprueba las entradas
checkInput(); checkInput();
@@ -73,44 +69,41 @@ void GameOver::update()
updateCounters(); updateCounters();
// Actualiza los dos sprites // Actualiza los dos sprites
playerSprite->update(); player_sprite_->update();
tvSprite->update(); tv_sprite_->update();
screen->update(); screen_->update();
} }
} }
// Dibuja el final en pantalla // Dibuja el final en pantalla
void GameOver::render() void GameOver::render()
{ {
const int y = 32; constexpr int Y = 32;
// Prepara para empezar a dibujar en la textura de juego screen_->start();
screen->start(); screen_->clean();
// Limpia la pantalla
screen->clean();
// Escribe el texto de GAME OVER // 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 // Dibuja los sprites
playerSprite->setPosY(y + 30); player_sprite_->setPosY(Y + 30);
tvSprite->setPosY(y + 30); tv_sprite_->setPosY(Y + 30);
renderSprites(); renderSprites();
// Escribe el texto con las habitaciones y los items // 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 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); 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 + 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 + 90, "ROOMS: " + roomsTxt, 1, color_);
// Escribe el texto con "Tu peor pesadilla" // 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 + 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 + 120, options.stats.worst_nightmare, 1, color_);
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen->render(); screen_->render();
} }
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
@@ -143,53 +136,53 @@ void GameOver::run()
// Actualiza el color usado para renderizar los textos e imagenes // Actualiza el color usado para renderizar los textos e imagenes
void GameOver::updateColor() 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 float step = std::min(counter_, COUNTER_FADE_LENGHT_) / (float)COUNTER_FADE_LENGHT_;
const int index = (colors.size() - 1) - int((colors.size() - 1) * step); const int index = (colors_.size() - 1) - int((colors_.size() - 1) * step);
color = colors[index]; color_ = colors_[index];
} }
else else
{ {
const float step = std::min(std::max(counter, iniFade) - iniFade, fadeLenght) / (float)fadeLenght; 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; const int index = (colors_.size() - 1) * step;
color = colors[index]; color_ = colors_[index];
} }
} }
// Dibuja los sprites // Dibuja los sprites
void GameOver::renderSprites() void GameOver::renderSprites()
{ {
playerSprite->getTexture()->setColor(color.r, color.g, color.b); player_sprite_->getTexture()->setColor(color_.r, color_.g, color_.b);
playerSprite->render(); player_sprite_->render();
tvSprite->getTexture()->setColor(color.r, color.g, color.b); tv_sprite_->getTexture()->setColor(color_.r, color_.g, color_.b);
tvSprite->render(); tv_sprite_->render();
} }
// Actualiza los contadores // Actualiza los contadores
void GameOver::updateCounters() void GameOver::updateCounters()
{ {
// Actualiza el contador // Actualiza el contador
if (preCounter < 50) if (pre_counter_ < 50)
{ {
preCounter++; pre_counter_++;
} }
else else
{ {
counter++; counter_++;
} }
// Hace sonar la música // 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 // Comprueba si ha terminado la sección
else if (counter == endSection) else if (counter_ == COUNTER_SECTION_END_)
{ {
options.section.section = Section::LOGO; options.section.section = Section::LOGO;
options.section.subsection = Subsection::LOGO_TO_TITLE; options.section.subsection = Subsection::LOGO_TO_TITLE;

View File

@@ -1,42 +1,43 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr #include <memory> // for shared_ptr
#include <vector> // for vector #include <vector> // for vector
#include "utils.h" // for Color #include "utils.h" // for Color
class AnimatedSprite; // lines 9-9 class AnimatedSprite; // lines 9-9
class Asset; // lines 10-10 class Asset; // lines 10-10
class Input; // lines 11-11 class Input; // lines 11-11
class Resource; // lines 12-12 class Resource; // lines 12-12
class Screen; // lines 13-13 class Screen; // lines 13-13
class Text; // lines 14-14 class Text; // lines 14-14
struct JA_Music_t; // lines 15-15 struct JA_Music_t; // lines 15-15
class GameOver class GameOver
{ {
private: 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 // Objetos y punteros
Screen *screen; // Objeto encargado de dibujar en pantalla Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
Resource *resource; // Objeto con los recursos Resource *resource_; // Objeto con los recursos
Asset *asset; // Objeto con los ficheros de recursos Asset *asset_; // Objeto con los ficheros de recursos
Input *input; // Objeto pata gestionar la entrada Input *input_; // Objeto pata gestionar la entrada
std::shared_ptr<Text> text; // Objeto para escribir texto en pantalla std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
std::shared_ptr<AnimatedSprite> playerSprite; // Sprite con el jugador std::shared_ptr<AnimatedSprite> player_sprite_; // Sprite con el jugador
std::shared_ptr<AnimatedSprite> tvSprite; // Sprite con el televisor std::shared_ptr<AnimatedSprite> tv_sprite_; // Sprite con el televisor
// Variables // Variables
int preCounter; // Contador previo int pre_counter_ = 0; // Contador previo
int counter; // Contador int counter_ = 0; // Contador
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_ = 0; // 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
std::vector<Color> colors; // Vector con los colores para el fade Color color_; // Color usado para el texto y los sprites
Color color; // Color usado para el texto y los sprites JA_Music_t *music_; // Musica que suena durante el juego
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
// Actualiza el objeto // Actualiza el objeto
void update(); void update();

View File

@@ -1,94 +1,9 @@
#include "gif.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <fcntl.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, void uncompress( int code_length,
const unsigned char *input, const unsigned char *input,
int input_length, int input_length,

65
source/gif.h Normal file
View 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);

View File

@@ -1,15 +1,30 @@
#include "global_inputs.h" #include "global_inputs.h"
#include <string> // for basic_string #include <string> // for basic_string
#include <vector> // for vector #include <vector> // for vector
#include "input.h" // for Input, REPEAT_FALSE, inputs_e #include "input.h" // for Input, REPEAT_FALSE, inputs_e
#include "notifier.h" // for Notifier #include "notifier.h" // for Notifier
#include "options.h" // for Section, Options, options, SectionState, Optio... #include "options.h" // for Section, Options, options, SectionState, Optio...
#include "screen.h" // for Screen #include "screen.h" // for Screen
#include "utils.h" // for Palette #include "utils.h" // for Palette
namespace globalInputs 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() void switchPalette()
{ {
options.video.palette = options.video.palette == Palette::ZXSPECTRUM ? Palette::ZXARNE : Palette::ZXSPECTRUM; 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)) if (Input::get()->checkInput(input_exit, REPEAT_FALSE))
{ {
options.section.section = Section::QUIT; quit();
} }
else if (Input::get()->checkInput(input_accept, REPEAT_FALSE)) 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)) else if (Input::get()->checkInput(input_toggle_border, REPEAT_FALSE))
{ {
Screen::get()->toggleBorder(); 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)) else if (Input::get()->checkInput(input_toggle_videomode, REPEAT_FALSE))
{ {
Screen::get()->toggleVideoMode(); 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)) 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)) 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)) else if (Input::get()->checkInput(input_toggle_shaders, REPEAT_FALSE))
{ {
Screen::get()->toggleShaders(); 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)) else if (Input::get()->checkInput(input_toggle_palette, REPEAT_FALSE))
{ {
switchPalette(); switchPalette();
Notifier::get()->show({"PALETTE " + std::string(options.video.palette == Palette::ZXSPECTRUM ? "ZX SPECTRUM" : "ZX ARNE")}, NotificationText::CENTER);
} }
} }
} }

View File

@@ -76,9 +76,9 @@ private:
std::vector<std::string> controller_names_; // Vector con los nombres de los mandos std::vector<std::string> controller_names_; // Vector con los nombres de los mandos
int num_gamepads_; // Numero de mandos conectados int num_gamepads_; // Numero de mandos conectados
std::string db_path_; // Ruta al archivo gamecontrollerdb.txt std::string db_path_; // Ruta al archivo gamecontrollerdb.txt
bool verbose_ = true; // Indica si ha de mostrar mensajes bool verbose_ = true; // Indica si ha de mostrar mensajes
i_disable_e disabled_until_; // Tiempo que esta deshabilitado i_disable_e disabled_until_; // Tiempo que esta deshabilitado
bool enabled_ = true; // Indica si está habilitado bool enabled_ = true; // Indica si está habilitado
// Constructor // Constructor
explicit Input(const std::string &game_controller_db_path); explicit Input(const std::string &game_controller_db_path);

View File

@@ -1,59 +1,57 @@
#include "item.h" #include "item.h"
#include "resource.h"
#include "sprite.h" // Para Sprite #include "sprite.h" // Para Sprite
#include "texture.h" // Para Texture #include "texture.h" // Para Texture
// Constructor // Constructor
Item::Item(item_t item) Item::Item(ItemData item)
{ {
constexpr int ITEMSIZE = 8; constexpr int ITEMSIZE = 8;
// Crea objetos; // 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 // Inicia variables
sprite->setClip((item.tile % 10) * ITEMSIZE, (item.tile / 10) * ITEMSIZE, ITEMSIZE, ITEMSIZE); sprite_->setClip((item.tile % 10) * ITEMSIZE, (item.tile / 10) * ITEMSIZE, ITEMSIZE, ITEMSIZE);
collider = sprite->getRect(); collider_ = sprite_->getRect();
colorChangeSpeed = 4; change_color_speed = 4;
counter = item.counter * colorChangeSpeed; counter_ = item.counter * change_color_speed;
// Inicializa los colores // Inicializa los colores
Color c = item.color1; color_.push_back(item.color1);
color.push_back(c); color_.push_back(item.color1);
color.push_back(c);
c = item.color2; color_.push_back(item.color2);
color.push_back(c); color_.push_back(item.color2);
color.push_back(c);
} }
// Pinta el objeto en pantalla // Pinta el objeto en pantalla
void Item::render() void Item::render()
{ {
const int index = (counter / colorChangeSpeed) % color.size(); const int index = (counter_ / change_color_speed) % color_.size();
sprite->getTexture()->setColor(color[index].r, color[index].g, color[index].b); sprite_->getTexture()->setColor(color_[index].r, color_[index].g, color_[index].b);
sprite->render(); sprite_->render();
sprite->getTexture()->setColor(255, 255, 255); sprite_->getTexture()->setColor(255, 255, 255);
} }
// Obtiene su ubicación // Obtiene su ubicación
SDL_Point Item::getPos() SDL_Point Item::getPos()
{ {
const SDL_Point p = {sprite->getX(), sprite->getY()}; const SDL_Point p = {sprite_->getX(), sprite_->getY()};
return p; return p;
} }
// Asigna los colores del objeto // Asigna los colores del objeto
void Item::setColors(Color col1, Color col2) void Item::setColors(Color col1, Color col2)
{ {
// Reinicializa el vector de colores // Reinicializa el vector de colores
color.clear(); color_.clear();
// Añade el primer color // 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 // Añade el segundo color
color.push_back(col2); color_.push_back(col2);
color.push_back(col2); color_.push_back(col2);
} }

View File

@@ -1,45 +1,43 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point #include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_render.h> // for SDL_Renderer
#include <memory> // for shared_ptr, __shared_ptr_access #include <memory> // for shared_ptr, __shared_ptr_access
#include <string> // for string #include <string> // for string
#include <vector> // for vector #include <vector> // for vector
#include "sprite.h" // for Sprite #include "sprite.h" // for Sprite
#include "texture.h" // for Texture #include "texture.h" // for Texture
#include "utils.h" // for Color #include "utils.h" // for Color
struct item_t struct ItemData
{ {
SDL_Renderer *renderer; // El renderizador de la ventana std::string tile_set_file; // Ruta al fichero con los gráficos del item
std::shared_ptr<Texture> texture; // Textura con los gráficos del item int x; // Posición del item en pantalla
std::string tileSetFile; // Ruta al fichero con los gráficos del item int y; // Posición del item en pantalla
int x; // Posición del item en pantalla int tile; // Número de tile dentro de la textura
int y; // Posición del item en pantalla int counter; // Contador inicial. Es el que lo hace cambiar de color
int tile; // Número de tile dentro de la textura Color color1; // Uno de los dos colores que se utiliza para el item
int counter; // Contador inicial. Es el que lo hace cambiar de color Color color2; // Uno de los dos colores que se utiliza para el item
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 // Constructor
item_t() : renderer(nullptr), texture(nullptr), x(0), y(0), tile(0), counter(0), color1(), color2() {} ItemData() : x(0), y(0), tile(0), counter(0), color1(), color2() {}
}; };
class Item class Item
{ {
private: private:
// Objetos y punteros // Objetos y punteros
std::shared_ptr<Sprite> sprite; // Sprite del objeto std::shared_ptr<Sprite> sprite_; // Sprite del objeto
// Variables // Variables
std::vector<Color> color; // Vector con los colores del objeto std::vector<Color> color_; // Vector con los colores del objeto
int counter; // Contador interno int counter_; // Contador interno
SDL_Rect collider; // Rectangulo de colisión SDL_Rect collider_; // Rectangulo de colisión
int colorChangeSpeed; // Cuanto mas alto, mas tarda en cambiar de color int change_color_speed; // Cuanto mas alto, mas tarda en cambiar de color
public: public:
// Constructor // Constructor
Item(item_t item); Item(ItemData item);
// Destructor // Destructor
~Item() = default; ~Item() = default;
@@ -48,18 +46,17 @@ public:
void render(); void render();
// Actualiza las variables del objeto // Actualiza las variables del objeto
void update() { counter++; } void update() { counter_++; }
// Obtiene el rectangulo de colision del objeto // Obtiene el rectangulo de colision del objeto
SDL_Rect &getCollider() { return collider; } SDL_Rect &getCollider() { return collider_; }
// Obtiene su ubicación // Obtiene su ubicación
SDL_Point getPos(); SDL_Point getPos();
// Recarga la textura // Recarga la textura
void reLoadTexture() { sprite->getTexture()->reLoad(); } void reLoadTexture() { sprite_->getTexture()->reLoad(); }
// Asigna los colores del objeto // Asigna los colores del objeto
void setColors(Color col1, Color col2); void setColors(Color col1, Color col2);
}; };

View File

@@ -1,50 +1,57 @@
#include "item_tracker.h" #include "item_tracker.h"
// Destructor // [SINGLETON]
ItemTracker::~ItemTracker() 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 // 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 // Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name); if (const int index = findByName(name); index != -1)
if (index != -1)
{ {
// Luego busca si existe ya una entrada con esa posición // Luego busca si existe ya una entrada con esa posición
if (findByPos(index, pos) != -1) if (findByPos(index, pos) != -1)
{ {
success = true; return true;
} }
} }
return success; return false;
} }
// Añade el objeto a la lista de objetos cogidos // 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 // Comprueba si el objeto no ha sido recogido con anterioridad
if (!hasBeenPicked(name, pos)) if (!hasBeenPicked(name, pos))
{ {
// Primero busca si ya hay una entrada con ese nombre // Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name); if (const int index = findByName(name); index != -1)
if (index != -1)
{ {
list[index].pos.push_back(pos); item_list_.at(index).pos.push_back(pos);
} }
// En caso contrario crea la entrada // En caso contrario crea la entrada
else else
{ {
item_tracker_t item; item_list_.emplace_back(name, pos);
item.name = name;
item.pos.push_back(pos);
list.push_back(item);
} }
} }
} }
@@ -54,7 +61,7 @@ int ItemTracker::findByName(std::string name)
{ {
int i = 0; int i = 0;
for (auto l : list) for (const auto &l : item_list_)
{ {
if (l.name == name) if (l.name == name)
{ {
@@ -71,7 +78,7 @@ int ItemTracker::findByPos(int index, SDL_Point pos)
{ {
int i = 0; 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)) if ((l.x == pos.x) && (l.y == pos.y))
{ {

View File

@@ -4,17 +4,27 @@
#include <string> // Para string, basic_string #include <string> // Para string, basic_string
#include <vector> // Para vector #include <vector> // Para vector
struct item_tracker_t struct ItemTrackerData
{ {
std::string name; // Nombre de la habitación donde se encuentra el objeto 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 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 class ItemTracker
{ {
private: private:
// [SINGLETON] Objeto privado
static ItemTracker *item_tracker_;
// Variables // 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 // Busca una entrada en la lista por nombre
int findByName(std::string name); int findByName(std::string name);
@@ -22,13 +32,25 @@ private:
// Busca una entrada en la lista por posición // Busca una entrada en la lista por posición
int findByPos(int index, SDL_Point pos); int findByPos(int index, SDL_Point pos);
public: // Constructor
ItemTracker() = default;
// Destructor // 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 // 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 // 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);
}; };

View File

@@ -14,6 +14,7 @@
#include "sprite.h" // for Sprite #include "sprite.h" // for Sprite
#include "texture.h" // for Texture #include "texture.h" // for Texture
#include "utils.h" // for Color, stringToColor, Palette #include "utils.h" // for Color, stringToColor, Palette
#include <iostream>
// Constructor // Constructor
LoadingScreen::LoadingScreen() LoadingScreen::LoadingScreen()
@@ -40,6 +41,16 @@ LoadingScreen::LoadingScreen()
loading_sound2_ = resource_->getMusic("loading_sound2.ogg"); loading_sound2_ = resource_->getMusic("loading_sound2.ogg");
loading_sound3_ = resource_->getMusic("loading_sound3.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 // Inicializa variables
options.section.section = Section::LOADING_SCREEN; options.section.section = Section::LOADING_SCREEN;
options.section.subsection = Subsection::NONE; options.section.subsection = Subsection::NONE;
@@ -71,6 +82,7 @@ LoadingScreen::LoadingScreen()
LoadingScreen::~LoadingScreen() LoadingScreen::~LoadingScreen()
{ {
JA_StopMusic(); JA_StopMusic();
SDL_DestroyTexture(texture_);
} }
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
@@ -165,8 +177,8 @@ void LoadingScreen::renderBorder()
// Añade lineas amarillas // Añade lineas amarillas
color = stringToColor(options.video.palette, "yellow"); color = stringToColor(options.video.palette, "yellow");
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF); SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
const int width = GAMECANVAS_WIDTH + (options.video.border.width * 2); const int width = options.game.width + (options.video.border.width * 2);
const int height = GAMECANVAS_HEIGHT + (options.video.border.height * 2); const int height = options.game.height + (options.video.border.height * 2);
bool drawEnabled = rand() % 2 == 0 ? true : false; bool drawEnabled = rand() % 2 == 0 ? true : false;
int row = 0; int row = 0;
int rowSize = 1; int rowSize = 1;
@@ -187,12 +199,13 @@ void LoadingScreen::renderBorder()
void LoadingScreen::update() void LoadingScreen::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // 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(); ticks_ = SDL_GetTicks();
checkInput(); checkInput();
updateCounter(); updateCounter();
updateLoad(); updateLoad();
fillTexture();
screen_->update(); screen_->update();
} }
} }
@@ -212,8 +225,8 @@ void LoadingScreen::render()
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
screen_->start(); screen_->start();
// Dibuja la pantalla de carga // Copila la textura a la pantalla
renderLoad(); SDL_RenderCopy(renderer_, texture_, nullptr, nullptr);
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen_->render(); screen_->render();
@@ -278,4 +291,33 @@ void LoadingScreen::recreateLoadingScreen()
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen_->render(); 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);
} }

View File

@@ -1,16 +1,16 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr #include <memory> // for shared_ptr
class Asset; // lines 8-8 class Asset; // lines 8-8
class Input; // lines 9-9 class Input; // lines 9-9
class Resource; // lines 10-10 class Resource; // lines 10-10
class Screen; // lines 11-11 class Screen; // lines 11-11
class Sprite; // lines 12-12 class Sprite; // lines 12-12
class Texture; // lines 13-13 class Texture; // lines 13-13
struct JA_Music_t; // lines 14-14 struct JA_Music_t; // lines 14-14
class LoadingScreen class LoadingScreen
{ {
@@ -30,7 +30,6 @@ private:
int pre_counter_ = 0; // Contador previo para realizar una pausa inicial int pre_counter_ = 0; // Contador previo para realizar una pausa inicial
int counter_ = 0; // Contador int counter_ = 0; // Contador
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa 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 int load_counter_ = 0; // Contador para controlar las cargas
bool loading_first_part_ = true; // Para saber en que parte de la carga se encuentra 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 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 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 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_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 // Actualiza las variables
void update(); void update();
@@ -66,6 +66,12 @@ private:
// Reconstruye la pantalla de carga // Reconstruye la pantalla de carga
void recreateLoadingScreen(); void recreateLoadingScreen();
// Dibuja sobre la textura
void fillTexture();
// Limpia la textura
void clearTexture();
public: public:
// Constructor // Constructor
LoadingScreen(); LoadingScreen();

View File

@@ -1,18 +1,19 @@
#include "logo.h" #include "logo.h"
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <string> // for basic_string, string #include <string> // for basic_string, string
#include "asset.h" // for Asset #include "asset.h" // for Asset
#include "global_events.h" // for check #include "global_events.h" // for check
#include "global_inputs.h" // for check #include "global_inputs.h" // for check
#include "input.h" // for Input #include "input.h" // for Input
#include "jail_audio.h" // for JA_StopMusic #include "jail_audio.h" // for JA_StopMusic
#include "options.h" // for Options, options, SectionState, Section #include "options.h" // for Options, options, SectionState, Section
#include "resource.h" // for Resource #include "resource.h" // for Resource
#include "screen.h" // for Screen #include "screen.h" // for Screen
#include "sprite.h" // for Sprite #include "sprite.h" // for Sprite
#include "texture.h" // for Texture #include "texture.h" // for Texture
#include "utils.h" // for Color, stringToColor #include "utils.h" // for Color, stringToColor
#include "defines.h"
// Constructor // Constructor
Logo::Logo() Logo::Logo()
@@ -153,43 +154,43 @@ void Logo::updateTextureColors()
since_1998_texture_->setColor(color_[7].r, color_[7].g, color_[7].b); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); since_1998_texture_->setColor(color_[0].r, color_[0].g, color_[0].b);
@@ -200,7 +201,7 @@ void Logo::updateTextureColors()
void Logo::update() void Logo::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // 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 // Actualiza el contador de ticks
ticks_ = SDL_GetTicks(); ticks_ = SDL_GetTicks();
@@ -220,7 +221,7 @@ void Logo::update()
screen_->update(); screen_->update();
// Comprueba si ha terminado el logo // Comprueba si ha terminado el logo
if (counter_ == end_logo_ + post_logo_) if (counter_ == END_LOGO_ + POST_LOGO_)
{ {
endSection(); endSection();
} }

View File

@@ -1,20 +1,25 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr #include <memory> // for shared_ptr
#include <vector> // for vector #include <vector> // for vector
#include "utils.h" // for Color #include "utils.h" // for Color
class Asset; // lines 8-8 class Asset; // lines 8-8
class Input; // lines 9-9 class Input; // lines 9-9
class Resource; // lines 10-10 class Resource; // lines 10-10
class Screen; // lines 11-11 class Screen; // lines 11-11
class Sprite; // lines 12-12 class Sprite; // lines 12-12
class Texture; // lines 13-13 class Texture; // lines 13-13
class Logo class Logo
{ {
private: 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 // Objetos y punteros
Screen *screen_; // Objeto encargado de dibujar en pantalla Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
@@ -30,10 +35,6 @@ private:
std::vector<Color> color_; // Vector con los colores para el fade std::vector<Color> color_; // Vector con los colores para el fade
int counter_ = 0; // Contador int counter_ = 0; // Contador
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa 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 // Actualiza las variables
void update(); void update();

View File

@@ -16,7 +16,7 @@
Notifier *Notifier::notifier_ = nullptr; Notifier *Notifier::notifier_ = nullptr;
// [SINGLETON] Crearemos el objeto con esta función estática // [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); Notifier::notifier_ = new Notifier(icon_file, text);
} }
@@ -34,10 +34,10 @@ Notifier *Notifier::get()
} }
// Constructor // 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()), : renderer_(Screen::get()->getRenderer()),
icon_texture_(!icon_file.empty() ? std::make_unique<Texture>(renderer_, icon_file) : nullptr), icon_texture_(!icon_file.empty() ? Resource::get()->getTexture(icon_file) : nullptr),
text_(text), text_(Resource::get()->getText(text)),
bg_color_(options.notifications.color), bg_color_(options.notifications.color),
wait_time_(150), wait_time_(150),
stack_(false), stack_(false),
@@ -84,18 +84,19 @@ void Notifier::update()
// Comprueba los estados // Comprueba los estados
if (notifications_[i].state == NotificationStatus::RISING) if (notifications_[i].state == NotificationStatus::RISING)
{ {
const float step = ((float)notifications_[i].counter / notifications_[i].travel_dist); //const float step = ((float)notifications_[i].counter / notifications_[i].travel_dist);
const int alpha = 255 * step; //const int alpha = 255 * step;
constexpr int ALPHA = 255;
if (options.notifications.getVerticalPosition() == "TOP") if (options.notifications.getVerticalPosition() == NotificationPosition::TOP)
{ {
notifications_[i].rect.y++; notifications_[i].rect.y++;
} }
else else if (options.notifications.getVerticalPosition() == NotificationPosition::BOTTOM)
{ {
notifications_[i].rect.y--; notifications_[i].rect.y--;
} }
notifications_[i].texture->setAlpha(alpha); notifications_[i].texture->setAlpha(ALPHA);
if (notifications_[i].rect.y == notifications_[i].y) if (notifications_[i].rect.y == notifications_[i].y)
{ {
@@ -116,18 +117,20 @@ void Notifier::update()
else if (notifications_[i].state == NotificationStatus::VANISHING) else if (notifications_[i].state == NotificationStatus::VANISHING)
{ {
const float step = (notifications_[i].counter / (float)notifications_[i].travel_dist); //const float step = (notifications_[i].counter / (float)notifications_[i].travel_dist);
const int alpha = 255 * (1 - step); //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--; notifications_[i].rect.y--;
} }
else else if (options.notifications.getVerticalPosition() == NotificationPosition::BOTTOM)
{ {
notifications_[i].rect.y++; 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) 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 // Si no hay texto, acaba
if (texts.empty()) if (texts.empty())
@@ -181,43 +184,41 @@ void Notifier::show(std::vector<std::string> texts, int icon, const std::string
} }
// Inicializa variables // Inicializa variables
constexpr int icon_size = 16;
constexpr int padding_out = 1;
const auto padding_in_h = text_->getCharacterSize(); const auto padding_in_h = text_->getCharacterSize();
const auto padding_in_v = text_->getCharacterSize() / 2; const auto padding_in_v = text_->getCharacterSize() / 2;
const int icon_space = icon >= 0 ? icon_size + padding_in_h : 0; const int icon_space = icon >= 0 ? ICON_SIZE_ + padding_in_h : 0;
const int width = text_->lenght(longest) + (padding_in_h * 2) + icon_space; 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 int height = (text_->getCharacterSize() * texts.size()) + (padding_in_v * 2);
const auto shape = NotificationShape::SQUARED; const auto shape = NotificationShape::SQUARED;
// Posición horizontal // Posición horizontal
auto desp_h = 0; 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)); 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 // 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 // Offset
const auto travel_dist = height + padding_out; const auto travel_dist = height + PADDING_OUT_;
auto offset = 0; 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 // Crea la notificacion
@@ -225,11 +226,12 @@ void Notifier::show(std::vector<std::string> texts, int icon, const std::string
// Inicializa variables // Inicializa variables
n.code = code; n.code = code;
n.can_be_removed = can_be_removed;
n.y = offset; n.y = offset;
n.travel_dist = travel_dist; n.travel_dist = travel_dist;
n.texts = texts; n.texts = texts;
n.shape = shape; 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}; n.rect = {desp_h, y_pos, width, height};
// Crea la textura // 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 // Dibuja el icono de la notificación
if (has_icons_ && icon >= 0 && texts.size() >= 2) if (has_icons_ && icon >= 0 && texts.size() >= 2)
{ {
auto sp = std::make_unique<Sprite>(icon_texture_, (SDL_Rect){0, 0, 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->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->setClip({ICON_SIZE_ * (icon % 10), ICON_SIZE_ * (icon / 10), ICON_SIZE_, ICON_SIZE_});
sp->render(); sp->render();
} }
@@ -277,7 +279,14 @@ void Notifier::show(std::vector<std::string> texts, int icon, const std::string
int iterator = 0; int iterator = 0;
for (const auto &text : texts) for (const auto &text : texts)
{ {
text_->writeColored(padding_in_h + icon_space, padding_in_v + iterator * (text_->getCharacterSize() + 1), text, color); 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; ++iterator;
} }
@@ -302,7 +311,10 @@ void Notifier::clearNotifications()
{ {
for (auto &notification : notifications_) for (auto &notification : notifications_)
{ {
notification.state = NotificationStatus::FINISHED; if (notification.can_be_removed)
{
notification.state = NotificationStatus::FINISHED;
}
} }
clearFinishedNotifications(); clearFinishedNotifications();

View File

@@ -10,9 +10,19 @@ class Sprite; // lines 9-9
class Text; // lines 10-10 class Text; // lines 10-10
class Texture; // lines 11-11 class Texture; // lines 11-11
enum class NotificationText
{
LEFT,
CENTER,
};
class Notifier class Notifier
{ {
private: private:
// Constantes
static constexpr int ICON_SIZE_ = 16;
static constexpr int PADDING_OUT_ = 0;
// [SINGLETON] Objeto notifier // [SINGLETON] Objeto notifier
static Notifier *notifier_; static Notifier *notifier_;
@@ -42,11 +52,14 @@ private:
int y; int y;
int travel_dist; int travel_dist;
std::string code; // Permite asignar un código a la notificación std::string code; // Permite asignar un código a la notificación
bool can_be_removed;
int height;
// Constructor // Constructor
explicit Notification() explicit Notification()
: texture(nullptr), sprite(nullptr), texts(), counter(0), state(NotificationStatus::RISING), : 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 // 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 // [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos notifier desde fuera
// Constructor // Constructor
Notifier(std::string icon_file, std::shared_ptr<Text> text); Notifier(const std::string &icon_file, const std::string &text);
// Destructor // Destructor
~Notifier() = default; ~Notifier() = default;
public: public:
// [SINGLETON] Crearemos el objeto con esta función estática // [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 // [SINGLETON] Destruiremos el objeto con esta función estática
static void destroy(); static void destroy();
@@ -93,7 +106,7 @@ public:
void update(); void update();
// Muestra una notificación de texto por pantalla // 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 // Indica si hay notificaciones activas
bool isActive(); bool isActive();

View File

@@ -53,8 +53,13 @@ bool loadOptionsFromFile(const std::string &file_path)
while (std::getline(file, line)) while (std::getline(file, line))
{ {
// Elimina espacios en blanco iniciales y finales // 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 = std::string(std::find_if(line.begin(), line.end(), [](int ch)
line.erase(std::find_if(line.rbegin(), line.rend(), [](int ch) { return !std::isspace(ch); }).base(), line.end()); { 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 // Ignora líneas vacías o comentarios
if (line.empty() || line[0] == '#') if (line.empty() || line[0] == '#')
@@ -107,7 +112,6 @@ bool loadOptionsFromFile(const std::string &file_path)
return success; return success;
} }
// Guarda las opciones en un fichero // Guarda las opciones en un fichero
bool saveOptionsToFile(const std::string &file_path) bool saveOptionsToFile(const std::string &file_path)
{ {
@@ -169,36 +173,105 @@ bool saveOptionsToFile(const std::string &file_path)
return success; return success;
} }
// Establece las opciones
bool setOptions(const std::string &var, const std::string &value) bool setOptions(const std::string &var, const std::string &value)
{ {
static const std::unordered_map<std::string, std::function<void(std::string)>> optionHandlers = { static const std::unordered_map<std::string, std::function<void(const std::string &)>> optionHandlers = {
{"version", [](std::string v) {"version", [](const std::string &v)
{ options.version = v; }}, { options.version = v; }},
{"keys", [](std::string v) {"keys", [](const std::string &v)
{ options.keys = static_cast<ControlScheme>(safeStoi(v, static_cast<int>(ControlScheme::CURSOR))); }}, {
{"window.zoom", [](std::string v) int val = safeStoi(v, static_cast<int>(DEFAULT_CONTROL_SCHEME));
{ options.window.zoom = safeStoi(v, 1); }}, if (val == static_cast<int>(ControlScheme::CURSOR) || val == static_cast<int>(ControlScheme::OPQA) || val == static_cast<int>(ControlScheme::WASD))
{"video.mode", [](std::string v) {
{ options.video.mode = safeStoi(v, 0); }}, options.keys = static_cast<ControlScheme>(val);
{"video.filter", [](std::string v) }
{ options.video.filter = static_cast<ScreenFilter>(safeStoi(v, static_cast<int>(DEFAULT_VIDEO_FILTER))); }}, else
{"video.shaders", [](std::string v) {
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); }}, { options.video.shaders = stringToBool(v); }},
{"video.vertical_sync", [](std::string v) {"video.vertical_sync", [](const std::string &v)
{ options.video.vertical_sync = stringToBool(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); }}, { 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); }}, { 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); }}, { options.video.border.enabled = stringToBool(v); }},
{"video.border.width", [](std::string v) {"video.border.width", [](const std::string &v)
{ options.video.border.width = safeStoi(v, 32); }}, {
{"video.border.height", [](std::string v) int val = safeStoi(v, DEFAULT_BORDER_WIDTH);
{ options.video.border.height = safeStoi(v, 24); }}, if (val > 0)
{"video.palette", [](std::string v) {
{ options.video.palette = static_cast<Palette>(safeStoi(v, static_cast<int>(DEFAULT_PALETTE))); }}}; 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); auto it = optionHandlers.find(var);
if (it != optionHandlers.end()) if (it != optionHandlers.end())
@@ -207,4 +280,4 @@ bool setOptions(const std::string &var, const std::string &value)
return true; return true;
} }
return false; return false;
} }

View File

@@ -1,9 +1,10 @@
#pragma once #pragma once
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <string> // for string, basic_string #include <string> // for string, basic_string
#include "screen.h" // for ScreenFilter #include "screen.h" // for ScreenFilter
#include "utils.h" // for Color, Palette #include "utils.h" // for Color, Palette
#include <algorithm>
// Secciones del programa // Secciones del programa
enum class Section enum class Section
@@ -36,11 +37,15 @@ enum class NotificationPosition
UPPER_LEFT, UPPER_LEFT,
UPPER_CENTER, UPPER_CENTER,
UPPER_RIGHT, UPPER_RIGHT,
MIDDLE_LEFT,
MIDDLE_RIGHT,
BOTTOM_LEFT, BOTTOM_LEFT,
BOTTOM_CENTER, BOTTOM_CENTER,
BOTTOM_RIGHT BOTTOM_RIGHT,
TOP,
BOTTOM,
LEFT,
RIGHT,
CENTER,
UNKNOWN,
}; };
// Tipos de control de teclado // 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 bool DEFAULT_BORDER_ENABLED = true; // Borde activado por defecto
constexpr int DEFAULT_BORDER_WIDTH = 32; // Ancho del borde 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_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 Palette DEFAULT_PALETTE = Palette::ZXSPECTRUM; // Paleta por defecto
constexpr Section DEFAULT_SECTION = Section::LOGO; // Sección por defecto constexpr Section DEFAULT_SECTION = Section::LOGO; // Sección por defecto
constexpr Subsection DEFAULT_SUBSECTION = Subsection::LOGO_TO_INTRO; // Subsecció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 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 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 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 // Estructura para las opciones de las notificaciones
struct OptionsNotification struct OptionsNotification
@@ -94,43 +105,42 @@ struct OptionsNotification
color(c) {} color(c) {}
// Método que devuelve la posición horizontal // Método que devuelve la posición horizontal
std::string getHorizontalPosition() const NotificationPosition getHorizontalPosition() const
{ {
switch (pos) switch (pos)
{ {
case NotificationPosition::UPPER_LEFT: case NotificationPosition::UPPER_LEFT:
case NotificationPosition::MIDDLE_LEFT:
case NotificationPosition::BOTTOM_LEFT: case NotificationPosition::BOTTOM_LEFT:
return "LEFT"; return NotificationPosition::LEFT;
case NotificationPosition::UPPER_CENTER: case NotificationPosition::UPPER_CENTER:
case NotificationPosition::BOTTOM_CENTER: case NotificationPosition::BOTTOM_CENTER:
return "CENTER"; return NotificationPosition::CENTER;
case NotificationPosition::UPPER_RIGHT: case NotificationPosition::UPPER_RIGHT:
case NotificationPosition::MIDDLE_RIGHT:
case NotificationPosition::BOTTOM_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 // Método que devuelve la posición vertical
std::string getVerticalPosition() const NotificationPosition getVerticalPosition() const
{ {
switch (pos) switch (pos)
{ {
case NotificationPosition::UPPER_LEFT: case NotificationPosition::UPPER_LEFT:
case NotificationPosition::UPPER_CENTER: case NotificationPosition::UPPER_CENTER:
case NotificationPosition::UPPER_RIGHT: case NotificationPosition::UPPER_RIGHT:
return "UPPER"; return NotificationPosition::TOP;
case NotificationPosition::MIDDLE_LEFT:
case NotificationPosition::MIDDLE_RIGHT:
return "MIDDLE";
case NotificationPosition::BOTTOM_LEFT: case NotificationPosition::BOTTOM_LEFT:
case NotificationPosition::BOTTOM_CENTER: case NotificationPosition::BOTTOM_CENTER:
case NotificationPosition::BOTTOM_RIGHT: case NotificationPosition::BOTTOM_RIGHT:
return "BOTTOM"; return NotificationPosition::BOTTOM;
default:
return NotificationPosition::UNKNOWN;
} }
return "UNKNOWN"; return NotificationPosition::UNKNOWN;
} }
}; };
@@ -211,15 +221,18 @@ struct OptionsStats
// Estructura con opciones de la ventana // Estructura con opciones de la ventana
struct OptionsWindow struct OptionsWindow
{ {
int zoom; // Zoom de la ventana int zoom; // Zoom de la ventana
int max_zoom; // Máximo tamaño de zoom para la ventana
// Constructor por defecto // Constructor por defecto
OptionsWindow() OptionsWindow()
: zoom(DEFAULT_WINDOW_ZOOM) {} : zoom(DEFAULT_WINDOW_ZOOM),
max_zoom(DEFAULT_WINDOW_ZOOM) {}
// Constructor // Constructor
OptionsWindow(int z) OptionsWindow(int z, int mz)
: zoom(z) {} : zoom(z),
max_zoom(mz) {}
}; };
// Estructura para gestionar el borde de la pantalla // Estructura para gestionar el borde de la pantalla
@@ -277,6 +290,89 @@ struct OptionsVideo
palette(p) {} 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 // Estructura para las opciones de juego
struct OptionsGame struct OptionsGame
{ {
@@ -305,6 +401,7 @@ struct Options
OptionsStats stats; // Datos con las estadisticas de juego OptionsStats stats; // Datos con las estadisticas de juego
OptionsNotification notifications; // Opciones relativas a las notificaciones; OptionsNotification notifications; // Opciones relativas a las notificaciones;
OptionsWindow window; // Opciones relativas a la ventana OptionsWindow window; // Opciones relativas a la ventana
OptionsAudio audio; // Opciones relativas al audio
ControlScheme keys; // Teclas usadas para jugar ControlScheme keys; // Teclas usadas para jugar
SectionState section; // Sección actual del programa SectionState section; // Sección actual del programa
@@ -318,11 +415,12 @@ struct Options
stats(OptionsStats()), stats(OptionsStats()),
notifications(OptionsNotification()), notifications(OptionsNotification()),
window(OptionsWindow()), window(OptionsWindow()),
audio(OptionsAudio()),
keys(DEFAULT_CONTROL_SCHEME), keys(DEFAULT_CONTROL_SCHEME),
section(SectionState()) {} section(SectionState()) {}
// Constructor // 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), : version(cv),
console(c), console(c),
cheats(ch), cheats(ch),
@@ -331,6 +429,7 @@ struct Options
stats(s), stats(s),
notifications(n), notifications(n),
window(sw), window(sw),
audio(a),
keys(k), keys(k),
section(sec) {} section(sec) {}
}; };

View File

@@ -4,7 +4,7 @@
#include <fcntl.h> // Para SEEK_END, SEEK_SET #include <fcntl.h> // Para SEEK_END, SEEK_SET
#include <stdio.h> // Para NULL, fseek, fclose, fopen, fread, ftell #include <stdio.h> // Para NULL, fseek, fclose, fopen, fread, ftell
#include <stdlib.h> // Para malloc, free #include <stdlib.h> // Para malloc, free
#include "gif.c" // Para LoadGif, LoadPalette #include "gif.h" // Para LoadGif, LoadPalette
struct jSurface_s struct jSurface_s
{ {

View File

@@ -16,99 +16,32 @@
#include "screen.h" #include "screen.h"
// Constructor // Constructor
Player::Player(player_t player) Player::Player(PlayerData player)
: renderer_(Screen::get()->getRenderer()), : renderer_(Screen::get()->getRenderer()),
input_(Input::get()), input_(Input::get()),
resource_(Resource::get()),
asset_(Asset::get()), asset_(Asset::get()),
debug_(Debug::get()), debug_(Debug::get()),
room_(player.room) room_(player.room)
{ {
// Crea objetos // Inicializa algunas variables
sprite_ = std::make_shared<AnimatedSprite>(resource_->getTexture(player.png), resource_->getAnimation(player.animation)); 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_; 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(); last_position_ = getRect();
collider_box_ = getRect(); collider_box_ = getRect();
const SDL_Point p = {0, 0}; collider_points_.resize(collider_points_.size() + 8, {0, 0});
collider_points_.insert(collider_points_.end(), {p, p, p, p, p, p, p, p}); under_feet_.resize(under_feet_.size() + 2, {0, 0});
under_feet_.insert(under_feet_.end(), {p, p}); feet_.resize(feet_.size() + 2, {0, 0});
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;
#ifdef DEBUG #ifdef DEBUG
rx = {0, 0, 0, 0}; debug_rect_x_ = {0, 0, 0, 0};
ry = {0, 0, 0, 0}; debug_rect_y_ = {0, 0, 0, 0};
debugColor = {0, 255, 0}; debug_color_ = {0, 255, 0};
debugPoint = {0, 0}; debug_point_ = {0, 0};
#endif #endif
} }
@@ -119,65 +52,35 @@ void Player::render()
sprite_->render(); sprite_->render();
#ifdef DEBUG #ifdef DEBUG
if (debug_->getEnabled()) renderDebugInfo();
{
// 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);
}
#endif #endif
} }
// Actualiza las variables del objeto // Actualiza las variables del objeto
void Player::update() void Player::update()
{ {
if (is_paused_) if (!is_paused_)
{ // Si está en modo pausa no se actualiza nada {
return; 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}
} }
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
} }
// Comprueba las entradas y modifica variables // Comprueba las entradas y modifica variables
void Player::checkInput() void Player::checkInput()
{ {
// Solo comprueba las entradas de dirección cuando está sobre una superficie // Solo comprueba las entradas de dirección cuando está sobre una superficie
if (state_ != s_standing) if (state_ != PlayerState::STANDING)
{ {
return; return;
} }
if (!auto_movement_) if (!auto_movement_)
{ {
// Comprueba las entradas de desplazamiento lateral solo en el caso de no estar enganchado a una superficie automatica // Comprueba las entradas de desplazamiento lateral solo en el caso de no estar enganchado a una superficie automatica
if (input_->checkInput(input_left)) if (input_->checkInput(input_left))
{ {
@@ -192,10 +95,12 @@ void Player::checkInput()
} }
else else
{ // No se pulsa ninguna dirección {
// No se pulsa ninguna dirección
vx_ = 0.0f; vx_ = 0.0f;
if (isOnAutoSurface()) if (isOnAutoSurface())
{ // Si deja de moverse sobre una superficie se engancha {
// Si deja de moverse sobre una superficie se engancha
auto_movement_ = true; auto_movement_ = true;
} }
} }
@@ -223,7 +128,7 @@ void Player::checkInput()
if (isOnFloor() || isOnAutoSurface()) if (isOnFloor() || isOnAutoSurface())
{ {
setState(s_jumping); setState(PlayerState::JUMPING);
vy_ = -MAX_VY_; vy_ = -MAX_VY_;
jump_init_pos_ = y_; jump_init_pos_ = y_;
jumping_counter_ = 0; 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 // Comprueba si está situado en alguno de los cuatro bordes de la habitación
void Player::checkBorders() void Player::checkBorders()
{ {
@@ -252,7 +145,7 @@ void Player::checkBorders()
is_on_border_ = true; is_on_border_ = true;
} }
else if (x_ + w_ > PLAY_AREA_RIGHT) else if (x_ + WIDTH_ > PLAY_AREA_RIGHT)
{ {
border_ = BORDER_RIGHT; border_ = BORDER_RIGHT;
is_on_border_ = true; is_on_border_ = true;
@@ -264,7 +157,7 @@ void Player::checkBorders()
is_on_border_ = true; is_on_border_ = true;
} }
else if (y_ + h_ > PLAY_AREA_BOTTOM) else if (y_ + HEIGHT_ > PLAY_AREA_BOTTOM)
{ {
border_ = BORDER_BOTTOM; border_ = BORDER_BOTTOM;
is_on_border_ = true; is_on_border_ = true;
@@ -280,7 +173,7 @@ void Player::checkBorders()
void Player::checkState() void Player::checkState()
{ {
// Actualiza las variables en función del estado // Actualiza las variables en función del estado
if (state_ == s_falling) if (state_ == PlayerState::FALLING)
{ {
vx_ = 0.0f; vx_ = 0.0f;
vy_ = MAX_VY_; vy_ = MAX_VY_;
@@ -288,9 +181,9 @@ void Player::checkState()
playFallSound(); 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 { // Si cae de muy alto, el jugador muere
is_alive_ = false; is_alive_ = false;
} }
@@ -299,7 +192,7 @@ void Player::checkState()
falling_counter_ = 0; falling_counter_ = 0;
if (!isOnFloor() && !isOnAutoSurface() && !isOnDownSlope()) if (!isOnFloor() && !isOnAutoSurface() && !isOnDownSlope())
{ {
setState(s_falling); setState(PlayerState::FALLING);
vx_ = 0.0f; vx_ = 0.0f;
vy_ = MAX_VY_; vy_ = MAX_VY_;
falling_counter_++; falling_counter_++;
@@ -307,7 +200,7 @@ void Player::checkState()
} }
} }
else if (state_ == s_jumping) else if (state_ == PlayerState::JUMPING)
{ {
falling_counter_ = 0; falling_counter_ = 0;
jumping_counter_++; jumping_counter_++;
@@ -320,13 +213,13 @@ void Player::switchBorders()
{ {
if (border_ == BORDER_TOP) if (border_ == BORDER_TOP)
{ {
y_ = PLAY_AREA_BOTTOM - h_ - 0 - BLOCK; y_ = PLAY_AREA_BOTTOM - HEIGHT_ - 0 - BLOCK;
setState(s_standing); setState(PlayerState::STANDING);
} }
else if (border_ == BORDER_BOTTOM) else if (border_ == BORDER_BOTTOM)
{ {
y_ = PLAY_AREA_TOP + 0; y_ = PLAY_AREA_TOP + 0;
setState(s_standing); setState(PlayerState::STANDING);
} }
else if (border_ == BORDER_RIGHT) else if (border_ == BORDER_RIGHT)
{ {
@@ -334,7 +227,7 @@ void Player::switchBorders()
} }
if (border_ == BORDER_LEFT) if (border_ == BORDER_LEFT)
{ {
x_ = PLAY_AREA_RIGHT - w_ - 0; x_ = PLAY_AREA_RIGHT - WIDTH_ - 0;
} }
is_on_border_ = false; is_on_border_ = false;
@@ -347,7 +240,7 @@ void Player::applyGravity()
// La gravedad solo se aplica cuando el jugador esta saltando // La gravedad solo se aplica cuando el jugador esta saltando
// Nunca mientras cae o esta de pie // Nunca mientras cae o esta de pie
if (state_ == s_jumping) if (state_ == PlayerState::JUMPING)
{ {
vy_ += GF; vy_ += GF;
if (vy_ > MAX_VY_) 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 // Recalcula la posición del jugador y su animación
void Player::move() void Player::move()
{ {
@@ -378,7 +258,7 @@ void Player::move()
checkState(); // Comprueba el estado del jugador checkState(); // Comprueba el estado del jugador
#ifdef DEBUG #ifdef DEBUG
debugColor = {0, 255, 0}; debug_color_ = {0, 255, 0};
#endif #endif
// Se mueve hacia la izquierda // Se mueve hacia la izquierda
@@ -388,11 +268,11 @@ void Player::move()
SDL_Rect proj; SDL_Rect proj;
proj.x = static_cast<int>(x_ + vx_); proj.x = static_cast<int>(x_ + vx_);
proj.y = static_cast<int>(y_); 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 proj.w = ceil(abs(vx_)); // Para evitar que tenga un ancho de 0 pixels
#ifdef DEBUG #ifdef DEBUG
rx = proj; debug_rect_x_ = proj;
#endif #endif
// Comprueba la colisión con las superficies // Comprueba la colisión con las superficies
@@ -411,18 +291,18 @@ void Player::move()
} }
// Si ha tocado alguna rampa mientras camina (sin saltar), asciende // 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); const int ly = room_->checkLeftSlopes(&leftSide);
if (ly > -1) if (ly > -1)
{ {
y_ = ly - h_; y_ = ly - HEIGHT_;
} }
} }
// Si está bajando la rampa, recoloca al jugador // Si está bajando la rampa, recoloca al jugador
if (isOnDownSlope() && state_ != s_jumping) if (isOnDownSlope() && state_ != PlayerState::JUMPING)
{ {
y_ += 1; y_ += 1;
} }
@@ -433,13 +313,13 @@ void Player::move()
{ {
// Crea el rectangulo de proyección en el eje X para ver si colisiona // Crea el rectangulo de proyección en el eje X para ver si colisiona
SDL_Rect proj; SDL_Rect proj;
proj.x = static_cast<int>(x_) + w_; proj.x = static_cast<int>(x_) + WIDTH_;
proj.y = static_cast<int>(y_); 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 proj.w = ceil(vx_); // Para evitar que tenga un ancho de 0 pixels
#ifdef DEBUG #ifdef DEBUG
rx = proj; debug_rect_x_ = proj;
#endif #endif
// Comprueba la colisión // Comprueba la colisión
@@ -454,38 +334,38 @@ void Player::move()
else else
{ {
// Si hay colisión lo mueve hasta donde no colisiona // 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 // 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); const int ry = room_->checkRightSlopes(&rightSide);
if (ry > -1) if (ry > -1)
{ {
y_ = ry - h_; y_ = ry - HEIGHT_;
} }
} }
// Si está bajando la rampa, recoloca al jugador // Si está bajando la rampa, recoloca al jugador
if (isOnDownSlope() && state_ != s_jumping) if (isOnDownSlope() && state_ != PlayerState::JUMPING)
{ {
y_ += 1; y_ += 1;
} }
} }
// Si ha salido del suelo, el jugador cae // 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 // Deja de estar enganchado a la superficie automatica
auto_movement_ = false; auto_movement_ = false;
} }
// Si ha salido de una superficie automatica, detiene el movimiento automatico // 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 // Deja de estar enganchado a la superficie automatica
auto_movement_ = false; auto_movement_ = false;
@@ -499,10 +379,10 @@ void Player::move()
proj.x = static_cast<int>(x_); proj.x = static_cast<int>(x_);
proj.y = static_cast<int>(y_ + vy_); proj.y = static_cast<int>(y_ + vy_);
proj.h = ceil(abs(vy_)); // Para evitar que tenga una altura de 0 pixels proj.h = ceil(abs(vy_)); // Para evitar que tenga una altura de 0 pixels
proj.w = w_; proj.w = WIDTH_;
#ifdef DEBUG #ifdef DEBUG
ry = proj; debug_rect_y_ = proj;
#endif #endif
// Comprueba la colisión // 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 // Si hay colisión lo mueve hasta donde no colisiona y entra en caída
y_ = pos + 1; 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 // Crea el rectangulo de proyección en el eje Y para ver si colisiona
SDL_Rect proj; SDL_Rect proj;
proj.x = static_cast<int>(x_); 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.h = ceil(vy_); // Para evitar que tenga una altura de 0 pixels
proj.w = w_; proj.w = WIDTH_;
#ifdef DEBUG #ifdef DEBUG
ry = proj; debug_rect_y_ = proj;
#endif #endif
// Comprueba la colisión con las superficies normales y las automáticas // Comprueba la colisión con las superficies normales y las automáticas
@@ -541,8 +421,8 @@ void Player::move()
if (pos > -1) if (pos > -1)
{ {
// Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre la superficie // Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre la superficie
y_ = pos - h_; y_ = pos - HEIGHT_;
setState(s_standing); setState(PlayerState::STANDING);
// Deja de estar enganchado a la superficie automatica // Deja de estar enganchado a la superficie automatica
auto_movement_ = false; auto_movement_ = false;
@@ -550,7 +430,7 @@ void Player::move()
else else
{ {
// Si no hay colisión con los muros, comprueba la colisión con las rampas // 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 { // 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 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}; 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 // No está saltando y hay colisión con una rampa
// Calcula la nueva posición // Calcula la nueva posición
y_ = p - h_; y_ = p - HEIGHT_;
setState(s_standing); setState(PlayerState::STANDING);
#ifdef DEBUG #ifdef DEBUG
debugColor = {255, 255, 0}; debug_color_ = {255, 255, 0};
debugPoint = {(int)x_ + (w_ / 2), p}; debug_point_ = {(int)x_ + (WIDTH_ / 2), p};
#endif #endif
} }
else else
@@ -572,7 +452,7 @@ void Player::move()
// Calcula la nueva posición // Calcula la nueva posición
y_ += vy_; y_ += vy_;
#ifdef DEBUG #ifdef DEBUG
debugColor = {255, 0, 0}; debug_color_ = {255, 0, 0};
#endif #endif
} }
} }
@@ -585,13 +465,12 @@ void Player::move()
} }
} }
// Actualiza la posición del sprite placeSprite(); // Coloca el sprite en la nueva posición
sprite_->setPosX(x_); collider_box_ = getRect(); // Actualiza el rectangulo de colisión
sprite_->setPosY(y_);
#ifdef DEBUG #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_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(ry.x) + "," + std::to_string(ry.y) + "," + std::to_string(ry.w) + "," + std::to_string(ry.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 #endif
} }
@@ -607,14 +486,14 @@ void Player::animate()
// Comprueba si ha finalizado el salto al alcanzar la altura de inicio // Comprueba si ha finalizado el salto al alcanzar la altura de inicio
void Player::checkJumpEnd() void Player::checkJumpEnd()
{ {
if (state_ == s_jumping) if (state_ == PlayerState::JUMPING)
{ {
if (vy_ > 0) if (vy_ > 0)
{ {
if (y_ >= jump_init_pos_) if (y_ >= jump_init_pos_)
{ {
// Si alcanza la altura de salto inicial, pasa al estado de caída // Si alcanza la altura de salto inicial, pasa al estado de caída
setState(s_falling); setState(PlayerState::FALLING);
vy_ = MAX_VY_; vy_ = MAX_VY_;
jumping_counter_ = 0; jumping_counter_ = 0;
} }
@@ -760,46 +639,21 @@ bool Player::checkKillingTiles()
return check; return check;
} }
// Obtiene algunos parametros del jugador // Establece el color del jugador
playerSpawn_t Player::getSpawnParams() 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) if (options.cheats.invincible == Cheat::CheatState::ENABLED)
{ {
color_ = stringToColor(options.video.palette, "cyan"); color_ = stringToColor(options.video.palette, "cyan");
} }
} else if (options.cheats.infinite_lives == Cheat::CheatState::ENABLED)
{
// Establece el valor de la variable color_ = stringToColor(options.video.palette, "yellow");
void Player::setRoom(std::shared_ptr<Room> room) }
{ else
room_ = room; {
color_ = stringToColor(options.video.palette, "white");
}
} }
// Actualiza los puntos de colisión // 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_)}; const SDL_Point p = {static_cast<int>(x_), static_cast<int>(y_)};
under_feet_[0] = {p.x, p.y + h_}; under_feet_[0] = {p.x, p.y + HEIGHT_};
under_feet_[1] = {p.x + 7, p.y + h_}; under_feet_[1] = {p.x + 7, p.y + HEIGHT_};
feet_[0] = {p.x, p.y + h_ - 1}; feet_[0] = {p.x, p.y + HEIGHT_ - 1};
feet_[1] = {p.x + 7, p.y + h_ - 1}; feet_[1] = {p.x + 7, p.y + HEIGHT_ - 1};
} }
// Cambia el estado del jugador // Cambia el estado del jugador
void Player::setState(state_e value) void Player::setState(PlayerState value)
{ {
previous_state_ = state_; previous_state_ = state_;
state_ = value; state_ = value;
@@ -837,20 +691,87 @@ void Player::setState(state_e value)
checkState(); checkState();
} }
// Comprueba si el jugador esta vivo // Inicializa los sonidos de salto y caida
bool Player::isAlive() 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 // Coloca el sprite en la posición del jugador
void Player::pause() void Player::placeSprite()
{ {
is_paused_ = true; sprite_->setPosX(x_);
sprite_->setPosY(y_);
} }
// Quita el modo pausa del jugador // Aplica los valores de spawn al jugador
void Player::resume() 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

View File

@@ -8,7 +8,7 @@
#include "utils.h" // Para color_t #include "utils.h" // Para color_t
#include "defines.h" // Para BLOCK #include "defines.h" // Para BLOCK
#include "room.h" #include "room.h"
class AnimatedSprite; #include "animated_sprite.h"
class Asset; class Asset;
class Debug; class Debug;
class Input; class Input;
@@ -16,43 +16,55 @@ class Resource;
class Room; class Room;
struct JA_Sound_t; struct JA_Sound_t;
enum state_e enum class PlayerState
{ {
s_standing, STANDING,
s_jumping, JUMPING,
s_falling FALLING,
}; };
struct playerSpawn_t struct PlayerSpawn
{ {
float x; float x;
float y; float y;
float vx; float vx;
float vy; float vy;
int jump_init_pos; int jump_init_pos;
state_e state; PlayerState state;
SDL_RendererFlip flip; 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; PlayerSpawn spawn;
std::string png; std::string texture_path;
std::string animation; std::string animations_path;
std::shared_ptr<Room> room; 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 class Player
{ {
public: public:
// Constantes // 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 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 static constexpr float MAX_VY_ = 1.2f; // Velocidad máxima que puede alcanzar al desplazarse en vertical
// Objetos y punteros // Objetos y punteros
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
Input *input_; // Objeto para gestionar la entrada 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 Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos
Debug *debug_; // Objeto para gestionar la información de debug 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<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 y_; // Posición del jugador en el eje Y
float vx_; // Velocidad/desplazamiento del jugador en el eje X float vx_; // Velocidad/desplazamiento del jugador en el eje X
float vy_; // Velocidad/desplazamiento del jugador en el eje Y 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 Color color_; // Color del jugador
SDL_Rect collider_box_; // Caja de colisión con los enemigos u objetos 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> 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> 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 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 PlayerState 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 PlayerState 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 bool is_on_border_ = false; // 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 is_alive_ = true; // Indica si el jugador esta vivo o no
bool auto_movement_; // Indica si esta siendo arrastrado por una superficie automatica bool is_paused_ = false; // Indica si el jugador esta en modo pausa
bool is_paused_; // 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 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 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 *> 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 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 jumping_counter_ = 0; // Cuenta el tiempo de salto
int falling_counter_; // Cuenta el tiempo de caida int falling_counter_ = 0; // Cuenta el tiempo de caida
bool is_alive_; // Indica si el jugador esta vivo o no
#ifdef DEBUG #ifdef DEBUG
SDL_Rect rx; // Rectangulo de desplazamiento para el modo debug SDL_Rect debug_rect_x_; // Rectangulo de desplazamiento para el modo debug
SDL_Rect ry; // Rectangulo de desplazamiento para el modo debug SDL_Rect debug_rect_y_; // Rectangulo de desplazamiento para el modo debug
Color debugColor; // Color del recuadro de debug del jugador Color debug_color_; // Color del recuadro de debug del jugador
SDL_Point debugPoint; // Punto para debug SDL_Point debug_point_; // Punto para debug
#endif #endif
// Comprueba las entradas y modifica variables // Comprueba las entradas y modifica variables
@@ -100,9 +110,6 @@ public:
// Comprueba el estado del jugador // Comprueba el estado del jugador
void checkState(); void checkState();
// Asigna velocidad negativa en el eje Y al jugador
void jump();
// Aplica gravedad al jugador // Aplica gravedad al jugador
void applyGravity(); void applyGravity();
@@ -140,11 +147,28 @@ public:
void updateFeet(); void updateFeet();
// Cambia el estado del jugador // 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: public:
// Constructor // Constructor
Player(player_t player); Player(PlayerData player);
// Destructor // Destructor
~Player() = default; ~Player() = default;
@@ -156,38 +180,38 @@ public:
void update(); void update();
// Indica si el jugador esta en uno de los cuatro bordes de la pantalla // 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 // 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 // Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla
void switchBorders(); void switchBorders();
// Obtiene el rectangulo que delimita al jugador // 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 // Obtiene el rectangulo de colision del jugador
SDL_Rect &getCollider(); SDL_Rect &getCollider() { return collider_box_; }
// Obtiene algunos parametros del jugador // Obtiene el estado de reaparición del jugador
playerSpawn_t getSpawnParams(); PlayerSpawn getSpawnParams() { return {x_, y_, vx_, vy_, jump_init_pos_, state_, sprite_->getFlip()}; }
// Recarga la textura // Recarga la textura
void reLoadTexture(); void reLoadTexture() { sprite_->getTexture()->reLoad(); }
// Recarga la paleta // Establece el color del jugador
void reLoadPalette(); void setColor();
// Establece el valor de la variable // Establece la habitación en la que se encuentra el jugador
void setRoom(std::shared_ptr<Room> room); void setRoom(std::shared_ptr<Room> room) { room_ = room; }
// Comprueba si el jugador esta vivo // Comprueba si el jugador esta vivo
bool isAlive(); bool isAlive() { return is_alive_; }
// Pone el jugador en modo pausa // Pone el jugador en modo pausa
void pause(); void pause() { is_paused_ = true; }
// Quita el modo pausa del jugador // Quita el modo pausa del jugador
void resume(); void resume() { is_paused_ = false; }
}; };

View File

@@ -151,7 +151,7 @@ std::shared_ptr<Text> Resource::getText(const std::string &name)
} }
// Obtiene la animación a partir de un nombre // 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) auto it = std::find_if(animations_.begin(), animations_.end(), [&name](const auto &a)
{ return a.name == name; }); { 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 // 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) auto it = std::find_if(rooms_.begin(), rooms_.end(), [&name](const auto &r)
{ return r.name == name; }); { return r.name == name; });
@@ -304,7 +304,7 @@ void Resource::loadRooms()
for (const auto &l : list) for (const auto &l : list)
{ {
auto name = getFileName(l); 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 ]"); printWithDots("Room : ", name, "[ LOADED ]");
updateLoadingProgress(); updateLoadingProgress();
} }
@@ -440,6 +440,9 @@ void Resource::checkEvents()
void Resource::updateLoadingProgress() void Resource::updateLoadingProgress()
{ {
count_.add(1); count_.add(1);
renderProgress(); if (count_.loaded % 5 == 0 || count_.loaded == count_.total)
{
renderProgress();
}
checkEvents(); checkEvents();
} }

View File

@@ -68,11 +68,11 @@ struct ResourceText
// Estructura para almacenar ficheros animaciones y su nombre // Estructura para almacenar ficheros animaciones y su nombre
struct ResourceAnimation struct ResourceAnimation
{ {
std::string name; // Nombre del fichero std::string name; // Nombre del fichero
AnimationsFileBuffer animation; // Objeto con las animaciones Animations animation; // Objeto con las animaciones
// Constructor // Constructor
ResourceAnimation(const std::string &name, const AnimationsFileBuffer &animation) ResourceAnimation(const std::string &name, const Animations &animation)
: name(name), animation(animation) {} : name(name), animation(animation) {}
}; };
@@ -90,11 +90,11 @@ struct ResourceTileMap
// Estructura para almacenar habitaciones y su nombre // Estructura para almacenar habitaciones y su nombre
struct ResourceRoom struct ResourceRoom
{ {
std::string name; // Nombre de la habitación std::string name; // Nombre de la habitación
std::shared_ptr<room_t> room; // Habitación std::shared_ptr<RoomData> room; // Habitación
// Constructor // 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) {} : name(name), room(room) {}
}; };
@@ -232,13 +232,13 @@ public:
std::shared_ptr<Text> getText(const std::string &name); std::shared_ptr<Text> getText(const std::string &name);
// Obtiene la animación a partir de un nombre // 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 // Obtiene el mapa de tiles a partir de un nombre
std::vector<int> &getTileMap(const std::string &name); std::vector<int> &getTileMap(const std::string &name);
// Obtiene la habitación a partir de un nombre // 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 // Obtiene todas las habitaciones
std::vector<ResourceRoom> &getRooms(); std::vector<ResourceRoom> &getRooms();

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +1,21 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point #include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture #include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture
#include <memory> // for shared_ptr #include <memory> // for shared_ptr
#include <string> // for string #include <string> // for string
#include <vector> // for vector #include <vector> // for vector
#include "enemy.h" // for EnemyData #include "enemy.h" // for EnemyData
#include "item.h" // for item_t #include "item.h" // for item_t
#include "utils.h" // for Color #include "utils.h" // for Color
class Asset; // lines 12-12 #include "scoreboard.h"
class Debug; // lines 13-13 class Asset; // lines 12-12
class Debug; // lines 13-13
class ItemTracker; class ItemTracker;
class Screen; // lines 14-14 class Screen; // lines 14-14
class Sprite; // lines 15-15 class Sprite; // lines 15-15
class Texture; // lines 16-16 class Texture; // lines 16-16
struct JA_Sound_t; // lines 17-17 struct JA_Sound_t; // lines 17-17
enum tile_e enum tile_e
{ {
@@ -30,94 +31,90 @@ enum tile_e
struct aTile_t struct aTile_t
{ {
std::shared_ptr<Sprite> sprite; // Sprite para dibujar el tile 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 number; // Numero de la habitación
std::string name; // Nombre de la habitación std::string name; // Nombre de la habitación
std::string bgColor; // Color de fondo de la habitación std::string bg_color; // Color de fondo de la habitación
std::string borderColor; // Color del borde de la pantalla std::string border_color; // Color del borde de la pantalla
std::string itemColor1; // Color 1 para los items de la habitación std::string item_color1; // Color 1 para los items de la habitación
std::string itemColor2; // Color 2 para los items de la habitación std::string item_color2; // Color 2 para los items de la habitación
std::string roomUp; // Identificador de la habitación que se encuentra arriba std::string room_top; // Identificador de la habitación que se encuentra arriba
std::string roomDown; // Identificador de la habitación que se encuentra abajp std::string room_bottom; // 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 room_left; // 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 room_right; // Identificador de la habitación que se encuentra a la derecha
std::string tileSetFile; // Imagen con los graficos para la habitación std::string tile_set_file; // Imagen con los graficos para la habitación
std::string tileMapFile; // Fichero con el mapa de indices de tile std::string tile_map_file; // Fichero con el mapa de indices de tile
std::vector<int> tileMap; // Indice de los tiles a dibujar en la habitación std::vector<int> tile_map; // 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 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<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::vector<ItemData> items; // Listado con los items que hay en la habitación
std::shared_ptr<Texture> textureA; // Textura con los graficos de la habitación
std::shared_ptr<Texture> textureB; // Textura con los graficos de la habitación
}; };
// Carga las variables desde un fichero de mapa // 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 // 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 // Asigna variables a una estructura RoomData
bool setVars(room_t *room, std::string var, std::string value); bool setRoom(RoomData *room, const std::string &key, const std::string &value);
// Asigna variables a una estructura enemy_t // Asigna variables a una estructura EnemyData
bool setEnemy(EnemyData *enemy, std::string var, std::string value); bool setEnemy(EnemyData *enemy, const std::string &key, const std::string &value);
// Asigna variables a una estructura item_t // Asigna variables a una estructura ItemData
bool setItem(item_t *item, std::string var, std::string value); bool setItem(ItemData *item, const std::string &key, const std::string &value);
class Room class Room
{ {
private: 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 // Objetos y punteros
Screen *screen; // Objeto encargado de dibujar en pantalla Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos
Debug *debug; // Objeto para gestionar la información de debug 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<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::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> texture_; // Textura con los graficos de la habitación
std::shared_ptr<Texture> textureA; // Textura con los graficos de la habitación SDL_Texture *map_texture_; // Textura para dibujar el mapa de la habitación
std::shared_ptr<Texture> textureB; // Textura con los graficos de la habitación std::shared_ptr<ScoreboardData> data_; // Puntero a los datos del marcador
std::shared_ptr<ItemTracker> itemTracker; // Lleva el control de los objetos recogidos
SDL_Texture *mapTexture; // Textura para dibujar el mapa de la habitación
int *itemsPicked; // Puntero a la cantidad de items recogidos que lleva el juego
// Variables // Variables
std::string number; // Numero de la habitación std::string number_; // Numero de la habitación
std::string name; // Nombre de la habitación std::string name_; // Nombre de la habitación
std::string bgColor; // Color de fondo de la habitación std::string bg_color_; // Color de fondo de la habitación
std::string borderColor; // Color del borde de la pantalla std::string border_color_; // Color del borde de la pantalla
std::string itemColor1; // Color 1 para los items de la habitación std::string item_color1_; // Color 1 para los items de la habitación
std::string itemColor2; // Color 2 para los items de la habitación std::string item_color2_; // Color 2 para los items de la habitación
std::string roomUp; // Identificador de la habitación que se encuentra arriba std::string room_top_; // Identificador de la habitación que se encuentra arriba
std::string roomDown; // Identificador de la habitación que se encuentra abajp std::string room_bottom_; // 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 room_left_; // 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 room_right_; // Identificador de la habitación que se encuentra a la derecha
std::string tileSetFile; // Imagen con los graficos para la habitación std::string tile_set_file_; // Imagen con los graficos para la habitación
std::string tileMapFile; // Fichero con el mapa de indices de tile std::string tile_map_file_; // Fichero con el mapa de indices de tile
std::vector<int> tileMap; // Indice de los tiles a dibujar en la habitación std::vector<int> tile_map_; // 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 int auto_surface_direction_; // Sentido en el que arrastran las superficies automáticas de la habitación
JA_Sound_t *itemSound; // Sonido producido al coger un objeto JA_Sound_t *item_sound_; // 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> bottom_surfaces_; // 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<h_line_t> top_surfaces_; // 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> left_surfaces_; // 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<v_line_t> right_surfaces_; // 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> left_slopes_; // 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 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 int counter_; // Contador para lo que haga falta
bool paused; // Indica si el mapa esta en modo pausa bool paused_; // Indica si el mapa esta en modo pausa
std::vector<aTile_t> aTile; // Vector con los indices de tiles animados std::vector<aTile_t> animated_tiles_; // Vector con los indices de tiles animados
std::vector<h_line_t> autoSurfaces; // Lista con las superficies automaticas de la habitación std::vector<h_line_t> auto_surfaces_; // Lista con las superficies automaticas de la habitación
int tileSize; // Ancho del tile en pixels int tile_set_width_; // Ancho del tileset en tiles
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
// Pinta el mapa de la habitación en la textura // Pinta el mapa de la habitación en la textura
void fillMapTexture(); void fillMapTexture();
@@ -160,7 +157,7 @@ private:
public: public:
// Constructor // 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 // Destructor
~Room(); ~Room();

View File

@@ -1,115 +1,97 @@
#include "scoreboard.h" #include "scoreboard.h"
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include "animated_sprite.h" // for AnimatedSprite #include "animated_sprite.h" // for AnimatedSprite
#include "asset.h" // for Asset #include "asset.h" // for Asset
#include "defines.h" // for BLOCK, GAMECANVAS_HEIGHT, PLAY_AREA_HEIGHT #include "defines.h" // for BLOCK, GAMECANVAS_HEIGHT, PLAY_AREA_HEIGHT
#include "options.h" // for Options, options, OptionsVideo, Cheat #include "options.h" // for Options, options, OptionsVideo, Cheat
#include "resource.h" // for Resource #include "resource.h" // for Resource
#include "screen.h" // for Screen #include "screen.h" // for Screen
#include "text.h" // for Text #include "text.h" // for Text
#include "texture.h" // for Texture #include "texture.h" // for Texture
#include <iostream>
// Constructor // Constructor
Scoreboard::Scoreboard(board_t *board) Scoreboard::Scoreboard(std::shared_ptr<ScoreboardData> data)
: renderer(Screen::get()->getRenderer()), : renderer_(Screen::get()->getRenderer()),
resource(Resource::get()), resource_(Resource::get()),
asset(Asset::get()), asset_(Asset::get()),
board(board) data_(data)
{ {
const int TEXTURE_WIDTH_ = options.game.width;
constexpr int TEXTURE_HEIGHT_ = 6 * BLOCK;
// Reserva memoria para los objetos // Reserva memoria para los objetos
itemTexture = resource->getTexture("items.png"); item_texture_ = resource_->getTexture("items.png");
const std::string playerPNG = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png"; auto player_texture = resource_->getTexture(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"; auto player_animations = resource_->getAnimations(options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani");
sprite = std::make_shared<AnimatedSprite>(resource->getTexture(playerPNG), resource->getAnimation(playerANI)); player_sprite_ = std::make_shared<AnimatedSprite>(player_texture, player_animations);
sprite->setCurrentAnimation("walk_menu"); player_sprite_->setCurrentAnimation("walk_menu");
text = resource->getText("smb2"); 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 // Inicializa las variables
counter = 0; counter_ = 0;
colorChangeSpeed = 4; change_color_speed_ = 4;
paused = false; is_paused_ = false;
timePaused = 0; paused_time_ = 0;
totalTimePaused = 0; paused_time_elapsed_ = 0;
itemsColor = stringToColor(options.video.palette, "white"); items_color_ = stringToColor(options.video.palette, "white");
// Inicializa el vector de colores // 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"}; 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) 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 // Pinta el objeto en pantalla
void Scoreboard::render() void Scoreboard::render()
{ {
// Anclas SDL_RenderCopy(renderer_, texture_, nullptr, &texture_dest_);
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"));
} }
// Actualiza las variables del objeto // Actualiza las variables del objeto
void Scoreboard::update() void Scoreboard::update()
{ {
counter++; counter_++;
sprite->update(); player_sprite_->update();
// Actualiza el color de la cantidad de items recogidos // Actualiza el color de la cantidad de items recogidos
updateItemsColor(); updateItemsColor();
if (!paused) // Dibuja la textura
fillTexture();
if (!is_paused_)
{ {
// Si está en pausa no se actualiza el reloj // Si está en pausa no se actualiza el reloj
clock = getTime(); clock_ = getTime();
} }
} }
// Obtiene el tiempo transcurrido de partida // 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.hours = timeElapsed / 3600000;
time.minutes = timeElapsed / 60000; time.minutes = timeElapsed / 60000;
time.seconds = timeElapsed / 1000; time.seconds = timeElapsed / 1000;
@@ -121,10 +103,10 @@ Scoreboard::clock_t Scoreboard::getTime()
// Recarga la textura // Recarga la textura
void Scoreboard::reLoadTexture() void Scoreboard::reLoadTexture()
{ {
sprite->getTexture()->reLoad(); player_sprite_->getTexture()->reLoad();
// playerTexture->reLoad(); // playerTexture->reLoad();
itemTexture->reLoad(); item_texture_->reLoad();
text->reLoadTexture(); text_->reLoadTexture();
} }
// Recarga la paleta // Recarga la paleta
@@ -132,42 +114,42 @@ void Scoreboard::reLoadPalette()
{ {
// Reinicia el vector de colores // 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"}; 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) 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 // Pone el marcador en modo pausa
void Scoreboard::pause() void Scoreboard::pause()
{ {
paused = true; is_paused_ = true;
timePaused = SDL_GetTicks(); paused_time_ = SDL_GetTicks();
} }
// Quita el modo pausa del marcador // Quita el modo pausa del marcador
void Scoreboard::resume() void Scoreboard::resume()
{ {
paused = false; is_paused_ = false;
totalTimePaused += SDL_GetTicks() - timePaused; paused_time_elapsed_ += SDL_GetTicks() - paused_time_;
} }
// Actualiza el color de la cantidad de items recogidos // Actualiza el color de la cantidad de items recogidos
void Scoreboard::updateItemsColor() void Scoreboard::updateItemsColor()
{ {
if (!board->jail_is_open) if (!data_->jail_is_open)
{ {
return; return;
} }
if (counter % 20 < 10) if (counter_ % 20 < 10)
{ {
itemsColor = stringToColor(options.video.palette, "white"); items_color_ = stringToColor(options.video.palette, "white");
} }
else else
{ {
itemsColor = stringToColor(options.video.palette, "magenta"); items_color_ = stringToColor(options.video.palette, "magenta");
} }
} }
@@ -175,4 +157,57 @@ void Scoreboard::updateItemsColor()
int Scoreboard::getMinutes() int Scoreboard::getMinutes()
{ {
return getTime().minutes; 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);
} }

View File

@@ -12,21 +12,25 @@ class Resource;
class Text; class Text;
class Texture; class Texture;
struct board_t struct ScoreboardData
{ {
int items; // Lleva la cuenta de los objetos recogidos int items; // Lleva la cuenta de los objetos recogidos
int lives; // Lleva la cuenta de ls vidas restantes del jugador int lives; // Lleva la cuenta de ls vidas restantes del jugador
int rooms; // Lleva la cuenta de las habitaciones visitadas int rooms; // Lleva la cuenta de las habitaciones visitadas
bool music; // Indica si ha de sonar la musica durante el juego bool music; // Indica si ha de sonar la musica durante el juego
Color color; // Color para escribir el texto del marcador 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 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 class Scoreboard
{ {
private: private:
struct clock_t struct ClockData
{ {
int hours; int hours;
int minutes; int minutes;
@@ -35,36 +39,41 @@ private:
}; };
// Objetos y punteros // Objetos y punteros
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
Resource *resource; // Objeto con los recursos Resource *resource_; // Objeto con los recursos
Asset *asset; // Objeto con la ruta a todos los ficheros de 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<Text> text_; // Objeto para escribir texto
std::shared_ptr<AnimatedSprite> sprite; // Sprite para mostrar las vidas en el marcador std::shared_ptr<AnimatedSprite> player_sprite_; // Sprite para mostrar las vidas en el marcador
std::shared_ptr<Texture> itemTexture; // Textura con los graficos para las vidas std::shared_ptr<Texture> item_texture_; // Textura con los graficos para las vidas
std::shared_ptr<board_t> board; // Contiene las variables a mostrar en el marcador std::shared_ptr<ScoreboardData> data_; // Contiene las variables a mostrar en el marcador
SDL_Texture *texture_; // Textura donde dibujar el marcador;
// Variables // Variables
std::vector<Color> color; // Vector con los colores del objeto std::vector<Color> color_; // Vector con los colores del objeto
int counter; // Contador interno int counter_; // Contador interno
int colorChangeSpeed; // Cuanto mas alto, mas tarda en cambiar de color int change_color_speed_; // Cuanto mas alto, mas tarda en cambiar de color
bool paused; // Indica si el marcador esta en modo pausa bool is_paused_; // Indica si el marcador esta en modo pausa
Uint32 timePaused; // Milisegundos que ha estado el marcador en pausa Uint32 paused_time_; // Milisegundos que ha estado el marcador en pausa
Uint32 totalTimePaused; // Tiempo acumulado en pausa Uint32 paused_time_elapsed_; // Tiempo acumulado en pausa
clock_t clock; // Contiene las horas, minutos y segundos transcurridos desde el inicio de la partida ClockData clock_; // Contiene las horas, minutos y segundos transcurridos desde el inicio de la partida
Color itemsColor; // Color de la cantidad de items recogidos 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 // Obtiene el tiempo transcurrido de partida
clock_t getTime(); ClockData getTime();
// Actualiza el color de la cantidad de items recogidos // Actualiza el color de la cantidad de items recogidos
void updateItemsColor(); void updateItemsColor();
// Dibuja los elementos del marcador en la textura
void fillTexture();
public: public:
// Constructor // Constructor
Scoreboard(board_t *board); Scoreboard(std::shared_ptr<ScoreboardData> data);
// Destructor // Destructor
~Scoreboard() = default; ~Scoreboard();
// Pinta el objeto en pantalla // Pinta el objeto en pantalla
void render(); void render();

View File

@@ -13,6 +13,7 @@
#include "notifier.h" // Para Notify #include "notifier.h" // Para Notify
#include "options.h" #include "options.h"
#include "mouse.h" #include "mouse.h"
//#include "surface.h"
// [SINGLETON] // [SINGLETON]
Screen *Screen::screen_ = nullptr; Screen *Screen::screen_ = nullptr;
@@ -40,50 +41,66 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
: window_(window), : window_(window),
renderer_(renderer) renderer_(renderer)
{ {
game_canvas_width_ = options.game.width; // Ajusta los tamaños
game_canvas_height_ = options.game.height; adjustGameCanvasRect();
notification_logical_width_ = game_canvas_width_; adjustWindowSize();
notification_logical_height_ = game_canvas_height_;
iniFade();
iniSpectrumFade();
// Define el color del borde para el modo de pantalla completa // Define el color del borde para el modo de pantalla completa
border_color_ = {0x00, 0x00, 0x00}; border_color_ = {0x00, 0x00, 0x00};
// Crea la textura donde se dibujan los graficos del juego // Establece el modo de escalado
game_canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, game_canvas_width_, game_canvas_height_); SDL_RenderSetIntegerScale(renderer_, options.video.integer_scale ? SDL_TRUE : SDL_FALSE);
if (game_canvas_ == nullptr)
// 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) 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 // 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); 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_canvas_ == nullptr) if (border_texture_ == nullptr)
{ {
if (options.console) 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_); 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 // Establece el modo de video
setVideoMode(options.video.mode); setVideoMode(options.video.mode);
// Muestra la ventana // Muestra la ventana
SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
show(); show();
} }
// Destructor // Destructor
Screen::~Screen() Screen::~Screen()
{ {
SDL_DestroyTexture(game_canvas_); SDL_DestroyTexture(surface_texture_);
SDL_DestroyTexture(border_canvas_); SDL_DestroyTexture(game_texture_);
SDL_DestroyTexture(border_texture_);
} }
// Limpia la pantalla // Limpia la pantalla
@@ -96,13 +113,14 @@ void Screen::clean(Color color)
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
void Screen::start() 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 // Prepara para empezar a dibujar en la textura del borde
void Screen::startDrawOnBorder() void Screen::startDrawOnBorder()
{ {
SDL_SetRenderTarget(renderer_, border_canvas_); SDL_SetRenderTarget(renderer_, border_texture_);
} }
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
@@ -111,6 +129,10 @@ void Screen::render()
// Renderiza sobre gameCanvas los overlays // Renderiza sobre gameCanvas los overlays
renderNotifications(); 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 // Si está el borde activo, vuelca gameCanvas sobre borderCanvas
if (options.video.border.enabled) if (options.video.border.enabled)
{ {
@@ -121,7 +143,6 @@ void Screen::render()
renderPresent(); renderPresent();
} }
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
void Screen::renderWithoutNotifier() void Screen::renderWithoutNotifier()
{ {
@@ -139,7 +160,6 @@ void Screen::renderWithoutNotifier()
void Screen::setVideoMode(int videoMode) void Screen::setVideoMode(int videoMode)
{ {
// Aplica el modo de video // Aplica el modo de video
SDL_SetWindowFullscreen(window_, videoMode);
// Modo ventana // Modo ventana
if (videoMode == 0) if (videoMode == 0)
@@ -147,79 +167,23 @@ void Screen::setVideoMode(int videoMode)
// Muestra el puntero // Muestra el puntero
SDL_ShowCursor(SDL_ENABLE); SDL_ShowCursor(SDL_ENABLE);
// Modifica el tamaño de la ventana en función del borde SDL_SetWindowFullscreen(window_, videoMode);
if (options.video.border.enabled) adjustWindowSize();
{ adjustGameCanvasRect();
window_width_ = game_canvas_width_ + options.video.border.width * 2; adjustRenderLogicalSize();
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_};
}
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 // Modo pantalla completa
else if (videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP) else
{ {
// Oculta el puntero // Oculta el puntero
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
adjustWindowSize();
// Obten el alto y el ancho de la ventana adjustGameCanvasRect();
SDL_GetWindowSize(window_, &window_width_, &window_height_); SDL_SetWindowFullscreen(window_, videoMode);
// 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++;
}
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 // Actualiza las opciones
options.video.mode = videoMode; options.video.mode = videoMode;
@@ -232,11 +196,11 @@ void Screen::setVideoMode(int videoMode)
if (options.video.border.enabled) if (options.video.border.enabled)
{ {
shader::init(window_, border_canvas_, source.c_str()); shader::init(window_, border_texture_, source.c_str());
} }
else 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); 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 // Reduce el tamaño de la ventana
void Screen::decWindowZoom() bool Screen::decWindowZoom()
{ {
--options.window.zoom; if (options.video.mode == 0)
options.window.zoom = std::max(options.window.zoom, 1); {
setVideoMode(0); int previous_zoom = options.window.zoom;
--options.window.zoom;
options.window.zoom = std::max(options.window.zoom, 1);
if (options.window.zoom != previous_zoom)
{
adjustWindowSize();
return true;
}
}
return false;
} }
// Aumenta el tamaño de la ventana // Aumenta el tamaño de la ventana
void Screen::incWindowZoom() bool Screen::incWindowZoom()
{ {
++options.window.zoom; if (options.video.mode == 0)
options.window.zoom = std::min(options.window.zoom, 4); {
setVideoMode(0); int previous_zoom = options.window.zoom;
++options.window.zoom;
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 // Cambia el color del borde
@@ -276,7 +255,7 @@ void Screen::setBorderColor(Color color)
{ {
border_color_ = color; border_color_ = color;
auto temp = SDL_GetRenderTarget(renderer_); 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_SetRenderDrawColor(renderer_, border_color_.r, border_color_.g, border_color_.b, 0xFF);
SDL_RenderClear(renderer_); SDL_RenderClear(renderer_);
SDL_SetRenderTarget(renderer_, temp); SDL_SetRenderTarget(renderer_, temp);
@@ -307,139 +286,9 @@ void Screen::setBorderEnabled(bool value) { options.video.border.enabled = value
void Screen::toggleBorder() void Screen::toggleBorder()
{ {
options.video.border.enabled = !options.video.border.enabled; options.video.border.enabled = !options.video.border.enabled;
setVideoMode(0); adjustWindowSize();
} adjustGameCanvasRect();
adjustRenderLogicalSize();
// 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();
} }
// Dibuja las notificaciones // Dibuja las notificaciones
@@ -452,10 +301,8 @@ void Screen::renderNotifications()
void Screen::gameCanvasToBorderCanvas() void Screen::gameCanvasToBorderCanvas()
{ {
auto temp = SDL_GetRenderTarget(renderer_); 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_RenderCopy(renderer_, game_texture_, nullptr, &game_texture_rect_);
SDL_RenderClear(renderer_);
SDL_RenderCopy(renderer_, game_canvas_, nullptr, &dest_);
SDL_SetRenderTarget(renderer_, temp); SDL_SetRenderTarget(renderer_, temp);
} }
@@ -463,7 +310,7 @@ void Screen::gameCanvasToBorderCanvas()
void Screen::renderPresent() void Screen::renderPresent()
{ {
SDL_SetRenderTarget(renderer_, nullptr); 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_); SDL_RenderClear(renderer_);
if (options.video.shaders) if (options.video.shaders)
@@ -475,11 +322,11 @@ void Screen::renderPresent()
{ {
if (options.video.border.enabled) if (options.video.border.enabled)
{ {
SDL_RenderCopy(renderer_, border_canvas_, nullptr, nullptr); SDL_RenderCopy(renderer_, border_texture_, nullptr, nullptr);
} }
else else
{ {
SDL_RenderCopy(renderer_, game_canvas_, nullptr, &dest_); SDL_RenderCopy(renderer_, game_texture_, nullptr, &game_texture_rect_);
} }
SDL_RenderPresent(renderer_); SDL_RenderPresent(renderer_);
} }
@@ -509,4 +356,72 @@ void Screen::show()
void Screen::hide() void Screen::hide()
{ {
SDL_HideWindow(window_); 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_);
} }

View File

@@ -6,7 +6,9 @@
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <SDL2/SDL_video.h> // for SDL_Window #include <SDL2/SDL_video.h> // for SDL_Window
#include <vector> // for vector #include <vector> // for vector
#include <memory> // for shared_ptr
#include "utils.h" // for Color #include "utils.h" // for Color
//#include "surface.h"
// Tipos de filtro // Tipos de filtro
enum class ScreenFilter : Uint32 enum class ScreenFilter : Uint32
@@ -18,51 +20,25 @@ enum class ScreenFilter : Uint32
class Screen class Screen
{ {
private: private:
// Constantes
static constexpr int WINDOWS_DECORATIONS_ = 35;
// [SINGLETON] Objeto privado // [SINGLETON] Objeto privado
static Screen *screen_; static Screen *screen_;
// Objetos y punteros // Objetos y punteros
SDL_Window *window_; // Ventana de la aplicación SDL_Window *window_; // Ventana de la aplicación
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
SDL_Texture *game_canvas_; // Textura donde se dibuja el juego SDL_Texture *surface_texture_; // Textura donde se dibuja el juego
SDL_Texture *border_canvas_; // Textura donde se dibuja el borde del 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 // Variables
int window_width_; // Ancho de la pantalla o ventana int window_width_; // Ancho de la pantalla o ventana
int window_height_; // Alto 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 SDL_Rect game_texture_rect_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
int game_canvas_height_; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego Color border_color_; // Color del borde añadido a la textura de juego para rellenar la pantalla
SDL_Rect dest_; // 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 // Dibuja las notificaciones
void renderNotifications(); void renderNotifications();
@@ -73,6 +49,18 @@ private:
// Muestra el contenido de Screen por pantalla // Muestra el contenido de Screen por pantalla
void renderPresent(); 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 // Constructor
Screen(SDL_Window *window, SDL_Renderer *renderer); Screen(SDL_Window *window, SDL_Renderer *renderer);
@@ -111,14 +99,11 @@ public:
// Camibia entre pantalla completa y ventana // Camibia entre pantalla completa y ventana
void toggleVideoMode(); void toggleVideoMode();
// Cambia el tamaño de la ventana
void setWindowZoom(int size);
// Reduce el tamaño de la ventana // Reduce el tamaño de la ventana
void decWindowZoom(); bool decWindowZoom();
// Aumenta el tamaño de la ventana // Aumenta el tamaño de la ventana
void incWindowZoom(); bool incWindowZoom();
// Cambia el color del borde // Cambia el color del borde
void setBorderColor(Color color); void setBorderColor(Color color);
@@ -136,24 +121,6 @@ public:
// Cambia entre borde visible y no visible // Cambia entre borde visible y no visible
void toggleBorder(); 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 // Cambia el estado de los shaders
void toggleShaders(); void toggleShaders();
@@ -163,6 +130,12 @@ public:
// Oculta la ventana // Oculta la ventana
void hide(); void hide();
// Obtiene el tamaño máximo de zoom posible para la ventana
int getMaxZoom();
// Getters // Getters
SDL_Renderer *getRenderer() { return renderer_; } 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
View 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
View 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_; }
};

View File

@@ -52,7 +52,7 @@ Texture::Texture(SDL_Renderer *renderer, const std::string &path)
Texture::~Texture() Texture::~Texture()
{ {
unloadTexture(); unloadTexture();
//unloadSurface(); // unloadSurface();
palettes_.clear(); palettes_.clear();
} }

View File

@@ -11,7 +11,7 @@
struct Color; struct Color;
// Definiciones de tipos // Definiciones de tipos
struct Surface /*struct Surface
{ {
std::shared_ptr<Uint8[]> data; std::shared_ptr<Uint8[]> data;
Uint16 w, h; Uint16 w, h;
@@ -19,7 +19,7 @@ struct Surface
// Constructor // Constructor
Surface(Uint16 width, Uint16 height, std::shared_ptr<Uint8[]> pixels) Surface(Uint16 width, Uint16 height, std::shared_ptr<Uint8[]> pixels)
: data(pixels), w(width), h(height) {} : data(pixels), w(width), h(height) {}
}; };*/
class Texture class Texture
{ {
@@ -27,7 +27,7 @@ private:
// Objetos y punteros // Objetos y punteros
SDL_Renderer *renderer_; // Renderizador donde dibujar la textura SDL_Renderer *renderer_; // Renderizador donde dibujar la textura
SDL_Texture *texture_ = nullptr; // 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 // Variables
std::string path_; // Ruta de la imagen de la textura std::string path_; // Ruta de la imagen de la textura
@@ -37,19 +37,19 @@ private:
int current_palette_ = 0; // Indice de la paleta en uso int current_palette_ = 0; // Indice de la paleta en uso
// Crea una surface desde un fichero .gif // Crea una surface desde un fichero .gif
//std::shared_ptr<Surface> loadSurface(const std::string &file_name); // std::shared_ptr<Surface> loadSurface(const std::string &file_name);
// Vuelca la surface en la textura // Vuelca la surface en la textura
//void flipSurface(); // void flipSurface();
// Carga una paleta desde un fichero // Carga una paleta desde un fichero
//std::vector<Uint32> loadPaletteFromFile(const std::string &file_name); // std::vector<Uint32> loadPaletteFromFile(const std::string &file_name);
// Libera la memoria de la textura // Libera la memoria de la textura
void unloadTexture(); void unloadTexture();
// Desencadenar la superficie actual // Desencadenar la superficie actual
//void unloadSurface(); // void unloadSurface();
public: public:
// Constructor // Constructor
@@ -93,13 +93,13 @@ public:
SDL_Texture *getSDLTexture(); SDL_Texture *getSDLTexture();
// Añade una paleta a la lista // Añade una paleta a la lista
//void addPaletteFromFile(const std::string &path); // void addPaletteFromFile(const std::string &path);
// Establece un color de la paleta // Establece un color de la paleta
//void setPaletteColor(int palette, int index, Uint32 color); // void setPaletteColor(int palette, int index, Uint32 color);
// Cambia la paleta de la textura // Cambia la paleta de la textura
//void setPalette(int palette); // void setPalette(int palette);
// Obtiene el renderizador // Obtiene el renderizador
SDL_Renderer *getRenderer(); SDL_Renderer *getRenderer();

View File

@@ -1,24 +1,25 @@
#include "title.h" #include "title.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_error.h> // for SDL_GetError #include <SDL2/SDL_error.h> // for SDL_GetError
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event, SDL_KEYDOWN #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event, SDL_KEYDOWN
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_scancode.h> // for SDL_SCANCODE_1, SDL_SCANCODE_2 #include <SDL2/SDL_scancode.h> // for SDL_SCANCODE_1, SDL_SCANCODE_2
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <iostream> // for basic_ostream, operator<<, cout, endl #include <iostream> // for basic_ostream, operator<<, cout, endl
#include "asset.h" // for Asset #include "asset.h" // for Asset
#include "cheevos.h" // for Achievement, Cheevos #include "cheevos.h" // for Achievement, Cheevos
#include "defines.h" // for PLAY_AREA_CENTER_X, GAMECANVAS_WIDTH #include "defines.h" // for PLAY_AREA_CENTER_X, GAMECANVAS_WIDTH
#include "global_events.h" // for check #include "global_events.h" // for check
#include "global_inputs.h" // for check #include "global_inputs.h" // for check
#include "input.h" // for Input, inputs_e, REPEAT_FALSE, REPEA... #include "input.h" // for Input, inputs_e, REPEAT_FALSE, REPEA...
#include "options.h" // for Options, options, OptionsVideo, Sect... #include "options.h" // for Options, options, OptionsVideo, Sect...
#include "resource.h" // for Resource #include "resource.h" // for Resource
#include "screen.h" // for Screen #include "screen.h" // for Screen
#include "sprite.h" // for Sprite #include "sprite.h" // for Sprite
#include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR #include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR
#include "texture.h" // for Texture #include "texture.h" // for Texture
#include "utils.h" // for Color, stringToColor, Palette #include "utils.h" // for Color, stringToColor, Palette
#include "paleta.h"
// Constructor // Constructor
Title::Title() Title::Title()
@@ -71,6 +72,9 @@ Title::Title()
// Rellena la textura de fondo con todos los gráficos // Rellena la textura de fondo con todos los gráficos
fillTexture(); fillTexture();
// Inicia la musica
playMusic("title.ogg");
} }
// Destructor // Destructor
@@ -213,7 +217,7 @@ void Title::renderInfo()
void Title::update() void Title::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // 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 // Actualiza el contador de ticks
ticks_ = SDL_GetTicks(); ticks_ = SDL_GetTicks();

View File

@@ -1,18 +1,18 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture #include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr #include <memory> // for shared_ptr
#include <string> // for string #include <string> // for string
#include <vector> // for vector #include <vector> // for vector
#include "paleta.h" // for jSurface #include "paleta.h" // for jSurface
class Input; // lines 13-13 class Input; // lines 13-13
class Resource; // lines 14-14 class Resource; // lines 14-14
class Screen; // lines 15-15 class Screen; // lines 15-15
class Sprite; // lines 16-16 class Sprite; // lines 16-16
class Text; // lines 17-17 class Text; // lines 17-17
class Texture; // lines 18-18 class Texture; // lines 18-18
class Title class Title
{ {
@@ -32,13 +32,13 @@ private:
}; };
// Objetos y punteros // Objetos y punteros
Screen *screen_; // Objeto encargado de dibujar en pantalla Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
Resource *resource_; // Objeto con los recursos Resource *resource_; // Objeto con los recursos
Input *input_; // Objeto pata gestionar la entrada Input *input_; // Objeto pata gestionar la entrada
std::shared_ptr<Texture> texture_; // Textura con los graficos std::shared_ptr<Texture> texture_; // Textura con los graficos
std::shared_ptr<Sprite> sprite_; // Sprite para manejar la textura std::shared_ptr<Sprite> sprite_; // Sprite para manejar la textura
SDL_Texture *bg_texture_; // Textura para dibujar el fondo de la pantalla SDL_Texture *bg_texture_; // Textura para dibujar el fondo de la pantalla
std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
std::shared_ptr<Text> info_text_; // Objeto para escribir texto en pantalla std::shared_ptr<Text> info_text_; // Objeto para escribir texto en pantalla
std::shared_ptr<Texture> cheevos_texture_; // Textura con la lista de logros std::shared_ptr<Texture> cheevos_texture_; // Textura con la lista de logros
@@ -48,13 +48,12 @@ private:
int counter_ = 0; // Contador int counter_ = 0; // Contador
std::string long_text_; // Texto que aparece en la parte inferior del titulo 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_ = 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 std::vector<letter_t> letters_; // Vector con las letras de la marquesina
int marquee_speed_ = 3; // Velocidad de desplazamiento 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 bool show_cheevos_ = false; // Indica si se muestra por pantalla el listado de logros
SDL_Rect cheevos_texture_view_; // Zona visible de la textura con el listado de logros SDL_Rect cheevos_texture_view_; // Zona visible de la textura con el listado de logros
states_e state_; // Estado en el que se encuentra el bucle principal states_e state_; // Estado en el que se encuentra el bucle principal
jSurface loading_screen_; // Surface con los gráficos de la pantalla de carga jSurface loading_screen_; // Surface con los gráficos de la pantalla de carga
// Actualiza las variables // Actualiza las variables
void update(); void update();

View File

@@ -8,6 +8,8 @@
#include <iostream> // for basic_ostream, cout, basic_ios, ios, endl #include <iostream> // for basic_ostream, cout, basic_ios, ios, endl
#include <unordered_map> // for unordered_map #include <unordered_map> // for unordered_map
#include <string> // for string #include <string> // for string
#include "jail_audio.h"
#include "resource.h"
// Calcula el cuadrado de la distancia entre dos puntos // Calcula el cuadrado de la distancia entre dos puntos
double distanceSquared(int x1, int y1, int x2, int y2) double distanceSquared(int x1, int y1, int x2, int y2)
@@ -518,4 +520,39 @@ void printWithDots(const std::string &text1, const std::string &text2, const std
std::cout << text2; std::cout << text2;
std::cout << text3 << std::endl; 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);
}

View File

@@ -3,6 +3,10 @@
#include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point #include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point
#include <SDL2/SDL_stdinc.h> // for Uint8 #include <SDL2/SDL_stdinc.h> // for Uint8
#include <string> // for string #include <string> // for string
#include <vector>
#include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL.h> // for SDL_Texture
// Tipos de paleta // Tipos de paleta
enum class Palette : int enum class Palette : int
@@ -122,4 +126,13 @@ std::string getFileName(const std::string &path);
std::string getPath(const std::string &full_path); std::string getPath(const std::string &full_path);
// Imprime por pantalla una linea de texto de tamaño fijo rellena con puntos // 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); 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);