Title: afegit fade i post_fade

This commit is contained in:
2025-11-02 14:04:33 +01:00
parent 4eac48ed78
commit af7420d7c7
3 changed files with 204 additions and 113 deletions

View File

@@ -34,7 +34,7 @@ enum class Options {
// --- Variables de estado globales ---
#ifdef _DEBUG
inline Scene current = Scene::LOADING_SCREEN; // Escena actual
inline Scene current = Scene::TITLE; // Escena actual
inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual
#else
inline Scene current = Scene::LOGO; // Escena actual

View File

@@ -21,19 +21,20 @@
// Constructor
Title::Title()
: title_logo_surface_(Resource::get()->getSurface("title_logo.gif")),
title_logo_sprite_(std::make_shared<SurfaceSprite>(title_logo_surface_, 29, 9, title_logo_surface_->getWidth(), title_logo_surface_->getHeight())),
: game_logo_surface_(Resource::get()->getSurface("title_logo.gif")),
game_logo_sprite_(std::make_unique<SurfaceSprite>(game_logo_surface_, 29, 9, game_logo_surface_->getWidth(), game_logo_surface_->getHeight())),
loading_screen_surface_(Resource::get()->getSurface("loading_screen_color.gif")),
loading_screen_sprite_(std::make_shared<SurfaceSprite>(loading_screen_surface_, 0, 0, loading_screen_surface_->getWidth(), loading_screen_surface_->getHeight())),
bg_surface_(std::make_shared<Surface>(Options::game.width, Options::game.height)),
loading_screen_sprite_(std::make_unique<SurfaceSprite>(loading_screen_surface_, 0, 0, loading_screen_surface_->getWidth(), loading_screen_surface_->getHeight())),
title_surface_(std::make_shared<Surface>(Options::game.width, Options::game.height)),
delta_timer_(std::make_unique<DeltaTimer>()),
marquee_text_(Resource::get()->getText("gauntlet")),
menu_text_(Resource::get()->getText("gauntlet")),
first_active_letter_(0),
last_active_letter_(0),
state_time_(0.0F),
fade_accumulator_(0.0F) {
// Inicializa variables
state_ = SceneManager::options == SceneManager::Options::TITLE_WITH_LOADING_SCREEN ? State::SHOW_LOADING_SCREEN : State::SHOW_MENU;
state_ = SceneManager::options == SceneManager::Options::TITLE_WITH_LOADING_SCREEN ? State::SHOW_LOADING_SCREEN : State::MAIN_MENU;
SceneManager::current = SceneManager::Scene::TITLE;
SceneManager::options = SceneManager::Options::NONE;
initMarquee();
@@ -44,9 +45,6 @@ Title::Title()
// Cambia el color del borde
Screen::get()->setBorderColor(static_cast<Uint8>(PaletteColor::BLACK));
// Rellena la textura de fondo con todos los gráficos
fillSurface();
// Inicia la musica
playMusic("title.ogg");
}
@@ -77,22 +75,29 @@ void Title::handleEvents() {
while (SDL_PollEvent(&event)) {
GlobalEvents::handle(event);
// Solo se comprueban estas teclas si no está activo el menu de logros
if (event.type == SDL_EVENT_KEY_DOWN) {
if (!show_cheevos_) {
switch (event.key.key) {
case SDLK_1:
SceneManager::current = SceneManager::Scene::GAME;
SceneManager::options = SceneManager::Options::NONE;
break;
switch (state_) {
case State::MAIN_MENU:
switch (event.key.key) {
case SDLK_1:
transitionToState(State::FADE_MENU);
break;
case SDLK_2:
show_cheevos_ = true;
break;
case SDLK_2:
transitionToState(State::CONTROLS_MENU);
break;
default:
break;
}
case SDLK_3:
transitionToState(State::CHEEVOS_MENU);
break;
default:
break;
}
break;
default:
break;
}
}
}
@@ -102,20 +107,36 @@ void Title::handleEvents() {
void Title::handleInput(float delta_time) {
Input::get()->update();
if (show_cheevos_) {
if (Input::get()->checkAction(InputAction::RIGHT, Input::ALLOW_REPEAT)) {
moveCheevosList(1, delta_time);
} else if (Input::get()->checkAction(InputAction::LEFT, Input::ALLOW_REPEAT)) {
moveCheevosList(0, delta_time);
} else if (Input::get()->checkAction(InputAction::ACCEPT, Input::DO_NOT_ALLOW_REPEAT)) {
hideCheevosList();
}
}
switch (state_) {
case State::SHOW_LOADING_SCREEN:
if (Input::get()->checkAction(InputAction::ACCEPT, Input::DO_NOT_ALLOW_REPEAT)) {
transitionToState(State::FADE_LOADING_SCREEN);
}
break;
if (Input::get()->checkAction(InputAction::ACCEPT, Input::DO_NOT_ALLOW_REPEAT)) {
if (state_ == State::SHOW_LOADING_SCREEN) {
transitionToState(State::FADE_LOADING_SCREEN);
}
case State::CHEEVOS_MENU:
if (Input::get()->checkAction(InputAction::RIGHT, Input::ALLOW_REPEAT)) {
moveCheevosList(1, delta_time);
} else if (Input::get()->checkAction(InputAction::LEFT, Input::ALLOW_REPEAT)) {
moveCheevosList(0, delta_time);
}
if (Input::get()->checkAction(InputAction::ACCEPT, Input::DO_NOT_ALLOW_REPEAT) ||
Input::get()->checkAction(InputAction::CANCEL, Input::DO_NOT_ALLOW_REPEAT)) {
resetCheevosScroll();
transitionToState(State::MAIN_MENU);
}
break;
case State::CONTROLS_MENU:
if (Input::get()->checkAction(InputAction::ACCEPT, Input::DO_NOT_ALLOW_REPEAT) ||
Input::get()->checkAction(InputAction::CANCEL, Input::DO_NOT_ALLOW_REPEAT)) {
transitionToState(State::MAIN_MENU);
}
break;
default:
break;
}
GlobalInputs::handle();
@@ -163,7 +184,7 @@ void Title::renderMarquee() {
static_cast<int>(letter.x), // Conversión explícita float→int
static_cast<int>(MARQUEE_Y), // Usar constante
std::string(1, letter.letter), // Convertir char a string
static_cast<Uint8>(PaletteColor::BRIGHT_RED));
static_cast<Uint8>(PaletteColor::MAGENTA));
}
}
}
@@ -183,10 +204,9 @@ void Title::update() {
// Actualiza el estado actual
void Title::updateState(float delta_time) {
state_time_ += delta_time;
switch (state_) {
case State::SHOW_LOADING_SCREEN:
state_time_ += delta_time;
if (state_time_ >= SHOW_LOADING_DURATION) {
transitionToState(State::FADE_LOADING_SCREEN);
}
@@ -197,22 +217,57 @@ void Title::updateState(float delta_time) {
if (fade_accumulator_ >= FADE_STEP_INTERVAL) {
fade_accumulator_ = 0.0F;
if (loading_screen_surface_->fadeSubPalette()) {
transitionToState(State::SHOW_MENU);
transitionToState(State::MAIN_MENU);
}
}
break;
case State::SHOW_MENU:
case State::MAIN_MENU:
// Actualiza la marquesina
updateMarquee(delta_time);
// Incrementa el temporizador solo en el menú principal
state_time_ += delta_time;
// Si el tiempo alcanza el timeout, va a créditos
if (state_time_ >= AUTO_CREDITS_TIMEOUT && !show_cheevos_) {
if (state_time_ >= AUTO_CREDITS_TIMEOUT) {
SceneManager::current = SceneManager::Scene::CREDITS;
SceneManager::options = SceneManager::Options::NONE;
}
break;
case State::CHEEVOS_MENU:
// Actualiza la marquesina (sigue visible en fondo)
updateMarquee(delta_time);
// No incrementar state_time_ (no timeout en este estado)
break;
case State::CONTROLS_MENU:
// Actualiza la marquesina (sigue visible en fondo)
updateMarquee(delta_time);
// No incrementar state_time_ (no timeout en este estado)
break;
case State::FADE_MENU:
fade_accumulator_ += delta_time;
if (fade_accumulator_ >= FADE_STEP_INTERVAL) {
fade_accumulator_ = 0.0F;
if (title_surface_->fadeSubPalette()) {
transitionToState(State::POST_FADE_MENU);
}
}
// Actualiza la marquesina (sigue visible en fondo)
updateMarquee(delta_time);
break;
case State::POST_FADE_MENU:
state_time_ += delta_time;
if (state_time_ >= POST_FADE_DELAY) {
SceneManager::current = SceneManager::Scene::GAME;
SceneManager::options = SceneManager::Options::NONE;
}
break;
default:
break;
}
@@ -227,33 +282,15 @@ void Title::transitionToState(State new_state) {
// Dibuja en pantalla
void Title::render() {
// Rellena la surface
fillTitleSurface();
// Prepara para empezar a dibujar en la textura de juego
Screen::get()->start();
Screen::get()->clearSurface(static_cast<Uint8>(PaletteColor::BLACK));
switch (state_) {
case State::SHOW_MENU:
// Dibuja la textura de fondo
bg_surface_->render(0, 0);
// Dibuja la marquesina
renderMarquee();
// Dibuja la información de logros
if (show_cheevos_) {
cheevos_sprite_->render();
}
break;
case State::SHOW_LOADING_SCREEN:
case State::FADE_LOADING_SCREEN:
loading_screen_sprite_->render();
title_logo_sprite_->render();
break;
default:
break;
}
// Dibuja en pantalla la surface con la composicion
title_surface_->render();
// Vuelca el contenido del renderizador en pantalla
Screen::get()->render();
@@ -284,30 +321,6 @@ void Title::moveCheevosList(int direction, float delta_time) {
cheevos_sprite_->setClip(cheevos_surface_view_);
}
// Rellena la textura de fondo con todos los gráficos
void Title::fillSurface() {
// Coloca el puntero del renderizador sobre la textura
auto previuos_renderer = Screen::get()->getRendererSurface();
Screen::get()->setRendererSurface(bg_surface_);
// Rellena la textura de color
bg_surface_->clear(static_cast<Uint8>(PaletteColor::BLACK));
// Pinta el gráfico del titulo a partir del sprite
title_logo_sprite_->render();
// Escribe el texto en la textura
auto text = Resource::get()->getText("smb2");
const Uint8 COLOR = stringToColor("green");
const int TEXT_SIZE = text->getCharacterSize();
text->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 11 * TEXT_SIZE, "1.PLAY", 1, COLOR);
text->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 13 * TEXT_SIZE, "2.ACHIEVEMENTS", 1, COLOR);
text->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 15 * TEXT_SIZE, "3.REDEFINE KEYS", 1, COLOR);
// Devuelve el puntero del renderizador a su sitio
Screen::get()->setRendererSurface(previuos_renderer);
}
// Crea y rellena la textura para mostrar los logros
void Title::createCheevosTexture() {
// Crea la textura con el listado de logros
@@ -355,14 +368,83 @@ void Title::createCheevosTexture() {
Screen::get()->setRendererSurface(previuos_renderer);
// Crea el sprite para el listado de logros
cheevos_sprite_ = std::make_shared<SurfaceSprite>(cheevos_surface_, (GAMECANVAS_WIDTH - cheevos_surface_->getWidth()) / 2, CHEEVOS_TEXTURE_POS_Y, cheevos_surface_->getWidth(), cheevos_surface_->getHeight());
cheevos_sprite_ = std::make_unique<SurfaceSprite>(cheevos_surface_, (GAMECANVAS_WIDTH - cheevos_surface_->getWidth()) / 2, CHEEVOS_TEXTURE_POS_Y, cheevos_surface_->getWidth(), cheevos_surface_->getHeight());
cheevos_surface_view_ = {.x = 0, .y = 0, .w = cheevos_surface_->getWidth(), .h = CHEEVOS_TEXTURE_VIEW_HEIGHT};
cheevos_sprite_->setClip(cheevos_surface_view_);
}
// Oculta la lista de logros
void Title::hideCheevosList() {
show_cheevos_ = false;
// Resetea el scroll de la lista de logros
void Title::resetCheevosScroll() {
cheevos_surface_view_.y = 0;
cheevos_sprite_->setClip(cheevos_surface_view_);
}
// Dibuja el logo con el titulo del juego
void Title::renderGameLogo() {
game_logo_sprite_->render();
}
// Dibuja el menu principal
void Title::renderMainMenu() {
const Uint8 COLOR = stringToColor("green");
const int TEXT_SIZE = menu_text_->getCharacterSize();
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 11 * TEXT_SIZE, "1. PLAY", 1, COLOR);
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 13 * TEXT_SIZE, "2. CONTROLS", 1, COLOR);
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 15 * TEXT_SIZE, "3. ACHIEVEMENTS", 1, COLOR);
}
// Dibuja el menu de logros
void Title::renderCheevosMenu() {
cheevos_sprite_->render();
}
// Dibuja el menu de controles
void Title::renderControlsMenu() {
const Uint8 COLOR = stringToColor("green");
const int TEXT_SIZE = menu_text_->getCharacterSize();
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 11 * TEXT_SIZE, "1. REDEFINE KEYBOARD", 1, COLOR);
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 13 * TEXT_SIZE, "2. REDEFINE JOYSTICK", 1, COLOR);
}
// Dibuja los elementos en la surface
void Title::fillTitleSurface() {
// Renderiza sobre la textura
auto previuos_renderer = Screen::get()->getRendererSurface();
Screen::get()->setRendererSurface(title_surface_);
// Rellena la textura de color
title_surface_->clear(static_cast<Uint8>(PaletteColor::BLACK));
switch (state_) {
case State::MAIN_MENU:
case State::FADE_MENU:
renderGameLogo();
renderMainMenu();
renderMarquee();
break;
case State::CHEEVOS_MENU:
renderGameLogo();
renderCheevosMenu();
renderMarquee();
break;
case State::CONTROLS_MENU:
renderGameLogo();
renderControlsMenu();
renderMarquee();
break;
case State::SHOW_LOADING_SCREEN:
case State::FADE_LOADING_SCREEN:
loading_screen_sprite_->render();
renderGameLogo();
break;
default:
break;
}
// Deja el renderizador como estaba
Screen::get()->setRendererSurface(previuos_renderer);
}

View File

@@ -32,13 +32,18 @@ class Title {
enum class State {
SHOW_LOADING_SCREEN,
FADE_LOADING_SCREEN,
SHOW_MENU
MAIN_MENU,
CHEEVOS_MENU,
CONTROLS_MENU,
FADE_MENU,
POST_FADE_MENU,
};
// --- Constantes de tiempo (en segundos) ---
static constexpr float SHOW_LOADING_DURATION = 5.0F; // Tiempo mostrando loading screen (antes 500 frames)
static constexpr float FADE_STEP_INTERVAL = 0.033F; // Intervalo entre pasos de fade (antes cada 4 frames)
static constexpr float AUTO_CREDITS_TIMEOUT = 22.0F; // Timeout para ir a créditos (antes 2200 frames)
static constexpr float FADE_STEP_INTERVAL = 0.05F; // Intervalo entre pasos de fade (antes cada 4 frames)
static constexpr float POST_FADE_DELAY = 1.0F; // Delay después del fade (pantalla en negro)
static constexpr float AUTO_CREDITS_TIMEOUT = 20.0F; // Timeout para ir a créditos (antes 2200 frames)
static constexpr float MARQUEE_SPEED = 100.0F; // Velocidad de marquesina (pixels/segundo)
static constexpr float CHEEVOS_SCROLL_SPEED = 120.0F; // Velocidad de scroll de logros (pixels/segundo)
@@ -49,26 +54,26 @@ class Title {
static constexpr float MARQUEE_LETTER_SPACING = 1.0F; // Espaciado entre letras
// --- Objetos y punteros ---
std::shared_ptr<Surface> title_logo_surface_; // Textura con los graficos
std::shared_ptr<SurfaceSprite> title_logo_sprite_; // SSprite para manejar la surface
std::shared_ptr<Surface> game_logo_surface_; // Textura con los graficos
std::unique_ptr<SurfaceSprite> game_logo_sprite_; // SSprite para manejar la surface
std::shared_ptr<Surface> loading_screen_surface_; // Surface con los gráficos de la pantalla de carga
std::shared_ptr<SurfaceSprite> loading_screen_sprite_; // SSprite con los gráficos de la pantalla de carga
std::shared_ptr<Surface> bg_surface_; // Textura para dibujar el fondo de la pantalla
std::unique_ptr<SurfaceSprite> loading_screen_sprite_; // SSprite con los gráficos de la pantalla de carga
std::shared_ptr<Surface> cheevos_surface_; // Textura con la lista de logros
std::shared_ptr<SurfaceSprite> cheevos_sprite_; // SSprite para manejar la surface con la lista de logros
std::unique_ptr<SurfaceSprite> cheevos_sprite_; // SSprite para manejar la surface con la lista de logros
std::shared_ptr<Surface> title_surface_; // Surface donde se dibuja toda la clase
std::unique_ptr<DeltaTimer> delta_timer_; // Timer para delta time
std::shared_ptr<Text> marquee_text_; // Texto para marquesina
std::shared_ptr<Text> menu_text_; // Texto para los menus
// --- Variables de estado ---
std::unique_ptr<DeltaTimer> delta_timer_; // Timer para delta time
std::shared_ptr<Text> marquee_text_; // Cache del texto para marquesina
std::string long_text_; // Texto que aparece en la parte inferior del titulo
std::vector<Glyph> letters_; // Vector con las letras de la marquesina
int first_active_letter_; // Primera letra activa (optimización)
int last_active_letter_; // Última letra activa (optimización)
bool show_cheevos_ = false; // Indica si se muestra por pantalla el listado de logros
SDL_FRect cheevos_surface_view_; // Zona visible de la surface con el listado de logros
State state_; // Estado en el que se encuentra el bucle principal
float state_time_; // Tiempo acumulado en el estado actual
float fade_accumulator_; // Acumulador para controlar el fade por tiempo
std::string long_text_; // Texto que aparece en la parte inferior del titulo
std::vector<Glyph> letters_; // Vector con las letras de la marquesina
int first_active_letter_; // Primera letra activa (optimización)
int last_active_letter_; // Última letra activa (optimización)
SDL_FRect cheevos_surface_view_; // Zona visible de la surface con el listado de logros
State state_; // Estado en el que se encuentra el bucle principal
float state_time_; // Tiempo acumulado en el estado actual
float fade_accumulator_; // Acumulador para controlar el fade por tiempo
// --- Funciones ---
void update(); // Actualiza las variables
@@ -80,8 +85,12 @@ class Title {
void initMarquee(); // Inicializa la marquesina
void updateMarquee(float delta_time); // Actualiza la marquesina (time-based)
void renderMarquee(); // Dibuja la marquesina
void renderGameLogo(); // Dibuja el logo con el titulo del juego
void renderMainMenu(); // Dibuja el menu principal
void renderCheevosMenu(); // Dibuja el menu de logros
void renderControlsMenu(); // Dibuja el menu de controles
void moveCheevosList(int direction, float delta_time); // Desplaza la lista de logros (time-based)
void fillSurface(); // Rellena la surface de fondo con todos los gráficos
void createCheevosTexture(); // Crea y rellena la surface para mostrar los logros
void hideCheevosList(); // Oculta la lista de logros
void resetCheevosScroll(); // Resetea el scroll de la lista de logros
void fillTitleSurface(); // Dibuja los elementos en la surface
};