migrat GameOver a time based
This commit is contained in:
@@ -10,86 +10,85 @@
|
||||
#include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite
|
||||
#include "core/rendering/text.hpp" // Para TEXT_CENTER, TEXT_COLOR, Text
|
||||
#include "core/resources/resource.hpp" // Para Resource
|
||||
#include "core/system/global_events.hpp" // Para check
|
||||
#include "external/jail_audio.h" // Para JA_PlayMusic
|
||||
#include "game/options.hpp" // Para Options, options, OptionsStats, Secti...
|
||||
#include "game/scene_manager.hpp" // Para SceneManager
|
||||
#include "utils/defines.hpp" // Para GAMECANVAS_CENTER_X, GAME_SPEED
|
||||
#include "core/system/global_events.hpp" // Para check
|
||||
#include "utils/defines.hpp" // Para GAMECANVAS_CENTER_X
|
||||
#include "utils/delta_timer.hpp" // Para DeltaTimer
|
||||
#include "utils/utils.hpp" // Para PaletteColor, stringToColor
|
||||
|
||||
// Constructor
|
||||
GameOver::GameOver()
|
||||
: player_sprite_(std::make_shared<SurfaceAnimatedSprite>(Resource::get()->getSurface("player_game_over.gif"), Resource::get()->getAnimations("player_game_over.ani"))),
|
||||
tv_sprite_(std::make_shared<SurfaceAnimatedSprite>(Resource::get()->getSurface("tv.gif"), Resource::get()->getAnimations("tv.ani"))) {
|
||||
tv_sprite_(std::make_shared<SurfaceAnimatedSprite>(Resource::get()->getSurface("tv.gif"), Resource::get()->getAnimations("tv.ani"))),
|
||||
delta_timer_(std::make_shared<DeltaTimer>()) {
|
||||
SceneManager::current = SceneManager::Scene::GAME_OVER;
|
||||
SceneManager::options = SceneManager::Options::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);
|
||||
// Inicializa las posiciones de los sprites usando las constantes
|
||||
player_sprite_->setPosX(GAMECANVAS_CENTER_X + PLAYER_X_OFFSET);
|
||||
player_sprite_->setPosY(TEXT_Y + SPRITE_Y_OFFSET);
|
||||
tv_sprite_->setPosX(GAMECANVAS_CENTER_X - tv_sprite_->getWidth() - TV_X_OFFSET);
|
||||
tv_sprite_->setPosY(TEXT_Y + SPRITE_Y_OFFSET);
|
||||
|
||||
Screen::get()->setBorderColor(static_cast<Uint8>(PaletteColor::BLACK));
|
||||
|
||||
// Inicializa el vector de colores
|
||||
// Inicializa el vector de colores (de brillante a oscuro para fade)
|
||||
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();
|
||||
color_ = colors_.back(); // Empieza en black
|
||||
}
|
||||
|
||||
// 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();
|
||||
// Obtiene el delta time desde el último frame
|
||||
const float delta = delta_timer_->tick();
|
||||
elapsed_time_ += delta;
|
||||
|
||||
// Comprueba las entradas
|
||||
checkInput();
|
||||
// Comprueba las entradas
|
||||
checkInput();
|
||||
|
||||
// Actualiza el color usado para renderizar los textos e imagenes
|
||||
updateColor();
|
||||
// Actualiza el estado de la escena
|
||||
updateState();
|
||||
|
||||
// Actualiza los contadores
|
||||
updateCounters();
|
||||
// Actualiza el color usado para renderizar los textos e imagenes
|
||||
updateColor();
|
||||
|
||||
// Actualiza los dos sprites
|
||||
player_sprite_->update();
|
||||
tv_sprite_->update();
|
||||
// Actualiza los dos sprites (con delta time escalado por velocidad)
|
||||
player_sprite_->update();
|
||||
tv_sprite_->update();
|
||||
|
||||
// Actualiza el objeto Screen
|
||||
Screen::get()->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_);
|
||||
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, TEXT_Y, "G A M E O V E R", 1, color_);
|
||||
|
||||
// Dibuja los sprites
|
||||
player_sprite_->setPosY(Y + 30);
|
||||
tv_sprite_->setPosY(Y + 30);
|
||||
// Dibuja los sprites (ya posicionados en el constructor, solo ajustamos Y)
|
||||
player_sprite_->setPosY(TEXT_Y + SPRITE_Y_OFFSET);
|
||||
tv_sprite_->setPosY(TEXT_Y + SPRITE_Y_OFFSET);
|
||||
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_);
|
||||
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, TEXT_Y + ITEMS_Y_OFFSET, "ITEMS: " + ITEMS_TEXT, 1, color_);
|
||||
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, TEXT_Y + ROOMS_Y_OFFSET, "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_);
|
||||
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, TEXT_Y + NIGHTMARE_TITLE_Y_OFFSET, "YOUR WORST NIGHTMARE IS", 1, color_);
|
||||
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, TEXT_Y + NIGHTMARE_TEXT_Y_OFFSET, Options::stats.worst_nightmare, 1, color_);
|
||||
|
||||
// Vuelca el contenido del renderizador en pantalla
|
||||
Screen::get()->render();
|
||||
@@ -119,16 +118,41 @@ void GameOver::run() {
|
||||
|
||||
// Actualiza el color usado para renderizar los textos e imagenes
|
||||
void GameOver::updateColor() {
|
||||
const int HALF = COUNTER_SECTION_END / 2;
|
||||
// Calcula el color basado en el estado actual
|
||||
switch (state_) {
|
||||
case State::WAITING:
|
||||
// Durante la espera, mantener en black
|
||||
color_ = colors_.back(); // black
|
||||
break;
|
||||
|
||||
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];
|
||||
case State::FADE_IN: {
|
||||
// Fade in: de black (último color) a white (primer color)
|
||||
// Progreso: 0.0 (black) -> 1.0 (white)
|
||||
const float progress = std::min(elapsed_time_ / FADE_IN_DURATION, 1.0f);
|
||||
const int index = (colors_.size() - 1) - static_cast<int>((colors_.size() - 1) * progress);
|
||||
color_ = colors_[std::clamp(index, 0, static_cast<int>(colors_.size() - 1))];
|
||||
break;
|
||||
}
|
||||
|
||||
case State::DISPLAY:
|
||||
// Durante display, mantener el color más brillante
|
||||
color_ = colors_[0]; // white
|
||||
break;
|
||||
|
||||
case State::FADE_OUT: {
|
||||
// Fade out: de white (primer color) a black (último color)
|
||||
// Progreso: 0.0 (white) -> 1.0 (black)
|
||||
const float progress = std::min(elapsed_time_ / FADE_OUT_DURATION, 1.0f);
|
||||
const int index = static_cast<int>((colors_.size() - 1) * progress);
|
||||
color_ = colors_[std::clamp(index, 0, static_cast<int>(colors_.size() - 1))];
|
||||
break;
|
||||
}
|
||||
|
||||
case State::ENDING:
|
||||
case State::TRANSITION:
|
||||
// Al final, mantener en black
|
||||
color_ = colors_.back(); // black
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,23 +162,56 @@ void GameOver::renderSprites() {
|
||||
tv_sprite_->render(1, color_);
|
||||
}
|
||||
|
||||
// Actualiza los contadores
|
||||
void GameOver::updateCounters() {
|
||||
// Actualiza el contador
|
||||
if (pre_counter_ < 50) {
|
||||
pre_counter_++;
|
||||
} else {
|
||||
counter_++;
|
||||
}
|
||||
// Actualiza el estado de la escena y gestiona transiciones
|
||||
void GameOver::updateState() {
|
||||
// Máquina de estados basada en tiempo transcurrido
|
||||
switch (state_) {
|
||||
case State::WAITING:
|
||||
// Espera inicial antes de empezar
|
||||
if (elapsed_time_ >= WAITING_DURATION) {
|
||||
state_ = State::FADE_IN;
|
||||
elapsed_time_ = 0.0f;
|
||||
// Hace sonar la música cuando termina la espera
|
||||
JA_PlayMusic(Resource::get()->getMusic("game_over.ogg"), 0);
|
||||
}
|
||||
break;
|
||||
|
||||
// Hace sonar la música
|
||||
if (counter_ == 1) {
|
||||
JA_PlayMusic(Resource::get()->getMusic("game_over.ogg"), 0);
|
||||
}
|
||||
case State::FADE_IN:
|
||||
// Fade in de colores desde black
|
||||
if (elapsed_time_ >= FADE_IN_DURATION) {
|
||||
state_ = State::DISPLAY;
|
||||
elapsed_time_ = 0.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
// Comprueba si ha terminado la sección
|
||||
else if (counter_ == COUNTER_SECTION_END) {
|
||||
SceneManager::current = SceneManager::Scene::LOGO;
|
||||
SceneManager::options = SceneManager::Options::LOGO_TO_TITLE;
|
||||
case State::DISPLAY:
|
||||
// Mostrando contenido con color brillante
|
||||
if (elapsed_time_ >= DISPLAY_DURATION) {
|
||||
state_ = State::FADE_OUT;
|
||||
elapsed_time_ = 0.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case State::FADE_OUT:
|
||||
// Fade out hacia black
|
||||
if (elapsed_time_ >= FADE_OUT_DURATION) {
|
||||
state_ = State::ENDING;
|
||||
elapsed_time_ = 0.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case State::ENDING:
|
||||
// Pantalla en negro antes de salir
|
||||
if (elapsed_time_ >= ENDING_DURATION) {
|
||||
state_ = State::TRANSITION;
|
||||
elapsed_time_ = 0.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case State::TRANSITION:
|
||||
// Transición a la escena de logo
|
||||
SceneManager::current = SceneManager::Scene::LOGO;
|
||||
SceneManager::options = SceneManager::Options::LOGO_TO_TITLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user