migrat Ending2 a time based

This commit is contained in:
2025-10-31 08:40:46 +01:00
parent 3680ff3935
commit f08b2f9193
3 changed files with 109 additions and 121 deletions

View File

@@ -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);
}