Files
jaildoctors_dilemma/source2/Game/Scenes/game_over.cpp
2025-10-26 12:31:49 +01:00

162 lines
5.7 KiB
C++

#include "game_over.h"
#include <SDL3/SDL.h>
#include <algorithm> // Para min, max
#include <string> // Para basic_string, operator+, to_string
#include "defines.h" // Para GAMECANVAS_CENTER_X, GAME_SPEED
#include "external/jail_audio.h" // Para JA_PlayMusic
#include "global_events.h" // Para check
#include "global_inputs.h" // Para check
#include "options.h" // Para Options, options, OptionsStats, Secti...
#include "resource.h" // Para Resource
#include "screen.h" // Para Screen
#include "sprite/surface_animated_sprite.h" // Para SAnimatedSprite
#include "text.h" // Para TEXT_CENTER, TEXT_COLOR, Text
#include "utils.h" // Para PaletteColor, stringToColor
// Constructor
GameOver::GameOver()
: player_sprite_(std::make_shared<SAnimatedSprite>(Resource::get()->getSurface("player_game_over.gif"), Resource::get()->getAnimations("player_game_over.ani"))),
tv_sprite_(std::make_shared<SAnimatedSprite>(Resource::get()->getSurface("tv.gif"), Resource::get()->getAnimations("tv.ani"))),
pre_counter_(0),
counter_(0),
ticks_(0) {
options.section.section = Section::GAME_OVER;
options.section.subsection = Subsection::NONE;
player_sprite_->setPosX(GAMECANVAS_CENTER_X + 10);
player_sprite_->setPosY(30);
tv_sprite_->setPosX(GAMECANVAS_CENTER_X - tv_sprite_->getWidth() - 10);
tv_sprite_->setPosY(30);
Screen::get()->setBorderColor(static_cast<Uint8>(PaletteColor::BLACK));
// Inicializa el vector de colores
const std::vector<std::string> COLORS = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
for (const auto& color : COLORS) {
colors_.push_back(stringToColor(color));
}
color_ = colors_.back();
}
// Actualiza el objeto
void GameOver::update() {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks_ > GAME_SPEED) {
// Actualiza el contador de ticks
ticks_ = SDL_GetTicks();
// Comprueba las entradas
checkInput();
// Actualiza el color usado para renderizar los textos e imagenes
updateColor();
// Actualiza los contadores
updateCounters();
// Actualiza los dos sprites
player_sprite_->update();
tv_sprite_->update();
// Actualiza el objeto Screen
Screen::get()->update();
}
}
// Dibuja el final en pantalla
void GameOver::render() {
constexpr int Y = 32;
Screen::get()->start();
Screen::get()->clearSurface(static_cast<Uint8>(PaletteColor::BLACK));
auto text = Resource::get()->getText("smb2");
// Escribe el texto de GAME OVER
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y, "G A M E O V E R", 1, color_);
// Dibuja los sprites
player_sprite_->setPosY(Y + 30);
tv_sprite_->setPosY(Y + 30);
renderSprites();
// Escribe el texto con las habitaciones y los items
const std::string ITEMS_TEXT = std::to_string(options.stats.items / 100) + std::to_string((options.stats.items % 100) / 10) + std::to_string(options.stats.items % 10);
const std::string ROOMS_TEXT = std::to_string(options.stats.rooms / 100) + std::to_string((options.stats.rooms % 100) / 10) + std::to_string(options.stats.rooms % 10);
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 80, "ITEMS: " + ITEMS_TEXT, 1, color_);
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 90, "ROOMS: " + ROOMS_TEXT, 1, color_);
// Escribe el texto con "Tu peor pesadilla"
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 110, "YOUR WORST NIGHTMARE IS", 1, color_);
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 120, options.stats.worst_nightmare, 1, color_);
// Vuelca el contenido del renderizador en pantalla
Screen::get()->render();
}
// Comprueba el manejador de eventos
void GameOver::checkEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
globalEvents::check(event);
}
}
// Comprueba las entradas
void GameOver::checkInput() {
globalInputs::check();
}
// Bucle principal
void GameOver::run() {
while (options.section.section == Section::GAME_OVER) {
update();
checkEvents();
render();
}
}
// Actualiza el color usado para renderizar los textos e imagenes
void GameOver::updateColor() {
const int half = COUNTER_SECTION_END_ / 2;
if (counter_ < half) {
const float STEP = std::min(counter_, COUNTER_FADE_LENGHT_) / (float)COUNTER_FADE_LENGHT_;
const int INDEX = (colors_.size() - 1) - int((colors_.size() - 1) * STEP);
color_ = colors_[INDEX];
} else {
const float STEP = std::min(std::max(counter_, COUNTER_INIT_FADE_) - COUNTER_INIT_FADE_, COUNTER_FADE_LENGHT_) / (float)COUNTER_FADE_LENGHT_;
const int INDEX = (colors_.size() - 1) * STEP;
color_ = colors_[INDEX];
}
}
// Dibuja los sprites
void GameOver::renderSprites() {
player_sprite_->render(1, color_);
tv_sprite_->render(1, color_);
}
// Actualiza los contadores
void GameOver::updateCounters() {
// Actualiza el contador
if (pre_counter_ < 50) {
pre_counter_++;
} else {
counter_++;
}
// Hace sonar la música
if (counter_ == 1) {
JA_PlayMusic(Resource::get()->getMusic("game_over.ogg"), 0);
}
// Comprueba si ha terminado la sección
else if (counter_ == COUNTER_SECTION_END_) {
options.section.section = Section::LOGO;
options.section.subsection = Subsection::LOGO_TO_TITLE;
}
}