Files
jdd_opendingux/source/game/scenes/credits.cpp

246 lines
9.6 KiB
C++

#include "game/scenes/credits.hpp"
#include <SDL3/SDL.h>
#include "core/audio/audio.hpp" // Para Audio
#include "core/input/global_inputs.hpp" // Para check
#include "core/input/input.hpp" // Para Input
#include "core/rendering/pixel_reveal.hpp" // Para PixelReveal
#include "core/rendering/screen.hpp" // Para Screen
#include "core/rendering/surface.hpp" // Para Surface
#include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite
#include "core/rendering/text.hpp" // Para Text, Text::CENTER_FLAG, Text::COLOR_FLAG
#include "core/resources/resource_cache.hpp" // Para Resource
#include "core/system/global_events.hpp" // Para check
#include "game/options.hpp" // Para Options, options, OptionsGame, Sectio...
#include "game/scene_manager.hpp" // Para SceneManager
#include "utils/defines.hpp" // Para GAME_SPEED, PlayArea::CENTER_X, PLAY_...
#include "utils/delta_timer.hpp" // Para DeltaTimer
#include "utils/utils.hpp" // Para PaletteColor
// Destructor
Credits::~Credits() = default;
// Constructor
Credits::Credits()
: text_surface_(std::make_shared<Surface>(Options::game.width, Options::game.height)),
shining_sprite_(std::make_shared<SurfaceAnimatedSprite>(Resource::Cache::get()->getAnimationData("shine.yaml"))),
delta_timer_(std::make_unique<DeltaTimer>()) {
// Configura la escena
SceneManager::current = SceneManager::Scene::CREDITS;
SceneManager::options = SceneManager::Options::NONE;
shining_sprite_->setPos({194, 174, 8, 8});
Screen::get()->setBorderColor(static_cast<Uint8>(PaletteColor::BLACK)); // Cambia el color del borde
fillTexture(); // Escribe el texto en la textura
Audio::get()->playMusic("title.ogg"); // Inicia la musica
}
// Comprueba el manejador de eventos
void Credits::handleEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
GlobalEvents::handle(event);
}
}
// Comprueba las entradas
void Credits::handleInput() {
Input::get()->update();
GlobalInputs::handle();
}
// Inicializa los textos
void Credits::iniTexts() {
std::string keys = "CURSORS";
texts_.clear();
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"INSTRUCTIONS:", static_cast<Uint8>(PaletteColor::YELLOW)});
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"HELP JAILDOC TO GET BACK ALL", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"HIS PROJECTS AND GO TO THE", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"JAIL TO FINISH THEM", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"KEYS:", static_cast<Uint8>(PaletteColor::YELLOW)});
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({keys + " TO MOVE AND JUMP", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"F8 TOGGLE THE MUSIC", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"F11 PAUSE THE GAME", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"F1-F2 WINDOWS SIZE", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"F3 TOGGLE FULLSCREEN", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"F9 TOOGLE BORDER SCREEN", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"A GAME BY JAILDESIGNER", static_cast<Uint8>(PaletteColor::YELLOW)});
texts_.push_back({"MADE ON SUMMER/FALL 2022", static_cast<Uint8>(PaletteColor::YELLOW)});
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"I LOVE JAILGAMES! ", static_cast<Uint8>(PaletteColor::WHITE)});
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
}
// Escribe el texto en la textura
void Credits::fillTexture() {
// Inicializa los textos
iniTexts();
// Rellena la textura de texto
auto previuos_renderer = Screen::get()->getRendererSurface();
Screen::get()->setRendererSurface(text_surface_);
text_surface_->clear(static_cast<Uint8>(PaletteColor::BLACK));
auto text = Resource::Cache::get()->getText("smb2");
// Escribe el texto en la textura
const int SIZE = text->getCharacterSize();
int pos_y = 0;
for (const auto& t : texts_) {
text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, pos_y * SIZE, t.label, 1, t.color);
pos_y++;
}
// Escribe el corazón
const int TEXT_LENGHT = text->length(texts_[22].label, 1) - text->length(" ", 1); // Se resta el ultimo caracter que es un espacio
const int POS_X = ((PlayArea::WIDTH - TEXT_LENGHT) / 2) + TEXT_LENGHT;
text->writeColored(POS_X, 176, "}", static_cast<Uint8>(PaletteColor::BRIGHT_RED));
Screen::get()->setRendererSurface(previuos_renderer);
// Recoloca el sprite del brillo
shining_sprite_->setPosX(POS_X + 2);
// Crea el efecto de revelado pixel a pixel
pixel_reveal_ = std::make_unique<PixelReveal>(Options::game.width, Options::game.height, PIXELS_PER_SECOND, STEP_DURATION, REVEAL_STEPS);
}
// Actualiza las variables
void Credits::update() {
const float DELTA_TIME = delta_timer_->tick();
total_time_ += DELTA_TIME; // Actualiza el tiempo total
handleEvents(); // Comprueba los eventos
handleInput(); // Comprueba las entradas
updateState(DELTA_TIME); // Actualiza la máquina de estados
pixel_reveal_->update(reveal_time_); // Actualiza el efecto de revelado
// Actualiza el sprite con el brillo si está después del tiempo de inicio
if (reveal_time_ > SHINE_START_TIME) {
shining_sprite_->update(DELTA_TIME);
}
Audio::update(); // Actualiza el objeto Audio
Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen
}
// Transición entre estados
void Credits::transitionToState(State new_state) {
state_ = new_state;
state_time_ = 0.0F;
}
// Actualiza la máquina de estados
void Credits::updateState(float delta_time) {
state_time_ += delta_time;
switch (state_) {
case State::REVEALING_TEXT:
reveal_time_ += delta_time; // Incrementa reveal_time durante revelación
if (state_time_ >= REVEAL_PHASE_1_DURATION) {
transitionToState(State::PAUSE_1);
}
break;
case State::PAUSE_1:
// reveal_time_ NO incrementa durante pausa (se congela)
if (state_time_ >= PAUSE_DURATION) {
transitionToState(State::REVEALING_TEXT_2);
}
break;
case State::REVEALING_TEXT_2:
reveal_time_ += delta_time; // Incrementa reveal_time durante revelación
if (state_time_ >= REVEAL_PHASE_2_DURATION) {
transitionToState(State::PAUSE_2);
}
break;
case State::PAUSE_2:
// reveal_time_ NO incrementa durante pausa (se congela)
if (state_time_ >= PAUSE_DURATION) {
transitionToState(State::REVEALING_TEXT_3);
}
break;
case State::REVEALING_TEXT_3:
reveal_time_ += delta_time; // Incrementa reveal_time durante revelación
if (state_time_ >= REVEAL_PHASE_3_DURATION) {
transitionToState(State::PAUSE_3);
}
break;
case State::PAUSE_3:
// reveal_time_ NO incrementa durante pausa (se congela)
if (state_time_ >= PAUSE_DURATION) {
transitionToState(State::DISPLAYING_WITH_SHINE);
}
break;
case State::DISPLAYING_WITH_SHINE:
reveal_time_ += delta_time; // Incrementa reveal_time durante revelación
if (state_time_ >= DISPLAY_WITH_SHINE_DURATION) {
transitionToState(State::FADING_OUT);
}
break;
case State::FADING_OUT:
reveal_time_ += delta_time; // Incrementa reveal_time durante fade
if (state_time_ >= FADE_OUT_DURATION) {
transitionToState(State::EXITING);
}
break;
case State::EXITING:
SceneManager::current = SceneManager::Scene::DEMO;
break;
}
}
// Dibuja en pantalla
void Credits::render() {
// Prepara para empezar a dibujar en la textura de juego
Screen::get()->start();
// Limpia la pantalla
Screen::get()->clearSurface(static_cast<Uint8>(PaletteColor::BLACK));
if (state_ != State::EXITING) {
// Dibuja la textura con el texto en pantalla
text_surface_->render(0, 0);
// Dibuja la máscara de revelado pixel a pixel
pixel_reveal_->render(0, 0);
// Dibuja el sprite con el brillo
if (reveal_time_ > SHINE_START_TIME) {
shining_sprite_->render(1, static_cast<Uint8>(PaletteColor::BRIGHT_WHITE));
}
}
// Vuelca el contenido del renderizador en pantalla
Screen::get()->render();
}
// Bucle para el logo del juego
void Credits::run() {
while (SceneManager::current == SceneManager::Scene::CREDITS) {
update();
render();
}
}