Compare commits
3 Commits
c5cfb518a2
...
f08b2f9193
| Author | SHA1 | Date | |
|---|---|---|---|
| f08b2f9193 | |||
| 3680ff3935 | |||
| 99893a0c83 |
@@ -33,11 +33,11 @@ enum class Options {
|
||||
};
|
||||
|
||||
// --- Variables de estado globales ---
|
||||
#ifndef _DEBUG
|
||||
inline Scene current = Scene::LOGO; // Escena actual
|
||||
#ifdef _DEBUG
|
||||
inline Scene current = Scene::ENDING2; // Escena actual
|
||||
inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual
|
||||
#else
|
||||
inline Scene current = Scene::GAME; // Escena actual
|
||||
inline Scene current = Scene::LOGO; // Escena actual
|
||||
inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual
|
||||
#endif
|
||||
|
||||
|
||||
@@ -10,15 +10,17 @@
|
||||
#include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite
|
||||
#include "core/rendering/text.hpp" // Para Text, TEXT_CENTER, TEXT_COLOR
|
||||
#include "core/resources/resource.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, PLAY_AREA_CENTER_X, PLAY_...
|
||||
#include "core/system/global_events.hpp" // Para check
|
||||
#include "utils/delta_timer.hpp" // Para DeltaTimer
|
||||
#include "utils/utils.hpp" // Para PaletteColor
|
||||
|
||||
// Constructor
|
||||
Credits::Credits()
|
||||
: shining_sprite_(std::make_shared<SurfaceAnimatedSprite>(Resource::get()->getAnimations("shine.ani"))) {
|
||||
: shining_sprite_(std::make_shared<SurfaceAnimatedSprite>(Resource::get()->getAnimations("shine.ani"))),
|
||||
delta_timer_(std::make_unique<DeltaTimer>()) {
|
||||
// Inicializa variables
|
||||
SceneManager::current = SceneManager::Scene::CREDITS;
|
||||
SceneManager::options = SceneManager::Options::NONE;
|
||||
@@ -148,47 +150,99 @@ void Credits::fillTexture() {
|
||||
cover_surface_->fillRect(&rect, color);
|
||||
}
|
||||
|
||||
// Actualiza el contador
|
||||
void Credits::updateCounter() {
|
||||
// Incrementa el contador
|
||||
if (counter_enabled_) {
|
||||
counter_++;
|
||||
if (counter_ == 224 || counter_ == 544 || counter_ == 672) {
|
||||
counter_enabled_ = false;
|
||||
}
|
||||
} else {
|
||||
sub_counter_++;
|
||||
if (sub_counter_ == 100) {
|
||||
counter_enabled_ = true;
|
||||
sub_counter_ = 0;
|
||||
}
|
||||
}
|
||||
// Actualiza las variables
|
||||
void Credits::update() {
|
||||
// Obtiene el delta time
|
||||
current_delta_ = delta_timer_->tick();
|
||||
|
||||
// Comprueba si ha terminado la sección
|
||||
if (counter_ > 1200) {
|
||||
SceneManager::current = SceneManager::Scene::DEMO;
|
||||
// Comprueba las entradas
|
||||
checkInput();
|
||||
|
||||
// Actualiza el tiempo total
|
||||
total_time_ += current_delta_;
|
||||
|
||||
// Actualiza la máquina de estados
|
||||
updateState(current_delta_);
|
||||
|
||||
// Actualiza la pantalla
|
||||
Screen::get()->update(current_delta_);
|
||||
|
||||
// Actualiza el sprite con el brillo si está después del tiempo de inicio
|
||||
if (reveal_time_ > SHINE_START_TIME) {
|
||||
shining_sprite_->update(current_delta_);
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza las variables
|
||||
void Credits::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();
|
||||
// Transición entre estados
|
||||
void Credits::transitionToState(State new_state) {
|
||||
state_ = new_state;
|
||||
state_time_ = 0.0F;
|
||||
}
|
||||
|
||||
// Comprueba las entradas
|
||||
checkInput();
|
||||
// Actualiza la máquina de estados
|
||||
void Credits::updateState(float delta_time) {
|
||||
state_time_ += delta_time;
|
||||
|
||||
// Actualiza el contador
|
||||
updateCounter();
|
||||
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;
|
||||
|
||||
Screen::get()->update();
|
||||
case State::PAUSE_1:
|
||||
// reveal_time_ NO incrementa durante pausa (se congela)
|
||||
if (state_time_ >= PAUSE_DURATION) {
|
||||
transitionToState(State::REVEALING_TEXT_2);
|
||||
}
|
||||
break;
|
||||
|
||||
// Actualiza el sprite con el brillo
|
||||
if (counter_ > 770) {
|
||||
shining_sprite_->update();
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,14 +254,15 @@ void Credits::render() {
|
||||
// Limpia la pantalla
|
||||
Screen::get()->clearSurface(static_cast<Uint8>(PaletteColor::BLACK));
|
||||
|
||||
if (counter_ < 1150) {
|
||||
if (state_ != State::EXITING) {
|
||||
// Dibuja la textura con el texto en pantalla
|
||||
text_surface_->render(0, 0);
|
||||
|
||||
// Dibuja la textura que cubre el texto
|
||||
const int OFFSET = std::min(counter_ / 8, 192 / 2);
|
||||
// OFFSET basado en reveal_time_ (que se congela durante pausas, como counter_ original)
|
||||
const float OFFSET = std::min(reveal_time_ * REVEAL_SPEED / 8.0F, 192.0F / 2.0F);
|
||||
SDL_FRect src_rect = {0.0F, 0.0F, 256.0F, 192.0F - (OFFSET * 2.0F)};
|
||||
cover_surface_->render(0, OFFSET * 2, &src_rect);
|
||||
cover_surface_->render(0, static_cast<int>(OFFSET * 2.0F), &src_rect);
|
||||
|
||||
// Dibuja el sprite con el brillo
|
||||
shining_sprite_->render(1, static_cast<Uint8>(PaletteColor::BRIGHT_WHITE));
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <vector> // Para vector
|
||||
class SurfaceAnimatedSprite; // lines 11-11
|
||||
class Surface;
|
||||
class DeltaTimer;
|
||||
|
||||
class Credits {
|
||||
public:
|
||||
@@ -18,6 +19,30 @@ class Credits {
|
||||
void run();
|
||||
|
||||
private:
|
||||
// --- Estados ---
|
||||
enum class State {
|
||||
REVEALING_TEXT,
|
||||
PAUSE_1,
|
||||
REVEALING_TEXT_2,
|
||||
PAUSE_2,
|
||||
REVEALING_TEXT_3,
|
||||
PAUSE_3,
|
||||
DISPLAYING_WITH_SHINE,
|
||||
FADING_OUT,
|
||||
EXITING
|
||||
};
|
||||
|
||||
// --- Constantes de tiempo (basado en 60 FPS) ---
|
||||
static constexpr float REVEAL_PHASE_1_DURATION = 3.733F; // 224 frames @ 60fps
|
||||
static constexpr float PAUSE_DURATION = 1.667F; // 100 frames @ 60fps
|
||||
static constexpr float REVEAL_PHASE_2_DURATION = 5.333F; // 320 frames (544-224) @ 60fps
|
||||
static constexpr float REVEAL_PHASE_3_DURATION = 2.133F; // 128 frames (672-544) @ 60fps
|
||||
static constexpr float DISPLAY_WITH_SHINE_DURATION = 7.967F; // 478 frames (1150-672) @ 60fps
|
||||
static constexpr float FADE_OUT_DURATION = 0.833F; // 50 frames (1200-1150) @ 60fps
|
||||
static constexpr float TOTAL_DURATION = 20.0F; // 1200 frames @ 60fps
|
||||
static constexpr float SHINE_START_TIME = 12.833F; // 770 frames @ 60fps
|
||||
static constexpr float FADE_OUT_START = 19.167F; // 1150 frames @ 60fps
|
||||
static constexpr float REVEAL_SPEED = 60.0F; // counter equivalente por segundo @ 60fps
|
||||
struct Captions {
|
||||
std::string label; // Texto a escribir
|
||||
Uint8 color; // Color del texto
|
||||
@@ -29,18 +54,21 @@ class Credits {
|
||||
std::shared_ptr<SurfaceAnimatedSprite> shining_sprite_; // Sprite para el brillo del corazón
|
||||
|
||||
// --- Variables ---
|
||||
int counter_ = 0; // Contador
|
||||
bool counter_enabled_ = true; // Indica si esta activo el contador
|
||||
int sub_counter_ = 0; // Contador secundario
|
||||
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
||||
std::vector<Captions> texts_; // Vector con los textos
|
||||
std::unique_ptr<DeltaTimer> delta_timer_; // Temporizador delta para time-based update
|
||||
State state_ = State::REVEALING_TEXT; // Estado actual
|
||||
float state_time_ = 0.0F; // Tiempo acumulado en el estado actual
|
||||
float total_time_ = 0.0F; // Tiempo total acumulado
|
||||
float reveal_time_ = 0.0F; // Tiempo acumulado solo durante revelación (se congela en pausas)
|
||||
float current_delta_ = 0.0F; // Delta time del frame actual
|
||||
std::vector<Captions> texts_; // Vector con los textos
|
||||
|
||||
// --- Funciones ---
|
||||
void update(); // Actualiza las variables
|
||||
void render(); // Dibuja en pantalla
|
||||
static void checkEvents(); // Comprueba el manejador de eventos
|
||||
static void checkInput(); // Comprueba las entradas
|
||||
void updateCounter(); // Actualiza el contador
|
||||
void iniTexts(); // Inicializa los textos
|
||||
void fillTexture(); // Escribe el texto en la textura
|
||||
void update(); // Actualiza las variables
|
||||
void render(); // Dibuja en pantalla
|
||||
static void checkEvents(); // Comprueba el manejador de eventos
|
||||
static void checkInput(); // Comprueba las entradas
|
||||
void updateState(float delta_time); // Actualiza la máquina de estados
|
||||
void transitionToState(State new_state); // Transición entre estados
|
||||
void iniTexts(); // Inicializa los textos
|
||||
void fillTexture(); // Escribe el texto en la textura
|
||||
};
|
||||
|
||||
@@ -10,20 +10,17 @@
|
||||
#include "core/rendering/surface_sprite.hpp" // Para SSprite
|
||||
#include "core/rendering/text.hpp" // Para Text, TEXT_STROKE
|
||||
#include "core/resources/resource.hpp" // Para Resource
|
||||
#include "core/system/global_events.hpp" // Para check
|
||||
#include "external/jail_audio.h" // Para JA_SetVolume, JA_PlayMusic, JA_StopMusic
|
||||
#include "game/options.hpp" // Para Options, options, OptionsGame, SectionS...
|
||||
#include "game/scene_manager.hpp" // Para SceneManager
|
||||
#include "utils/defines.hpp" // Para GAME_SPEED
|
||||
#include "core/system/global_events.hpp" // Para check
|
||||
#include "utils/delta_timer.hpp" // Para DeltaTimer
|
||||
#include "utils/utils.hpp" // Para PaletteColor
|
||||
|
||||
// Constructor
|
||||
Ending::Ending()
|
||||
: counter_(-1),
|
||||
pre_counter_(0),
|
||||
cover_counter_(0),
|
||||
ticks_(0),
|
||||
current_scene_(0) {
|
||||
: delta_timer_(std::make_unique<DeltaTimer>()) {
|
||||
SceneManager::current = SceneManager::Scene::ENDING;
|
||||
SceneManager::options = SceneManager::Options::NONE;
|
||||
|
||||
@@ -48,29 +45,26 @@ Ending::Ending()
|
||||
|
||||
// Actualiza el objeto
|
||||
void Ending::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
|
||||
current_delta_ = delta_timer_->tick();
|
||||
|
||||
// Comprueba las entradas
|
||||
checkInput();
|
||||
// Comprueba las entradas
|
||||
checkInput();
|
||||
|
||||
// Actualiza el contador
|
||||
updateCounters();
|
||||
// Actualiza el tiempo total
|
||||
total_time_ += current_delta_;
|
||||
|
||||
// Actualiza las cortinillas de los elementos
|
||||
updateSpriteCovers();
|
||||
// Actualiza la máquina de estados
|
||||
updateState(current_delta_);
|
||||
|
||||
// Comprueba si se ha de cambiar de escena
|
||||
checkChangeScene();
|
||||
// Actualiza las cortinillas de los elementos
|
||||
updateSpriteCovers();
|
||||
|
||||
// Actualiza el volumen de la musica
|
||||
updateMusicVolume();
|
||||
// Actualiza el volumen de la musica
|
||||
updateMusicVolume();
|
||||
|
||||
// Actualiza el objeto Screen
|
||||
Screen::get()->update();
|
||||
}
|
||||
// Actualiza el objeto Screen
|
||||
Screen::get()->update(current_delta_);
|
||||
}
|
||||
|
||||
// Dibuja el final en pantalla
|
||||
@@ -81,20 +75,26 @@ void Ending::render() {
|
||||
// Limpia la pantalla
|
||||
Screen::get()->clearSurface(static_cast<Uint8>(PaletteColor::BLACK));
|
||||
|
||||
// Dibuja las imagenes de la escena
|
||||
sprite_pics_.at(current_scene_).image_sprite->render();
|
||||
sprite_pics_.at(current_scene_).cover_sprite->render();
|
||||
// Skip rendering durante WARMING_UP
|
||||
if (state_ != State::WARMING_UP) {
|
||||
// Dibuja las imagenes de la escena
|
||||
sprite_pics_.at(current_scene_).image_sprite->render();
|
||||
sprite_pics_.at(current_scene_).cover_sprite->render();
|
||||
|
||||
// Dibuja los textos de la escena
|
||||
for (const auto& ti : scenes_.at(current_scene_).text_index) {
|
||||
if (counter_ > ti.trigger) {
|
||||
sprite_texts_.at(ti.index).image_sprite->render();
|
||||
sprite_texts_.at(ti.index).cover_sprite->render();
|
||||
// Dibuja los textos de la escena
|
||||
for (const auto& ti : scenes_.at(current_scene_).text_index) {
|
||||
// Convertir trigger de frames a segundos @ 60fps
|
||||
const float TRIGGER_TIME = static_cast<float>(ti.trigger) / 60.0F;
|
||||
|
||||
if (state_time_ > TRIGGER_TIME) {
|
||||
sprite_texts_.at(ti.index).image_sprite->render();
|
||||
sprite_texts_.at(ti.index).cover_sprite->render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dibuja la cortinilla de cambio de escena
|
||||
renderCoverTexture();
|
||||
// Dibuja la cortinilla de cambio de escena
|
||||
renderCoverTexture();
|
||||
}
|
||||
|
||||
// Vuelca el contenido del renderizador en pantalla
|
||||
Screen::get()->render();
|
||||
@@ -113,6 +113,71 @@ void Ending::checkInput() {
|
||||
GlobalInputs::check();
|
||||
}
|
||||
|
||||
// Transición entre estados
|
||||
void Ending::transitionToState(State new_state) {
|
||||
state_ = new_state;
|
||||
state_time_ = 0.0F;
|
||||
|
||||
// Al cambiar a una escena, resetear fadeout_time_
|
||||
if (new_state != State::WARMING_UP && new_state != State::ENDING) {
|
||||
fadeout_time_ = 0.0F;
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza la máquina de estados
|
||||
void Ending::updateState(float delta_time) {
|
||||
state_time_ += delta_time;
|
||||
|
||||
switch (state_) {
|
||||
case State::WARMING_UP:
|
||||
if (state_time_ >= WARMUP_DURATION) {
|
||||
transitionToState(State::SCENE_0);
|
||||
current_scene_ = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case State::SCENE_0:
|
||||
checkChangeScene();
|
||||
// Actualizar fadeout_time_ si estamos cerca del final
|
||||
if (state_time_ >= SCENE_0_DURATION - FADEOUT_START_OFFSET) {
|
||||
fadeout_time_ += delta_time;
|
||||
}
|
||||
break;
|
||||
|
||||
case State::SCENE_1:
|
||||
checkChangeScene();
|
||||
if (state_time_ >= SCENE_1_DURATION - FADEOUT_START_OFFSET) {
|
||||
fadeout_time_ += delta_time;
|
||||
}
|
||||
break;
|
||||
|
||||
case State::SCENE_2:
|
||||
checkChangeScene();
|
||||
if (state_time_ >= SCENE_2_DURATION - FADEOUT_START_OFFSET) {
|
||||
fadeout_time_ += delta_time;
|
||||
}
|
||||
break;
|
||||
|
||||
case State::SCENE_3:
|
||||
checkChangeScene();
|
||||
if (state_time_ >= SCENE_3_DURATION - FADEOUT_START_OFFSET) {
|
||||
fadeout_time_ += delta_time;
|
||||
}
|
||||
break;
|
||||
|
||||
case State::SCENE_4:
|
||||
checkChangeScene();
|
||||
if (state_time_ >= SCENE_4_DURATION - FADEOUT_START_OFFSET) {
|
||||
fadeout_time_ += delta_time;
|
||||
}
|
||||
break;
|
||||
|
||||
case State::ENDING:
|
||||
// Transición a ENDING2
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Inicializa los textos
|
||||
void Ending::iniTexts() {
|
||||
// Vector con los textos
|
||||
@@ -370,63 +435,119 @@ void Ending::run() {
|
||||
JA_SetVolume(128);
|
||||
}
|
||||
|
||||
// Actualiza los contadores
|
||||
void Ending::updateCounters() {
|
||||
// Incrementa el contador
|
||||
if (pre_counter_ < 200) {
|
||||
pre_counter_++;
|
||||
} else {
|
||||
counter_++;
|
||||
}
|
||||
|
||||
if (counter_ > scenes_[current_scene_].counter_end - 100) {
|
||||
cover_counter_++;
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza las cortinillas de los elementos
|
||||
void Ending::updateSpriteCovers() {
|
||||
// Skip durante WARMING_UP
|
||||
if (state_ == State::WARMING_UP) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Actualiza la cortinilla de los textos
|
||||
if (counter_ % 4 == 0) {
|
||||
for (auto ti : scenes_.at(current_scene_).text_index) {
|
||||
if (counter_ > ti.trigger) {
|
||||
if (sprite_texts_.at(ti.index).cover_clip_desp > 0) {
|
||||
sprite_texts_.at(ti.index).cover_clip_desp -= 2;
|
||||
} else if (sprite_texts_.at(ti.index).cover_clip_height > 0) {
|
||||
sprite_texts_.at(ti.index).cover_clip_height -= 2;
|
||||
sprite_texts_.at(ti.index).cover_sprite->setY(sprite_texts_.at(ti.index).cover_sprite->getY() + 2);
|
||||
}
|
||||
sprite_texts_.at(ti.index).cover_sprite->setClip(0, sprite_texts_.at(ti.index).cover_clip_desp, sprite_texts_.at(ti.index).cover_sprite->getWidth(), sprite_texts_.at(ti.index).cover_clip_height);
|
||||
for (const auto& ti : scenes_.at(current_scene_).text_index) {
|
||||
// Convertir trigger de frames a segundos @ 60fps
|
||||
const float TRIGGER_TIME = static_cast<float>(ti.trigger) / 60.0F;
|
||||
|
||||
if (state_time_ > TRIGGER_TIME) {
|
||||
// Tiempo transcurrido desde que se activó el trigger
|
||||
const float TIME_SINCE_TRIGGER = state_time_ - TRIGGER_TIME;
|
||||
|
||||
// Píxeles revelados: tiempo * velocidad
|
||||
const float PIXELS_REVEALED = TIME_SINCE_TRIGGER * TEXT_REVEAL_SPEED;
|
||||
|
||||
// Obtener altura inicial de la superficie
|
||||
const float INITIAL_HEIGHT = sprite_texts_.at(ti.index).image_surface->getHeight();
|
||||
const float Y_INITIAL = sprite_texts_.at(ti.index).image_sprite->getY();
|
||||
|
||||
// Fase 1: Revelar malla decorativa (8 píxeles)
|
||||
if (PIXELS_REVEALED < 8.0F) {
|
||||
sprite_texts_.at(ti.index).cover_clip_desp = static_cast<int>(8.0F - PIXELS_REVEALED);
|
||||
sprite_texts_.at(ti.index).cover_clip_height = static_cast<int>(INITIAL_HEIGHT);
|
||||
sprite_texts_.at(ti.index).cover_sprite->setY(Y_INITIAL);
|
||||
}
|
||||
// Fase 2: Revelar contenido
|
||||
else {
|
||||
sprite_texts_.at(ti.index).cover_clip_desp = 0;
|
||||
const float CONTENT_PIXELS = PIXELS_REVEALED - 8.0F;
|
||||
sprite_texts_.at(ti.index).cover_clip_height = std::max(0, static_cast<int>(INITIAL_HEIGHT - CONTENT_PIXELS));
|
||||
sprite_texts_.at(ti.index).cover_sprite->setY(Y_INITIAL + static_cast<int>(CONTENT_PIXELS));
|
||||
}
|
||||
|
||||
sprite_texts_.at(ti.index).cover_sprite->setClip(
|
||||
0,
|
||||
sprite_texts_.at(ti.index).cover_clip_desp,
|
||||
sprite_texts_.at(ti.index).cover_sprite->getWidth(),
|
||||
sprite_texts_.at(ti.index).cover_clip_height
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza la cortinilla de las imágenes
|
||||
if (counter_ % 2 == 0) {
|
||||
if (sprite_pics_.at(current_scene_).cover_clip_desp > 0) {
|
||||
sprite_pics_.at(current_scene_).cover_clip_desp -= 2;
|
||||
} else if (sprite_pics_.at(current_scene_).cover_clip_height > 0) {
|
||||
sprite_pics_.at(current_scene_).cover_clip_height -= 2;
|
||||
sprite_pics_.at(current_scene_).cover_clip_height = std::max(sprite_pics_.at(current_scene_).cover_clip_height, 0);
|
||||
sprite_pics_.at(current_scene_).cover_sprite->setY(sprite_pics_.at(current_scene_).cover_sprite->getY() + 2);
|
||||
}
|
||||
sprite_pics_.at(current_scene_).cover_sprite->setClip(0, sprite_pics_.at(current_scene_).cover_clip_desp, sprite_pics_.at(current_scene_).cover_sprite->getWidth(), sprite_pics_.at(current_scene_).cover_clip_height);
|
||||
// Actualiza la cortinilla de las imágenes (revelación continua desde el inicio de la escena)
|
||||
const float PIXELS_REVEALED = state_time_ * IMAGE_REVEAL_SPEED;
|
||||
const float INITIAL_HEIGHT = sprite_pics_.at(current_scene_).image_surface->getHeight();
|
||||
const float Y_INITIAL = sprite_pics_.at(current_scene_).image_sprite->getY();
|
||||
|
||||
// Fase 1: Revelar malla decorativa (8 píxeles)
|
||||
if (PIXELS_REVEALED < 8.0F) {
|
||||
sprite_pics_.at(current_scene_).cover_clip_desp = static_cast<int>(8.0F - PIXELS_REVEALED);
|
||||
sprite_pics_.at(current_scene_).cover_clip_height = static_cast<int>(INITIAL_HEIGHT);
|
||||
sprite_pics_.at(current_scene_).cover_sprite->setY(Y_INITIAL);
|
||||
}
|
||||
// Fase 2: Revelar contenido
|
||||
else {
|
||||
sprite_pics_.at(current_scene_).cover_clip_desp = 0;
|
||||
const float CONTENT_PIXELS = PIXELS_REVEALED - 8.0F;
|
||||
sprite_pics_.at(current_scene_).cover_clip_height = std::max(0, static_cast<int>(INITIAL_HEIGHT - CONTENT_PIXELS));
|
||||
sprite_pics_.at(current_scene_).cover_sprite->setY(Y_INITIAL + static_cast<int>(CONTENT_PIXELS));
|
||||
}
|
||||
|
||||
sprite_pics_.at(current_scene_).cover_sprite->setClip(
|
||||
0,
|
||||
sprite_pics_.at(current_scene_).cover_clip_desp,
|
||||
sprite_pics_.at(current_scene_).cover_sprite->getWidth(),
|
||||
sprite_pics_.at(current_scene_).cover_clip_height
|
||||
);
|
||||
}
|
||||
|
||||
// Comprueba si se ha de cambiar de escena
|
||||
void Ending::checkChangeScene() {
|
||||
if (counter_ > scenes_[current_scene_].counter_end) {
|
||||
current_scene_++;
|
||||
counter_ = 0;
|
||||
cover_counter_ = 0;
|
||||
if (current_scene_ == 5) {
|
||||
// Obtener duración de la escena actual
|
||||
float CURRENT_DURATION = 0.0F;
|
||||
State NEXT_STATE = State::ENDING;
|
||||
|
||||
switch (state_) {
|
||||
case State::SCENE_0:
|
||||
CURRENT_DURATION = SCENE_0_DURATION;
|
||||
NEXT_STATE = State::SCENE_1;
|
||||
break;
|
||||
case State::SCENE_1:
|
||||
CURRENT_DURATION = SCENE_1_DURATION;
|
||||
NEXT_STATE = State::SCENE_2;
|
||||
break;
|
||||
case State::SCENE_2:
|
||||
CURRENT_DURATION = SCENE_2_DURATION;
|
||||
NEXT_STATE = State::SCENE_3;
|
||||
break;
|
||||
case State::SCENE_3:
|
||||
CURRENT_DURATION = SCENE_3_DURATION;
|
||||
NEXT_STATE = State::SCENE_4;
|
||||
break;
|
||||
case State::SCENE_4:
|
||||
CURRENT_DURATION = SCENE_4_DURATION;
|
||||
NEXT_STATE = State::ENDING;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// Comprobar si ha pasado la duración de la escena
|
||||
if (state_time_ >= CURRENT_DURATION) {
|
||||
if (NEXT_STATE == State::ENDING) {
|
||||
// Termina el bucle
|
||||
SceneManager::current = SceneManager::Scene::ENDING2;
|
||||
|
||||
// Mantiene los valores anteriores
|
||||
current_scene_ = 4;
|
||||
cover_counter_ = 100;
|
||||
} else {
|
||||
// Transición a la siguiente escena
|
||||
current_scene_++;
|
||||
transitionToState(NEXT_STATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -460,20 +581,23 @@ void Ending::fillCoverTexture() {
|
||||
|
||||
// Dibuja la cortinilla de cambio de escena
|
||||
void Ending::renderCoverTexture() {
|
||||
if (cover_counter_ > 0) {
|
||||
// Dibuja la textura que cubre el texto
|
||||
const int OFFSET = std::min(cover_counter_, 100);
|
||||
SDL_FRect src_rect = {0.0F, 200.0F - (cover_counter_ * 2.0F), 256.0F, OFFSET * 2.0F};
|
||||
SDL_FRect dst_rect = {0.0F, 0.0F, 256.0F, OFFSET * 2.0F};
|
||||
if (fadeout_time_ > 0.0F) {
|
||||
// Convertir fadeout_time_ a equivalente de cover_counter_ @ 60fps
|
||||
const float FADEOUT_COUNTER = std::min(fadeout_time_ * 60.0F, 100.0F);
|
||||
|
||||
SDL_FRect src_rect = {0.0F, 200.0F - (FADEOUT_COUNTER * 2.0F), 256.0F, FADEOUT_COUNTER * 2.0F};
|
||||
SDL_FRect dst_rect = {0.0F, 0.0F, 256.0F, FADEOUT_COUNTER * 2.0F};
|
||||
cover_surface_->render(&src_rect, &dst_rect);
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza el volumen de la musica
|
||||
void Ending::updateMusicVolume() const {
|
||||
if (current_scene_ == 4 && cover_counter_ > 0) {
|
||||
const float STEP = (100.0F - cover_counter_) / 100.0F;
|
||||
const int VOLUME = 128 * STEP;
|
||||
if (state_ == State::SCENE_4 && fadeout_time_ > 0.0F) {
|
||||
// Convertir fadeout_time_ a equivalente de cover_counter_ @ 60fps
|
||||
const float FADEOUT_COUNTER = std::min(fadeout_time_ * 60.0F, 100.0F);
|
||||
const float STEP = (100.0F - FADEOUT_COUNTER) / 100.0F;
|
||||
const int VOLUME = static_cast<int>(128.0F * STEP);
|
||||
JA_SetVolume(VOLUME);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <vector> // Para vector
|
||||
class SurfaceSprite; // lines 8-8
|
||||
class Surface; // lines 9-9
|
||||
class DeltaTimer;
|
||||
|
||||
class Ending {
|
||||
public:
|
||||
@@ -18,6 +19,30 @@ class Ending {
|
||||
void run();
|
||||
|
||||
private:
|
||||
// --- Estados ---
|
||||
enum class State {
|
||||
WARMING_UP,
|
||||
SCENE_0,
|
||||
SCENE_1,
|
||||
SCENE_2,
|
||||
SCENE_3,
|
||||
SCENE_4,
|
||||
ENDING
|
||||
};
|
||||
|
||||
// --- Constantes de tiempo (basado en 60 FPS) ---
|
||||
static constexpr float WARMUP_DURATION = 3.333F; // 200 frames @ 60fps
|
||||
static constexpr float FADEOUT_DURATION = 1.667F; // 100 frames @ 60fps
|
||||
static constexpr float SCENE_0_DURATION = 16.667F; // 1000 frames @ 60fps
|
||||
static constexpr float SCENE_1_DURATION = 23.333F; // 1400 frames @ 60fps
|
||||
static constexpr float SCENE_2_DURATION = 16.667F; // 1000 frames @ 60fps
|
||||
static constexpr float SCENE_3_DURATION = 13.333F; // 800 frames @ 60fps
|
||||
static constexpr float SCENE_4_DURATION = 16.667F; // 1000 frames @ 60fps
|
||||
static constexpr float TEXT_REVEAL_SPEED = 30.0F; // 2px cada 4 frames @ 60fps
|
||||
static constexpr float IMAGE_REVEAL_SPEED = 60.0F; // 2px cada 2 frames @ 60fps
|
||||
static constexpr float TEXT_LAPSE = 1.333F; // 80 frames @ 60fps
|
||||
static constexpr float FADEOUT_START_OFFSET = 1.667F; // Inicio fade-out 100 frames antes del fin
|
||||
|
||||
// --- Estructuras ---
|
||||
struct EndingSurface // Estructura con dos texturas y sprites, uno para mostrar y el otro hace de cortinilla
|
||||
{
|
||||
@@ -51,27 +76,30 @@ class Ending {
|
||||
std::shared_ptr<Surface> cover_surface_; // Surface para cubrir el texto
|
||||
|
||||
// --- Variables ---
|
||||
int counter_; // Contador
|
||||
int pre_counter_; // Contador previo
|
||||
int cover_counter_; // Contador para la cortinilla
|
||||
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
|
||||
std::unique_ptr<DeltaTimer> delta_timer_; // Temporizador delta para time-based update
|
||||
State state_ = State::WARMING_UP; // Estado actual
|
||||
float state_time_ = 0.0F; // Tiempo acumulado en el estado actual
|
||||
float total_time_ = 0.0F; // Tiempo total acumulado desde el inicio
|
||||
float fadeout_time_ = 0.0F; // Tiempo acumulado para el fade-out
|
||||
float current_delta_ = 0.0F; // Delta time del frame actual
|
||||
std::vector<EndingSurface> sprite_texts_; // Vector con los sprites de texto con su cortinilla
|
||||
std::vector<EndingSurface> sprite_pics_; // Vector con los sprites de texto con su cortinilla
|
||||
int current_scene_; // Escena actual
|
||||
int current_scene_ = 0; // Escena actual (0-4)
|
||||
std::vector<SceneData> scenes_; // Vector con los textos e imagenes de cada escena
|
||||
|
||||
// --- 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 iniTexts(); // Inicializa los textos
|
||||
void iniPics(); // Inicializa las imagenes
|
||||
void iniScenes(); // Inicializa las escenas
|
||||
void updateCounters(); // Actualiza los contadores
|
||||
void updateSpriteCovers(); // Actualiza las cortinillas de los elementos
|
||||
void checkChangeScene(); // Comprueba si se ha de cambiar de escena
|
||||
void fillCoverTexture(); // Rellena la textura para la cortinilla
|
||||
void renderCoverTexture(); // Dibuja la cortinilla de cambio de escena
|
||||
void updateMusicVolume() const; // Actualiza el volumen de la musica
|
||||
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 iniTexts(); // Inicializa los textos
|
||||
void iniPics(); // Inicializa las imagenes
|
||||
void iniScenes(); // Inicializa las escenas
|
||||
void updateState(float delta_time); // Actualiza la máquina de estados
|
||||
void transitionToState(State new_state); // Transición entre estados
|
||||
void updateSpriteCovers(); // Actualiza las cortinillas de los elementos
|
||||
void checkChangeScene(); // Comprueba si se ha de cambiar de escena
|
||||
void fillCoverTexture(); // Rellena la textura para la cortinilla
|
||||
void renderCoverTexture(); // Dibuja la cortinilla de cambio de escena
|
||||
void updateMusicVolume() const; // Actualiza el volumen de la musica
|
||||
};
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <algorithm> // Para max, replace
|
||||
|
||||
#include "core/audio/audio.hpp" // Para Audio
|
||||
#include "core/input/global_inputs.hpp" // Para check
|
||||
#include "core/rendering/screen.hpp" // Para Screen
|
||||
#include "core/rendering/surface.hpp" // Para Surface
|
||||
@@ -11,16 +12,17 @@
|
||||
#include "core/rendering/surface_moving_sprite.hpp" // Para SMovingSprite
|
||||
#include "core/rendering/text.hpp" // Para Text
|
||||
#include "core/resources/resource.hpp" // Para Resource
|
||||
#include "external/jail_audio.h" // Para JA_SetVolume, JA_PlayMusic, JA_StopMusic
|
||||
#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 GAMECANVAS_CENTER_X, GAMECANVAS_CENTER_Y
|
||||
#include "core/system/global_events.hpp" // Para check
|
||||
#include "utils/delta_timer.hpp" // Para DeltaTimer
|
||||
#include "utils/utils.hpp" // Para PaletteColor, stringToColor
|
||||
|
||||
// Constructor
|
||||
Ending2::Ending2()
|
||||
: state_(EndingState::PRE_CREDITS, SDL_GetTicks(), STATE_PRE_CREDITS_DURATION) {
|
||||
: delta_timer_(std::make_unique<DeltaTimer>()),
|
||||
state_(EndingState::PRE_CREDITS, STATE_PRE_CREDITS_DURATION) {
|
||||
SceneManager::current = SceneManager::Scene::ENDING2;
|
||||
SceneManager::options = SceneManager::Options::NONE;
|
||||
|
||||
@@ -51,41 +53,35 @@ Ending2::Ending2()
|
||||
|
||||
// Actualiza el objeto
|
||||
void Ending2::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
|
||||
current_delta_ = delta_timer_->tick();
|
||||
|
||||
// Comprueba las entradas
|
||||
checkInput();
|
||||
// Comprueba las entradas
|
||||
checkInput();
|
||||
|
||||
// Actualiza el estado
|
||||
updateState();
|
||||
// Actualiza el estado
|
||||
updateState(current_delta_);
|
||||
|
||||
switch (state_.state) {
|
||||
case EndingState::CREDITS:
|
||||
// Actualiza los sprites, los textos y los textos del final
|
||||
for (int i = 0; i < 25; ++i) {
|
||||
updateSprites();
|
||||
updateTextSprites();
|
||||
updateTexts();
|
||||
}
|
||||
break;
|
||||
switch (state_.state) {
|
||||
case EndingState::CREDITS:
|
||||
// Actualiza los sprites, los textos y los textos del final
|
||||
updateSprites(current_delta_);
|
||||
updateTextSprites(current_delta_);
|
||||
updateTexts(current_delta_);
|
||||
break;
|
||||
|
||||
case EndingState::FADING:
|
||||
// Actualiza el fade final y el volumen de la música
|
||||
updateFinalFade();
|
||||
updateMusicVolume();
|
||||
break;
|
||||
case EndingState::FADING:
|
||||
// Actualiza el fade final
|
||||
updateFinalFade();
|
||||
break;
|
||||
|
||||
default:
|
||||
// No hacer nada si el estado no corresponde a un caso manejado
|
||||
break;
|
||||
}
|
||||
|
||||
// Actualiza el objeto
|
||||
Screen::get()->update();
|
||||
default:
|
||||
// No hacer nada si el estado no corresponde a un caso manejado
|
||||
break;
|
||||
}
|
||||
|
||||
// Actualiza el objeto
|
||||
Screen::get()->update(current_delta_);
|
||||
}
|
||||
|
||||
// Dibuja el final en pantalla
|
||||
@@ -145,7 +141,7 @@ void Ending2::checkInput() {
|
||||
|
||||
// Bucle principal
|
||||
void Ending2::run() {
|
||||
JA_PlayMusic(Resource::get()->getMusic("ending2.ogg"));
|
||||
Audio::get()->playMusic("ending2.ogg");
|
||||
|
||||
while (SceneManager::current == SceneManager::Scene::ENDING2) {
|
||||
update();
|
||||
@@ -153,33 +149,34 @@ void Ending2::run() {
|
||||
render();
|
||||
}
|
||||
|
||||
JA_StopMusic();
|
||||
JA_SetVolume(128);
|
||||
Audio::get()->stopMusic();
|
||||
}
|
||||
|
||||
// Actualiza el estado
|
||||
void Ending2::updateState() {
|
||||
void Ending2::updateState(float delta_time) {
|
||||
state_time_ += delta_time;
|
||||
|
||||
switch (state_.state) {
|
||||
case EndingState::PRE_CREDITS:
|
||||
if (state_.hasEnded(EndingState::PRE_CREDITS)) {
|
||||
state_.set(EndingState::CREDITS, 0);
|
||||
if (state_time_ >= STATE_PRE_CREDITS_DURATION) {
|
||||
transitionToState(EndingState::CREDITS);
|
||||
}
|
||||
break;
|
||||
|
||||
case EndingState::CREDITS:
|
||||
if (texts_.back()->getPosY() <= GAMECANVAS_CENTER_Y) {
|
||||
state_.set(EndingState::POST_CREDITS, STATE_POST_CREDITS_DURATION);
|
||||
transitionToState(EndingState::POST_CREDITS);
|
||||
}
|
||||
break;
|
||||
|
||||
case EndingState::POST_CREDITS:
|
||||
if (state_.hasEnded(EndingState::POST_CREDITS)) {
|
||||
state_.set(EndingState::FADING, STATE_FADE_DURATION);
|
||||
if (state_time_ >= STATE_POST_CREDITS_DURATION) {
|
||||
transitionToState(EndingState::FADING);
|
||||
}
|
||||
break;
|
||||
|
||||
case EndingState::FADING:
|
||||
if (state_.hasEnded(EndingState::FADING)) {
|
||||
if (state_time_ >= STATE_FADE_DURATION) {
|
||||
SceneManager::current = SceneManager::Scene::LOGO;
|
||||
SceneManager::options = SceneManager::Options::LOGO_TO_LOADING_SCREEN;
|
||||
}
|
||||
@@ -190,6 +187,32 @@ void Ending2::updateState() {
|
||||
}
|
||||
}
|
||||
|
||||
// Transición entre estados
|
||||
void Ending2::transitionToState(EndingState new_state) {
|
||||
state_.state = new_state;
|
||||
state_time_ = 0.0F;
|
||||
|
||||
// Actualizar duración según el nuevo estado
|
||||
switch (new_state) {
|
||||
case EndingState::PRE_CREDITS:
|
||||
state_.duration = STATE_PRE_CREDITS_DURATION;
|
||||
break;
|
||||
case EndingState::POST_CREDITS:
|
||||
state_.duration = STATE_POST_CREDITS_DURATION;
|
||||
break;
|
||||
case EndingState::FADING:
|
||||
state_.duration = STATE_FADE_DURATION;
|
||||
// Al entrar en FADING, iniciar fade de audio
|
||||
Audio::get()->fadeOutMusic(MUSIC_FADE_DURATION);
|
||||
break;
|
||||
case EndingState::CREDITS:
|
||||
state_.duration = 0.0F; // CREDITS no tiene duración fija, termina cuando el último texto llega al centro
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Inicializa la lista de sprites
|
||||
void Ending2::iniSpriteList() {
|
||||
// Reinicia el vector
|
||||
@@ -282,23 +305,23 @@ void Ending2::loadSprites() {
|
||||
}
|
||||
|
||||
// Actualiza los sprites
|
||||
void Ending2::updateSprites() {
|
||||
void Ending2::updateSprites(float delta) {
|
||||
for (const auto& sprite : sprites_) {
|
||||
sprite->update();
|
||||
sprite->update(delta);
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza los sprites de texto
|
||||
void Ending2::updateTextSprites() {
|
||||
void Ending2::updateTextSprites(float delta) {
|
||||
for (const auto& sprite : sprite_texts_) {
|
||||
sprite->update();
|
||||
sprite->update(delta);
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza los sprites de texto del final
|
||||
void Ending2::updateTexts() {
|
||||
void Ending2::updateTexts(float delta) {
|
||||
for (const auto& sprite : texts_) {
|
||||
sprite->update();
|
||||
sprite->update(delta);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,7 +368,7 @@ void Ending2::renderTexts() {
|
||||
void Ending2::placeSprites() {
|
||||
for (int i = 0; i < static_cast<int>(sprites_.size()); ++i) {
|
||||
const float X = i % 2 == 0 ? FIRST_COL : SECOND_COL;
|
||||
const float Y = ((i / 1) * (sprite_max_height_ + DIST_SPRITE_TEXT + Resource::get()->getText("smb2")->getCharacterSize() + DIST_SPRITE_SPRITE)) + Options::game.height + 40;
|
||||
const float Y = ((i / 1) * (sprite_max_height_ + DIST_SPRITE_TEXT + Resource::get()->getText("smb2")->getCharacterSize() + DIST_SPRITE_SPRITE)) + Options::game.height + INITIAL_Y_OFFSET;
|
||||
const float W = sprites_.at(i)->getWidth();
|
||||
const float H = sprites_.at(i)->getHeight();
|
||||
const float DX = -(W / 2);
|
||||
@@ -416,7 +439,7 @@ void Ending2::createTexts() {
|
||||
const float H = text->getCharacterSize();
|
||||
const float X = GAMECANVAS_CENTER_X;
|
||||
const float DX = -(W / 2);
|
||||
const float Y = Options::game.height + (text->getCharacterSize() * (i * 2));
|
||||
const float Y = Options::game.height + (text->getCharacterSize() * (i * TEXT_SPACING_MULTIPLIER));
|
||||
|
||||
// Crea la surface
|
||||
auto surface = std::make_shared<Surface>(W, H);
|
||||
@@ -445,7 +468,7 @@ void Ending2::createTexts() {
|
||||
const float H = text->getCharacterSize();
|
||||
const float X = GAMECANVAS_CENTER_X;
|
||||
const float DX = -(W / 2);
|
||||
const float Y = START + (text->getCharacterSize() * (i * 2));
|
||||
const float Y = START + (text->getCharacterSize() * (i * TEXT_SPACING_MULTIPLIER));
|
||||
|
||||
// Crea la surface
|
||||
auto surface = std::make_shared<Surface>(W, H);
|
||||
@@ -467,27 +490,3 @@ void Ending2::updateFinalFade() {
|
||||
sprite->getSurface()->fadeSubPalette(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Actualiza el volumen de la musica
|
||||
void Ending2::updateMusicVolume() const {
|
||||
// Constante para la duración en milisegundos
|
||||
constexpr Uint32 VOLUME_FADE_DURATION = 3000;
|
||||
|
||||
// Tiempo actual
|
||||
const Uint32 CURRENT_TICKS = SDL_GetTicks();
|
||||
|
||||
// Calcular el tiempo transcurrido desde init_ticks
|
||||
Uint32 elapsed_ticks = CURRENT_TICKS - state_.init_ticks;
|
||||
|
||||
// Limitar el tiempo máximo a la duración definida
|
||||
elapsed_ticks = std::min(elapsed_ticks, VOLUME_FADE_DURATION);
|
||||
|
||||
// Calcular el step basado en la duración
|
||||
const float STEP = (static_cast<float>(VOLUME_FADE_DURATION) - elapsed_ticks) / VOLUME_FADE_DURATION;
|
||||
|
||||
// Calcular el volumen en función del step
|
||||
const int VOLUME = static_cast<int>(128 * STEP);
|
||||
|
||||
// Actualizar el volumen
|
||||
JA_SetVolume(VOLUME);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "utils/defines.hpp" // Para GAMECANVAS_WIDTH, GAMECANVAS_FIRST_QUAR...
|
||||
class SurfaceAnimatedSprite; // lines 9-9
|
||||
class SurfaceMovingSprite; // lines 10-10
|
||||
class DeltaTimer;
|
||||
|
||||
class Ending2 {
|
||||
public:
|
||||
@@ -31,32 +32,12 @@ class Ending2 {
|
||||
// --- Estructura para controlar los estados y su duración ---
|
||||
struct State {
|
||||
EndingState state; // Estado actual
|
||||
Uint32 init_ticks; // Ticks en los que se inicializó el estado
|
||||
Uint32 duration; // Duración en milisegundos para el estado actual
|
||||
float duration; // Duración en segundos para el estado actual
|
||||
|
||||
// Constructor parametrizado para inicializar la estructura
|
||||
State(EndingState initial_state, Uint32 initial_ticks, Uint32 state_duration)
|
||||
State(EndingState initial_state, float state_duration)
|
||||
: state(initial_state),
|
||||
init_ticks(initial_ticks),
|
||||
duration(state_duration) {}
|
||||
|
||||
// Método para comprobar si el estado ha terminado y verifica el nombre del estado
|
||||
[[nodiscard]] auto hasEnded(EndingState expected_state) const -> bool {
|
||||
// Comprobar si el estado actual coincide con el estado esperado
|
||||
if (state != expected_state) {
|
||||
return false; // Si no coincide, considerar que no ha terminado
|
||||
}
|
||||
|
||||
// Comprobar si el tiempo transcurrido excede la duración
|
||||
return (SDL_GetTicks() - init_ticks) >= duration;
|
||||
}
|
||||
|
||||
// Método para establecer un nuevo estado
|
||||
void set(EndingState new_state, Uint32 new_duration) {
|
||||
state = new_state; // Actualizar el estado
|
||||
init_ticks = SDL_GetTicks(); // Reiniciar el tiempo de inicio
|
||||
duration = new_duration; // Actualizar la duración
|
||||
}
|
||||
};
|
||||
|
||||
// --- Constantes ---
|
||||
@@ -64,41 +45,49 @@ class Ending2 {
|
||||
static constexpr int SECOND_COL = GAMECANVAS_THIRD_QUARTER_X - (GAMECANVAS_WIDTH / 16); // Segunda columna por donde desfilan los sprites
|
||||
static constexpr int DIST_SPRITE_TEXT = 8; // Distancia entre el sprite y el texto que lo acompaña
|
||||
static constexpr int DIST_SPRITE_SPRITE = 0; // Distancia entre dos sprites de la misma columna
|
||||
static constexpr float SPRITE_DESP_SPEED = -0.2F; // Velocidad de desplazamiento de los sprites
|
||||
static constexpr int STATE_PRE_CREDITS_DURATION = 3000;
|
||||
static constexpr int STATE_POST_CREDITS_DURATION = 5000;
|
||||
static constexpr int STATE_FADE_DURATION = 5000;
|
||||
static constexpr int INITIAL_Y_OFFSET = 40; // Offset inicial en Y para posicionar sprites
|
||||
static constexpr int SCREEN_MESH_HEIGHT = 8; // Altura de la malla superior/inferior de la pantalla
|
||||
static constexpr int TEXT_SPACING_MULTIPLIER = 2; // Multiplicador para espaciado entre líneas de texto
|
||||
|
||||
// Constantes de tiempo (basadas en tiempo real, no en frames)
|
||||
static constexpr float SPRITE_DESP_SPEED = -12.0F; // Velocidad de desplazamiento en pixels/segundo (era -0.2 px/frame @ 60fps)
|
||||
static constexpr float STATE_PRE_CREDITS_DURATION = 3.0F; // Duración del estado previo a créditos en segundos
|
||||
static constexpr float STATE_POST_CREDITS_DURATION = 5.0F; // Duración del estado posterior a créditos en segundos
|
||||
static constexpr float STATE_FADE_DURATION = 5.0F; // Duración del fade final en segundos
|
||||
static constexpr int MUSIC_FADE_DURATION = 3000; // Duración del fade de música en milisegundos (para Audio API)
|
||||
|
||||
// --- Objetos y punteros ---
|
||||
std::vector<std::shared_ptr<SurfaceAnimatedSprite>> sprites_; // Vector con todos los sprites a dibujar
|
||||
std::vector<std::shared_ptr<SurfaceMovingSprite>> sprite_texts_; // Vector con los sprites de texto de los sprites
|
||||
std::vector<std::shared_ptr<SurfaceMovingSprite>> texts_; // Vector con los sprites de texto
|
||||
std::unique_ptr<DeltaTimer> delta_timer_; // Temporizador delta para time-based update
|
||||
|
||||
// --- Variables ---
|
||||
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
||||
std::vector<std::string> sprite_list_; // Lista con todos los sprites a dibujar
|
||||
std::vector<Uint8> colors_; // Vector con los colores para el fade
|
||||
float sprite_max_width_ = 0; // El valor de ancho del sprite mas ancho
|
||||
float sprite_max_height_ = 0; // El valor de alto del sprite mas alto
|
||||
float state_time_ = 0.0F; // Tiempo acumulado en el estado actual
|
||||
float current_delta_ = 0.0F; // Delta time del frame actual
|
||||
State state_; // Controla el estado de la clase
|
||||
|
||||
// --- Fucniones ---
|
||||
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
|
||||
void iniSpriteList(); // Inicializa la lista de sprites
|
||||
void loadSprites(); // Carga todos los sprites desde una lista
|
||||
void updateSprites(); // Actualiza los sprites
|
||||
void updateTextSprites(); // Actualiza los sprites de texto
|
||||
void updateTexts(); // Actualiza los sprites de texto del final
|
||||
void renderSprites(); // Dibuja los sprites
|
||||
void renderSpriteTexts(); // Dibuja los sprites con el texto
|
||||
void renderTexts(); // Dibuja los sprites con el texto del final
|
||||
void placeSprites(); // Coloca los sprites en su sito
|
||||
void createSpriteTexts(); // Crea los sprites con las texturas con los textos
|
||||
void createTexts(); // Crea los sprites con las texturas con los textos del final
|
||||
void updateFinalFade(); // Actualiza el fade final
|
||||
void updateMusicVolume() const; // Actualiza el volumen de la musica
|
||||
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(float delta_time); // Actualiza el estado
|
||||
void transitionToState(EndingState new_state); // Transición entre estados
|
||||
void iniSpriteList(); // Inicializa la lista de sprites
|
||||
void loadSprites(); // Carga todos los sprites desde una lista
|
||||
void updateSprites(float delta); // Actualiza los sprites
|
||||
void updateTextSprites(float delta); // Actualiza los sprites de texto
|
||||
void updateTexts(float delta); // Actualiza los sprites de texto del final
|
||||
void renderSprites(); // Dibuja los sprites
|
||||
void renderSpriteTexts(); // Dibuja los sprites con el texto
|
||||
void renderTexts(); // Dibuja los sprites con el texto del final
|
||||
void placeSprites(); // Coloca los sprites en su sito
|
||||
void createSpriteTexts(); // Crea los sprites con las texturas con los textos
|
||||
void createTexts(); // Crea los sprites con las texturas con los textos del final
|
||||
void updateFinalFade(); // Actualiza el fade final
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user