5 Commits

50 changed files with 734 additions and 1095 deletions

View File

@@ -2,7 +2,7 @@ executable = jaildoctors_dilemma
source = source/*.cpp
appName = JailDoctor's Dilemma
releaseFolder = jdd_release
version = v1.09
version = v1.10
# Release names
windowsRelease = $(executable)-$(version)-win32-x64.zip
@@ -90,7 +90,7 @@ macos_release:
ln -s /Applications "$(releaseFolder)"/Applications
# Build INTEL
clang++ $(source) -D MACOS_BUNDLE -std=$(cpp_standard) -Wall -Os -framework SDL2 -F ./Frameworks -framework OpenGL -Wno-deprecated -ffunction-sections -fdata-sections -o "$(releaseFolder)/$(appName).app/Contents/MacOS/$(executable)" -rpath @executable_path/../Frameworks/ -target x86_64-apple-macos10.12
clang++ $(source) -D MACOS_BUNDLE -std=$(cpp_standard) -Wall -Os -framework SDL2 -F ./Frameworks -framework OpenGL -Wno-deprecated -ffunction-sections -fdata-sections -o "$(releaseFolder)/$(appName).app/Contents/MacOS/$(executable)" -rpath @executable_path/../Frameworks/ -target x86_64-apple-macos10.15
# Build INTEL DMG
hdiutil create tmp.dmg -ov -volname "$(appName)" -fs HFS+ -srcfolder "$(releaseFolder)"

View File

@@ -23,11 +23,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.09</string>
<string>1.10</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.09</string>
<string>1.10</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>LSMinimumSystemVersion</key>

View File

@@ -187,7 +187,7 @@ void Cheevos::saveToFile()
int Cheevos::unlocked()
{
int count = 0;
for (auto cheevo : cheevos_list_)
for (const auto &cheevo : cheevos_list_)
{
if (cheevo.completed)
{

View File

@@ -45,7 +45,7 @@ private:
void saveToFile();
// Constructor
Cheevos(const std::string &file);
explicit Cheevos(const std::string &file);
// Destructor
~Cheevos();
@@ -76,5 +76,5 @@ public:
int unlocked();
// Devuelve el número total de logros
int count() { return cheevos_list_.size(); }
int size() { return cheevos_list_.size(); }
};

View File

@@ -90,21 +90,24 @@ void Credits::checkInput()
// Inicializa los textos
void Credits::iniTexts()
{
#ifndef GAME_CONSOLE
std::string keys = "";
if (options.keys == ControlScheme::CURSOR)
switch (options.keys)
{
case ControlScheme::CURSOR:
keys = "CURSORS";
}
else if (options.keys == ControlScheme::OPQA)
{
break;
case ControlScheme::OPQA:
keys = "O,P AND Q";
}
else
{
break;
case ControlScheme::WASD:
keys = "A,D AND W";
break;
default:
break;
}
#ifndef GAME_CONSOLE
texts_.clear();
texts_.push_back({"", stringToColor(options.video.palette, "white")});
texts_.push_back({"INSTRUCTIONS:", stringToColor(options.video.palette, "yellow")});
@@ -173,37 +176,37 @@ void Credits::fillTexture()
// Rellena la textura de texto
SDL_SetRenderTarget(renderer_, text_texture_);
Color c = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF);
Color color = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
SDL_RenderClear(renderer_);
// Escribe el texto en la textura
const int size = text_->getCharacterSize();
int i = 0;
const int SIZE = text_->getCharacterSize();
int pos_y = 0;
for (auto t : texts_)
for (const auto &t : texts_)
{
text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, i * size, t.label, 1, t.color);
i++;
text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, pos_y * SIZE, t.label, 1, t.color);
pos_y++;
}
// Escribe el corazón
const int textLenght = text_->lenght(texts_[22].label, 1) - text_->lenght(" ", 1); // Se resta el ultimo caracter que es un espacio
const int posX = ((PLAY_AREA_WIDTH - textLenght) / 2) + textLenght;
text_->writeColored(posX, 176, "}", stringToColor(options.video.palette, "bright_red"));
const int TEXT_LENGHT = text_->lenght(texts_[22].label, 1) - text_->lenght(" ", 1); // Se resta el ultimo caracter que es un espacio
const int POS_X = ((PLAY_AREA_WIDTH - TEXT_LENGHT) / 2) + TEXT_LENGHT;
text_->writeColored(POS_X, 176, "}", stringToColor(options.video.palette, "bright_red"));
// Recoloca el sprite del brillo
sprite_->setPosX(posX + 2);
sprite_->setPosX(POS_X + 2);
SDL_SetRenderTarget(renderer_, nullptr);
// Rellena la textura que cubre el texto con color transparente
SDL_SetRenderTarget(renderer_, cover_texture_);
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0x00);
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0x00);
SDL_RenderClear(renderer_);
// Los primeros 8 pixels crea una malla
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF);
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
for (int i = 0; i < 256; i += 2)
{
SDL_RenderDrawPoint(renderer_, i, 0);
@@ -314,10 +317,3 @@ void Credits::run()
render();
}
}
// Cambia la paleta
void Credits::switchPalette()
{
options.video.palette = options.video.palette == Palette::ZXSPECTRUM ? Palette::ZXARNE : Palette::ZXSPECTRUM;
fillTexture();
}

View File

@@ -16,7 +16,7 @@ class Text; // lines 15-15
class Credits
{
private:
struct captions_t
struct Captions
{
std::string label; // Texto a escribir
Color color; // Color del texto
@@ -38,7 +38,7 @@ private:
bool counter_enabled_ = true; // Indica si esta activo el contador
int sub_counter_ = 0; // Contador secundario
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
std::vector<captions_t> texts_; // Vector con los textos
std::vector<Captions> texts_; // Vector con los textos
// Actualiza las variables
void update();
@@ -61,9 +61,6 @@ private:
// Escribe el texto en la textura
void fillTexture();
// Cambia la paleta
void switchPalette();
public:
// Constructor
Credits();

View File

@@ -28,19 +28,9 @@ Debug *Debug::get()
// Constructor
Debug::Debug()
// Copia la dirección de los objetos
: screen_(Screen::get()),
renderer_(Screen::get()->getRenderer())
{
// Reserva memoria para los punteros
texture_ = Resource::get()->getTexture("debug.png");
text_ = Resource::get()->getText("debug");
}
// Actualiza las variables
void Debug::update()
{
}
renderer_(Screen::get()->getRenderer()),
text_(Resource::get()->getText("debug")) {}
// Dibuja en pantalla
void Debug::render()
@@ -48,7 +38,7 @@ void Debug::render()
int y = y_;
int w = 0;
for (auto s : slot_)
for (const auto &s : slot_)
{
text_->write(x_, y, s);
w = (std::max(w, (int)s.length()));
@@ -61,7 +51,7 @@ void Debug::render()
}
y = 0;
for (auto l : log_)
for (const auto &l : log_)
{
text_->writeColored(x_ + 10, y, l, Color(255, 255, 255));
y += text_->getCharacterSize() + 1;

View File

@@ -20,7 +20,6 @@ private:
Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer_; // El renderizador de la ventana
std::shared_ptr<Text> text_; // Objeto encargado de escribir texto en pantalla
std::shared_ptr<Texture> texture_; // Textura para el texto
// Variables
std::vector<std::string> slot_; // Vector con los textos a escribir
@@ -45,9 +44,6 @@ public:
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
static Debug *get();
// Actualiza las variables
void update();
// Dibuja en pantalla
void render();

View File

@@ -7,7 +7,7 @@
// Textos
constexpr const char *WINDOW_CAPTION = "JailDoctor's Dilemma";
constexpr const char *TEXT_COPYRIGHT = "@2022 JailDesigner";
constexpr const char *VERSION = "1.09";
constexpr const char *VERSION = "1.10";
// Velocidad del juego
constexpr Uint32 GAME_SPEED = 1000 / 60;

View File

@@ -24,10 +24,10 @@ Demo::Demo()
resource_(Resource::get()),
asset_(Asset::get()),
input_(Input::get()),
debug_(Debug::get())
debug_(Debug::get()),
board_(std::make_shared<ScoreboardData>())
{
// Inicia algunas variables
board_ = std::make_shared<ScoreboardData>();
board_->ini_clock = SDL_GetTicks();
rooms_.push_back("04.room");
rooms_.push_back("54.room");
@@ -44,7 +44,7 @@ Demo::Demo()
// Crea los objetos
ItemTracker::init();
scoreboard_ = std::make_shared<Scoreboard>(board_);
room_ = std::make_shared<Room>(resource_->getRoom(current_room_), board_);
room_ = std::make_shared<Room>(current_room_, board_);
text_ = resource_->getText("smb2");
// Inicializa el resto de variables
@@ -145,49 +145,17 @@ void Demo::renderRoomName()
text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, 16 * 8 + 4, room_->getName(), 1, room_->getBGColor());
}
// Recarga todas las texturas
void Demo::reLoadTextures()
{
if (options.console)
{
std::cout << "** RELOAD REQUESTED" << std::endl;
}
room_->reLoadTexture();
scoreboard_->reLoadTexture();
text_->reLoadTexture();
}
// Cambia la paleta
void Demo::switchPalette()
{
// Modifica la variable
if (options.video.palette == Palette::ZXSPECTRUM)
{
options.video.palette = Palette::ZXARNE;
}
else
{
options.video.palette = Palette::ZXSPECTRUM;
}
room_->reLoadPalette();
scoreboard_->reLoadPalette();
// Pone el color del marcador en función del color del borde de la habitación
setScoreBoardColor();
}
// Cambia de habitación
bool Demo::changeRoom(std::string file)
bool Demo::changeRoom(const std::string &room_path)
{
// En las habitaciones los limites tienen la cadena del fichero o un 0 en caso de no limitar con nada
if (file != "0")
if (room_path != "0")
{
// Verifica que exista el fichero que se va a cargar
if (asset_->get(file) != "")
if (asset_->get(room_path) != "")
{
// Crea un objeto habitación a partir del fichero
room_ = std::make_shared<Room>(resource_->getRoom(file), board_);
room_ = std::make_shared<Room>(room_path, board_);
// Pone el color del marcador en función del color del borde de la habitación
setScoreBoardColor();

View File

@@ -53,14 +53,8 @@ private:
// Escribe el nombre de la pantalla
void renderRoomName();
// Recarga todas las texturas
void reLoadTextures();
// Cambia la paleta
void switchPalette();
// Cambia de habitación
bool changeRoom(std::string file);
bool changeRoom(const std::string &file);
// Comprueba si se ha de cambiar de habitación
void checkRoomChange();

View File

@@ -217,60 +217,60 @@ void Director::initInput()
// Teclado - Movimiento
if (options.keys == ControlScheme::CURSOR)
{
Input::get()->bindKey(input_jump, SDL_SCANCODE_UP);
Input::get()->bindKey(input_left, SDL_SCANCODE_LEFT);
Input::get()->bindKey(input_right, SDL_SCANCODE_RIGHT);
Input::get()->bindKey(input_up, SDL_SCANCODE_UP);
Input::get()->bindKey(input_down, SDL_SCANCODE_DOWN);
Input::get()->bindKey(InputAction::JUMP, SDL_SCANCODE_UP);
Input::get()->bindKey(InputAction::LEFT, SDL_SCANCODE_LEFT);
Input::get()->bindKey(InputAction::RIGHT, SDL_SCANCODE_RIGHT);
Input::get()->bindKey(InputAction::UP, SDL_SCANCODE_UP);
Input::get()->bindKey(InputAction::DOWN, SDL_SCANCODE_DOWN);
}
else if (options.keys == ControlScheme::OPQA)
{
Input::get()->bindKey(input_jump, SDL_SCANCODE_Q);
Input::get()->bindKey(input_left, SDL_SCANCODE_O);
Input::get()->bindKey(input_right, SDL_SCANCODE_P);
Input::get()->bindKey(input_up, SDL_SCANCODE_Q);
Input::get()->bindKey(input_down, SDL_SCANCODE_A);
Input::get()->bindKey(InputAction::JUMP, SDL_SCANCODE_Q);
Input::get()->bindKey(InputAction::LEFT, SDL_SCANCODE_O);
Input::get()->bindKey(InputAction::RIGHT, SDL_SCANCODE_P);
Input::get()->bindKey(InputAction::UP, SDL_SCANCODE_Q);
Input::get()->bindKey(InputAction::DOWN, SDL_SCANCODE_A);
}
else if (options.keys == ControlScheme::WASD)
{
Input::get()->bindKey(input_jump, SDL_SCANCODE_W);
Input::get()->bindKey(input_left, SDL_SCANCODE_A);
Input::get()->bindKey(input_right, SDL_SCANCODE_D);
Input::get()->bindKey(input_up, SDL_SCANCODE_W);
Input::get()->bindKey(input_down, SDL_SCANCODE_S);
Input::get()->bindKey(InputAction::JUMP, SDL_SCANCODE_W);
Input::get()->bindKey(InputAction::LEFT, SDL_SCANCODE_A);
Input::get()->bindKey(InputAction::RIGHT, SDL_SCANCODE_D);
Input::get()->bindKey(InputAction::UP, SDL_SCANCODE_W);
Input::get()->bindKey(InputAction::DOWN, SDL_SCANCODE_S);
}
// Teclado - Otros
Input::get()->bindKey(input_accept, SDL_SCANCODE_RETURN);
Input::get()->bindKey(input_cancel, SDL_SCANCODE_ESCAPE);
Input::get()->bindKey(input_pause, SDL_SCANCODE_H);
Input::get()->bindKey(input_exit, SDL_SCANCODE_ESCAPE);
Input::get()->bindKey(input_window_dec_size, SDL_SCANCODE_F1);
Input::get()->bindKey(input_window_inc_size, SDL_SCANCODE_F2);
Input::get()->bindKey(input_toggle_videomode, SDL_SCANCODE_F3);
Input::get()->bindKey(input_toggle_shaders, SDL_SCANCODE_F4);
Input::get()->bindKey(input_toggle_palette, SDL_SCANCODE_F5);
Input::get()->bindKey(input_toggle_music, SDL_SCANCODE_M);
Input::get()->bindKey(input_toggle_border, SDL_SCANCODE_B);
Input::get()->bindKey(InputAction::ACCEPT, SDL_SCANCODE_RETURN);
Input::get()->bindKey(InputAction::CANCEL, SDL_SCANCODE_ESCAPE);
Input::get()->bindKey(InputAction::PAUSE, SDL_SCANCODE_H);
Input::get()->bindKey(InputAction::EXIT, SDL_SCANCODE_ESCAPE);
Input::get()->bindKey(InputAction::WINDOW_DEC_ZOOM, SDL_SCANCODE_F1);
Input::get()->bindKey(InputAction::WINDOW_INC_ZOOM, SDL_SCANCODE_F2);
Input::get()->bindKey(InputAction::TOGGLE_VIDEOMODE, SDL_SCANCODE_F3);
Input::get()->bindKey(InputAction::TOGGLE_SHADERS, SDL_SCANCODE_F4);
Input::get()->bindKey(InputAction::TOGGLE_PALETTE, SDL_SCANCODE_F5);
Input::get()->bindKey(InputAction::TOGGLE_MUSIC, SDL_SCANCODE_M);
Input::get()->bindKey(InputAction::TOGGLE_BORDER, SDL_SCANCODE_B);
// Mando - Movimiento
Input::get()->bindGameControllerButton(input_jump, SDL_CONTROLLER_BUTTON_B);
Input::get()->bindGameControllerButton(input_left, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
Input::get()->bindGameControllerButton(input_right, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
Input::get()->bindGameControllerButton(InputAction::JUMP, SDL_CONTROLLER_BUTTON_B);
Input::get()->bindGameControllerButton(InputAction::LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
Input::get()->bindGameControllerButton(InputAction::RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
// Mando - Otros
Input::get()->bindGameControllerButton(input_accept, SDL_CONTROLLER_BUTTON_B);
Input::get()->bindGameControllerButton(input_cancel, SDL_CONTROLLER_BUTTON_A);
Input::get()->bindGameControllerButton(InputAction::ACCEPT, SDL_CONTROLLER_BUTTON_B);
Input::get()->bindGameControllerButton(InputAction::CANCEL, SDL_CONTROLLER_BUTTON_A);
#ifdef GAME_CONSOLE
Input::get()->bindGameControllerButton(input_pause, SDL_CONTROLLER_BUTTON_BACK);
Input::get()->bindGameControllerButton(input_exit, SDL_CONTROLLER_BUTTON_START);
Input::get()->bindGameControllerButton(InputAction::input_pause, SDL_CONTROLLER_BUTTON_BACK);
Input::get()->bindGameControllerButton(InputAction::input_exit, SDL_CONTROLLER_BUTTON_START);
#else
Input::get()->bindGameControllerButton(input_pause, SDL_CONTROLLER_BUTTON_START);
Input::get()->bindGameControllerButton(input_exit, SDL_CONTROLLER_BUTTON_BACK);
Input::get()->bindGameControllerButton(InputAction::PAUSE, SDL_CONTROLLER_BUTTON_START);
Input::get()->bindGameControllerButton(InputAction::EXIT, SDL_CONTROLLER_BUTTON_BACK);
#endif
Input::get()->bindGameControllerButton(input_toggle_palette, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
Input::get()->bindGameControllerButton(input_toggle_music, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
Input::get()->bindGameControllerButton(input_toggle_border, SDL_CONTROLLER_BUTTON_X);
Input::get()->bindGameControllerButton(InputAction::TOGGLE_PALETTE, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
Input::get()->bindGameControllerButton(InputAction::TOGGLE_MUSIC, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
Input::get()->bindGameControllerButton(InputAction::TOGGLE_BORDER, SDL_CONTROLLER_BUTTON_X);
}
// Inicializa JailAudio

View File

@@ -188,7 +188,7 @@ void Ending::iniTexts()
// Crea los sprites
sprite_texts_.clear();
for (auto t : texts)
for (const auto &t : texts)
{
EndingTexture st;
const int width = text_->lenght(t.caption, 1) + 2 + 2;
@@ -275,7 +275,7 @@ void Ending::iniPics()
// Crea los sprites
sprite_pics_.clear();
for (auto p : pics)
for (const auto &p : pics)
{
EndingTexture sp;

View File

@@ -34,7 +34,7 @@ private:
int pos; // Posición
};
struct asdhk
struct TextIndex
{
int index;
int trigger;
@@ -42,7 +42,7 @@ private:
struct SceneData // Estructura para crear cada una de las escenas del final
{
std::vector<asdhk> text_index; // Indices del vector de textos a mostrar y su disparador
std::vector<TextIndex> text_index; // Indices del vector de textos a mostrar y su disparador
int picture_index; // Indice del vector de imagenes a mostrar
int counter_end; // Valor del contador en el que finaliza la escena
};

View File

@@ -25,12 +25,10 @@ Ending2::Ending2()
renderer_(Screen::get()->getRenderer()),
resource_(Resource::get()),
asset_(Asset::get()),
input_(Input::get())
input_(Input::get()),
text_(resource_->getText("smb2")),
music_(resource_->getMusic("ending2.ogg"))
{
// Reserva memoria para los punteros a objetos
text_ = resource_->getText("smb2");
music_ = resource_->getMusic("ending2.ogg");
// Inicializa variables
counter_enabled_ = false;
pre_counter_ = 0;
@@ -45,7 +43,7 @@ Ending2::Ending2()
// Inicializa el vector de colores
const std::vector<std::string> color_list = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
for (auto color : color_list)
for (const auto &color : color_list)
{
colors_.push_back(stringToColor(options.video.palette, color));
}
@@ -124,25 +122,6 @@ void Ending2::render()
// Dibuja los sprites con el texto del final
renderTexts();
const std::string txt = std::to_string(post_counter_);
// text->write(0, 192 - 8, txt);
// Dibuja la cuadricula
/*{
SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255);
const int sw = maxSpriteWidth + 6;
const int sh = maxSpriteHeight + 6;
for (int i = 0; i < 256; i += sw)
{
SDL_RenderDrawLine(renderer, i, 0, i, 192);
}
for (int i = 0; i < 192; i += sh)
{
SDL_RenderDrawLine(renderer, 0, i, 255, i);
}
}*/
{
// Dibuja una trama arriba y abajo
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0xFF);
for (int i = 0; i < 256; i += 2)
@@ -163,11 +142,6 @@ void Ending2::render()
SDL_RenderDrawPoint(renderer_, i, 187);
SDL_RenderDrawPoint(renderer_, i, 185);
}
// SDL_RenderDrawLine(renderer, 0, 1, 255, 1);
// SDL_RenderDrawLine(renderer, 0, 3, 255, 3);
// SDL_RenderDrawLine(renderer, 0, 188, 255, 188);
// SDL_RenderDrawLine(renderer, 0, 190, 255, 190);
}
// Vuelca el contenido del renderizador en pantalla
screen_->render();
@@ -316,7 +290,7 @@ void Ending2::loadSprites()
sprite_max_height_ = 0;
// Carga los sprites
for (auto sl : sprite_list_)
for (const auto &sl : sprite_list_)
{
sprites_.emplace_back(std::make_shared<AnimatedSprite>(resource_->getTexture(sl + ".png"), resource_->getAnimations(sl + ".ani")));
sprite_max_width_ = std::max(sprites_.back()->getWidth(), sprite_max_width_);
@@ -414,23 +388,23 @@ void Ending2::placeSprites()
{
for (int i = 0; i < (int)sprites_.size(); ++i)
{
const int x = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_;
const int y = (i / 1) * (sprite_max_height_ + dist_sprite_text_ + text_->getCharacterSize() + dist_sprite_sprite_) + GAMECANVAS_HEIGHT + 40;
const int w = sprites_[i]->getWidth();
const int h = sprites_[i]->getHeight();
const int dx = -(w / 2);
const int dy = i % 1 == 0 ? sprite_max_height_ - h : (int)(sprite_max_height_ * 1.5f) - h;
const int X = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_;
const int Y = (i / 1) * (sprite_max_height_ + dist_sprite_text_ + text_->getCharacterSize() + dist_sprite_sprite_) + GAMECANVAS_HEIGHT + 40;
const int W = sprites_.at(i)->getWidth();
const int H = sprites_.at(i)->getHeight();
const int DX = -(W / 2);
const int DY = sprite_max_height_ - H;
sprites_[i]->setPosition({x + dx, y + dy, w, h});
sprites_[i]->setVelY(sprite_desp_speed_);
sprites_.at(i)->setPosition({X + DX, Y + DY, W, H});
sprites_.at(i)->setVelY(sprite_desp_speed_);
}
// Recoloca el último sprite, que es el del jugador
const int w = sprites_.back()->getWidth();
const int x = GAMECANVAS_CENTER_X - (w / 2);
const int y = sprites_.back()->getPosY() + sprite_max_height_ * 2;
sprites_.back()->setPosX(x);
sprites_.back()->setPosY(y);
const int W = sprites_.back()->getWidth();
const int X = GAMECANVAS_CENTER_X - (W / 2);
const int Y = sprites_.back()->getPosY() + sprite_max_height_ * 2;
sprites_.back()->setPosX(X);
sprites_.back()->setPosY(Y);
sprites_.back()->setCurrentAnimation("walk");
}
@@ -448,7 +422,7 @@ void Ending2::createSpriteTexts()
const int h = text_->getCharacterSize();
const int x = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_;
const int dx = -(w / 2);
const int y = sprites_[i]->getPosY() + sprites_[i]->getHeight() + dist_sprite_text_;
const int y = sprites_.at(i)->getPosY() + sprites_.at(i)->getHeight() + dist_sprite_text_;
// Cambia la posición del último sprite
const int X = (i == (int)sprite_list_.size() - 1) ? GAMECANVAS_CENTER_X - (w / 2) : x + dx;
@@ -535,7 +509,7 @@ void Ending2::updateFinalFade()
const float step = std::min(std::max(post_counter_, 500) - 500, 40) / 40.0f;
const int index = (colors_.size() - 1) * step;
for (auto t : texts_)
for (const auto &t : texts_)
{
t->getTexture()->setColor(colors_[index].r, colors_[index].g, colors_[index].b);
}

View File

@@ -7,17 +7,17 @@
#include "texture.h" // for Texture
// Constructor
Enemy::Enemy(EnemyData enemy)
Enemy::Enemy(const EnemyData enemy)
: sprite_(std::make_shared<AnimatedSprite>(Resource::get()->getTexture(enemy.texture_path), Resource::get()->getAnimations(enemy.animation_path))),
color_string_(enemy.color),
x1_(enemy.x1),
x2_(enemy.x2),
y1_(enemy.y1),
y2_(enemy.y2),
should_flip_(enemy.flip),
should_mirror_(enemy.mirror)
{
// Crea objetos
sprite_ = std::make_shared<AnimatedSprite>(Resource::get()->getTexture(enemy.texture_path), Resource::get()->getAnimations(enemy.animation_path));
// Obten el resto de valores
x1_ = enemy.x1;
x2_ = enemy.x2;
y1_ = enemy.y1;
y2_ = enemy.y2;
color_string_ = enemy.color;
setPalette(options.video.palette);
sprite_->setPosX(enemy.x);
sprite_->setPosY(enemy.y);
@@ -25,24 +25,16 @@ Enemy::Enemy(EnemyData enemy)
sprite_->setVelY(enemy.vy);
sprite_->setWidth(enemy.w);
sprite_->setHeight(enemy.h);
should_flip_ = enemy.flip;
should_mirror_ = enemy.mirror;
const SDL_RendererFlip flip = (should_flip_ && enemy.vx < 0.0f) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
const SDL_RendererFlip mirror = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
sprite_->setFlip(static_cast<SDL_RendererFlip>(flip | mirror));
const SDL_RendererFlip FLIP = (should_flip_ && enemy.vx < 0.0f) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
const SDL_RendererFlip MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
sprite_->setFlip(static_cast<SDL_RendererFlip>(FLIP | MIRROR));
collider_ = getRect();
// Coloca un frame al azar o el designado
if (enemy.frame == -1)
{
sprite_->setCurrentAnimationFrame(rand() % sprite_->getCurrentAnimationSize());
}
else
{
sprite_->setCurrentAnimationFrame(enemy.frame);
}
sprite_->setCurrentAnimationFrame(
(enemy.frame == -1) ? (rand() % sprite_->getCurrentAnimationSize()) : enemy.frame);
}
// Pinta el enemigo en pantalla

View File

@@ -49,7 +49,7 @@ private:
public:
// Constructor
Enemy(EnemyData enemy);
explicit Enemy(const EnemyData enemy);
// Destructor
~Enemy() = default;

View File

@@ -24,87 +24,34 @@
#include "notifier.h"
#include "global_inputs.h"
#include "global_events.h"
//#include "surface.h"
// #include "surface.h"
// Constructor
Game::Game()
: screen_(Screen::get()),
renderer_(Screen::get()->getRenderer()),
asset_(Asset::get()),
input_(Input::get()),
resource_(Resource::get()),
debug_(Debug::get()),
cheevos_(Cheevos::get())
: board_(std::make_shared<ScoreboardData>(0, 9, 0, true, Color(0, 0, 0), SDL_GetTicks(), options.cheats.jail_is_open == Cheat::CheatState::ENABLED)),
scoreboard_(std::make_shared<Scoreboard>(board_)),
room_tracker_(std::make_shared<RoomTracker>()),
stats_(std::make_shared<Stats>(Asset::get()->get("stats.csv"), Asset::get()->get("stats_buffer.csv"))),
// test_surface_(std::make_shared<Surface>(Screen::get()->getSurface(), "test.gif")),
spawn_point_(PlayerSpawn(25 * BLOCK, 13 * BLOCK, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL))
{
// Inicia algunas variables
//test_surface_ = std::make_shared<Surface>(Screen::get()->getSurface(), "test.gif");
board_ = std::make_shared<ScoreboardData>();
board_->ini_clock = SDL_GetTicks();
#ifdef DEBUG
current_room_ = "03.room";
constexpr int X = 25;
constexpr int Y = 13;
spawn_point_ = PlayerSpawn(X * 8, Y * 8, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL);
spawn_point_ = PlayerSpawn(25 * BLOC, 13 * BLOCK, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL);
debug_->setEnabled(false);
#else
current_room_ = "03.room";
constexpr int X = 25;
constexpr int Y = 13;
spawn_point_ = PlayerSpawn(X * 8, Y * 8, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL);
#endif
// Crea los objetos
// Crea objetos e inicializa variables
ItemTracker::init();
scoreboard_ = std::make_shared<Scoreboard>(board_);
room_tracker_ = std::make_shared<RoomTracker>();
room_ = std::make_shared<Room>(resource_->getRoom(current_room_), board_);
std::string player_texture = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png";
std::string player_animations = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani";
const PlayerData player(spawn_point_, player_texture, player_animations, room_);
player_ = std::make_shared<Player>(player);
text_ = resource_->getText("smb2");
music_ = resource_->getMusic("game.ogg");
death_sound_ = resource_->getSound("death.wav");
stats_ = std::make_shared<Stats>(asset_->get("stats.csv"), asset_->get("stats_buffer.csv"));
// Crea la textura para poner el nombre de la habitación
room_name_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, text_->getCharacterSize() * 2);
if (room_name_texture_ == nullptr)
{
if (options.console)
{
std::cout << "Error: roomNameTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
// Establece el blend mode de la textura
SDL_SetTextureBlendMode(room_name_texture_, SDL_BLENDMODE_BLEND);
// Establece el destino de la textura
room_name_rect_ = {0, PLAY_AREA_HEIGHT, GAMECANVAS_WIDTH, text_->getCharacterSize() * 2};
// Pone el nombre de la habitación en la textura
fillRoomNameTexture();
// Inicializa el resto de variables
ticks_ = 0;
board_->lives = 9;
#ifdef DEBUG
board_->lives = 9;
#endif
board_->items = 0;
board_->rooms = 1;
board_->music = true;
board_->jail_is_open = options.cheats.jail_is_open == Cheat::CheatState::ENABLED;
setScoreBoardColor();
room_tracker_->addRoom(current_room_);
paused_ = false;
black_screen_ = false;
black_screen_counter_ = 0;
total_items_ = getTotalItems();
room_ = std::make_shared<Room>(current_room_, board_);
initPlayer(spawn_point_, room_);
initStats();
stats_->addVisit(room_->getName());
cheevos_->enable(!options.cheats.enabled()); // Deshabilita los logros si hay trucos activados
total_items_ = getTotalItems();
createRoomNameTexture();
changeRoom(current_room_);
Cheevos::get()->enable(!options.cheats.enabled()); // Deshabilita los logros si hay trucos activados
options.section.section = Section::GAME;
options.section.subsection = Subsection::NONE;
@@ -123,58 +70,8 @@ void Game::checkEvents()
while (SDL_PollEvent(&event))
{
globalEvents::check(event);
#ifdef DEBUG
if (event.type == SDL_KEYDOWN && event.key.repeat == 0)
{
switch (event.key.keysym.scancode)
{
case SDL_SCANCODE_G:
debug_->switchEnabled();
options.cheats.invincible = static_cast<Cheat::CheatState>(debug_->getEnabled());
board_->music = !debug_->getEnabled();
board_->music ? JA_ResumeMusic() : JA_PauseMusic();
break;
case SDL_SCANCODE_R:
resource_->reload();
break;
case SDL_SCANCODE_W:
goToRoom(BORDER_TOP);
break;
case SDL_SCANCODE_A:
goToRoom(BORDER_LEFT);
break;
case SDL_SCANCODE_S:
goToRoom(BORDER_BOTTOM);
break;
case SDL_SCANCODE_D:
goToRoom(BORDER_RIGHT);
break;
case SDL_SCANCODE_F6:
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS"}, NotificationText::LEFT, 2, false, "F6");
break;
case SDL_SCANCODE_F7:
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS"}, NotificationText::LEFT, 3, false, "F7");
break;
case SDL_SCANCODE_F8:
Notifier::get()->show({"JAILDESIGNER", "IS LOGGED IN"}, NotificationText::LEFT, 4, false);
break;
case SDL_SCANCODE_F9:
Notifier::get()->show({"JAILDESIGNER", "IS LOGGED IN"}, NotificationText::LEFT, 5, false);
break;
default:
break;
}
}
checkDebugEvents(event);
#endif
}
}
@@ -182,16 +79,16 @@ void Game::checkEvents()
// Comprueba el teclado
void Game::checkInput()
{
if (input_->checkInput(input_toggle_music, REPEAT_FALSE))
if (Input::get()->checkInput(InputAction::TOGGLE_MUSIC, REPEAT_FALSE))
{
board_->music = !board_->music;
board_->music ? JA_ResumeMusic() : JA_PauseMusic();
Notifier::get()->show({"MUSIC " + std::string(board_->music ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
}
else if (input_->checkInput(input_pause, REPEAT_FALSE))
else if (Input::get()->checkInput(InputAction::PAUSE, REPEAT_FALSE))
{
switchPause();
togglePause();
Notifier::get()->show({std::string(paused_ ? "GAME PAUSED" : "GAME RUNNING")}, NotificationText::CENTER);
}
@@ -201,7 +98,7 @@ void Game::checkInput()
// Bucle para el juego
void Game::run()
{
JA_PlayMusic(music_);
JA_PlayMusic(Resource::get()->getMusic("game.ogg"));
if (!board_->music)
{
JA_PauseMusic();
@@ -245,11 +142,10 @@ void Game::update()
checkRestoringJail();
checkSomeCheevos();
scoreboard_->update();
input_->update();
updateBlackScreen();
screen_->update();
Screen::get()->update();
#ifdef DEBUG
updateDebugInfo();
@@ -261,8 +157,8 @@ void Game::update()
void Game::render()
{
// Prepara para dibujar el frame
screen_->start();
//test_surface_->render(0, 0, 10, 10, 64, 64);
Screen::get()->start();
// test_surface_->render(0, 0, 10, 10, 64, 64);
// Dibuja los elementos del juego en orden
room_->renderMap();
@@ -279,7 +175,7 @@ void Game::render()
#endif
// Actualiza la pantalla
screen_->render();
Screen::get()->render();
}
#ifdef DEBUG
@@ -301,47 +197,102 @@ void Game::renderDebugInfo()
// Borra el marcador
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);
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 255);
SDL_RenderFillRect(Screen::get()->getRenderer(), &rect);
// Pinta la rejilla
SDL_SetRenderDrawColor(renderer_, 255, 255, 255, 32);
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 255, 255, 255, 32);
for (int i = 0; i < PLAY_AREA_BOTTOM; i += 8)
{ // Lineas horizontales
SDL_RenderDrawLine(renderer_, 0, i, PLAY_AREA_RIGHT, i);
SDL_RenderDrawLine(Screen::get()->getRenderer(), 0, i, PLAY_AREA_RIGHT, i);
}
for (int i = 0; i < PLAY_AREA_RIGHT; i += 8)
{ // Lineas verticales
SDL_RenderDrawLine(renderer_, i, 0, i, PLAY_AREA_BOTTOM - 1);
SDL_RenderDrawLine(Screen::get()->getRenderer(), i, 0, i, PLAY_AREA_BOTTOM - 1);
}
// Pinta el texto
debug_->setPos({1, 18 * 8});
debug_->render();
}
// Comprueba los eventos
void Game::checkDebugEvents(const SDL_Event &event)
{
if (event.type == SDL_KEYDOWN && event.key.repeat == 0)
{
switch (event.key.keysym.scancode)
{
case SDL_SCANCODE_G:
Debug::get()->switchEnabled();
options.cheats.invincible = static_cast<Cheat::CheatState>(Debug::get()->getEnabled());
board_->music = !Debug::get()->getEnabled();
board_->music ? JA_ResumeMusic() : JA_PauseMusic();
break;
case SDL_SCANCODE_R:
Resource::get()->reload();
break;
case SDL_SCANCODE_W:
changeRoom(room_->getRoom(BORDER_TOP));
break;
case SDL_SCANCODE_A:
changeRoom(room_->getRoom(BORDER_LEFT));
break;
case SDL_SCANCODE_S:
changeRoom(room_->getRoom(BORDER_BOTTOM));
break;
case SDL_SCANCODE_D:
changeRoom(room_->getRoom(BORDER_RIGHT));
break;
case SDL_SCANCODE_F6:
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS"}, NotificationText::LEFT, 2, false, "F6");
break;
case SDL_SCANCODE_F7:
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS"}, NotificationText::LEFT, 3, false, "F7");
break;
case SDL_SCANCODE_F8:
Notifier::get()->show({"JAILDESIGNER", "IS LOGGED IN"}, NotificationText::LEFT, 4, false);
break;
case SDL_SCANCODE_F9:
Notifier::get()->show({"JAILDESIGNER", "IS LOGGED IN"}, NotificationText::LEFT, 5, false);
break;
default:
break;
}
}
}
#endif
// Escribe el nombre de la pantalla
void Game::renderRoomName()
{
// Dibuja la textura con el nombre de la habitación
SDL_RenderCopy(renderer_, room_name_texture_, nullptr, &room_name_rect_);
SDL_RenderCopy(Screen::get()->getRenderer(), room_name_texture_, nullptr, &room_name_rect_);
}
// Cambia de habitación
bool Game::changeRoom(std::string file)
bool Game::changeRoom(const std::string &room_path)
{
// En las habitaciones los limites tienen la cadena del fichero o un 0 en caso de no limitar con nada
if (file == "0")
if (room_path == "0")
{
return false;
}
// Verifica que exista el fichero que se va a cargar
if (asset_->get(file) != "")
if (Asset::get()->get(room_path) != "")
{
// Crea un objeto habitación nuevo a partir del fichero
room_ = std::make_shared<Room>(resource_->getRoom(file), board_);
room_ = std::make_shared<Room>(room_path, board_);
// Pone el nombre de la habitación en la textura
fillRoomNameTexture();
@@ -349,7 +300,7 @@ bool Game::changeRoom(std::string file)
// Pone el color del marcador en función del color del borde de la habitación
setScoreBoardColor();
if (room_tracker_->addRoom(file))
if (room_tracker_->addRoom(room_path))
{
// Incrementa el contador de habitaciones visitadas
board_->rooms++;
@@ -362,6 +313,9 @@ bool Game::changeRoom(std::string file)
// Pasa la nueva habitación al jugador
player_->setRoom(room_);
// Cambia la habitación actual
current_room_ = room_path;
return true;
}
@@ -377,7 +331,6 @@ void Game::checkPlayerOnBorder()
if (changeRoom(roomName))
{
player_->switchBorders();
current_room_ = roomName;
spawn_point_ = player_->getSpawnParams();
}
}
@@ -436,37 +389,21 @@ void Game::killPlayer()
stats_->addDeath(room_->getName());
// Invalida el logro de pasarse el juego sin morir
cheevos_->invalidate(11);
Cheevos::get()->invalidate(11);
// Sonido
JA_PlaySound(death_sound_);
JA_PlaySound(Resource::get()->getSound("death.wav"));
// Pone la pantalla en negro un tiempo
setBlackScreen();
// Crea la nueva habitación y el nuevo jugador
room_ = std::make_shared<Room>(resource_->getRoom(current_room_), board_);
std::string player_texture = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png";
std::string player_animations = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani";
const PlayerData player(spawn_point_, player_texture, player_animations, room_);
player_ = std::make_shared<Player>(player);
room_ = std::make_shared<Room>(current_room_, board_);
initPlayer(spawn_point_, room_);
// Pone los objetos en pausa mientras esta la habitación en negro
room_->pause();
player_->pause();
}
// Recarga todas las texturas
void Game::reLoadTextures()
{
if (options.console)
{
std::cout << "** RELOAD REQUESTED" << std::endl;
}
player_->reLoadTexture();
room_->reLoadTexture();
scoreboard_->reLoadTexture();
text_->reLoadTexture();
room_->setPaused(true);
player_->setPaused(true);
}
// Establece la pantalla en negro
@@ -486,9 +423,9 @@ void Game::updateBlackScreen()
black_screen_ = false;
black_screen_counter_ = 0;
player_->resume();
room_->resume();
screen_->setBorderColor(room_->getBorderColor());
player_->setPaused(false);
room_->setPaused(false);
Screen::get()->setBorderColor(room_->getBorderColor());
}
}
}
@@ -498,8 +435,8 @@ void Game::renderBlackScreen()
{
if (black_screen_)
{
screen_->clean();
screen_->setBorderColor(stringToColor(options.video.palette, "black"));
Screen::get()->clean();
Screen::get()->setBorderColor(stringToColor(options.video.palette, "black"));
}
}
@@ -544,9 +481,9 @@ bool Game::checkEndGame()
int Game::getTotalItems()
{
int items = 0;
auto rooms = resource_->getRooms();
auto rooms = Resource::get()->getRooms();
for (auto room : rooms)
for (const auto &room : rooms)
{
items += room.room->items.size();
}
@@ -554,33 +491,14 @@ int Game::getTotalItems()
return items;
}
// Va a la habitación designada
void Game::goToRoom(int border)
{
const std::string roomName = room_->getRoom(border);
if (changeRoom(roomName))
{
current_room_ = roomName;
}
}
// Pone el juego en pausa
void Game::switchPause()
void Game::togglePause()
{
if (paused_)
{
player_->resume();
room_->resume();
scoreboard_->resume();
paused_ = false;
}
else
{
player_->pause();
room_->pause();
scoreboard_->pause();
paused_ = true;
}
paused_ = !paused_;
player_->setPaused(paused_);
room_->setPaused(paused_);
scoreboard_->setPaused(paused_);
}
// Da vidas al jugador cuando está en la Jail
@@ -603,13 +521,13 @@ void Game::checkRestoringJail()
{
counter = 0;
board_->lives++;
JA_PlaySound(death_sound_);
JA_PlaySound(Resource::get()->getSound("death.wav"));
// Invalida el logro de completar el juego sin entrar a la jail
const bool haveTheItems = board_->items >= int(total_items_ * 0.9f);
if (!haveTheItems)
{
cheevos_->invalidate(9);
Cheevos::get()->invalidate(9);
}
}
}
@@ -617,9 +535,9 @@ void Game::checkRestoringJail()
// Inicializa el diccionario de las estadísticas
void Game::initStats()
{
auto rooms = resource_->getRooms();
auto rooms = Resource::get()->getRooms();
for (auto room : rooms)
for (const auto &room : rooms)
{
stats_->addDictionary(room.room->number, room.room->name);
}
@@ -631,86 +549,120 @@ void Game::initStats()
void Game::fillRoomNameTexture()
{
// Pone la textura como destino de renderizado
SDL_SetRenderTarget(renderer_, room_name_texture_);
SDL_SetRenderTarget(Screen::get()->getRenderer(), room_name_texture_);
// Rellena la textura de color
const Color color = stringToColor(options.video.palette, "white");
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
SDL_RenderClear(renderer_);
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF);
SDL_RenderClear(Screen::get()->getRenderer());
// Escribe el texto en la textura
text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, text_->getCharacterSize() / 2, room_->getName(), 1, room_->getBGColor());
auto text = Resource::get()->getText("smb2");
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, text->getCharacterSize() / 2, room_->getName(), 1, room_->getBGColor());
// Deja el renderizador por defecto
SDL_SetRenderTarget(renderer_, nullptr);
SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
}
// Comprueba algunos logros
void Game::checkSomeCheevos()
{
auto cheevos = Cheevos::get();
// Logros sobre la cantidad de items
if (board_->items == total_items_)
{
cheevos_->unlock(4);
cheevos_->unlock(3);
cheevos_->unlock(2);
cheevos_->unlock(1);
cheevos->unlock(4);
cheevos->unlock(3);
cheevos->unlock(2);
cheevos->unlock(1);
}
else if (board_->items >= total_items_ * 0.75f)
{
cheevos_->unlock(3);
cheevos_->unlock(2);
cheevos_->unlock(1);
cheevos->unlock(3);
cheevos->unlock(2);
cheevos->unlock(1);
}
else if (board_->items >= total_items_ * 0.5f)
{
cheevos_->unlock(2);
cheevos_->unlock(1);
cheevos->unlock(2);
cheevos->unlock(1);
}
else if (board_->items >= total_items_ * 0.25f)
{
cheevos_->unlock(1);
cheevos->unlock(1);
}
// Logros sobre las habitaciones visitadas
if (board_->rooms >= 60)
{
cheevos_->unlock(7);
cheevos_->unlock(6);
cheevos_->unlock(5);
cheevos->unlock(7);
cheevos->unlock(6);
cheevos->unlock(5);
}
else if (board_->rooms >= 40)
{
cheevos_->unlock(6);
cheevos_->unlock(5);
cheevos->unlock(6);
cheevos->unlock(5);
}
else if (board_->rooms >= 20)
{
cheevos_->unlock(5);
cheevos->unlock(5);
}
}
// Comprueba los logros de completar el juego
void Game::checkEndGameCheevos()
{
auto cheevos = Cheevos::get();
// "Complete the game"
cheevos_->unlock(8);
cheevos->unlock(8);
// "Complete the game without entering the jail"
cheevos_->unlock(9);
cheevos->unlock(9);
// "Complete the game with all items"
if (board_->items == total_items_)
{
cheevos_->unlock(10);
cheevos->unlock(10);
}
// "Complete the game without dying"
cheevos_->unlock(11);
cheevos->unlock(11);
// "Complete the game in under 30 minutes"
if (scoreboard_->getMinutes() < 30)
{
cheevos_->unlock(12);
cheevos->unlock(12);
}
}
// Inicializa al jugador
void Game::initPlayer(PlayerSpawn spawn_point, std::shared_ptr<Room> room)
{
std::string player_texture = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png";
std::string player_animations = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani";
const PlayerData player(spawn_point, player_texture, player_animations, room);
player_ = std::make_shared<Player>(player);
}
// Crea la textura para poner el nombre de la habitación
void Game::createRoomNameTexture()
{
auto text = Resource::get()->getText("smb2");
room_name_texture_ = SDL_CreateTexture(Screen::get()->getRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, text->getCharacterSize() * 2);
if (room_name_texture_ == nullptr)
{
if (options.console)
{
std::cout << "Error: room_name_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
// Establece el blend mode de la textura
SDL_SetTextureBlendMode(room_name_texture_, SDL_BLENDMODE_BLEND);
// Establece el destino de la textura
room_name_rect_ = {0, PLAY_AREA_HEIGHT, GAMECANVAS_WIDTH, text->getCharacterSize() * 2};
}

View File

@@ -8,7 +8,7 @@
#include "player.h" // Para playerSpawn_t
#include "scoreboard.h" // Para board_t
#include "room.h"
//#include "surface.h"
// #include "surface.h"
class Asset;
class Cheevos;
class Debug;
@@ -29,32 +29,22 @@ class Game
{
private:
// Objetos y punteros
Screen *screen_; // Objeto encargado de manejar el renderizador
SDL_Renderer *renderer_; // El renderizador de la ventana
Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos
Input *input_; // Objeto pata gestionar la entrada
Resource *resource_; // Objeto con los recursos
Debug *debug_; // Objeto para gestionar la información de debug
Cheevos *cheevos_; // Objeto encargado de gestionar los logros del juego
std::shared_ptr<ScoreboardData> board_; // Estructura con los datos del marcador
std::shared_ptr<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador
std::shared_ptr<RoomTracker> room_tracker_; // Lleva el control de las habitaciones visitadas
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<RoomTracker> room_tracker_; // Lleva el control de las habitaciones visitadas
std::shared_ptr<Text> text_; // Objeto para los textos del juego
std::shared_ptr<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador
std::shared_ptr<Stats> stats_; // Objeto encargado de gestionar las estadísticas
SDL_Texture *room_name_texture_; // Textura para escribir el nombre de la habitación
//std::shared_ptr<Surface> test_surface_;
// std::shared_ptr<Surface> test_surface_;
// Variables
JA_Music_t *music_; // Musica que suena durante el juego
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
std::string current_room_; // Fichero de la habitación actual
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
std::string current_room_ = "03.room"; // Fichero de la habitación actual
PlayerSpawn spawn_point_; // Lugar de la habitación donde aparece 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
bool paused_; // Indica si el juego se encuentra en pausa
bool black_screen_; // Indica si la pantalla está en negro. Se utiliza para la muerte del jugador
int black_screen_counter_; // Contador para temporizar la pantalla en negro
bool paused_ = false; // Indica si el juego se encuentra en pausa
bool black_screen_ = false; // Indica si la pantalla está en negro. Se utiliza para la muerte del jugador
int black_screen_counter_ = 0; // Contador para temporizar la pantalla en negro
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
@@ -73,13 +63,16 @@ private:
// Pone la información de debug en pantalla
void renderDebugInfo();
// Comprueba los eventos
void checkDebugEvents(const SDL_Event &event);
#endif
// Escribe el nombre de la pantalla
void renderRoomName();
// Cambia de habitación
bool changeRoom(std::string file);
bool changeRoom(const std::string &file);
// Comprueba el teclado
void checkInput();
@@ -102,9 +95,6 @@ private:
// Mata al jugador
void killPlayer();
// Recarga todas las texturas
void reLoadTextures();
// Establece la pantalla en negro
void setBlackScreen();
@@ -123,11 +113,8 @@ private:
// Obtiene la cantidad total de items que hay en el mapeado del juego
int getTotalItems();
// Va a la habitación designada
void goToRoom(int border);
// Pone el juego en pausa
void switchPause();
void togglePause();
// Da vidas al jugador cuando está en la Jail
void checkRestoringJail();
@@ -144,6 +131,12 @@ private:
// Comprueba los logros de completar el juego
void checkEndGameCheevos();
// Inicializa al jugador
void initPlayer(PlayerSpawn spawn_point, std::shared_ptr<Room> room);
// Crea la textura para poner el nombre de la habitación
void createRoomNameTexture();
public:
// Constructor
Game();

View File

@@ -43,7 +43,7 @@ GameOver::GameOver()
// Inicializa el vector de colores
const std::vector<std::string> colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
for (auto cl : colorList)
for (const auto &cl : colorList)
{
colors_.push_back(stringToColor(options.video.palette, cl));
}

View File

@@ -54,29 +54,29 @@ namespace globalInputs
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
void check()
{
if (Input::get()->checkInput(input_exit, REPEAT_FALSE))
if (Input::get()->checkInput(InputAction::EXIT, REPEAT_FALSE))
{
quit();
}
else if (Input::get()->checkInput(input_accept, REPEAT_FALSE))
else if (Input::get()->checkInput(InputAction::ACCEPT, REPEAT_FALSE))
{
skip_section();
}
else if (Input::get()->checkInput(input_toggle_border, REPEAT_FALSE))
else if (Input::get()->checkInput(InputAction::TOGGLE_BORDER, REPEAT_FALSE))
{
Screen::get()->toggleBorder();
Notifier::get()->show({"BORDER " + std::string(options.video.border.enabled ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
}
else if (Input::get()->checkInput(input_toggle_videomode, REPEAT_FALSE))
else if (Input::get()->checkInput(InputAction::TOGGLE_VIDEOMODE, REPEAT_FALSE))
{
Screen::get()->toggleVideoMode();
Notifier::get()->show({"FULLSCREEN " + std::string(options.video.mode == 0 ? "DISABLED" : "ENABLED")}, NotificationText::CENTER);
}
else if (Input::get()->checkInput(input_window_dec_size, REPEAT_FALSE))
else if (Input::get()->checkInput(InputAction::WINDOW_DEC_ZOOM, REPEAT_FALSE))
{
if (Screen::get()->decWindowZoom())
{
@@ -84,7 +84,7 @@ namespace globalInputs
}
}
else if (Input::get()->checkInput(input_window_inc_size, REPEAT_FALSE))
else if (Input::get()->checkInput(InputAction::WINDOW_INC_ZOOM, REPEAT_FALSE))
{
if (Screen::get()->incWindowZoom())
{
@@ -92,13 +92,13 @@ namespace globalInputs
}
}
else if (Input::get()->checkInput(input_toggle_shaders, REPEAT_FALSE))
else if (Input::get()->checkInput(InputAction::TOGGLE_SHADERS, REPEAT_FALSE))
{
Screen::get()->toggleShaders();
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(InputAction::TOGGLE_PALETTE, REPEAT_FALSE))
{
switchPalette();
Notifier::get()->show({"PALETTE " + std::string(options.video.palette == Palette::ZXSPECTRUM ? "ZX SPECTRUM" : "ZX ARNE")}, NotificationText::CENTER);

View File

@@ -35,37 +35,28 @@ Input::Input(const std::string &game_controller_db_path)
keyBindings_t kb;
kb.scancode = 0;
kb.active = false;
key_bindings_.resize(input_number_of_inputs, kb);
key_bindings_.resize(static_cast<int>(InputAction::SIZE), kb);
GameControllerBindings_t gcb;
gcb.button = SDL_CONTROLLER_BUTTON_INVALID;
gcb.active = false;
game_controller_bindings_.resize(input_number_of_inputs, gcb);
}
// Actualiza el estado del objeto
void Input::update()
{
if (disabled_until_ == d_keyPressed && !checkAnyInput())
{
enable();
}
game_controller_bindings_.resize(static_cast<int>(InputAction::SIZE), gcb);
}
// Asigna inputs a teclas
void Input::bindKey(Uint8 input, SDL_Scancode code)
void Input::bindKey(InputAction input, SDL_Scancode code)
{
key_bindings_[input].scancode = code;
key_bindings_.at(static_cast<int>(input)).scancode = code;
}
// Asigna inputs a botones del mando
void Input::bindGameControllerButton(Uint8 input, SDL_GameControllerButton button)
void Input::bindGameControllerButton(InputAction input, SDL_GameControllerButton button)
{
game_controller_bindings_[input].button = button;
game_controller_bindings_.at(static_cast<int>(input)).button = button;
}
// Comprueba si un input esta activo
bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
bool Input::checkInput(InputAction input, bool repeat, int device, int index)
{
if (!enabled_)
{
@@ -86,7 +77,7 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
if (repeat)
{
if (keyStates[key_bindings_[input].scancode] != 0)
if (keyStates[key_bindings_.at(static_cast<int>(input)).scancode] != 0)
{
successKeyboard = true;
}
@@ -97,11 +88,11 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
}
else
{
if (!key_bindings_[input].active)
if (!key_bindings_.at(static_cast<int>(input)).active)
{
if (keyStates[key_bindings_[input].scancode] != 0)
if (keyStates[key_bindings_.at(static_cast<int>(input)).scancode] != 0)
{
key_bindings_[input].active = true;
key_bindings_.at(static_cast<int>(input)).active = true;
successKeyboard = true;
}
else
@@ -111,9 +102,9 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
}
else
{
if (keyStates[key_bindings_[input].scancode] == 0)
if (keyStates[key_bindings_.at(static_cast<int>(input)).scancode] == 0)
{
key_bindings_[input].active = false;
key_bindings_.at(static_cast<int>(input)).active = false;
successKeyboard = false;
}
else
@@ -129,7 +120,7 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
{
if (repeat)
{
if (SDL_GameControllerGetButton(connected_controllers_[index], game_controller_bindings_[input].button) != 0)
if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_.at(static_cast<int>(input)).button) != 0)
{
successGameController = true;
}
@@ -140,11 +131,11 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
}
else
{
if (!game_controller_bindings_[input].active)
if (!game_controller_bindings_.at(static_cast<int>(input)).active)
{
if (SDL_GameControllerGetButton(connected_controllers_[index], game_controller_bindings_[input].button) != 0)
if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_.at(static_cast<int>(input)).button) != 0)
{
game_controller_bindings_[input].active = true;
game_controller_bindings_.at(static_cast<int>(input)).active = true;
successGameController = true;
}
else
@@ -154,9 +145,9 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
}
else
{
if (SDL_GameControllerGetButton(connected_controllers_[index], game_controller_bindings_[input].button) == 0)
if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_.at(static_cast<int>(input)).button) == 0)
{
game_controller_bindings_[input].active = false;
game_controller_bindings_.at(static_cast<int>(input)).active = false;
successGameController = false;
}
else
@@ -197,7 +188,7 @@ bool Input::checkAnyInput(int device, int index)
{
for (int i = 0; i < (int)game_controller_bindings_.size(); ++i)
{
if (SDL_GameControllerGetButton(connected_controllers_[index], game_controller_bindings_[i].button) != 0)
if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_[i].button) != 0)
{
return true;
}
@@ -317,17 +308,3 @@ void Input::setVerbose(bool value)
{
verbose_ = value;
}
// Deshabilita las entradas durante un periodo de tiempo
void Input::disableUntil(i_disable_e value)
{
disabled_until_ = value;
enabled_ = false;
}
// Hablita las entradas
void Input::enable()
{
enabled_ = true;
disabled_until_ = d_notDisabled;
}

View File

@@ -15,38 +15,31 @@ constexpr int INPUT_USE_KEYBOARD = 0;
constexpr int INPUT_USE_GAMECONTROLLER = 1;
constexpr int INPUT_USE_ANY = 2;
enum inputs_e
enum class InputAction
{
// Inputs obligatorios
input_null,
input_up,
input_down,
input_left,
input_right,
input_pause,
input_exit,
input_accept,
input_cancel,
NONE,
UP,
DOWN,
LEFT,
RIGHT,
PAUSE,
EXIT,
ACCEPT,
CANCEL,
// Inputs personalizados
input_jump,
input_window_inc_size,
input_window_dec_size,
input_toggle_videomode,
input_toggle_border,
input_toggle_music,
input_toggle_palette,
input_toggle_shaders,
JUMP,
WINDOW_INC_ZOOM,
WINDOW_DEC_ZOOM,
TOGGLE_VIDEOMODE,
TOGGLE_BORDER,
TOGGLE_MUSIC,
TOGGLE_PALETTE,
TOGGLE_SHADERS,
// Input obligatorio
input_number_of_inputs
};
enum i_disable_e
{
d_notDisabled,
d_forever,
d_keyPressed
SIZE
};
class Input
@@ -74,10 +67,9 @@ private:
std::vector<keyBindings_t> key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos
std::vector<GameControllerBindings_t> game_controller_bindings_; // Vector con las teclas asociadas a los inputs predefinidos
std::vector<std::string> controller_names_; // Vector con los nombres de los mandos
int num_gamepads_; // Numero de mandos conectados
int num_gamepads_ = 0; // Numero de mandos conectados
std::string db_path_; // Ruta al archivo gamecontrollerdb.txt
bool verbose_ = true; // Indica si ha de mostrar mensajes
i_disable_e disabled_until_; // Tiempo que esta deshabilitado
bool enabled_ = true; // Indica si está habilitado
// Constructor
@@ -96,17 +88,14 @@ public:
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
static Input *get();
// Actualiza el estado del objeto
void update();
// Asigna inputs a teclas
void bindKey(Uint8 input, SDL_Scancode code);
void bindKey(InputAction input, SDL_Scancode code);
// Asigna inputs a botones del mando
void bindGameControllerButton(Uint8 input, SDL_GameControllerButton button);
void bindGameControllerButton(InputAction input, SDL_GameControllerButton button);
// Comprueba si un input esta activo
bool checkInput(Uint8 input, bool repeat = true, int device = INPUT_USE_ANY, int index = 0);
bool checkInput(InputAction input, bool repeat = true, int device = INPUT_USE_ANY, int index = 0);
// Comprueba si hay almenos un input activo
bool checkAnyInput(int device = INPUT_USE_ANY, int index = 0);
@@ -125,10 +114,4 @@ public:
// Establece si ha de mostrar mensajes
void setVerbose(bool value);
// Deshabilita las entradas durante un periodo de tiempo
void disableUntil(i_disable_e value);
// Hablita las entradas
void enable();
};

View File

@@ -5,16 +5,12 @@
// Constructor
Item::Item(ItemData item)
: sprite_(std::make_shared<Sprite>(Resource::get()->getTexture(item.tile_set_file), item.x, item.y, ITEM_SIZE_, ITEM_SIZE_)),
change_color_speed(4)
{
constexpr int ITEMSIZE = 8;
// Crea objetos;
sprite_ = std::make_shared<Sprite>(Resource::get()->getTexture(item.tile_set_file), item.x, item.y, ITEMSIZE, ITEMSIZE);
// Inicia variables
sprite_->setClip((item.tile % 10) * ITEMSIZE, (item.tile / 10) * ITEMSIZE, ITEMSIZE, ITEMSIZE);
sprite_->setClip((item.tile % 10) * ITEM_SIZE_, (item.tile / 10) * ITEM_SIZE_, ITEM_SIZE_, ITEM_SIZE_);
collider_ = sprite_->getRect();
change_color_speed = 4;
counter_ = item.counter * change_color_speed;
// Inicializa los colores
@@ -28,8 +24,8 @@ Item::Item(ItemData item)
// Pinta el objeto en pantalla
void Item::render()
{
const int index = (counter_ / change_color_speed) % color_.size();
sprite_->getTexture()->setColor(color_[index].r, color_[index].g, color_[index].b);
const int INDEX = (counter_ / change_color_speed) % color_.size();
sprite_->getTexture()->setColor(color_.at(INDEX).r, color_.at(INDEX).g, color_.at(INDEX).b);
sprite_->render();
sprite_->getTexture()->setColor(255, 255, 255);
}

View File

@@ -26,6 +26,9 @@ struct ItemData
class Item
{
private:
// Constantes
static constexpr int ITEM_SIZE_ = 8;
// Objetos y punteros
std::shared_ptr<Sprite> sprite_; // Sprite del objeto
@@ -37,7 +40,7 @@ private:
public:
// Constructor
Item(ItemData item);
explicit Item(ItemData item);
// Destructor
~Item() = default;

View File

@@ -57,7 +57,7 @@ void ItemTracker::addItem(const std::string &name, SDL_Point pos)
}
// Busca una entrada en la lista por nombre
int ItemTracker::findByName(std::string name)
int ItemTracker::findByName(const std::string &name)
{
int i = 0;

View File

@@ -27,7 +27,7 @@ private:
std::vector<ItemTrackerData> item_list_; // Lista con todos los objetos recogidos
// Busca una entrada en la lista por nombre
int findByName(std::string name);
int findByName(const std::string &name);
// Busca una entrada en la lista por posición
int findByPos(int index, SDL_Point pos);

View File

@@ -62,14 +62,12 @@ LoadingScreen::LoadingScreen()
{ // Primer bloque de 2K
line_index_[i] = ((i % 8) * 8) + (i / 8);
}
else if (i >= 64 && i < 128)
else if (i < 128)
{ // Segundo bloque de 2K
line_index_[i] = 64 + ((i % 8) * 8) + ((i - 64) / 8);
}
else if (i >= 128 && i < 192)
{ // tercer bloque de 2K
else
{ // Tercer bloque de 2K
line_index_[i] = 128 + ((i % 8) * 8) + ((i - 128) / 8);
}
}
@@ -177,20 +175,22 @@ void LoadingScreen::renderBorder()
// Añade lineas amarillas
color = stringToColor(options.video.palette, "yellow");
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
const int width = options.game.width + (options.video.border.width * 2);
const int height = options.game.height + (options.video.border.height * 2);
const int WIDTH = options.game.width + (options.video.border.width * 2);
const int HEIGHT = options.game.height + (options.video.border.height * 2);
bool drawEnabled = rand() % 2 == 0 ? true : false;
int row = 0;
int rowSize = 1;
while (row < height)
while (row < HEIGHT)
{
rowSize = (rand() % 4) + 3;
const int ROW_HEIGHT = (rand() % 4) + 3;
if (drawEnabled)
for (int i = row; i < row + rowSize; ++i)
{
SDL_RenderDrawLine(renderer_, 0, i, width, i);
for (int i = row; i < row + ROW_HEIGHT; ++i)
{
SDL_RenderDrawLine(renderer_, 0, i, WIDTH, i);
}
row += rowSize;
}
row += ROW_HEIGHT;
drawEnabled = !drawEnabled;
}
}
@@ -254,45 +254,6 @@ void LoadingScreen::run()
JA_SetVolume(128);
}
// Reconstruye la pantalla de carga
void LoadingScreen::recreateLoadingScreen()
{
// Prepara para empezar a dibujar en la textura de juego
screen_->start();
// Primera parte de la carga, la parte en blanco y negro
if (loading_first_part_)
{
const int numSteps = 5;
const int step = 51;
for (int i = 0; i <= counter_; i++)
{
load_counter_ = i / numSteps;
load_rect_.x = step * (i % numSteps);
load_rect_.y = line_index_[load_counter_];
mono_loading_screen_sprite_->setClip(load_rect_);
mono_loading_screen_sprite_->setPosition(load_rect_);
mono_loading_screen_sprite_->render();
}
}
// Segunda parte de la carga, la parte de los bloques en color
else
{
for (int i = 0; i <= load_counter_; i++)
{
load_rect_.x = (i * 8) % 256;
load_rect_.y = (i / 32) * 8;
color_loading_screen_sprite_->setClip(load_rect_);
color_loading_screen_sprite_->setPosition(load_rect_);
color_loading_screen_sprite_->render();
}
}
// Vuelca el contenido del renderizador en pantalla
screen_->render();
}
// Dibuja sobre la textura
void LoadingScreen::fillTexture()
{

View File

@@ -63,9 +63,6 @@ private:
// Dibuja el efecto de carga en el borde
void renderBorder();
// Reconstruye la pantalla de carga
void recreateLoadingScreen();
// Dibuja sobre la textura
void fillTexture();

View File

@@ -35,25 +35,18 @@ Logo::Logo()
{
jailgames_sprite_.push_back(std::make_shared<Sprite>(jailgames_texture_, 0, i, jailgames_texture_->getWidth(), 1));
jailgames_sprite_.back()->setClip(0, i, jailgames_texture_->getWidth(), 1);
if (i % 2 == 0)
{
jailgames_sprite_[i]->setX(256 + (i * 3));
}
else
{
jailgames_sprite_[i]->setX(-181 - (i * 3));
}
jailgames_sprite_[i]->setY(83 + i);
jailgames_sprite_.at(i)->setX((i % 2 == 0) ? (256 + (i * 3)) : (-181 - (i * 3)));
jailgames_sprite_.at(i)->setY(83 + i);
}
// Inicializa variables
options.section.section = Section::LOGO;
// Inicializa el vector de colores
const std::vector<std::string> vColors = {"black", "blue", "red", "magenta", "green", "cyan", "yellow", "bright_white"};
for (auto v : vColors)
const std::vector<std::string> COLORS = {"black", "blue", "red", "magenta", "green", "cyan", "yellow", "bright_white"};
for (const auto &color : COLORS)
{
color_.push_back(stringToColor(options.video.palette, v));
color_.push_back(stringToColor(options.video.palette, color));
}
// Cambia el color del borde
@@ -83,24 +76,24 @@ void Logo::updateJAILGAMES()
{
for (int i = 1; i < (int)jailgames_sprite_.size(); ++i)
{
const int speed = 8;
const int dest = 37;
if (jailgames_sprite_[i]->getX() != 37)
constexpr int SPEED = 8;
constexpr int DEST = 37;
if (jailgames_sprite_.at(i)->getX() != 37)
{
if (i % 2 == 0)
{
jailgames_sprite_[i]->incX(-speed);
if (jailgames_sprite_[i]->getX() < dest)
jailgames_sprite_.at(i)->incX(-SPEED);
if (jailgames_sprite_.at(i)->getX() < DEST)
{
jailgames_sprite_[i]->setX(dest);
jailgames_sprite_.at(i)->setX(DEST);
}
}
else
{
jailgames_sprite_[i]->incX(speed);
if (jailgames_sprite_[i]->getX() > dest)
jailgames_sprite_.at(i)->incX(SPEED);
if (jailgames_sprite_.at(i)->getX() > DEST)
{
jailgames_sprite_[i]->setX(dest);
jailgames_sprite_.at(i)->setX(DEST);
}
}
}
@@ -111,89 +104,89 @@ void Logo::updateJAILGAMES()
// Gestiona el color de las texturas
void Logo::updateTextureColors()
{
const int ini = 70;
const int inc = 4;
constexpr int INI = 70;
constexpr int INC = 4;
if (counter_ == ini + inc * 0)
if (counter_ == INI + INC * 0)
{
since_1998_texture_->setColor(color_[0].r, color_[0].g, color_[0].b);
since_1998_texture_->setColor(color_.at(0).r, color_.at(0).g, color_.at(0).b);
}
else if (counter_ == ini + inc * 1)
else if (counter_ == INI + INC * 1)
{
since_1998_texture_->setColor(color_[1].r, color_[1].g, color_[1].b);
since_1998_texture_->setColor(color_.at(1).r, color_.at(1).g, color_.at(1).b);
}
else if (counter_ == ini + inc * 2)
else if (counter_ == INI + INC * 2)
{
since_1998_texture_->setColor(color_[2].r, color_[2].g, color_[2].b);
since_1998_texture_->setColor(color_.at(2).r, color_.at(2).g, color_.at(2).b);
}
else if (counter_ == ini + inc * 3)
else if (counter_ == INI + INC * 3)
{
since_1998_texture_->setColor(color_[3].r, color_[3].g, color_[3].b);
since_1998_texture_->setColor(color_.at(3).r, color_.at(3).g, color_.at(3).b);
}
else if (counter_ == ini + inc * 4)
else if (counter_ == INI + INC * 4)
{
since_1998_texture_->setColor(color_[4].r, color_[4].g, color_[4].b);
since_1998_texture_->setColor(color_.at(4).r, color_.at(4).g, color_.at(4).b);
}
else if (counter_ == ini + inc * 5)
else if (counter_ == INI + INC * 5)
{
since_1998_texture_->setColor(color_[5].r, color_[5].g, color_[5].b);
since_1998_texture_->setColor(color_.at(5).r, color_.at(5).g, color_.at(5).b);
}
else if (counter_ == ini + inc * 6)
else if (counter_ == INI + INC * 6)
{
since_1998_texture_->setColor(color_[6].r, color_[6].g, color_[6].b);
since_1998_texture_->setColor(color_.at(6).r, color_.at(6).g, color_.at(6).b);
}
else if (counter_ == ini + inc * 7)
else if (counter_ == INI + INC * 7)
{
since_1998_texture_->setColor(color_[7].r, color_[7].g, color_[7].b);
since_1998_texture_->setColor(color_.at(7).r, color_.at(7).g, color_.at(7).b);
}
else if (counter_ == INIT_FADE_ + inc * 0)
else if (counter_ == INIT_FADE_ + INC * 0)
{
jailgames_texture_->setColor(color_[6].r, color_[6].g, color_[6].b);
since_1998_texture_->setColor(color_[6].r, color_[6].g, color_[6].b);
jailgames_texture_->setColor(color_.at(6).r, color_.at(6).g, color_.at(6).b);
since_1998_texture_->setColor(color_.at(6).r, color_.at(6).g, color_.at(6).b);
}
else if (counter_ == INIT_FADE_ + inc * 1)
else if (counter_ == INIT_FADE_ + INC * 1)
{
jailgames_texture_->setColor(color_[5].r, color_[5].g, color_[5].b);
since_1998_texture_->setColor(color_[5].r, color_[5].g, color_[5].b);
jailgames_texture_->setColor(color_.at(5).r, color_.at(5).g, color_.at(5).b);
since_1998_texture_->setColor(color_.at(5).r, color_.at(5).g, color_.at(5).b);
}
else if (counter_ == INIT_FADE_ + inc * 2)
else if (counter_ == INIT_FADE_ + INC * 2)
{
jailgames_texture_->setColor(color_[4].r, color_[4].g, color_[4].b);
since_1998_texture_->setColor(color_[4].r, color_[4].g, color_[4].b);
jailgames_texture_->setColor(color_.at(4).r, color_.at(4).g, color_.at(4).b);
since_1998_texture_->setColor(color_.at(4).r, color_.at(4).g, color_.at(4).b);
}
else if (counter_ == INIT_FADE_ + inc * 3)
else if (counter_ == INIT_FADE_ + INC * 3)
{
jailgames_texture_->setColor(color_[3].r, color_[3].g, color_[3].b);
since_1998_texture_->setColor(color_[3].r, color_[3].g, color_[3].b);
jailgames_texture_->setColor(color_.at(3).r, color_.at(3).g, color_.at(3).b);
since_1998_texture_->setColor(color_.at(3).r, color_.at(3).g, color_.at(3).b);
}
else if (counter_ == INIT_FADE_ + inc * 4)
else if (counter_ == INIT_FADE_ + INC * 4)
{
jailgames_texture_->setColor(color_[2].r, color_[2].g, color_[2].b);
since_1998_texture_->setColor(color_[2].r, color_[2].g, color_[2].b);
jailgames_texture_->setColor(color_.at(2).r, color_.at(2).g, color_.at(2).b);
since_1998_texture_->setColor(color_.at(2).r, color_.at(2).g, color_.at(2).b);
}
else if (counter_ == INIT_FADE_ + inc * 5)
else if (counter_ == INIT_FADE_ + INC * 5)
{
jailgames_texture_->setColor(color_[1].r, color_[1].g, color_[1].b);
since_1998_texture_->setColor(color_[1].r, color_[1].g, color_[1].b);
jailgames_texture_->setColor(color_.at(1).r, color_.at(1).g, color_.at(1).b);
since_1998_texture_->setColor(color_.at(1).r, color_.at(1).g, color_.at(1).b);
}
else if (counter_ == INIT_FADE_ + inc * 6)
else if (counter_ == INIT_FADE_ + INC * 6)
{
jailgames_texture_->setColor(color_[0].r, color_[0].g, color_[0].b);
since_1998_texture_->setColor(color_[0].r, color_[0].g, color_[0].b);
jailgames_texture_->setColor(color_.at(0).r, color_.at(0).g, color_.at(0).b);
since_1998_texture_->setColor(color_.at(0).r, color_.at(0).g, color_.at(0).b);
}
}

View File

@@ -39,7 +39,6 @@ bool loadOptionsFromFile(const std::string &file_path)
options.version = "";
// Variables para manejar el fichero
std::string line;
std::ifstream file(file_path);
// Si el fichero se puede abrir
@@ -50,6 +49,7 @@ bool loadOptionsFromFile(const std::string &file_path)
{
std::cout << "Reading file config.txt\n";
}
std::string line;
while (std::getline(file, line))
{
// Elimina espacios en blanco iniciales y finales

View File

@@ -83,7 +83,7 @@ constexpr NotificationPosition DEFAULT_NOTIFICATION_POSITION = NotificationPosit
constexpr bool DEFAULT_NOTIFICATION_SOUND = true; // Sonido de las notificaciones por defecto
const Color DEFAULT_NOTIFICATION_COLOR = Color(48, 48, 48); // Color de las notificaciones por defecto
constexpr bool DEFAULT_CONSOLE = false; // Consola desactivada por defecto
constexpr const char *DEFAULT_VERSION = "1.09"; // Versión por defecto
constexpr const char *DEFAULT_VERSION = "1.10"; // Versión por defecto
// Estructura para las opciones de las notificaciones
struct OptionsNotification
@@ -212,7 +212,7 @@ struct OptionsStats
worst_nightmare("") {}
// Constructor
OptionsStats(int r, int i, std::string wn)
OptionsStats(int r, int i, const std::string wn)
: rooms(r),
items(i),
worst_nightmare(wn) {}

View File

@@ -16,7 +16,7 @@
#include "screen.h"
// Constructor
Player::Player(PlayerData player)
Player::Player(const PlayerData &player)
: renderer_(Screen::get()->getRenderer()),
input_(Input::get()),
asset_(Asset::get()),
@@ -82,13 +82,13 @@ void Player::checkInput()
if (!auto_movement_)
{
// Comprueba las entradas de desplazamiento lateral solo en el caso de no estar enganchado a una superficie automatica
if (input_->checkInput(input_left))
if (input_->checkInput(InputAction::LEFT))
{
vx_ = -0.6f;
sprite_->setFlip(SDL_FLIP_HORIZONTAL);
}
else if (input_->checkInput(input_right))
else if (input_->checkInput(InputAction::RIGHT))
{
vx_ = 0.6f;
sprite_->setFlip(SDL_FLIP_NONE);
@@ -119,7 +119,7 @@ void Player::checkInput()
}
}
if (input_->checkInput(input_jump))
if (input_->checkInput(InputAction::JUMP))
{
// Solo puede saltar si ademas de estar (state == s_standing)
// Esta sobre el suelo, rampa o suelo que se mueve

View File

@@ -168,7 +168,7 @@ public:
public:
// Constructor
Player(PlayerData player);
explicit Player(const PlayerData &player);
// Destructor
~Player() = default;
@@ -210,8 +210,5 @@ public:
bool isAlive() { return is_alive_; }
// Pone el jugador en modo pausa
void pause() { is_paused_ = true; }
// Quita el modo pausa del jugador
void resume() { is_paused_ = false; }
void setPaused(bool value) { is_paused_ = value; }
};

View File

@@ -23,12 +23,12 @@ std::vector<int> loadRoomTileFile(const std::string &file_path, bool verbose)
{
std::vector<int> tileMapFile;
const std::string filename = file_path.substr(file_path.find_last_of("\\/") + 1);
std::string line;
std::ifstream file(file_path);
// El fichero se puede abrir
if (file.good())
{
std::string line;
// Procesa el fichero linea a linea
while (std::getline(file, line))
{ // Lee el fichero linea a linea
@@ -81,12 +81,12 @@ RoomData loadRoomFile(const std::string &file_path, bool verbose)
const std::string fileName = file_path.substr(file_path.find_last_of("\\/") + 1);
room.number = fileName.substr(0, fileName.find_last_of("."));
std::string line;
std::ifstream file(file_path);
// El fichero se puede abrir
if (file.good())
{
std::string line;
// Procesa el fichero linea a linea
while (std::getline(file, line))
{
@@ -398,13 +398,14 @@ bool setItem(ItemData *item, const std::string &key, const std::string &value)
}
// Constructor
Room::Room(std::shared_ptr<RoomData> room, std::shared_ptr<ScoreboardData> data)
Room::Room(const std::string &room_path, std::shared_ptr<ScoreboardData> data)
: screen_(Screen::get()),
renderer_(Screen::get()->getRenderer()),
asset_(Asset::get()),
debug_(Debug::get()),
data_(data)
{
auto room = Resource::get()->getRoom(room_path);
number_ = room->number;
name_ = room->name;
bg_color_ = room->bg_color;
@@ -419,11 +420,11 @@ Room::Room(std::shared_ptr<RoomData> room, std::shared_ptr<ScoreboardData> data)
tile_map_file_ = room->tile_map_file;
auto_surface_direction_ = room->auto_surface_direction;
tile_map_ = Resource::get()->getTileMap(room->tile_map_file);
texture_ = (options.video.palette == Palette::ZXSPECTRUM) ? Resource::get()->getTexture(room->tile_set_file) : Resource::get()->getTexture(room->tile_set_file);
texture_ = Resource::get()->getTexture(room->tile_set_file);
// Inicializa variables
tile_set_width_ = texture_->getWidth() / TILE_SIZE_;
paused_ = false;
is_paused_ = false;
counter_ = 0;
// Crea los enemigos
@@ -674,7 +675,7 @@ void Room::renderItems()
// Actualiza las variables y objetos de la habitación
void Room::update()
{
if (paused_)
if (is_paused_)
{ // Si está en modo pausa no se actualiza nada
return;
}
@@ -846,7 +847,7 @@ void Room::reLoadPalette()
screen_->setBorderColor(stringToColor(options.video.palette, border_color_));
// Cambia la textura
//texture_ = (options.video.palette == Palette::ZXSPECTRUM) ? Resource::get()->getTexture(room->tile_set_file) : Resource::get()->getTexture(room->tile_set_file);
// texture_ = (options.video.palette == Palette::ZXSPECTRUM) ? Resource::get()->getTexture(room->tile_set_file) : Resource::get()->getTexture(room->tile_set_file);
// Pone la nueva textura a los tiles animados
for (auto tile : animated_tiles_)
@@ -926,20 +927,19 @@ void Room::setBottomSurfaces()
if ((int)tile.size() > 1)
{
int i = 0;
int lastOne = 0;
do
{
h_line_t line;
line.x1 = (tile[i] % MAP_WIDTH_) * TILE_SIZE_;
line.y = ((tile[i] / MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1;
lastOne = i;
int last_one = i;
i++;
if (i <= (int)tile.size() - 1)
{
while (tile[i] == tile[i - 1] + 1)
{
lastOne = i;
last_one = i;
if (i == (int)tile.size() - 1)
{
break;
@@ -948,7 +948,7 @@ void Room::setBottomSurfaces()
}
}
line.x2 = ((tile[lastOne] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1;
line.x2 = ((tile[last_one] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1;
bottom_surfaces_.push_back(line);
if (i <= (int)tile.size() - 1)
{
@@ -989,20 +989,19 @@ void Room::setTopSurfaces()
if ((int)tile.size() > 1)
{
int i = 0;
int lastOne = 0;
do
{
h_line_t line;
line.x1 = (tile[i] % MAP_WIDTH_) * TILE_SIZE_;
line.y = (tile[i] / MAP_WIDTH_) * TILE_SIZE_;
lastOne = i;
int last_one = i;
i++;
if (i <= (int)tile.size() - 1)
{
while (tile[i] == tile[i - 1] + 1)
{
lastOne = i;
last_one = i;
if (i == (int)tile.size() - 1)
{
break;
@@ -1011,7 +1010,7 @@ void Room::setTopSurfaces()
}
}
line.x2 = ((tile[lastOne] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1;
line.x2 = ((tile[last_one] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1;
top_surfaces_.push_back(line);
if (i <= (int)tile.size() - 1)
{
@@ -1224,23 +1223,22 @@ void Room::setAutoSurfaces()
}
// Recorre el vector de tiles buscando tiles consecutivos para localizar las superficies
int i = 0;
int lastOne = 0;
if ((int)tile.size() > 0)
{
int i = 0;
do
{
h_line_t line;
line.x1 = (tile[i] % MAP_WIDTH_) * TILE_SIZE_;
line.y = (tile[i] / MAP_WIDTH_) * TILE_SIZE_;
lastOne = i;
int last_one = i;
i++;
if (i <= (int)tile.size() - 1)
{
while (tile[i] == tile[i - 1] + 1)
{
lastOne = i;
last_one = i;
if (i == (int)tile.size() - 1)
{
break;
@@ -1249,7 +1247,7 @@ void Room::setAutoSurfaces()
}
}
line.x2 = ((tile[lastOne] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1;
line.x2 = ((tile[last_one] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1;
auto_surfaces_.push_back(line);
if (i <= (int)tile.size() - 1)
{
@@ -1474,18 +1472,6 @@ bool Room::checkRightSlopes(SDL_Point *p)
return false;
}
// Pone el mapa en modo pausa
void Room::pause()
{
paused_ = true;
}
// Quita el modo pausa del mapa
void Room::resume()
{
paused_ = false;
}
// Obten la direccion de las superficies automaticas
int Room::getAutoSurfaceDirection()
{

View File

@@ -111,7 +111,7 @@ private:
std::vector<d_line_t> left_slopes_; // Lista con todas las rampas que suben hacia la izquierda
std::vector<d_line_t> right_slopes_; // Lista con todas las rampas que suben hacia la derecha
int counter_; // Contador para lo que haga falta
bool paused_; // Indica si el mapa esta en modo pausa
bool is_paused_; // Indica si el mapa esta en modo pausa
std::vector<aTile_t> animated_tiles_; // Vector con los indices de tiles animados
std::vector<h_line_t> auto_surfaces_; // Lista con las superficies automaticas de la habitación
int tile_set_width_; // Ancho del tileset en tiles
@@ -157,7 +157,7 @@ private:
public:
// Constructor
Room(std::shared_ptr<RoomData> room, std::shared_ptr<ScoreboardData> data);
Room(const std::string &room_path, std::shared_ptr<ScoreboardData> data);
// Destructor
~Room();
@@ -241,10 +241,7 @@ public:
bool checkRightSlopes(SDL_Point *p);
// Pone el mapa en modo pausa
void pause();
// Quita el modo pausa del mapa
void resume();
void setPaused(bool value) { is_paused_ = value; };
// Obten la direccion de las superficies automaticas
int getAutoSurfaceDirection();

View File

@@ -1,20 +1,9 @@
#include "room_tracker.h"
// Constructor
RoomTracker::RoomTracker()
{
}
// Destructor
RoomTracker::~RoomTracker()
{
list.clear();
}
// Comprueba si la habitación ya ha sido visitada
bool RoomTracker::hasBeenVisited(std::string name)
bool RoomTracker::hasBeenVisited(const std::string &name)
{
for (auto l : list)
for (const auto &l : list)
{
if (l == name)
{
@@ -26,7 +15,7 @@ bool RoomTracker::hasBeenVisited(std::string name)
}
// Añade la habitación a la lista
bool RoomTracker::addRoom(std::string name)
bool RoomTracker::addRoom(const std::string &name)
{
// Comprueba si la habitación ya ha sido visitada
if (!hasBeenVisited(name))

View File

@@ -10,15 +10,15 @@ private:
std::vector<std::string> list; // Lista con las habitaciones visitadas
// Comprueba si la habitación ya ha sido visitada
bool hasBeenVisited(std::string name);
bool hasBeenVisited(const std::string &name);
public:
// Constructor
RoomTracker();
RoomTracker() = default;
// Destructor
~RoomTracker();
~RoomTracker() = default;
// Añade la habitación a la lista
bool addRoom(std::string name);
bool addRoom(const std::string &name);
};

View File

@@ -16,7 +16,8 @@ Scoreboard::Scoreboard(std::shared_ptr<ScoreboardData> data)
: renderer_(Screen::get()->getRenderer()),
resource_(Resource::get()),
asset_(Asset::get()),
data_(data)
data_(data),
clock_(ClockData())
{
const int TEXTURE_WIDTH_ = options.game.width;
constexpr int TEXTURE_HEIGHT_ = 6 * BLOCK;
@@ -48,10 +49,10 @@ Scoreboard::Scoreboard(std::shared_ptr<ScoreboardData> data)
items_color_ = stringToColor(options.video.palette, "white");
// Inicializa el vector de colores
const std::vector<std::string> vColors = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"};
for (auto v : vColors)
const std::vector<std::string> COLORS = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"};
for (const auto &color : COLORS)
{
color_.push_back(stringToColor(options.video.palette, v));
color_.push_back(stringToColor(options.video.palette, color));
}
}
@@ -122,17 +123,26 @@ void Scoreboard::reLoadPalette()
}
// Pone el marcador en modo pausa
void Scoreboard::pause()
void Scoreboard::setPaused(bool value)
{
is_paused_ = true;
paused_time_ = SDL_GetTicks();
}
if (is_paused_ == value)
{
// Evita ejecutar lógica si el estado no cambia
return;
}
// Quita el modo pausa del marcador
void Scoreboard::resume()
{
is_paused_ = false;
is_paused_ = value;
if (is_paused_)
{
// Guarda el tiempo actual al pausar
paused_time_ = SDL_GetTicks();
}
else
{
// Calcula el tiempo pausado acumulado al reanudar
paused_time_elapsed_ += SDL_GetTicks() - paused_time_;
}
}
// Actualiza el color de la cantidad de items recogidos

View File

@@ -15,16 +15,20 @@ class Texture;
struct ScoreboardData
{
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 las vidas restantes del jugador
int rooms; // Lleva la cuenta de las habitaciones visitadas
bool music; // Indica si ha de sonar la musica durante el juego
bool music; // Indica si ha de sonar la música durante el juego
Color color; // Color para escribir el texto del marcador
Uint32 ini_clock; // Tiempo inicial para calcular el tiempo transcurrido
bool jail_is_open; // Indica si se puede entrar a la Jail
// Constructor
// Constructor por defecto
ScoreboardData()
: items(0), lives(3), rooms(0), music(true), color({0, 0, 0}), ini_clock(0), jail_is_open(false) {}
: items(0), lives(0), rooms(0), music(true), color({0, 0, 0}), ini_clock(0), jail_is_open(false) {}
// Constructor parametrizado
ScoreboardData(int items, int lives, int rooms, bool music, Color color, Uint32 ini_clock, bool jail_is_open)
: items(items), lives(lives), rooms(rooms), music(music), color(color), ini_clock(ini_clock), jail_is_open(jail_is_open) {}
};
class Scoreboard
@@ -36,6 +40,14 @@ private:
int minutes;
int seconds;
std::string separator;
// Constructor por defecto
ClockData()
: hours(0), minutes(0), seconds(0), separator(":") {}
// Constructor parametrizado
ClockData(int h, int m, int s, const std::string &sep)
: hours(h), minutes(m), seconds(s), separator(sep) {}
};
// Objetos y punteros
@@ -70,7 +82,7 @@ private:
public:
// Constructor
Scoreboard(std::shared_ptr<ScoreboardData> data);
explicit Scoreboard(std::shared_ptr<ScoreboardData> data);
// Destructor
~Scoreboard();
@@ -88,10 +100,7 @@ public:
void reLoadPalette();
// Pone el marcador en modo pausa
void pause();
// Quita el modo pausa del marcador
void resume();
void setPaused(bool value);
// Devuelve la cantidad de minutos de juego transcurridos
int getMinutes();

View File

@@ -416,12 +416,3 @@ int Screen::getMaxZoom()
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

@@ -58,9 +58,6 @@ private:
// Ajusta el tamaño lógico del renderizador
void adjustRenderLogicalSize();
// Renderiza un frame negro
void renderBlackFrame();
// Constructor
Screen(SDL_Window *window, SDL_Renderer *renderer);

View File

@@ -4,14 +4,9 @@
#include "options.h" // for Options, OptionsStats, options
// Constructor
Stats::Stats(std::string file, std::string buffer)
{
bufferPath = buffer;
filePath = file;
bufferList.clear();
list.clear();
dictionary.clear();
}
Stats::Stats(const std::string &file, const std::string &buffer)
: bufferPath(buffer),
filePath(file) {}
// Destructor
Stats::~Stats()
@@ -43,7 +38,7 @@ void Stats::init()
}
// Añade una muerte a las estadisticas
void Stats::addDeath(std::string name)
void Stats::addDeath(const std::string &name)
{
// Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name, bufferList);
@@ -64,7 +59,7 @@ void Stats::addDeath(std::string name)
}
// Añade una visita a las estadisticas
void Stats::addVisit(std::string name)
void Stats::addVisit(const std::string &name)
{
// Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name, bufferList);
@@ -85,11 +80,11 @@ void Stats::addVisit(std::string name)
}
// Busca una entrada en la lista por nombre
int Stats::findByName(std::string name, std::vector<stats_t> &list)
int Stats::findByName(const std::string &name, const std::vector<stats_t> &list)
{
int i = 0;
for (auto l : list)
for (const auto &l : list)
{
if (l.name == name)
{
@@ -102,7 +97,7 @@ int Stats::findByName(std::string name, std::vector<stats_t> &list)
}
// Carga las estadisticas desde un fichero
bool Stats::loadFromFile(std::string filePath, std::vector<stats_t> &list)
bool Stats::loadFromFile(const std::string &file_path, std::vector<stats_t> &list)
{
list.clear();
@@ -110,12 +105,12 @@ bool Stats::loadFromFile(std::string filePath, std::vector<stats_t> &list)
bool success = true;
// Variables para manejar el fichero
std::string line;
std::ifstream file(filePath);
std::ifstream file(file_path);
// Si el fichero se puede abrir
if (file.good())
{
std::string line;
// Procesa el fichero linea a linea
while (std::getline(file, line))
{
@@ -150,21 +145,21 @@ bool Stats::loadFromFile(std::string filePath, std::vector<stats_t> &list)
else
{
// Crea el fichero con los valores por defecto
saveToFile(filePath, list);
saveToFile(file_path, list);
}
return success;
}
// Guarda las estadisticas en un fichero
void Stats::saveToFile(std::string filePath, std::vector<stats_t> &list)
void Stats::saveToFile(const std::string &file_path, const std::vector<stats_t> &list)
{
// Crea y abre el fichero de texto
std::ofstream file(filePath);
std::ofstream file(file_path);
// Escribe en el fichero
file << "# ROOM NAME;VISITS;DEATHS" << std::endl;
for (auto item : list)
for (const auto &item : list)
{
file << item.name << ";" << item.visited << ";" << item.died << std::endl;
}
@@ -177,7 +172,7 @@ void Stats::saveToFile(std::string filePath, std::vector<stats_t> &list)
void Stats::checkWorstNightmare()
{
int deaths = 0;
for (auto item : list)
for (const auto &item : list)
{
if (item.died > deaths)
{
@@ -188,42 +183,16 @@ void Stats::checkWorstNightmare()
}
// Añade una entrada al diccionario
void Stats::addDictionary(std::string number, std::string name)
void Stats::addDictionary(const std::string &number, const std::string &name)
{
dictionary.push_back({number, name});
}
// Obtiene el nombre de una habitación a partir del número
std::string Stats::numberToName(std::string number)
{
for (auto l : dictionary)
{
if (l.number == number)
{
return l.name;
}
}
return "";
}
// Obtiene el número de una habitación a partir del nombre
std::string Stats::nameToNumber(std::string name)
{
for (auto l : dictionary)
{
if (l.name == name)
{
return l.number;
}
}
return "";
}
// Vuelca los datos del buffer en la lista de estadisticas
void Stats::updateListFromBuffer()
{
// Actualiza list desde bufferList
for (auto buffer : bufferList)
for (const auto &buffer : bufferList)
{
int index = findByName(buffer.name, list);

View File

@@ -27,29 +27,23 @@ private:
std::string filePath; // Fichero con las estadísticas completas
// Busca una entrada en la lista por nombre
int findByName(std::string name, std::vector<stats_t> &list);
int findByName(const std::string &name, const std::vector<stats_t> &list);
// Carga las estadisticas desde un fichero
bool loadFromFile(std::string filePath, std::vector<stats_t> &list);
bool loadFromFile(const std::string &filePath, std::vector<stats_t> &list);
// Guarda las estadisticas en un fichero
void saveToFile(std::string filePath, std::vector<stats_t> &list);
void saveToFile(const std::string &filePath, const std::vector<stats_t> &list);
// Calcula cual es la habitación con más muertes
void checkWorstNightmare();
// Obtiene el nombre de una habitación a partir del número
std::string numberToName(std::string number);
// Obtiene el número de una habitación a partir del nombre
std::string nameToNumber(std::string name);
// Vuelca los datos del buffer en la lista de estadisticas
void updateListFromBuffer();
public:
// Constructor
Stats(std::string file, std::string buffer);
Stats(const std::string &file, const std::string &buffer);
// Destructor
~Stats();
@@ -59,11 +53,11 @@ public:
void init();
// Añade una muerte a las estadisticas
void addDeath(std::string name);
void addDeath(const std::string &name);
// Añade una visita a las estadisticas
void addVisit(std::string name);
void addVisit(const std::string &name);
// Añade una entrada al diccionario
void addDictionary(std::string number, std::string name);
void addDictionary(const std::string &number, const std::string &name);
};

View File

@@ -15,12 +15,10 @@ Surface::Surface(std::shared_ptr<SurfaceData> surface_dest, int w, int h)
surface_(std::make_shared<SurfaceData>(w, h)),
transparent_color_(0) {}
Surface::Surface(std::shared_ptr<SurfaceData> surface_dest, std::string file_path)
Surface::Surface(std::shared_ptr<SurfaceData> surface_dest, const 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;
}
transparent_color_(0) {}
Surface::~Surface() {}

View File

@@ -74,7 +74,7 @@ private:
public:
// Constructor
Surface(std::shared_ptr<SurfaceData> surface_dest, int w, int h);
Surface(std::shared_ptr<SurfaceData> surface_dest, std::string file_path);
Surface(std::shared_ptr<SurfaceData> surface_dest, const std::string &file_path);
// Destructor
~Surface();

View File

@@ -59,7 +59,7 @@ Title::Title()
pSetSource(loading_screen_);
// Inicializa variables
state_ = options.section.subsection == Subsection::TITLE_WITH_LOADING_SCREEN ? show_loading_screen : show_menu;
state_ = options.section.subsection == Subsection::TITLE_WITH_LOADING_SCREEN ? TitleState::SHOW_LOADING_SCREEN : TitleState::SHOW_MENU;
options.section.section = Section::TITLE;
options.section.subsection = Subsection::NONE;
initMarquee();
@@ -91,7 +91,7 @@ void Title::initMarquee()
long_text_ = "HEY JAILERS!! IT'S 2022 AND WE'RE STILL ROCKING LIKE IT'S 1998!!! HAVE YOU HEARD IT? JAILGAMES ARE BACK!! YEEESSS BACK!! MORE THAN 10 TITLES ON JAILDOC'S KITCHEN!! THATS A LOOOOOOT OF JAILGAMES, BUT WHICH ONE WILL STRIKE FIRST? THERE IS ALSO A NEW DEVICE TO COME THAT WILL BLOW YOUR MIND WITH JAILGAMES ON THE GO: P.A.C.O. BUT WAIT! WHAT'S THAT BEAUTY I'M SEEING RIGHT OVER THERE?? OOOH THAT TINY MINIASCII IS PURE LOVE!! I WANT TO LICK EVERY BYTE OF IT!! OH SHIT! AND DON'T FORGET TO BRING BACK THOSE OLD AND FAT MS-DOS JAILGAMES TO GITHUB TO KEEP THEM ALIVE!! WHAT WILL BE THE NEXT JAILDOC RELEASE? WHAT WILL BE THE NEXT PROJECT TO COME ALIVE?? OH BABY WE DON'T KNOW BUT HERE YOU CAN FIND THE ANSWER, YOU JUST HAVE TO COMPLETE JAILDOCTOR'S DILEMMA ... COULD YOU?";
for (int i = 0; i < (int)long_text_.length(); ++i)
{
letter_t l;
TitleLetter l;
l.letter = long_text_.substr(i, 1);
l.x = 256;
l.enabled = false;
@@ -137,26 +137,26 @@ void Title::checkInput()
{
if (show_cheevos_)
{
if (input_->checkInput(input_down, REPEAT_TRUE))
if (input_->checkInput(InputAction::DOWN, REPEAT_TRUE))
{
moveCheevosList(1);
}
else if (input_->checkInput(input_up, REPEAT_TRUE))
else if (input_->checkInput(InputAction::UP, REPEAT_TRUE))
{
moveCheevosList(0);
}
else if (input_->checkInput(input_accept, REPEAT_FALSE))
else if (input_->checkInput(InputAction::ACCEPT, REPEAT_FALSE))
{
hideCheevosList();
counter_ = 0;
}
}
if (input_->checkInput(input_accept, REPEAT_FALSE))
if (input_->checkInput(InputAction::ACCEPT, REPEAT_FALSE))
{
if (state_ == show_loading_screen)
if (state_ == TitleState::SHOW_LOADING_SCREEN)
{
state_ = fade_loading_screen;
state_ = TitleState::FADE_LOADING_SCREEN;
}
}
@@ -196,7 +196,7 @@ void Title::updateMarquee()
// Dibuja la marquesina
void Title::renderMarquee()
{
for (auto l : letters_)
for (const auto &l : letters_)
{
if (l.enabled)
{
@@ -205,14 +205,6 @@ void Title::renderMarquee()
}
}
// Dibuja la linea de información inferior
void Title::renderInfo()
{
const std::string version = "v.1.09";
const int x = GAMECANVAS_WIDTH - info_text_->lenght(version) - 1;
info_text_->write(x, 1, version);
}
// Actualiza las variables
void Title::update()
{
@@ -232,24 +224,26 @@ void Title::update()
switch (state_)
{
case show_loading_screen:
case TitleState::SHOW_LOADING_SCREEN:
if (counter_ == 500)
{
counter_ = 0;
state_ = fade_loading_screen;
state_ = TitleState::FADE_LOADING_SCREEN;
}
break;
case fade_loading_screen:
case TitleState::FADE_LOADING_SCREEN:
if (counter_ % 4 == 0)
{
if (pFadePal())
{
counter_ = 0;
state_ = show_menu;
state_ = TitleState::SHOW_MENU;
}
}
break;
case show_menu:
case TitleState::SHOW_MENU:
// Actualiza la marquesina
updateMarquee();
@@ -277,7 +271,7 @@ void Title::render()
screen_->start();
screen_->clean(stringToColor(options.video.palette, "black"));
if (state_ == show_menu)
if (state_ == TitleState::SHOW_MENU)
{
// Dibuja la textura de fondo
SDL_RenderCopy(renderer_, bg_texture_, nullptr, nullptr);
@@ -317,40 +311,6 @@ void Title::run()
}
}
// Recarga las texturas
void Title::reLoadTextures()
{
// Carga la textura adecuada
if (options.video.palette == Palette::ZXSPECTRUM)
{
texture_ = resource_->getTexture("loading_screen_color.png");
}
else if (options.video.palette == Palette::ZXARNE)
{
texture_ = resource_->getTexture("loading_screen_color_zxarne.png");
}
texture_->reLoad();
}
// Cambia la paleta
void Title::switchPalette()
{
if (options.video.palette == Palette::ZXSPECTRUM)
{
options.video.palette = Palette::ZXARNE;
sprite_->setTexture(resource_->getTexture("loading_screen_color_zxarne.png"));
}
else
{
options.video.palette = Palette::ZXSPECTRUM;
sprite_->setTexture(resource_->getTexture("loading_screen_color.png"));
}
// Cambia el color del borde
screen_->setBorderColor(stringToColor(options.video.palette, "bright_blue"));
}
// Desplaza la lista de logros
void Title::moveCheevosList(int direction)
{
@@ -401,50 +361,50 @@ void Title::createCheevosTexture()
{
// Crea la textura con el listado de logros
const auto cheevosList = Cheevos::get()->list();
const int cheevosTextureWidth = 200;
const int cheevosTextureViewHeight = 110;
const int cheevosTexturePosY = 73;
const int cheevosPadding = 10;
const int cheevoHeight = cheevosPadding + (info_text_->getCharacterSize() * 2) + 1;
const int cheevosTextureHeight = (cheevoHeight * cheevosList.size()) + 2 + info_text_->getCharacterSize() + 8;
constexpr int CHEEVOS_TEXTURE_WIDTH = 200;
constexpr int CHEEVOS_TEXTURE_VIEW_HEIGHT = 110;
constexpr int CHEEVOS_TEXTURE_POS_Y = 73;
constexpr int CHEEVOS_PADDING = 10;
const int CHEEVO_HEIGHT = CHEEVOS_PADDING + (info_text_->getCharacterSize() * 2) + 1;
const int CHEEVOS_TEXTURE_HEIGHT = (CHEEVO_HEIGHT * cheevosList.size()) + 2 + info_text_->getCharacterSize() + 8;
cheevos_texture_ = std::make_shared<Texture>(renderer_);
cheevos_texture_->createBlank(cheevosTextureWidth, cheevosTextureHeight, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
cheevos_texture_->createBlank(CHEEVOS_TEXTURE_WIDTH, CHEEVOS_TEXTURE_HEIGHT, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
cheevos_texture_->setAsRenderTarget(renderer_);
cheevos_texture_->setBlendMode(SDL_BLENDMODE_BLEND);
// Rellena la textura con color sólido
const Color cheevosBGColor = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer_, cheevosBGColor.r, cheevosBGColor.g, cheevosBGColor.b, 0xFF);
const Color CHEEVOS_BG_COLOR = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer_, CHEEVOS_BG_COLOR.r, CHEEVOS_BG_COLOR.g, CHEEVOS_BG_COLOR.b, 0xFF);
SDL_RenderClear(renderer_);
// Escribe la lista de logros en la textura
const std::string cheevosOwner = "ACHIEVEMENTS";
const std::string cheevosListCaption = cheevosOwner + " (" + std::to_string(Cheevos::get()->unlocked()) + " / " + std::to_string(Cheevos::get()->count()) + ")";
const std::string CHEEVOS_OWNER = "ACHIEVEMENTS";
const std::string CHEEVOS_LIST_CAPTION = CHEEVOS_OWNER + " (" + std::to_string(Cheevos::get()->unlocked()) + " / " + std::to_string(Cheevos::get()->size()) + ")";
int pos = 2;
info_text_->writeDX(TEXT_CENTER | TEXT_COLOR, cheevos_texture_->getWidth() / 2, pos, cheevosListCaption, 1, stringToColor(options.video.palette, "bright_green"));
info_text_->writeDX(TEXT_CENTER | TEXT_COLOR, cheevos_texture_->getWidth() / 2, pos, CHEEVOS_LIST_CAPTION, 1, stringToColor(options.video.palette, "bright_green"));
pos += info_text_->getCharacterSize();
const Color cheevoLockedColor = stringToColor(options.video.palette, "white");
const Color cheevoUnlockedColor = stringToColor(options.video.palette, "bright_green");
const Color CHEEVO_LOCKED_COLOR = stringToColor(options.video.palette, "white");
const Color CHEEVO_UNLOCKED_COLOR = stringToColor(options.video.palette, "bright_green");
Color cheevoColor;
SDL_SetRenderDrawColor(renderer_, cheevoLockedColor.r, cheevoLockedColor.g, cheevoLockedColor.b, 0xFF);
const int lineX1 = (cheevosTextureWidth / 7) * 3;
const int lineX2 = lineX1 + ((cheevosTextureWidth / 7) * 1);
SDL_SetRenderDrawColor(renderer_, CHEEVO_LOCKED_COLOR.r, CHEEVO_LOCKED_COLOR.g, CHEEVO_LOCKED_COLOR.b, 0xFF);
constexpr int LINE_X1 = (CHEEVOS_TEXTURE_WIDTH / 7) * 3;
constexpr int LINE_X2 = LINE_X1 + ((CHEEVOS_TEXTURE_WIDTH / 7) * 1);
for (auto cheevo : cheevosList)
for (const auto &cheevo : cheevosList)
{
cheevoColor = cheevo.completed ? cheevoUnlockedColor : cheevoLockedColor;
pos += cheevosPadding;
int half = cheevosPadding / 2;
SDL_RenderDrawLine(renderer_, lineX1, pos - half - 1, lineX2, pos - half - 1);
info_text_->writeDX(TEXT_CENTER | TEXT_COLOR, cheevosTextureWidth / 2, pos, cheevo.caption, 1, cheevoColor);
cheevoColor = cheevo.completed ? CHEEVO_UNLOCKED_COLOR : CHEEVO_LOCKED_COLOR;
pos += CHEEVOS_PADDING;
constexpr int HALF = CHEEVOS_PADDING / 2;
SDL_RenderDrawLine(renderer_, LINE_X1, pos - HALF - 1, LINE_X2, pos - HALF - 1);
info_text_->writeDX(TEXT_CENTER | TEXT_COLOR, CHEEVOS_TEXTURE_WIDTH / 2, pos, cheevo.caption, 1, cheevoColor);
pos += info_text_->getCharacterSize() + 1;
info_text_->writeDX(TEXT_CENTER | TEXT_COLOR, cheevosTextureWidth / 2, pos, cheevo.description, 1, cheevoColor);
info_text_->writeDX(TEXT_CENTER | TEXT_COLOR, CHEEVOS_TEXTURE_WIDTH / 2, pos, cheevo.description, 1, cheevoColor);
pos += info_text_->getCharacterSize();
}
// Crea el sprite para el listado de logros
cheevos_sprite_ = std::make_shared<Sprite>(cheevos_texture_, (GAMECANVAS_WIDTH - cheevos_texture_->getWidth()) / 2, cheevosTexturePosY, cheevos_texture_->getWidth(), cheevos_texture_->getHeight());
cheevos_texture_view_ = {0, 0, cheevos_texture_->getWidth(), cheevosTextureViewHeight};
cheevos_sprite_ = std::make_shared<Sprite>(cheevos_texture_, (GAMECANVAS_WIDTH - cheevos_texture_->getWidth()) / 2, CHEEVOS_TEXTURE_POS_Y, cheevos_texture_->getWidth(), cheevos_texture_->getHeight());
cheevos_texture_view_ = {0, 0, cheevos_texture_->getWidth(), CHEEVOS_TEXTURE_VIEW_HEIGHT};
cheevos_sprite_->setClip(cheevos_texture_view_);
}

View File

@@ -17,18 +17,18 @@ class Texture; // lines 18-18
class Title
{
private:
struct letter_t
struct TitleLetter
{
std::string letter; // Letra a escribir
int x; // Posición en el eje x
bool enabled; // Solo se escriben y mueven si estan habilitadas
};
enum states_e
enum class TitleState
{
show_loading_screen,
fade_loading_screen,
show_menu
SHOW_LOADING_SCREEN,
FADE_LOADING_SCREEN,
SHOW_MENU
};
// Objetos y punteros
@@ -48,11 +48,11 @@ private:
int counter_ = 0; // Contador
std::string long_text_; // Texto que aparece en la parte inferior del titulo
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
std::vector<letter_t> letters_; // Vector con las letras de la marquesina
std::vector<TitleLetter> letters_; // Vector con las letras de la marquesina
int marquee_speed_ = 3; // Velocidad de desplazamiento de la marquesina
bool show_cheevos_ = false; // Indica si se muestra por pantalla el listado de logros
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
TitleState state_; // Estado en el que se encuentra el bucle principal
jSurface loading_screen_; // Surface con los gráficos de la pantalla de carga
// Actualiza las variables
@@ -76,15 +76,6 @@ private:
// Dibuja la marquesina
void renderMarquee();
// Dibuja la linea de información inferior
void renderInfo();
// Recarga las texturas
void reLoadTextures();
// Cambia la paleta
void switchPalette();
// Desplaza la lista de logros
void moveCheevosList(int direction);

View File

@@ -20,7 +20,7 @@ double distanceSquared(int x1, int y1, int x2, int y2)
}
// Detector de colisiones entre dos circulos
bool checkCollision(Circle &a, Circle &b)
bool checkCollision(const Circle &a, const Circle &b)
{
// Calcula el radio total al cuadrado
int totalRadiusSquared = a.r + b.r;
@@ -38,7 +38,7 @@ bool checkCollision(Circle &a, Circle &b)
}
// Detector de colisiones entre un circulo y un rectangulo
bool checkCollision(Circle &a, SDL_Rect &b)
bool checkCollision(const Circle &a, const SDL_Rect &b)
{
// Closest point on collision box
int cX, cY;
@@ -83,7 +83,7 @@ bool checkCollision(Circle &a, SDL_Rect &b)
}
// Detector de colisiones entre dos rectangulos
bool checkCollision(SDL_Rect &a, SDL_Rect &b)
bool checkCollision(const SDL_Rect &a, const SDL_Rect &b)
{
// Calcula las caras del rectangulo a
const int leftA = a.x;
@@ -123,7 +123,7 @@ bool checkCollision(SDL_Rect &a, SDL_Rect &b)
}
// Detector de colisiones entre un punto y un rectangulo
bool checkCollision(SDL_Point &p, SDL_Rect &r)
bool checkCollision(const SDL_Point &p, const SDL_Rect &r)
{
// Comprueba si el punto está a la izquierda del rectangulo
if (p.x < r.x)
@@ -154,7 +154,7 @@ bool checkCollision(SDL_Point &p, SDL_Rect &r)
}
// Detector de colisiones entre una linea horizontal y un rectangulo
bool checkCollision(h_line_t &l, SDL_Rect &r)
bool checkCollision(const h_line_t &l, const SDL_Rect &r)
{
// Comprueba si la linea esta por encima del rectangulo
if (l.y < r.y)
@@ -185,7 +185,7 @@ bool checkCollision(h_line_t &l, SDL_Rect &r)
}
// Detector de colisiones entre una linea vertical y un rectangulo
bool checkCollision(v_line_t &l, SDL_Rect &r)
bool checkCollision(const v_line_t &l, const SDL_Rect &r)
{
// Comprueba si la linea esta por la izquierda del rectangulo
if (l.x < r.x)
@@ -216,7 +216,7 @@ bool checkCollision(v_line_t &l, SDL_Rect &r)
}
// Detector de colisiones entre una linea horizontal y un punto
bool checkCollision(h_line_t &l, SDL_Point &p)
bool checkCollision(const h_line_t &l, const SDL_Point &p)
{
// Comprueba si el punto esta sobre la linea
if (p.y > l.y)
@@ -247,7 +247,7 @@ bool checkCollision(h_line_t &l, SDL_Point &p)
}
// Detector de colisiones entre dos lineas
SDL_Point checkCollision(line_t &l1, line_t &l2)
SDL_Point checkCollision(const line_t &l1, const line_t &l2)
{
const float x1 = l1.x1;
const float y1 = l1.y1;
@@ -276,7 +276,7 @@ SDL_Point checkCollision(line_t &l1, line_t &l2)
}
// Detector de colisiones entre dos lineas
SDL_Point checkCollision(d_line_t &l1, v_line_t &l2)
SDL_Point checkCollision(const d_line_t &l1, const v_line_t &l2)
{
const float x1 = l1.x1;
const float y1 = l1.y1;
@@ -321,7 +321,7 @@ void normalizeLine(d_line_t &l)
}
// Detector de colisiones entre un punto y una linea diagonal
bool checkCollision(SDL_Point &p, d_line_t &l)
bool checkCollision(const SDL_Point &p, const d_line_t &l)
{
// Comprueba si el punto está en alineado con la linea
if (abs(p.x - l.x1) != abs(p.y - l.y1))
@@ -464,36 +464,26 @@ bool colorAreEqual(Color color1, Color color2)
return (r && g && b);
}
// Convierte una cadena a minusculas
// Convierte una cadena a minúsculas
std::string toLower(std::string str)
{
const char *original = str.c_str();
char *lower = (char *)malloc(str.size() + 1);
for (int i = 0; i < (int)str.size(); ++i)
{
char c = original[i];
lower[i] = (c >= 65 && c <= 90) ? c + 32 : c;
for (char& c : str) {
if (c >= 'A' && c <= 'Z') {
c += 32; // Convierte a minúscula
}
lower[str.size()] = 0;
std::string result(lower);
free(lower);
return result;
}
return str;
}
// Convierte una cadena a mayúsculas
std::string toUpper(std::string str)
{
const char *original = str.c_str();
char *upper = (char *)malloc(str.size() + 1);
for (int i = 0; i < (int)str.size(); ++i)
{
char c = original[i];
upper[i] = (c >= 97 && c <= 122) ? c - 32 : c;
for (char& c : str) {
if (c >= 'a' && c <= 'z') {
c -= 32; // Convierte a mayúscula
}
upper[str.size()] = 0;
std::string result(upper);
free(upper);
return result;
}
return str;
}
// Obtiene el nombre de un fichero a partir de una ruta completa

View File

@@ -7,7 +7,6 @@
#include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL.h> // for SDL_Texture
// Tipos de paleta
enum class Palette : int
{
@@ -66,34 +65,34 @@ struct Color
double distanceSquared(int x1, int y1, int x2, int y2);
// Detector de colisiones entre dos circulos
bool checkCollision(Circle &a, Circle &b);
bool checkCollision(const Circle &a, const Circle &b);
// Detector de colisiones entre un circulo y un rectangulo
bool checkCollision(Circle &a, SDL_Rect &b);
bool checkCollision(const Circle &a, const SDL_Rect &b);
// Detector de colisiones entre un dos rectangulos
bool checkCollision(SDL_Rect &a, SDL_Rect &b);
bool checkCollision(const SDL_Rect &a, const SDL_Rect &b);
// Detector de colisiones entre un punto y un rectangulo
bool checkCollision(SDL_Point &p, SDL_Rect &r);
bool checkCollision(const SDL_Point &p, const SDL_Rect &r);
// Detector de colisiones entre una linea horizontal y un rectangulo
bool checkCollision(h_line_t &l, SDL_Rect &r);
bool checkCollision(const h_line_t &l, const SDL_Rect &r);
// Detector de colisiones entre una linea vertical y un rectangulo
bool checkCollision(v_line_t &l, SDL_Rect &r);
bool checkCollision(const v_line_t &l, const SDL_Rect &r);
// Detector de colisiones entre una linea horizontal y un punto
bool checkCollision(h_line_t &l, SDL_Point &p);
bool checkCollision(const h_line_t &l, const SDL_Point &p);
// Detector de colisiones entre dos lineas
SDL_Point checkCollision(line_t &l1, line_t &l2);
SDL_Point checkCollision(const line_t &l1, const line_t &l2);
// Detector de colisiones entre dos lineas
SDL_Point checkCollision(d_line_t &l1, v_line_t &l2);
SDL_Point checkCollision(const d_line_t &l1, const v_line_t &l2);
// Detector de colisiones entre un punto y una linea diagonal
bool checkCollision(SDL_Point &p, d_line_t &l);
bool checkCollision(const SDL_Point &p, const d_line_t &l);
// Normaliza una linea diagonal
void normalizeLine(d_line_t &l);
@@ -135,4 +134,4 @@ bool stringInVector(const std::vector<std::string> &vec, const std::string &str)
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);
void fillTextureWithColor(SDL_Renderer *renderer, SDL_Texture *texture, Uint8 r, Uint8 g, Uint8 b, Uint8 a);