treballant en les novetats de LoadingScreen

This commit is contained in:
2025-10-26 21:44:16 +01:00
parent 96506988b6
commit 0c87612a17
4 changed files with 211 additions and 117 deletions

View File

@@ -13,12 +13,12 @@
#include <memory> // Para make_unique, unique_ptr #include <memory> // Para make_unique, unique_ptr
#include <string> // Para operator+, allocator, char_traits #include <string> // Para operator+, allocator, char_traits
#include "core/audio/audio.hpp" // Para Audio
#include "core/input/input.hpp" // Para Input, InputAction #include "core/input/input.hpp" // Para Input, InputAction
#include "core/rendering/screen.hpp" // Para Screen #include "core/rendering/screen.hpp" // Para Screen
#include "core/resources/asset.hpp" // Para Asset, AssetType #include "core/resources/asset.hpp" // Para Asset, AssetType
#include "core/resources/resource.hpp" // Para Resource #include "core/resources/resource.hpp" // Para Resource
#include "core/system/debug.hpp" // Para Debug #include "core/system/debug.hpp" // Para Debug
#include "external/jail_audio.h" // Para JA_SetMusicVolume, JA_SetSoundV...
#include "game/gameplay/cheevos.hpp" // Para Cheevos #include "game/gameplay/cheevos.hpp" // Para Cheevos
#include "game/options.hpp" // Para Options, options, OptionsVideo #include "game/options.hpp" // Para Options, options, OptionsVideo
#include "game/scenes/credits.hpp" // Para Credits #include "game/scenes/credits.hpp" // Para Credits
@@ -62,7 +62,7 @@ Director::Director(int argc, const char* argv[]) {
Options::loadFromFile(Asset::get()->get("config.txt")); Options::loadFromFile(Asset::get()->get("config.txt"));
// Inicializa JailAudio // Inicializa JailAudio
initJailAudio(); Audio::init();
// Crea los objetos // Crea los objetos
Screen::init(); Screen::init();
@@ -86,6 +86,7 @@ Director::~Director() {
Input::destroy(); Input::destroy();
Notifier::destroy(); Notifier::destroy();
Resource::destroy(); Resource::destroy();
Audio::destroy();
Screen::destroy(); Screen::destroy();
Asset::destroy(); Asset::destroy();
@@ -237,22 +238,6 @@ void Director::initInput() {
} }
} }
// Inicializa JailAudio
void Director::initJailAudio() {
if (!SDL_Init(SDL_INIT_AUDIO)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_AUDIO could not initialize! SDL Error: %s", SDL_GetError());
} else {
JA_Init(48000, SDL_AUDIO_S16LE, 2);
if (Options::audio.enabled) {
JA_SetMusicVolume(Options::audio.music.volume);
JA_SetSoundVolume(Options::audio.sound.volume);
} else {
JA_SetMusicVolume(0);
JA_SetSoundVolume(0);
}
}
}
// Crea el indice de ficheros // Crea el indice de ficheros
bool Director::setFileList() { bool Director::setFileList() {
#ifdef MACOS_BUNDLE #ifdef MACOS_BUNDLE
@@ -537,7 +522,7 @@ void Director::runGameOver() {
// Ejecuta la seccion de juego donde se juega // Ejecuta la seccion de juego donde se juega
void Director::runGame() { void Director::runGame() {
JA_StopMusic(); Audio::get()->stopMusic();
auto game = std::make_unique<Game>(GameMode::GAME); auto game = std::make_unique<Game>(GameMode::GAME);
game->run(); game->run();
} }

View File

@@ -5,60 +5,28 @@
#include <string> // Para string #include <string> // Para string
class Director { class Director {
private:
// Variables
std::string executable_path_; // Path del ejecutable
std::string system_folder_; // Carpeta del sistema donde guardar datos
// Comprueba los parametros del programa
std::string checkProgramArguments(int argc, const char* argv[]);
// Crea la carpeta del sistema donde guardar datos
void createSystemFolder(const std::string& folder);
// Inicializa jail_audio
void initJailAudio();
// Inicializa el objeto Input
void initInput();
// Crea el indice de ficheros
bool setFileList();
// Ejecuta la seccion de juego con el logo
void runLogo();
// Ejecuta la seccion de juego de la pantalla de carga
void runLoadingScreen();
// Ejecuta la seccion de juego con el titulo y los menus
void runTitle();
// Ejecuta la seccion de los creditos del juego
void runCredits();
// Ejecuta la seccion de la demo, donde se ven pantallas del juego
void runDemo();
// Ejecuta la seccion del final del juego
void runEnding();
// Ejecuta la seccion del final del juego
void runEnding2();
// Ejecuta la seccion del final de la partida
void runGameOver();
// Ejecuta la seccion de juego donde se juega
void runGame();
public: public:
// Constructor Director(int argc, const char* argv[]); // Constructor
Director(int argc, const char* argv[]); ~Director(); // Destructor
int run(); // Bucle principal
// Destructor private:
~Director(); // --- Variables ---
std::string executable_path_; // Path del ejecutable
std::string system_folder_; // Carpeta del sistema donde guardar datos
std::string checkProgramArguments(int argc, const char* argv[]); // Comprueba los parametros del programa
// Bucle principal // --- Funciones ---
int run(); void createSystemFolder(const std::string& folder); // Crea la carpeta del sistema donde guardar datos
void initInput(); // Inicializa el objeto Input
bool setFileList(); // Crea el indice de ficheros
void runLogo(); // Ejecuta la seccion de juego con el logo
void runLoadingScreen(); // Ejecuta la seccion de juego de la pantalla de carga
void runTitle(); // Ejecuta la seccion de juego con el titulo y los menus
void runCredits(); // Ejecuta la seccion de los creditos del juego
void runDemo(); // Ejecuta la seccion de la demo, donde se ven pantallas del juego
void runEnding(); // Ejecuta la seccion del final del juego
void runEnding2(); // Ejecuta la seccion del final del juego
void runGameOver(); // Ejecuta la seccion del final de la partida
void runGame(); // Ejecuta la seccion de juego donde se juega
}; };

View File

@@ -3,12 +3,12 @@
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <stdlib.h> // Para rand #include <stdlib.h> // Para rand
#include "core/audio/audio.hpp" // Para Audio
#include "core/input/global_inputs.hpp" // Para check #include "core/input/global_inputs.hpp" // Para check
#include "core/rendering/screen.hpp" // Para Screen #include "core/rendering/screen.hpp" // Para Screen
#include "core/rendering/surface.hpp" // Para Surface #include "core/rendering/surface.hpp" // Para Surface
#include "core/rendering/surface_sprite.hpp" // Para SSprite #include "core/rendering/surface_sprite.hpp" // Para SSprite
#include "core/resources/resource.hpp" // Para Resource #include "core/resources/resource.hpp" // Para Resource
#include "external/jail_audio.h" // Para JA_PlayMusic, JA_SetVolume, JA_StopMusic
#include "game/options.hpp" // Para Options, options, SectionState, Options... #include "game/options.hpp" // Para Options, options, SectionState, Options...
#include "game/scene_manager.hpp" // Para SceneManager #include "game/scene_manager.hpp" // Para SceneManager
#include "utils/defines.hpp" // Para GAME_SPEED #include "utils/defines.hpp" // Para GAME_SPEED
@@ -23,8 +23,9 @@ LoadingScreen::LoadingScreen()
color_loading_screen_sprite_(std::make_shared<SurfaceSprite>(color_loading_screen_surface_, 0, 0, color_loading_screen_surface_->getWidth(), color_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>()), delta_timer_(std::make_unique<DeltaTimer>()),
state_(LoadingState::PRE_LOADING), state_(LoadingState::SILENT1),
state_time_(0.0f), state_time_(0.0f),
current_border_type_(BorderType::NONE),
load_rect_{0, 0, 0, 1.0f} { load_rect_{0, 0, 0, 1.0f} {
// Configura la superficie donde se van a pintar los sprites // Configura la superficie donde se van a pintar los sprites
screen_surface_->clear(static_cast<Uint8>(PaletteColor::WHITE)); screen_surface_->clear(static_cast<Uint8>(PaletteColor::WHITE));
@@ -37,12 +38,13 @@ LoadingScreen::LoadingScreen()
initLineIndexArray(); initLineIndexArray();
// Cambia el color del borde // Cambia el color del borde
Screen::get()->setBorderColor(stringToColor("black")); Screen::get()->setBorderColor(stringToColor("white"));
transitionToState(LoadingState::SILENT1);
} }
// Destructor // Destructor
LoadingScreen::~LoadingScreen() { LoadingScreen::~LoadingScreen() {
JA_StopMusic(); Audio::get()->stopMusic();
} }
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
@@ -78,25 +80,39 @@ void LoadingScreen::transitionToState(LoadingState new_state) {
// Acciones específicas al entrar en cada estado // Acciones específicas al entrar en cada estado
switch (new_state) { switch (new_state) {
case LoadingState::PRE_LOADING: case LoadingState::SILENT1:
// No hay acción específica case LoadingState::SILENT2:
current_border_type_ = BorderType::WHITE;
Audio::get()->stopMusic();
break; break;
case LoadingState::HEADER1:
case LoadingState::HEADER2:
current_border_type_ = BorderType::RED;
// Reproducir sonido de cargar el header
Audio::get()->playMusic("loading_sound1.ogg");
break;
case LoadingState::BYTES1:
case LoadingState::BYTES2:
case LoadingState::LOADING_MONO: case LoadingState::LOADING_MONO:
current_border_type_ = BorderType::YELLOW;
// Reproducir sonido de carga monocromática // Reproducir sonido de carga monocromática
JA_PlayMusic(Resource::get()->getMusic("loading_sound2.ogg")); Audio::get()->playMusic("loading_sound2.ogg");
break; break;
case LoadingState::LOADING_COLOR: case LoadingState::LOADING_COLOR:
current_border_type_ = BorderType::YELLOW;
// Reproducir sonido de carga en color // Reproducir sonido de carga en color
JA_PlayMusic(Resource::get()->getMusic("loading_sound3.ogg")); Audio::get()->playMusic("loading_sound3.ogg");
break; break;
case LoadingState::COMPLETE: case LoadingState::COMPLETE:
current_border_type_ = BorderType::WHITE;
// Transicionar a la pantalla de título // Transicionar a la pantalla de título
SceneManager::current = SceneManager::Scene::TITLE; SceneManager::current = SceneManager::Scene::TITLE;
SceneManager::options = SceneManager::Options::TITLE_WITH_LOADING_SCREEN; SceneManager::options = SceneManager::Options::TITLE_WITH_LOADING_SCREEN;
JA_StopMusic(); Audio::get()->stopMusic();
break; break;
} }
} }
@@ -105,12 +121,50 @@ void LoadingScreen::transitionToState(LoadingState new_state) {
void LoadingScreen::updateState(float delta_time) { void LoadingScreen::updateState(float delta_time) {
state_time_ += delta_time; state_time_ += delta_time;
// Solo PRE_LOADING transiciona por tiempo // Transiciones automáticas por tiempo para los estados iniciales
// LOADING_MONO y LOADING_COLOR transicionan cuando completan su progreso // LOADING_MONO y LOADING_COLOR transicionan en sus propias funciones
if (state_ == LoadingState::PRE_LOADING) { switch (state_) {
if (state_time_ >= PRE_LOADING_DURATION) { case LoadingState::SILENT1:
transitionToState(LoadingState::LOADING_MONO); if (state_time_ >= SILENT1_DURATION) {
} transitionToState(LoadingState::HEADER1);
}
break;
case LoadingState::HEADER1:
if (state_time_ >= HEADER1_DURATION) {
transitionToState(LoadingState::BYTES1);
}
break;
case LoadingState::BYTES1:
if (state_time_ >= BYTES1_DURATION) {
transitionToState(LoadingState::SILENT2);
}
break;
case LoadingState::SILENT2:
if (state_time_ >= SILENT2_DURATION) {
transitionToState(LoadingState::HEADER2);
}
break;
case LoadingState::HEADER2:
if (state_time_ >= HEADER2_DURATION) {
transitionToState(LoadingState::LOADING_MONO);
}
break;
case LoadingState::BYTES2:
if (state_time_ >= BYTES2_DURATION) {
transitionToState(LoadingState::COMPLETE);
}
break;
case LoadingState::LOADING_MONO:
case LoadingState::LOADING_COLOR:
case LoadingState::COMPLETE:
// Estos estados se gestionan en updateMonoLoad/updateColorLoad
break;
} }
} }
@@ -154,7 +208,7 @@ void LoadingScreen::updateMonoLoad(float delta_time) {
Screen::get()->setRendererSurface(previous_renderer); Screen::get()->setRendererSurface(previous_renderer);
} }
// Gestiona la carga en color (time-based simplificado) // Gestiona la carga en color
void LoadingScreen::updateColorLoad(float delta_time) { void LoadingScreen::updateColorLoad(float delta_time) {
// Calcular progreso lineal (0.0 - 1.0) // Calcular progreso lineal (0.0 - 1.0)
float progress = state_time_ / LOADING_COLOR_DURATION; float progress = state_time_ / LOADING_COLOR_DURATION;
@@ -169,7 +223,7 @@ void LoadingScreen::updateColorLoad(float delta_time) {
// Verificar si ha completado todos los bloques // Verificar si ha completado todos los bloques
if (current_block >= COLOR_TOTAL_BLOCKS) { if (current_block >= COLOR_TOTAL_BLOCKS) {
transitionToState(LoadingState::COMPLETE); transitionToState(LoadingState::BYTES2);
return; return;
} }
@@ -189,14 +243,8 @@ void LoadingScreen::updateColorLoad(float delta_time) {
Screen::get()->setRendererSurface(previous_renderer); Screen::get()->setRendererSurface(previous_renderer);
} }
// Dibuja la pantalla de carga // Dibuja el efecto de carga amarillo y azul en el borde
void LoadingScreen::renderLoad() { void LoadingScreen::renderYellowBorder() {
// 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
void LoadingScreen::renderBorder() {
// Obtiene la Surface del borde // Obtiene la Surface del borde
auto border = Screen::get()->getBorderSurface(); auto border = Screen::get()->getBorderSurface();
@@ -222,18 +270,71 @@ void LoadingScreen::renderBorder() {
} }
} }
// Dibuja el efecto de carga rojo y azul en el borde
void LoadingScreen::renderRedBorder() {
// Obtiene la Surface del borde
auto border = Screen::get()->getBorderSurface();
// Pinta el borde de color azul
border->clear(static_cast<Uint8>(PaletteColor::CYAN));
// Añade lineas rojas
const Uint8 COLOR = static_cast<Uint8>(PaletteColor::RED);
const int WIDTH = Options::game.width + (Options::video.border.width * 2);
const int HEIGHT = Options::game.height + (Options::video.border.height * 2);
bool draw_enabled = true;
// Primera linea (para que tenga poca variacion)
int row = 0;
const int FIRST_ROW_HEIGHT = (rand() % 4) + 3;
if (draw_enabled) {
for (int i = row; i < row + FIRST_ROW_HEIGHT; ++i) {
border->drawLine(0, i, WIDTH, i, COLOR);
}
}
row += FIRST_ROW_HEIGHT;
draw_enabled = !draw_enabled;
// Resto de lineas
while (row < HEIGHT) {
const int ROW_HEIGHT = (rand() % 3) + 8;
if (draw_enabled) {
for (int i = row; i < row + ROW_HEIGHT; ++i) {
border->drawLine(0, i, WIDTH, i, COLOR);
}
}
row += ROW_HEIGHT;
draw_enabled = !draw_enabled;
}
}
// Dibuja el borde de color blanco
void LoadingScreen::renderWhiteBorder() {
// Obtiene la Surface del borde
auto border = Screen::get()->getBorderSurface();
// Pinta el borde de color azul
border->clear(static_cast<Uint8>(PaletteColor::WHITE));
}
// Actualiza las variables // Actualiza las variables
void LoadingScreen::update() { void LoadingScreen::update() {
// Obtener delta time desde el último frame // Obtener delta time desde el último frame
const float delta_time = delta_timer_->tick(); const float delta_time = delta_timer_->tick();
checkInput(); // Comprueba las entradas checkInput(); // Comprueba las entradas
updateState(delta_time); // Actualiza el estado y gestiona transiciones updateState(delta_time); // Actualiza el estado y gestiona transiciones
// Actualizar la carga según el estado actual // Actualizar la carga según el estado actual
switch (state_) { switch (state_) {
case LoadingState::PRE_LOADING: case LoadingState::SILENT1:
// No hay animación de carga durante la pausa inicial case LoadingState::HEADER1:
case LoadingState::BYTES1:
case LoadingState::SILENT2:
case LoadingState::HEADER2:
case LoadingState::BYTES2:
// Por ahora no hacen nada específico
// Tú definirás la lógica de cada estado aquí
break; break;
case LoadingState::LOADING_MONO: case LoadingState::LOADING_MONO:
@@ -249,16 +350,15 @@ void LoadingScreen::update() {
break; break;
} }
renderLoad(); // Dibuja la pantalla de carga // Singletones
Screen::get()->update(); // Actualiza el objeto Screen Audio::get()->update(); // Actualiza el objeto Audio
Screen::get()->update(); // Actualiza el objeto Screen
} }
// Dibuja en pantalla // Dibuja en pantalla
void LoadingScreen::render() { void LoadingScreen::render() {
if (Options::video.border.enabled) { // Pinta el borde
// Dibuja el efecto de carga en el borde renderBorder();
renderBorder();
}
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
Screen::get()->start(); Screen::get()->start();
@@ -273,9 +373,8 @@ void LoadingScreen::render() {
// Bucle para el logo del juego // Bucle para el logo del juego
void LoadingScreen::run() { void LoadingScreen::run() {
// Inicia el sonido de carga // Ajusta el volumen
JA_SetVolume(64); Audio::get()->setMusicVolume(50);
JA_PlayMusic(Resource::get()->getMusic("loading_sound1.ogg"));
// Limpia la pantalla // Limpia la pantalla
Screen::get()->start(); Screen::get()->start();
@@ -288,5 +387,26 @@ void LoadingScreen::run() {
render(); render();
} }
JA_SetVolume(128); Audio::get()->setMusicVolume(100);
}
// Pinta el borde
void LoadingScreen::renderBorder() {
if (Options::video.border.enabled) {
// Dibuja el efecto de carga en el borde según el tipo actual
switch (current_border_type_) {
case BorderType::YELLOW:
renderYellowBorder();
break;
case BorderType::RED:
renderRedBorder();
break;
case BorderType::WHITE:
renderWhiteBorder();
break;
case BorderType::NONE:
// No renderizar borde
break;
}
}
} }

View File

@@ -11,12 +11,25 @@ class Surface; // Forward declaration
// Estados de la secuencia de carga // Estados de la secuencia de carga
enum class LoadingState { enum class LoadingState {
PRE_LOADING, // Pausa inicial antes de empezar SILENT1, // Pausa inicial antes de empezar
HEADER1, // Cabecera
BYTES1, // Datos
SILENT2, // Segunda pausa
HEADER2, // Cabecera pantalla
LOADING_MONO, // Carga de pantalla monocromática (escaneo de líneas) LOADING_MONO, // Carga de pantalla monocromática (escaneo de líneas)
LOADING_COLOR, // Carga de pantalla en color (bloques) LOADING_COLOR, // Carga de pantalla en color (bloques)
BYTES2, // Datos
COMPLETE // Carga completa COMPLETE // Carga completa
}; };
// Tipos de borde para la pantalla de carga
enum class BorderType {
NONE,
YELLOW,
RED,
WHITE
};
class LoadingScreen { class LoadingScreen {
public: public:
LoadingScreen(); // Constructor LoadingScreen(); // Constructor
@@ -25,9 +38,14 @@ class LoadingScreen {
private: private:
// --- Constantes de tiempo (en segundos) --- // --- Constantes de tiempo (en segundos) ---
static constexpr float PRE_LOADING_DURATION = 1.0f; // Pausa inicial static constexpr float SILENT1_DURATION = 1.0f; // Pausa inicial
static constexpr float HEADER1_DURATION = 2.0f; // Cabecera
static constexpr float BYTES1_DURATION = 0.5f; // Datos
static constexpr float SILENT2_DURATION = 2.0f; // Segunda pausa
static constexpr float HEADER2_DURATION = 2.0f; // Cabecera pantalla
static constexpr float LOADING_MONO_DURATION = 16.0f; // Duración total de la carga monocromática static constexpr float LOADING_MONO_DURATION = 16.0f; // Duración total de la carga monocromática
static constexpr float LOADING_COLOR_DURATION = 4.0f; // Duración total de la carga en color static constexpr float LOADING_COLOR_DURATION = 4.0f; // Duración total de la carga en color
static constexpr float BYTES2_DURATION = 2.0f; // Datos
// --- Constantes de geometría --- // --- Constantes de geometría ---
static constexpr int MONO_TOTAL_LINES = 192; // Total de líneas en carga monocromática static constexpr int MONO_TOTAL_LINES = 192; // Total de líneas en carga monocromática
@@ -49,6 +67,7 @@ class LoadingScreen {
std::unique_ptr<DeltaTimer> delta_timer_; // Timer para delta time std::unique_ptr<DeltaTimer> delta_timer_; // Timer para delta time
LoadingState state_; // Estado actual de la secuencia LoadingState state_; // Estado actual de la secuencia
float state_time_; // Tiempo acumulado en el estado actual float state_time_; // Tiempo acumulado en el estado actual
BorderType current_border_type_; // Tipo de borde actual
std::array<int, MONO_TOTAL_LINES> line_index_; // El orden en el que se procesan las 192 líneas de la pantalla de carga std::array<int, MONO_TOTAL_LINES> line_index_; // El orden en el que se procesan las 192 líneas de la pantalla de carga
SDL_FRect load_rect_; // Rectángulo para dibujar la pantalla de carga SDL_FRect load_rect_; // Rectángulo para dibujar la pantalla de carga
@@ -61,7 +80,9 @@ class LoadingScreen {
void transitionToState(LoadingState new_state); // Transiciona a un nuevo estado void transitionToState(LoadingState new_state); // Transiciona a un nuevo estado
void updateMonoLoad(float delta_time); // Gestiona la carga monocromática (time-based) void updateMonoLoad(float delta_time); // Gestiona la carga monocromática (time-based)
void updateColorLoad(float delta_time); // Gestiona la carga en color (time-based) void updateColorLoad(float delta_time); // Gestiona la carga en color (time-based)
void renderLoad(); // Dibuja la pantalla de carga void renderBorder(); // Pinta el borde
void renderBorder(); // Dibuja el efecto de carga en el borde void renderYellowBorder(); // Dibuja el efecto de carga amarillo y azul en el borde
void renderRedBorder(); // Dibuja el efecto de carga rojo y azul en el borde
void renderWhiteBorder(); // Dibuja el borde de color blanco
void initLineIndexArray(); // Inicializa el array de índices de líneas void initLineIndexArray(); // Inicializa el array de índices de líneas
}; };