Arreglos en la estructura i format del codi

This commit is contained in:
2025-03-01 17:01:50 +01:00
parent 3562b139c3
commit 31cded15cc
35 changed files with 496 additions and 755 deletions

View File

@@ -28,83 +28,30 @@
// 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(InputAction::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(InputAction::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,7 +157,7 @@ void Game::update()
void Game::render()
{
// Prepara para dibujar el frame
screen_->start();
Screen::get()->start();
// test_surface_->render(0, 0, 10, 10, 64, 64);
// Dibuja los elementos del juego en orden
@@ -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};
}