migrant LoadingScreen a delta_time i estats

This commit is contained in:
2025-10-26 19:51:08 +01:00
parent 0388adfed8
commit d1acc59319
5 changed files with 250 additions and 144 deletions

View File

@@ -21,7 +21,11 @@ LoadingScreen::LoadingScreen()
color_loading_screen_surface_(Resource::get()->getSurface("loading_screen_color.gif")),
mono_loading_screen_sprite_(std::make_shared<SurfaceSprite>(mono_loading_screen_surface_, 0, 0, mono_loading_screen_surface_->getWidth(), mono_loading_screen_surface_->getHeight())),
color_loading_screen_sprite_(std::make_shared<SurfaceSprite>(color_loading_screen_surface_, 0, 0, color_loading_screen_surface_->getWidth(), color_loading_screen_surface_->getHeight())),
screen_surface_(std::make_shared<Surface>(Options::game.width, Options::game.height)) {
screen_surface_(std::make_shared<Surface>(Options::game.width, Options::game.height)),
delta_timer_(std::make_unique<DeltaTimer>()),
state_(LoadingState::PRE_LOADING),
state_time_(0.0f),
load_rect_{0, 0, 0, 1.0f} {
// Configura la superficie donde se van a pintar los sprites
screen_surface_->clear(static_cast<Uint8>(PaletteColor::WHITE));
@@ -29,16 +33,8 @@ LoadingScreen::LoadingScreen()
SceneManager::current = SceneManager::Scene::LOADING_SCREEN;
SceneManager::options = SceneManager::Options::NONE;
// Establece el orden de las lineas para imitar el direccionamiento de memoria del spectrum
for (int i = 0; i < 192; ++i) {
if (i < 64) { // Primer bloque de 2K
line_index_[i] = ((i % 8) * 8) + (i / 8);
} else if (i < 128) { // Segundo bloque de 2K
line_index_[i] = 64 + ((i % 8) * 8) + ((i - 64) / 8);
} else { // Tercer bloque de 2K
line_index_[i] = 128 + ((i % 8) * 8) + ((i - 128) / 8);
}
}
// Inicializa el array de índices de líneas
initLineIndexArray();
// Cambia el color del borde
Screen::get()->setBorderColor(stringToColor("black"));
@@ -62,63 +58,141 @@ void LoadingScreen::checkInput() {
globalInputs::check();
}
// Gestiona el contador de carga
void LoadingScreen::updateLoad() {
// Primera parte de la carga, la parte en blanco y negro
if (loading_first_part_) {
// Cada 5 pasos el load_counter_ se incrementa en uno
constexpr int NUM_STEPS = 5;
constexpr int STEPS = 51;
load_counter_ = counter_ / NUM_STEPS;
if (load_counter_ < 192) {
load_rect_.x = STEPS * (counter_ % NUM_STEPS);
load_rect_.y = line_index_[load_counter_];
mono_loading_screen_sprite_->setClip(load_rect_);
mono_loading_screen_sprite_->setPosition(load_rect_);
}
// Una vez actualizadas las 192 lineas, pasa a la segunda fase de la carga
else if (load_counter_ == 192) {
loading_first_part_ = false;
load_counter_ = 0;
load_rect_ = {0, 0, 16, 8};
color_loading_screen_sprite_->setClip(load_rect_);
color_loading_screen_sprite_->setPosition(load_rect_);
JA_PlayMusic(Resource::get()->getMusic("loading_sound3.ogg"));
}
}
// Segunda parte de la carga, la parte de los bloques en color
else {
load_counter_ += 2;
load_rect_.x = (load_counter_ * 8) % 256;
load_rect_.y = (load_counter_ / 32) * 8;
color_loading_screen_sprite_->setClip(load_rect_);
color_loading_screen_sprite_->setPosition(load_rect_);
// Comprueba si ha terminado la intro
if (load_counter_ >= 768) {
SceneManager::current = SceneManager::Scene::TITLE;
SceneManager::options = SceneManager::Options::TITLE_WITH_LOADING_SCREEN;
JA_StopMusic();
// Inicializa el array de índices de líneas (imita el direccionamiento de memoria del Spectrum)
void LoadingScreen::initLineIndexArray() {
for (int i = 0; i < MONO_TOTAL_LINES; ++i) {
if (i < 64) { // Primer bloque de 2K
line_index_[i] = ((i % 8) * 8) + (i / 8);
} else if (i < 128) { // Segundo bloque de 2K
line_index_[i] = 64 + ((i % 8) * 8) + ((i - 64) / 8);
} else { // Tercer bloque de 2K
line_index_[i] = 128 + ((i % 8) * 8) + ((i - 128) / 8);
}
}
}
// Gestiona el contador interno
void LoadingScreen::updateCounter() {
(pre_counter_ >= 50) ? counter_++ : pre_counter_++;
// Transiciona a un nuevo estado
void LoadingScreen::transitionToState(LoadingState new_state) {
state_ = new_state;
state_time_ = 0.0f;
if (counter_ == 1) {
JA_PlayMusic(Resource::get()->getMusic("loading_sound2.ogg"));
// Acciones específicas al entrar en cada estado
switch (new_state) {
case LoadingState::PRE_LOADING:
// No hay acción específica
break;
case LoadingState::LOADING_MONO:
// Reproducir sonido de carga monocromática
JA_PlayMusic(Resource::get()->getMusic("loading_sound2.ogg"));
break;
case LoadingState::LOADING_COLOR:
// Reproducir sonido de carga en color
JA_PlayMusic(Resource::get()->getMusic("loading_sound3.ogg"));
break;
case LoadingState::COMPLETE:
// Transicionar a la pantalla de título
SceneManager::current = SceneManager::Scene::TITLE;
SceneManager::options = SceneManager::Options::TITLE_WITH_LOADING_SCREEN;
JA_StopMusic();
break;
}
}
// Actualiza el estado actual
void LoadingScreen::updateState(float delta_time) {
state_time_ += delta_time;
// Solo PRE_LOADING transiciona por tiempo
// LOADING_MONO y LOADING_COLOR transicionan cuando completan su progreso
if (state_ == LoadingState::PRE_LOADING) {
if (state_time_ >= PRE_LOADING_DURATION) {
transitionToState(LoadingState::LOADING_MONO);
}
}
}
// Gestiona la carga monocromática (time-based simplificado)
void LoadingScreen::updateMonoLoad(float delta_time) {
// Calcular progreso lineal (0.0 - 1.0)
float progress = state_time_ / LOADING_MONO_DURATION;
progress = std::min(progress, 1.0f);
// Calcular paso total actual (0-959)
const int total_steps = MONO_TOTAL_LINES * MONO_STEPS_PER_LINE; // 192 * 5 = 960
const int current_step = static_cast<int>(progress * total_steps);
// Calcular línea y sub-paso
const int current_line = current_step / MONO_STEPS_PER_LINE; // 0-191
const int current_substep = current_step % MONO_STEPS_PER_LINE; // 0-4
// Verificar si ha completado todas las líneas
if (current_line >= MONO_TOTAL_LINES) {
transitionToState(LoadingState::LOADING_COLOR);
return;
}
// Calcular rectángulo de clip (con floats para mayor precisión)
const float texture_width = static_cast<float>(mono_loading_screen_surface_->getWidth());
const float clip_width = texture_width / MONO_STEPS_PER_LINE;
const float clip_x = current_substep * clip_width;
load_rect_.x = clip_x;
load_rect_.y = static_cast<float>(line_index_[current_line]);
load_rect_.w = clip_width;
load_rect_.h = 1.0f;
// Configurar y dibujar sobre screen_surface_
mono_loading_screen_sprite_->setClip(load_rect_);
mono_loading_screen_sprite_->setPosition(load_rect_);
auto previous_renderer = Screen::get()->getRendererSurface();
Screen::get()->setRendererSurface(screen_surface_);
mono_loading_screen_sprite_->render(1, stringToColor("black"));
Screen::get()->setRendererSurface(previous_renderer);
}
// Gestiona la carga en color (time-based simplificado)
void LoadingScreen::updateColorLoad(float delta_time) {
// Calcular progreso lineal (0.0 - 1.0)
float progress = state_time_ / LOADING_COLOR_DURATION;
progress = std::min(progress, 1.0f);
// Calcular iteración actual (el código original incrementaba de 2 en 2)
const int total_iterations = COLOR_TOTAL_BLOCKS / 2; // 768 / 2 = 384 iteraciones
const int current_iteration = static_cast<int>(progress * total_iterations);
// Convertir a bloque (incrementa de 2 en 2, empezando en 2)
const int current_block = (current_iteration + 1) * 2;
// Verificar si ha completado todos los bloques
if (current_block >= COLOR_TOTAL_BLOCKS) {
transitionToState(LoadingState::COMPLETE);
return;
}
// Calcular posición del bloque
load_rect_.x = static_cast<float>((current_block * COLOR_BLOCK_SPACING) % 256);
load_rect_.y = static_cast<float>((current_block / COLOR_BLOCKS_PER_ROW) * COLOR_BLOCK_SPACING);
load_rect_.w = static_cast<float>(COLOR_BLOCK_WIDTH);
load_rect_.h = static_cast<float>(COLOR_BLOCK_HEIGHT);
// Configurar y dibujar sobre screen_surface_
color_loading_screen_sprite_->setClip(load_rect_);
color_loading_screen_sprite_->setPosition(load_rect_);
auto previous_renderer = Screen::get()->getRendererSurface();
Screen::get()->setRendererSurface(screen_surface_);
color_loading_screen_sprite_->render();
Screen::get()->setRendererSurface(previous_renderer);
}
// Dibuja la pantalla de carga
void LoadingScreen::renderLoad() {
auto previuos_renderer = Screen::get()->getRendererSurface();
Screen::get()->setRendererSurface(screen_surface_);
loading_first_part_ ? mono_loading_screen_sprite_->render(1, stringToColor("black")) : color_loading_screen_sprite_->render();
Screen::get()->setRendererSurface(previuos_renderer);
// El dibujo incremental ya se realiza en updateMonoLoad() y updateColorLoad()
// Esta función ya no es necesaria, pero se mantiene por compatibilidad
}
// Dibuja el efecto de carga en el borde
@@ -150,15 +224,33 @@ void LoadingScreen::renderBorder() {
// Actualiza las variables
void LoadingScreen::update() {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks_ > GAME_SPEED) {
ticks_ = SDL_GetTicks();
checkInput();
updateCounter();
updateLoad();
renderLoad();
Screen::get()->update();
// Obtener delta time desde el último frame
const float delta_time = delta_timer_->tick();
checkInput(); // Comprueba las entradas
updateState(delta_time); // Actualiza el estado y gestiona transiciones
// Actualizar la carga según el estado actual
switch (state_) {
case LoadingState::PRE_LOADING:
// No hay animación de carga durante la pausa inicial
break;
case LoadingState::LOADING_MONO:
updateMonoLoad(delta_time);
break;
case LoadingState::LOADING_COLOR:
updateColorLoad(delta_time);
break;
case LoadingState::COMPLETE:
// No hay más actualizaciones
break;
}
renderLoad(); // Dibuja la pantalla de carga
Screen::get()->update(); // Actualiza el objeto Screen
}
// Dibuja en pantalla