migrat GameOver a time based
This commit is contained in:
@@ -37,7 +37,7 @@ enum class Options {
|
|||||||
inline Scene current = Scene::LOGO; // Escena actual
|
inline Scene current = Scene::LOGO; // Escena actual
|
||||||
inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual
|
inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual
|
||||||
#else
|
#else
|
||||||
inline Scene current = Scene::TITLE; // Escena actual
|
inline Scene current = Scene::GAME_OVER; // Escena actual
|
||||||
inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual
|
inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -10,86 +10,85 @@
|
|||||||
#include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite
|
#include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite
|
||||||
#include "core/rendering/text.hpp" // Para TEXT_CENTER, TEXT_COLOR, Text
|
#include "core/rendering/text.hpp" // Para TEXT_CENTER, TEXT_COLOR, Text
|
||||||
#include "core/resources/resource.hpp" // Para Resource
|
#include "core/resources/resource.hpp" // Para Resource
|
||||||
|
#include "core/system/global_events.hpp" // Para check
|
||||||
#include "external/jail_audio.h" // Para JA_PlayMusic
|
#include "external/jail_audio.h" // Para JA_PlayMusic
|
||||||
#include "game/options.hpp" // Para Options, options, OptionsStats, Secti...
|
#include "game/options.hpp" // Para Options, options, OptionsStats, Secti...
|
||||||
#include "game/scene_manager.hpp" // Para SceneManager
|
#include "game/scene_manager.hpp" // Para SceneManager
|
||||||
#include "utils/defines.hpp" // Para GAMECANVAS_CENTER_X, GAME_SPEED
|
#include "utils/defines.hpp" // Para GAMECANVAS_CENTER_X
|
||||||
#include "core/system/global_events.hpp" // Para check
|
#include "utils/delta_timer.hpp" // Para DeltaTimer
|
||||||
#include "utils/utils.hpp" // Para PaletteColor, stringToColor
|
#include "utils/utils.hpp" // Para PaletteColor, stringToColor
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
GameOver::GameOver()
|
GameOver::GameOver()
|
||||||
: player_sprite_(std::make_shared<SurfaceAnimatedSprite>(Resource::get()->getSurface("player_game_over.gif"), Resource::get()->getAnimations("player_game_over.ani"))),
|
: 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::current = SceneManager::Scene::GAME_OVER;
|
||||||
SceneManager::options = SceneManager::Options::NONE;
|
SceneManager::options = SceneManager::Options::NONE;
|
||||||
|
|
||||||
player_sprite_->setPosX(GAMECANVAS_CENTER_X + 10);
|
// Inicializa las posiciones de los sprites usando las constantes
|
||||||
player_sprite_->setPosY(30);
|
player_sprite_->setPosX(GAMECANVAS_CENTER_X + PLAYER_X_OFFSET);
|
||||||
tv_sprite_->setPosX(GAMECANVAS_CENTER_X - tv_sprite_->getWidth() - 10);
|
player_sprite_->setPosY(TEXT_Y + SPRITE_Y_OFFSET);
|
||||||
tv_sprite_->setPosY(30);
|
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));
|
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"};
|
const std::vector<std::string> COLORS = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
|
||||||
for (const auto& color : COLORS) {
|
for (const auto& color : COLORS) {
|
||||||
colors_.push_back(stringToColor(color));
|
colors_.push_back(stringToColor(color));
|
||||||
}
|
}
|
||||||
color_ = colors_.back();
|
color_ = colors_.back(); // Empieza en black
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza el objeto
|
// Actualiza el objeto
|
||||||
void GameOver::update() {
|
void GameOver::update() {
|
||||||
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
|
// Obtiene el delta time desde el último frame
|
||||||
if (SDL_GetTicks() - ticks_ > GAME_SPEED) {
|
const float delta = delta_timer_->tick();
|
||||||
// Actualiza el contador de ticks
|
elapsed_time_ += delta;
|
||||||
ticks_ = SDL_GetTicks();
|
|
||||||
|
|
||||||
// Comprueba las entradas
|
// Comprueba las entradas
|
||||||
checkInput();
|
checkInput();
|
||||||
|
|
||||||
// Actualiza el color usado para renderizar los textos e imagenes
|
// Actualiza el estado de la escena
|
||||||
updateColor();
|
updateState();
|
||||||
|
|
||||||
// Actualiza los contadores
|
// Actualiza el color usado para renderizar los textos e imagenes
|
||||||
updateCounters();
|
updateColor();
|
||||||
|
|
||||||
// Actualiza los dos sprites
|
// Actualiza los dos sprites (con delta time escalado por velocidad)
|
||||||
player_sprite_->update();
|
player_sprite_->update();
|
||||||
tv_sprite_->update();
|
tv_sprite_->update();
|
||||||
|
|
||||||
// Actualiza el objeto Screen
|
// Actualiza el objeto Screen
|
||||||
Screen::get()->update();
|
Screen::get()->update();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dibuja el final en pantalla
|
// Dibuja el final en pantalla
|
||||||
void GameOver::render() {
|
void GameOver::render() {
|
||||||
constexpr int Y = 32;
|
|
||||||
|
|
||||||
Screen::get()->start();
|
Screen::get()->start();
|
||||||
Screen::get()->clearSurface(static_cast<Uint8>(PaletteColor::BLACK));
|
Screen::get()->clearSurface(static_cast<Uint8>(PaletteColor::BLACK));
|
||||||
|
|
||||||
auto text = Resource::get()->getText("smb2");
|
auto text = Resource::get()->getText("smb2");
|
||||||
|
|
||||||
// Escribe el texto de GAME OVER
|
// Escribe el texto de GAME OVER
|
||||||
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y, "G A M E O V E R", 1, color_);
|
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, TEXT_Y, "G A M E O V E R", 1, color_);
|
||||||
|
|
||||||
// Dibuja los sprites
|
// Dibuja los sprites (ya posicionados en el constructor, solo ajustamos Y)
|
||||||
player_sprite_->setPosY(Y + 30);
|
player_sprite_->setPosY(TEXT_Y + SPRITE_Y_OFFSET);
|
||||||
tv_sprite_->setPosY(Y + 30);
|
tv_sprite_->setPosY(TEXT_Y + SPRITE_Y_OFFSET);
|
||||||
renderSprites();
|
renderSprites();
|
||||||
|
|
||||||
// Escribe el texto con las habitaciones y los items
|
// 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 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);
|
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, TEXT_Y + ITEMS_Y_OFFSET, "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 + ROOMS_Y_OFFSET, "ROOMS: " + ROOMS_TEXT, 1, color_);
|
||||||
|
|
||||||
// Escribe el texto con "Tu peor pesadilla"
|
// Escribe el texto con "Tu peor pesadilla"
|
||||||
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 110, "YOUR WORST NIGHTMARE IS", 1, color_);
|
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, TEXT_Y + NIGHTMARE_TITLE_Y_OFFSET, "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_TEXT_Y_OFFSET, Options::stats.worst_nightmare, 1, color_);
|
||||||
|
|
||||||
// Vuelca el contenido del renderizador en pantalla
|
// Vuelca el contenido del renderizador en pantalla
|
||||||
Screen::get()->render();
|
Screen::get()->render();
|
||||||
@@ -119,16 +118,41 @@ void GameOver::run() {
|
|||||||
|
|
||||||
// Actualiza el color usado para renderizar los textos e imagenes
|
// Actualiza el color usado para renderizar los textos e imagenes
|
||||||
void GameOver::updateColor() {
|
void GameOver::updateColor() {
|
||||||
const int HALF = 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) {
|
case State::FADE_IN: {
|
||||||
const float STEP = std::min(counter_, COUNTER_FADE_LENGHT) / (float)COUNTER_FADE_LENGHT;
|
// Fade in: de black (último color) a white (primer color)
|
||||||
const int INDEX = (colors_.size() - 1) - int((colors_.size() - 1) * STEP);
|
// Progreso: 0.0 (black) -> 1.0 (white)
|
||||||
color_ = colors_[INDEX];
|
const float progress = std::min(elapsed_time_ / FADE_IN_DURATION, 1.0f);
|
||||||
} else {
|
const int index = (colors_.size() - 1) - static_cast<int>((colors_.size() - 1) * progress);
|
||||||
const float STEP = std::min(std::max(counter_, COUNTER_INIT_FADE) - COUNTER_INIT_FADE, COUNTER_FADE_LENGHT) / (float)COUNTER_FADE_LENGHT;
|
color_ = colors_[std::clamp(index, 0, static_cast<int>(colors_.size() - 1))];
|
||||||
const int INDEX = (colors_.size() - 1) * STEP;
|
break;
|
||||||
color_ = colors_[INDEX];
|
}
|
||||||
|
|
||||||
|
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_);
|
tv_sprite_->render(1, color_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza los contadores
|
// Actualiza el estado de la escena y gestiona transiciones
|
||||||
void GameOver::updateCounters() {
|
void GameOver::updateState() {
|
||||||
// Actualiza el contador
|
// Máquina de estados basada en tiempo transcurrido
|
||||||
if (pre_counter_ < 50) {
|
switch (state_) {
|
||||||
pre_counter_++;
|
case State::WAITING:
|
||||||
} else {
|
// Espera inicial antes de empezar
|
||||||
counter_++;
|
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
|
case State::FADE_IN:
|
||||||
if (counter_ == 1) {
|
// Fade in de colores desde black
|
||||||
JA_PlayMusic(Resource::get()->getMusic("game_over.ogg"), 0);
|
if (elapsed_time_ >= FADE_IN_DURATION) {
|
||||||
}
|
state_ = State::DISPLAY;
|
||||||
|
elapsed_time_ = 0.0f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
// Comprueba si ha terminado la sección
|
case State::DISPLAY:
|
||||||
else if (counter_ == COUNTER_SECTION_END) {
|
// Mostrando contenido con color brillante
|
||||||
SceneManager::current = SceneManager::Scene::LOGO;
|
if (elapsed_time_ >= DISPLAY_DURATION) {
|
||||||
SceneManager::options = SceneManager::Options::LOGO_TO_TITLE;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,53 +5,62 @@
|
|||||||
#include <memory> // Para shared_ptr
|
#include <memory> // Para shared_ptr
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
class SurfaceAnimatedSprite; // lines 7-7
|
class SurfaceAnimatedSprite; // lines 7-7
|
||||||
|
class DeltaTimer; // Forward declaration
|
||||||
|
|
||||||
class GameOver {
|
class GameOver {
|
||||||
private:
|
|
||||||
// Constantes
|
|
||||||
static constexpr int COUNTER_SECTION_END = 400; // Contador: cuando acaba la sección
|
|
||||||
static constexpr int COUNTER_INIT_FADE = 310; // Contador: cuando emiepza el fade
|
|
||||||
static constexpr int COUNTER_FADE_LENGHT = 20; // Contador: duración del fade
|
|
||||||
|
|
||||||
// Objetos y punteros
|
|
||||||
std::shared_ptr<SurfaceAnimatedSprite> player_sprite_; // Sprite con el jugador
|
|
||||||
std::shared_ptr<SurfaceAnimatedSprite> tv_sprite_; // Sprite con el televisor
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
int pre_counter_ = 0; // Contador previo
|
|
||||||
int counter_ = 0; // Contador
|
|
||||||
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
|
||||||
std::vector<Uint8> colors_; // Vector con los colores para el fade
|
|
||||||
Uint8 color_; // Color usado para el texto y los sprites
|
|
||||||
|
|
||||||
// Actualiza el objeto
|
|
||||||
void update();
|
|
||||||
|
|
||||||
// Dibuja el final en pantalla
|
|
||||||
void render();
|
|
||||||
|
|
||||||
// Comprueba el manejador de eventos
|
|
||||||
static void checkEvents();
|
|
||||||
|
|
||||||
// Comprueba las entradas
|
|
||||||
static void checkInput();
|
|
||||||
|
|
||||||
// Actualiza el color usado para renderizar los textos e imagenes
|
|
||||||
void updateColor();
|
|
||||||
|
|
||||||
// Dibuja los sprites
|
|
||||||
void renderSprites();
|
|
||||||
|
|
||||||
// Actualiza los contadores
|
|
||||||
void updateCounters();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor y Destructor
|
||||||
GameOver();
|
GameOver();
|
||||||
|
|
||||||
// Destructor
|
|
||||||
~GameOver() = default;
|
~GameOver() = default;
|
||||||
|
|
||||||
// Bucle principal
|
// Bucle principal
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// --- Estados ---
|
||||||
|
enum class State {
|
||||||
|
WAITING, // Espera inicial antes de empezar
|
||||||
|
FADE_IN, // Fade in de colores desde black
|
||||||
|
DISPLAY, // Mostrando contenido con color brillante
|
||||||
|
FADE_OUT, // Fade out hacia black
|
||||||
|
ENDING, // Pantalla en negro antes de salir
|
||||||
|
TRANSITION // Cambio a logo
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Constantes de Duración (segundos) ---
|
||||||
|
static constexpr float WAITING_DURATION = 0.8f; // Espera inicial
|
||||||
|
static constexpr float FADE_IN_DURATION = 0.32f; // Duración del fade in
|
||||||
|
static constexpr float DISPLAY_DURATION = 4.64f; // Duración mostrando contenido
|
||||||
|
static constexpr float FADE_OUT_DURATION = 0.32f; // Duración del fade out
|
||||||
|
static constexpr float ENDING_DURATION = 1.12f; // Espera en negro antes de salir
|
||||||
|
|
||||||
|
// --- Constantes de Posición ---
|
||||||
|
static constexpr int TEXT_Y = 32; // Posición Y del texto principal
|
||||||
|
static constexpr int SPRITE_Y_OFFSET = 30; // Offset Y para sprites desde TEXT_Y
|
||||||
|
static constexpr int PLAYER_X_OFFSET = 10; // Offset X del jugador desde el centro
|
||||||
|
static constexpr int TV_X_OFFSET = 10; // Offset X del TV desde el centro
|
||||||
|
static constexpr int ITEMS_Y_OFFSET = 80; // Offset Y del texto de items desde TEXT_Y
|
||||||
|
static constexpr int ROOMS_Y_OFFSET = 90; // Offset Y del texto de rooms desde TEXT_Y
|
||||||
|
static constexpr int NIGHTMARE_TITLE_Y_OFFSET = 110; // Offset Y del título nightmare desde TEXT_Y
|
||||||
|
static constexpr int NIGHTMARE_TEXT_Y_OFFSET = 120; // Offset Y del texto nightmare desde TEXT_Y
|
||||||
|
|
||||||
|
// --- Objetos y punteros ---
|
||||||
|
std::shared_ptr<SurfaceAnimatedSprite> player_sprite_; // Sprite con el jugador
|
||||||
|
std::shared_ptr<SurfaceAnimatedSprite> tv_sprite_; // Sprite con el televisor
|
||||||
|
std::shared_ptr<DeltaTimer> delta_timer_; // Timer para time-based logic
|
||||||
|
|
||||||
|
// --- Variables ---
|
||||||
|
State state_ = State::WAITING; // Estado actual de la escena
|
||||||
|
float elapsed_time_ = 0.0f; // Tiempo transcurrido en el estado actual
|
||||||
|
std::vector<Uint8> colors_; // Vector con los colores para el fade
|
||||||
|
Uint8 color_; // Color usado para el texto y los sprites
|
||||||
|
|
||||||
|
// --- Funciones ---
|
||||||
|
void update(); // Actualiza el objeto
|
||||||
|
void render(); // Dibuja el final en pantalla
|
||||||
|
static void checkEvents(); // Comprueba el manejador de eventos
|
||||||
|
static void checkInput(); // Comprueba las entradas
|
||||||
|
void updateState(); // Actualiza el estado y transiciones
|
||||||
|
void updateColor(); // Actualiza el color usado para renderizar los textos e imagenes
|
||||||
|
void renderSprites(); // Dibuja los sprites
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user