From 67bf6b201740f3246bf37f7470e1581c6384e5ae Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Mon, 6 Apr 2026 14:02:01 +0200 Subject: [PATCH] pasada de granera --- CMakeLists.txt | 5 - config/assets.yaml | 22 -- data/credits/shine.gif | Bin 107 -> 0 bytes data/credits/shine.yaml | 10 - data/ending/ending1.gif | Bin 1014 -> 0 bytes data/ending/ending2.gif | Bin 2999 -> 0 bytes data/ending/ending3.gif | Bin 2933 -> 0 bytes data/ending/ending4.gif | Bin 1166 -> 0 bytes data/ending/ending5.gif | Bin 1349 -> 0 bytes data/loading/loading_screen_bn.gif | Bin 4985 -> 0 bytes data/loading/loading_screen_color.gif | Bin 7141 -> 0 bytes data/loading/program_jaildoc.gif | Bin 175 -> 0 bytes source/core/input/global_inputs.cpp | 6 - source/core/system/debug.cpp | 15 - source/core/system/director.cpp | 65 ---- source/core/system/director.hpp | 6 - source/game/scene_manager.hpp | 19 +- source/game/scenes/credits.cpp | 247 ------------- source/game/scenes/credits.hpp | 80 ---- source/game/scenes/ending.cpp | 434 ---------------------- source/game/scenes/ending.hpp | 106 ------ source/game/scenes/ending2.cpp | 502 -------------------------- source/game/scenes/ending2.hpp | 94 ----- source/game/scenes/game.cpp | 8 +- source/game/scenes/game_over.cpp | 207 ----------- source/game/scenes/game_over.hpp | 67 ---- source/game/scenes/loading_screen.cpp | 498 ------------------------- source/game/scenes/loading_screen.hpp | 122 ------- source/game/scenes/logo.cpp | 14 +- source/game/scenes/title.cpp | 135 +------ source/game/scenes/title.hpp | 35 -- source/game/ui/console_commands.cpp | 18 +- 32 files changed, 14 insertions(+), 2701 deletions(-) delete mode 100644 data/credits/shine.gif delete mode 100644 data/credits/shine.yaml delete mode 100644 data/ending/ending1.gif delete mode 100644 data/ending/ending2.gif delete mode 100644 data/ending/ending3.gif delete mode 100644 data/ending/ending4.gif delete mode 100644 data/ending/ending5.gif delete mode 100644 data/loading/loading_screen_bn.gif delete mode 100644 data/loading/loading_screen_color.gif delete mode 100644 data/loading/program_jaildoc.gif delete mode 100644 source/game/scenes/credits.cpp delete mode 100644 source/game/scenes/credits.hpp delete mode 100644 source/game/scenes/ending.cpp delete mode 100644 source/game/scenes/ending.hpp delete mode 100644 source/game/scenes/ending2.cpp delete mode 100644 source/game/scenes/ending2.hpp delete mode 100644 source/game/scenes/game_over.cpp delete mode 100644 source/game/scenes/game_over.hpp delete mode 100644 source/game/scenes/loading_screen.cpp delete mode 100644 source/game/scenes/loading_screen.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e52a5e..67fbe56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,12 +86,7 @@ set(APP_SOURCES source/game/gameplay/tilemap_renderer.cpp # Game - Scenes - source/game/scenes/credits.cpp - source/game/scenes/ending.cpp - source/game/scenes/ending2.cpp - source/game/scenes/game_over.cpp source/game/scenes/game.cpp - source/game/scenes/loading_screen.cpp source/game/scenes/logo.cpp source/game/scenes/title.cpp diff --git a/config/assets.yaml b/config/assets.yaml index 59be9ec..90622c5 100644 --- a/config/assets.yaml +++ b/config/assets.yaml @@ -229,30 +229,8 @@ assets: - ${PREFIX}/data/logo/jailgames.gif - ${PREFIX}/data/logo/since_1998.gif - # LOADING - loading: - BITMAP: - - ${PREFIX}/data/loading/loading_screen_bn.gif - - ${PREFIX}/data/loading/loading_screen_color.gif - - ${PREFIX}/data/loading/program_jaildoc.gif - # TITLE title: BITMAP: - ${PREFIX}/data/title/title_logo.gif - # ENDING - ending: - BITMAP: - - ${PREFIX}/data/ending/ending1.gif - - ${PREFIX}/data/ending/ending2.gif - - ${PREFIX}/data/ending/ending3.gif - - ${PREFIX}/data/ending/ending4.gif - - ${PREFIX}/data/ending/ending5.gif - - # CREDITS - credits: - BITMAP: - - ${PREFIX}/data/credits/shine.gif - ANIMATION: - - ${PREFIX}/data/credits/shine.yaml diff --git a/data/credits/shine.gif b/data/credits/shine.gif deleted file mode 100644 index 04630327ad5461b077c8ee040b429ab3e6790372..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 107 zcmZ?wbh9u|bYS3MXkY+=|Ns9h{^#~{4GDI33~)8lGhk)}iYoqO;p76+Iv^z=#SBdP zE&XCA-|{C%cQ9#hwwtl}YGc%P&BoGY>84vdf8;&+dhyMhX^}5p?(6%_*?wfvLIwtF E07h&jxBvhE diff --git a/data/credits/shine.yaml b/data/credits/shine.yaml deleted file mode 100644 index c4b723f..0000000 --- a/data/credits/shine.yaml +++ /dev/null @@ -1,10 +0,0 @@ -# shine animation -tileSetFile: shine.gif -frameWidth: 8 -frameHeight: 8 - -animations: - - name: default - speed: 0.1 - loop: -1 - frames: [0, 1, 2, 3, 4, 5, 6, 7] diff --git a/data/ending/ending1.gif b/data/ending/ending1.gif deleted file mode 100644 index 2fd78f8737ff9bd618aea1ae693106958d9b0f53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1014 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 diff --git a/data/ending/ending3.gif b/data/ending/ending3.gif deleted file mode 100644 index 9b7011c99b9d2ea99e47b55ca06ddab8abf2a5e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2933 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 diff --git a/data/ending/ending4.gif b/data/ending/ending4.gif deleted file mode 100644 index 0f52a6a8e4f36c33d58b64c640f7c0c94b51f15f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1166 zcmV;91abRENk%v~VPpVT0J8u90000000000*Z=_k*Z=_k007tk*#7|k0N4Nk{{R5k z*Z}|k*w_I7{{Yz7*#H0kA^!_bMO0HmK~P09E-(WD0000X`2-0H0000i00000WB^wH z00jRK$VsccIP1;3|6nMNWNDsgs;+D+I&d7jG%CYSuIqB`Yd6O(m)XI7NI-1(xG(_E zXeBpGwuHorbPMfr0X%DJN#UBkXzAo}6pwJ(vph|Ig4ym6wp{PezhDk|9XJzzeqIcU zhj@b+aEO14laz{mjgAz1k%^U_pO##hj)fA3poXay1jw4O~aMBtjg8a$IO<_R>9Gf)2r9w*31&WF5Pm()8p;R+1oYg zb?e6N_sgwM=PL7N_4oo-+ZB(6zcc`?Nf6jhSHXVJ)Je0KOag(0)hGyb$dAOqEeZdX zStLLbV*?2VQWgNfkk!Kz!6bg8Sdpa7i^ou^T!~N1wl*bV(wj&vBT1DuSpp!iGbPJ* zBQGjtgGG?XCNd}CQV5`F%92dIJ{31o<SNxY%%T? zVHDvFiKLM&T~pN%eWpoJ{Oc=cAda>13OGQd%iPm}aUer;vKerKE3) zTB)MQjA<$psCK#~TaDG^s;C-?BkQa?)M{&?Y>+0#^!B6ZR@TRlNVP>-=S!)=@Vwwrh4D|Qx~ zC=Eg?ccz^Qq?^Fo7b>9Kr}yAWU~y&NPWqiU#)Zz`|PyWZu{-HGadl|J2zK4EC2ui diff --git a/data/ending/ending5.gif b/data/ending/ending5.gif deleted file mode 100644 index 102ece531bd9cc6948d49494ce60545b51e990dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1349 zcmV-L1-kl2Nk%v~VQ>Ij0J8u90000000000*Z=_k*Z=_k007tk*#7|k0N4Nk{{R5k z*Z}|k*w_I7{{Yz7*#H0kA^!_bMO0HmK~P09E-(WD0000X`2-0H0000i00000Z~$8X z00jRK$VsccIP1;3|6nMNWNDsgs;+G7zHlthbZy^wuJ3&B|G=PdNGuwU$fPo*Xabsw zjWal{MJ3lK)Ndh87l3tirl**5jTfyA zkG~Vao}Ybi6PA|`mwc)ooQj^8cm)jr)Ya7#wJ=eN$;-@|BzE7#)4;#!*~WUYr{So( ze-z)z(&)t1>VnQMd&*8F8YiOMH*~qyrQ=7CQk;O9=8Z6@=+r`W2rX)p2**;mfgJw} zS~zGip~i$8{kiZau-&GS6?09K`OBoWkYOZ9P zS#GNQV2C7BnGbUnJp{mkOC}ZUVZA_fDbcC6ygsE@?^}jbWY6Zf;uY?_Q=~;Rs&)5`$I`Qgs9#yb?n)VTXw_=DPSV2xyi7WY)Zuvs%wod;L7T zZO7!zyuz}sfEsXD%3R|jrp;sW>6~QslI~O6_U+$Ld;Xxi7&aC%&{d%>{+Ub$=EyN{ z+xBKp#Ou^kx7I$P^K}XX(yLd`-Ayce5f_DjCP8p^E_8WbSa$;hI)Q299DoQZGj!xl63Ukj*SD#u#66qfRI)3;Vi!D|u zB6c)R($xe99AG4S7Hmjml~N+$qyT9%2K06;1!mU&v*np?z4 zAZDB*(vfJWuO>N=qX?KY_ zg%!iHqKs88a)3-P$plM!a(aeYV-_>1bmQ@nv%O3ddjnU@9>$BNEKoCq{rnzcApc6U z(KsV5CR2H_+%TYG@tBpq%hp`*$*u~A=b4>;Chn2&?aY^lU{hT4&qa1Psh=!os3)df zKW0|8iMtH7$2*&!(BVO3(e_ee#M%7TUwBZ2FR~-)8&b zyOzD{^3N~*+pB8u+^__1SCc8Hh3iZozQ(t*u|Py*uwwWjBpqfVG2hSL*hi|hd>OX5F4n2 H2mk;(T`h>T diff --git a/data/loading/loading_screen_bn.gif b/data/loading/loading_screen_bn.gif deleted file mode 100644 index 330640b37593eef822a0add0873b5953b7709d74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4985 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 Dp)#+y diff --git a/data/loading/loading_screen_color.gif b/data/loading/loading_screen_color.gif deleted file mode 100644 index 2d269916dd80dc48a86dac0caab31bc0b4408523..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7141 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 diff --git a/data/loading/program_jaildoc.gif b/data/loading/program_jaildoc.gif deleted file mode 100644 index 5af6993d5b820d1fe0481e0680e1f6de3ccfba89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 zcmZ?wbh9u|Y+&GEXkdT>#sA!Xt|7tBjsdPldIrplKw-t7ESy|GS_h;Aq?m!JxTSyP z>9_og=jcXwZ@#DIu)g8AYTDDz-j%z`-nJ&FvUe1i+%A0m>hb&!R~uy8&rQC3rfrq0 zkVeY8yrT++yVe9w3_8{Mb<441m)2XftowH6$tQ!~itf8zwoZu6_m`~r(7!s}W$D*L Vj~{IpPw{X*@!|)^%m4-kYXCqxNaFwi diff --git a/source/core/input/global_inputs.cpp b/source/core/input/global_inputs.cpp index c36526c..cae33a6 100644 --- a/source/core/input/global_inputs.cpp +++ b/source/core/input/global_inputs.cpp @@ -53,12 +53,6 @@ namespace GlobalInputs { void handleSkipSection() { switch (SceneManager::current) { case SceneManager::Scene::LOGO: - case SceneManager::Scene::LOADING_SCREEN: - case SceneManager::Scene::CREDITS: - case SceneManager::Scene::DEMO: - case SceneManager::Scene::GAME_OVER: - case SceneManager::Scene::ENDING: - case SceneManager::Scene::ENDING2: SceneManager::current = SceneManager::Scene::TITLE; SceneManager::options = SceneManager::Options::NONE; break; diff --git a/source/core/system/debug.cpp b/source/core/system/debug.cpp index fbe2251..bc1985a 100644 --- a/source/core/system/debug.cpp +++ b/source/core/system/debug.cpp @@ -95,12 +95,7 @@ void Debug::setDebugFile(const std::string& path) { // Convierte string a SceneManager::Scene (para debug.yaml) static auto sceneFromString(const std::string& s) -> SceneManager::Scene { if (s == "LOGO") { return SceneManager::Scene::LOGO; } - if (s == "LOADING") { return SceneManager::Scene::LOADING_SCREEN; } if (s == "TITLE") { return SceneManager::Scene::TITLE; } - if (s == "CREDITS") { return SceneManager::Scene::CREDITS; } - if (s == "DEMO") { return SceneManager::Scene::DEMO; } - if (s == "ENDING") { return SceneManager::Scene::ENDING; } - if (s == "ENDING2") { return SceneManager::Scene::ENDING2; } return SceneManager::Scene::GAME; // Fallback seguro } @@ -109,18 +104,8 @@ static auto sceneToString(SceneManager::Scene scene) -> std::string { switch (scene) { case SceneManager::Scene::LOGO: return "LOGO"; - case SceneManager::Scene::LOADING_SCREEN: - return "LOADING"; case SceneManager::Scene::TITLE: return "TITLE"; - case SceneManager::Scene::CREDITS: - return "CREDITS"; - case SceneManager::Scene::DEMO: - return "DEMO"; - case SceneManager::Scene::ENDING: - return "ENDING"; - case SceneManager::Scene::ENDING2: - return "ENDING2"; default: return "GAME"; } diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index a189bf1..f4e8b21 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -23,12 +23,7 @@ #include "game/gameplay/cheevos.hpp" // Para Cheevos #include "game/options.hpp" // Para Options, options, OptionsVideo #include "game/scene_manager.hpp" // Para SceneManager -#include "game/scenes/credits.hpp" // Para Credits -#include "game/scenes/ending.hpp" // Para Ending -#include "game/scenes/ending2.hpp" // Para Ending2 #include "game/scenes/game.hpp" // Para Game, GameMode -#include "game/scenes/game_over.hpp" // Para GameOver -#include "game/scenes/loading_screen.hpp" // Para LoadingScreen #include "game/scenes/logo.hpp" // Para Logo #include "game/scenes/title.hpp" // Para Title #include "game/ui/console.hpp" // Para Console @@ -330,48 +325,12 @@ void Director::runLogo() { logo->run(); } -// Ejecuta la seccion de juego de la pantalla de carga -void Director::runLoadingScreen() { - auto loading_screen = std::make_unique(); - loading_screen->run(); -} - // Ejecuta la seccion de juego con el titulo y los menus void Director::runTitle() { auto title = std::make_unique(); title->run(); } -// Ejecuta la seccion de los creditos del juego -void Director::runCredits() { - auto credits = std::make_unique<Credits>(); - credits->run(); -} - -// Ejecuta la seccion de la demo, donde se ven pantallas del juego -void Director::runDemo() { - auto game = std::make_unique<Game>(Game::Mode::DEMO); - game->run(); -} - -// Ejecuta la seccion del final del juego -void Director::runEnding() { - auto ending = std::make_unique<Ending>(); - ending->run(); -} - -// Ejecuta la seccion del final del juego -void Director::runEnding2() { - auto ending2 = std::make_unique<Ending2>(); - ending2->run(); -} - -// Ejecuta la seccion del final de la partida -void Director::runGameOver() { - auto game_over = std::make_unique<GameOver>(); - game_over->run(); -} - // Ejecuta la seccion de juego donde se juega void Director::runGame() { Audio::get()->stopMusic(); @@ -389,38 +348,14 @@ auto Director::run() -> int { runLogo(); break; - case SceneManager::Scene::LOADING_SCREEN: - runLoadingScreen(); - break; - case SceneManager::Scene::TITLE: runTitle(); break; - case SceneManager::Scene::CREDITS: - runCredits(); - break; - - case SceneManager::Scene::DEMO: - runDemo(); - break; - case SceneManager::Scene::GAME: runGame(); break; - case SceneManager::Scene::GAME_OVER: - runGameOver(); - break; - - case SceneManager::Scene::ENDING: - runEnding(); - break; - - case SceneManager::Scene::ENDING2: - runEnding2(); - break; - case SceneManager::Scene::RESTART_CURRENT: // La escena salió por RESTART_CURRENT → relanzar la escena guardada SceneManager::current = SceneManager::scene_before_restart; diff --git a/source/core/system/director.hpp b/source/core/system/director.hpp index 33c8c5e..2d24e4f 100644 --- a/source/core/system/director.hpp +++ b/source/core/system/director.hpp @@ -19,12 +19,6 @@ class Director { void createSystemFolder(const std::string& folder); // Crea la carpeta del sistema donde guardar datos void setFileList(); // Carga la configuración de assets desde assets.yaml static void runLogo(); // Ejecuta la seccion de juego con el logo - static void runLoadingScreen(); // Ejecuta la seccion de juego de la pantalla de carga static void runTitle(); // Ejecuta la seccion de juego con el titulo y los menus - static void runCredits(); // Ejecuta la seccion de los creditos del juego - static void runDemo(); // Ejecuta la seccion de la demo, donde se ven pantallas del juego - static void runEnding(); // Ejecuta la seccion del final del juego - static void runEnding2(); // Ejecuta la seccion del final del juego - static void runGameOver(); // Ejecuta la seccion del final de la partida static void runGame(); // Ejecuta la seccion de juego donde se juega }; \ No newline at end of file diff --git a/source/game/scene_manager.hpp b/source/game/scene_manager.hpp index 89a2f35..11926cd 100644 --- a/source/game/scene_manager.hpp +++ b/source/game/scene_manager.hpp @@ -12,30 +12,21 @@ namespace SceneManager { // --- Escenas del programa --- enum class Scene { LOGO, // Pantalla del logo - LOADING_SCREEN, // Pantalla de carga TITLE, // Pantalla de título/menú principal - CREDITS, // Créditos del juego GAME, // Juego principal - DEMO, // Modo demostración - GAME_OVER, // Pantalla de game over - ENDING, // Final del juego (ending 1) - ENDING2, // Final del juego (ending 2) RESTART_CURRENT, // Especial: reinicia la escena que estaba corriendo QUIT // Salir del programa }; // --- Opciones para transiciones entre escenas --- enum class Options { - NONE, // Sin opciones especiales - LOGO_TO_LOADING_SCREEN, // Del logo a la intro - LOGO_TO_TITLE, // Del logo al título - TITLE_WITH_LOADING_SCREEN, // Al título mostrando pantalla de carga - TITLE_WITHOUT_LOADING_SCREEN // Al título sin pantalla de carga + NONE, // Sin opciones especiales + LOGO_TO_TITLE, // Del logo al título }; // --- Variables de estado globales --- - inline Scene current = Scene::LOGO; // Escena actual (en _DEBUG sobrescrito por Director tras cargar debug.yaml) - inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual - inline Scene scene_before_restart = Scene::LOGO; // escena a relanzar tras RESTART_CURRENT + inline Scene current = Scene::LOGO; // Escena actual (en _DEBUG sobrescrito por Director tras cargar debug.yaml) + inline Options options = Options::LOGO_TO_TITLE; // Opciones de la escena actual + inline Scene scene_before_restart = Scene::LOGO; // escena a relanzar tras RESTART_CURRENT } // namespace SceneManager diff --git a/source/game/scenes/credits.cpp b/source/game/scenes/credits.cpp deleted file mode 100644 index 3f628f8..0000000 --- a/source/game/scenes/credits.cpp +++ /dev/null @@ -1,247 +0,0 @@ -#include "game/scenes/credits.hpp" - -#include <SDL3/SDL.h> - -#include "core/audio/audio.hpp" // Para Audio -#include "core/input/global_inputs.hpp" // Para check -#include "core/input/input.hpp" // Para Input -#include "core/locale/locale.hpp" // Para Locale -#include "core/rendering/pixel_reveal.hpp" // Para PixelReveal -#include "core/rendering/screen.hpp" // Para Screen -#include "core/rendering/sprite/animated_sprite.hpp" // Para SAnimatedSprite -#include "core/rendering/surface.hpp" // Para Surface -#include "core/rendering/text.hpp" // Para Text, Text::CENTER_FLAG, Text::COLOR_FLAG -#include "core/resources/resource_cache.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, PlayArea::CENTER_X, PLAY_... -#include "utils/delta_timer.hpp" // Para DeltaTimer -#include "utils/utils.hpp" // Para PaletteColor - -// Destructor -Credits::~Credits() = default; - -// Constructor -Credits::Credits() - : text_surface_(std::make_shared<Surface>(Options::game.width, Options::game.height)), - shining_sprite_(std::make_shared<AnimatedSprite>(Resource::Cache::get()->getAnimationData("shine.yaml"))), - delta_timer_(std::make_unique<DeltaTimer>()) { - // Configura la escena - SceneManager::current = SceneManager::Scene::CREDITS; - SceneManager::options = SceneManager::Options::NONE; - shining_sprite_->setPos({.x = 194, .y = 174, .w = 8, .h = 8}); - - Screen::get()->setBorderColor(0); // Cambia el color del borde - fillTexture(); // Escribe el texto en la textura - Audio::get()->playMusic("574071_EA_DTV.ogg"); // Inicia la musica -} - -// Comprueba el manejador de eventos -void Credits::handleEvents() { - SDL_Event event; - while (SDL_PollEvent(&event)) { - GlobalEvents::handle(event); - } -} - -// Comprueba las entradas -void Credits::handleInput() { - Input::get()->update(); - GlobalInputs::handle(); -} - -// Inicializa los textos -void Credits::iniTexts() { // NOLINT(readability-convert-member-functions-to-static) - auto* loc = Locale::get(); - - texts_.clear(); - texts_.push_back({.label = "", .color = 14}); - texts_.push_back({.label = loc->get("credits.instructions"), .color = 12}); - texts_.push_back({.label = "", .color = 14}); - texts_.push_back({.label = loc->get("credits.l0"), .color = 14}); - texts_.push_back({.label = loc->get("credits.l1"), .color = 14}); - texts_.push_back({.label = loc->get("credits.l2"), .color = 14}); - texts_.push_back({.label = "", .color = 14}); - texts_.push_back({.label = "", .color = 14}); - - texts_.push_back({.label = loc->get("credits.keys"), .color = 12}); - texts_.push_back({.label = "", .color = 14}); - texts_.push_back({.label = loc->get("credits.keys_move"), .color = 14}); - texts_.push_back({.label = loc->get("credits.f8"), .color = 14}); - texts_.push_back({.label = loc->get("credits.f11"), .color = 14}); - texts_.push_back({.label = loc->get("credits.f1f2"), .color = 14}); - texts_.push_back({.label = loc->get("credits.f3"), .color = 14}); - texts_.push_back({.label = loc->get("credits.f9"), .color = 14}); - texts_.push_back({.label = "", .color = 14}); - texts_.push_back({.label = "", .color = 14}); - - texts_.push_back({.label = loc->get("credits.author"), .color = 12}); - texts_.push_back({.label = loc->get("credits.date"), .color = 12}); - texts_.push_back({.label = "", .color = 14}); - texts_.push_back({.label = "", .color = 14}); - - texts_.push_back({.label = loc->get("credits.love"), .color = 14}); - texts_.push_back({.label = "", .color = 14}); -} - -// Escribe el texto en la textura -void Credits::fillTexture() { - // Inicializa los textos - iniTexts(); - - // Rellena la textura de texto - auto previuos_renderer = Screen::get()->getRendererSurface(); - Screen::get()->setRendererSurface(text_surface_); - text_surface_->clear(0); - - auto text = Resource::Cache::get()->getText("smb2"); - - // Escribe el texto en la textura - const int SIZE = text->getCharacterSize(); - int pos_y = 0; - - for (const auto& t : texts_) { - text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, pos_y * SIZE, t.label, 1, t.color); - pos_y++; - } - - // Escribe el corazón - const int TEXT_LENGHT = text->length(texts_[22].label, 1) - text->length(" ", 1); // Se resta el ultimo caracter que es un espacio - const int POS_X = ((PlayArea::WIDTH - TEXT_LENGHT) / 2) + TEXT_LENGHT; - text->writeColored(POS_X, 176, "ä", 5); - Screen::get()->setRendererSurface(previuos_renderer); - - // Recoloca el sprite del brillo - shining_sprite_->setPosX(POS_X + 2); - - // Crea el efecto de revelado pixel a pixel - pixel_reveal_ = std::make_unique<PixelReveal>(Options::game.width, Options::game.height, PIXELS_PER_SECOND, STEP_DURATION, REVEAL_STEPS); -} - -// Actualiza las variables -void Credits::update() { - const float DELTA_TIME = delta_timer_->tick(); - total_time_ += DELTA_TIME; // Actualiza el tiempo total - - handleEvents(); // Comprueba los eventos - handleInput(); // Comprueba las entradas - - updateState(DELTA_TIME); // Actualiza la máquina de estados - - pixel_reveal_->update(reveal_time_); // Actualiza el efecto de revelado - - // Actualiza el sprite con el brillo si está después del tiempo de inicio - if (reveal_time_ > SHINE_START_TIME) { - shining_sprite_->update(DELTA_TIME); - } - - Audio::update(); // Actualiza el objeto Audio - Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen -} - -// Transición entre estados -void Credits::transitionToState(State new_state) { - state_ = new_state; - state_time_ = 0.0F; -} - -// Actualiza la máquina de estados -void Credits::updateState(float delta_time) { - state_time_ += delta_time; - - 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; - - case State::PAUSE_1: - // reveal_time_ NO incrementa durante pausa (se congela) - if (state_time_ >= PAUSE_DURATION) { - transitionToState(State::REVEALING_TEXT_2); - } - break; - - 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; - } -} - -// Dibuja en pantalla -void Credits::render() { - // Prepara para empezar a dibujar en la textura de juego - Screen::get()->start(); - - // Limpia la pantalla - Screen::get()->clearSurface(0); - - if (state_ != State::EXITING) { - // Dibuja la textura con el texto en pantalla - text_surface_->render(0, 0); - - // Dibuja la máscara de revelado pixel a pixel - pixel_reveal_->render(0, 0); - - // Dibuja el sprite con el brillo - if (reveal_time_ > SHINE_START_TIME) { - shining_sprite_->render(1, 15); - } - } - - // Vuelca el contenido del renderizador en pantalla - Screen::get()->render(); -} - -// Bucle para el logo del juego -void Credits::run() { - while (SceneManager::current == SceneManager::Scene::CREDITS) { - update(); - render(); - } -} \ No newline at end of file diff --git a/source/game/scenes/credits.hpp b/source/game/scenes/credits.hpp deleted file mode 100644 index ade576f..0000000 --- a/source/game/scenes/credits.hpp +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include <SDL3/SDL.h> - -#include <memory> // Para shared_ptr -#include <string> // Para string -#include <vector> // Para vector -class AnimatedSprite; // lines 11-11 -class Surface; -class PixelReveal; -class DeltaTimer; - -class Credits { - public: - // --- Constructor y Destructor --- - Credits(); - ~Credits(); // NOLINT(modernize-use-equals-default, performance-trivially-destructible) -- defined in .cpp for unique_ptr with forward declarations - - // --- Bucle principal --- - void run(); - - private: - // --- Tipos anidados --- - enum class State { - REVEALING_TEXT, - PAUSE_1, - REVEALING_TEXT_2, - PAUSE_2, - REVEALING_TEXT_3, - PAUSE_3, - DISPLAYING_WITH_SHINE, - FADING_OUT, - EXITING - }; - - struct Captions { - std::string label; // Texto a escribir - Uint8 color{0}; // Color del texto - }; - - // --- 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 PIXELS_PER_SECOND = 15.0F; // Filas reveladas por segundo (REVEAL_SPEED/8*2 = 60/8*2 = 15) - static constexpr float STEP_DURATION = 2.0F / 60.0F; // Segundos por paso de revelado (2 frames @ 60fps) - static constexpr int REVEAL_STEPS = 16; // Pasos de revelado por fila (más pasos = efecto más visible) - - // --- Métodos privados --- - void update(); // Actualiza las variables - void render(); // Dibuja en pantalla - static void handleEvents(); // Comprueba el manejador de eventos - static void handleInput(); // 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 - - // --- Variables miembro --- - // Recursos gráficos - std::shared_ptr<Surface> text_surface_; // Textura para dibujar el texto - std::unique_ptr<PixelReveal> pixel_reveal_; // Efecto de revelado pixel a pixel - std::shared_ptr<AnimatedSprite> shining_sprite_; // Sprite para el brillo del corazón - - // Temporizadores y estado - 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) - - // Textos - std::vector<Captions> texts_; // Vector con los textos -}; diff --git a/source/game/scenes/ending.cpp b/source/game/scenes/ending.cpp deleted file mode 100644 index aac5e2a..0000000 --- a/source/game/scenes/ending.cpp +++ /dev/null @@ -1,434 +0,0 @@ -#include "game/scenes/ending.hpp" - -#include <SDL3/SDL.h> - -#include "core/audio/audio.hpp" // Para Audio -#include "core/input/global_inputs.hpp" // Para check -#include "core/input/input.hpp" // Para Input -#include "core/locale/locale.hpp" // Para Locale -#include "core/rendering/pixel_reveal.hpp" // Para PixelReveal -#include "core/rendering/screen.hpp" // Para Screen -#include "core/rendering/sprite/sprite.hpp" // Para SSprite -#include "core/rendering/surface.hpp" // Para Surface -#include "core/rendering/text.hpp" // Para Text, TEXT_STROKE -#include "core/resources/resource_cache.hpp" // Para Resource -#include "core/system/global_events.hpp" // Para check -#include "game/options.hpp" // Para Options, options, OptionsGame, SectionS... -#include "game/scene_manager.hpp" // Para SceneManager -#include "utils/delta_timer.hpp" // Para DeltaTimer -#include "utils/utils.hpp" // Para PaletteColor - -// Destructor -Ending::~Ending() = default; - -// Constructor -Ending::Ending() - : delta_timer_(std::make_unique<DeltaTimer>()) { - SceneManager::current = SceneManager::Scene::ENDING; - SceneManager::options = SceneManager::Options::NONE; - - iniTexts(); // Inicializa los textos - iniPics(); // Inicializa las imagenes - iniScenes(); // Inicializa las escenas - - Screen::get()->setBorderColor(0); // Cambia el color del borde -} - -// Actualiza el objeto -void Ending::update() { - const float DELTA_TIME = delta_timer_->tick(); - total_time_ += DELTA_TIME; // Actualiza el tiempo total - - handleEvents(); // Comprueba los eventos - handleInput(); // Comprueba las entradas - - updateState(DELTA_TIME); // Actualiza la máquina de estados - updateSpriteCovers(); // Actualiza las cortinillas de los elementos - - Audio::update(); // Actualiza el objeto Audio - Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen -} - -// Dibuja el final en pantalla -void Ending::render() { - // Prepara para empezar a dibujar en la textura de juego - Screen::get()->start(); - - // Limpia la pantalla - Screen::get()->clearSurface(0); - - // Skip rendering durante WARMING_UP - if (state_ != State::WARMING_UP) { - // Dibuja las imagenes de la escena - const auto& pic = sprite_pics_.at(current_scene_); - pic.image_sprite->render(); - pic.pixel_reveal->render(pic.pos_x, pic.pos_y); - - // 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) { - const auto& txt = sprite_texts_.at(ti.index); - txt.image_sprite->render(); - txt.pixel_reveal->render(txt.pos_x, txt.pos_y); - } - } - - // Dibuja la cortinilla de cambio de escena - if (scene_cover_) { - scene_cover_->render(0, 0); - } - } - - // Vuelca el contenido del renderizador en pantalla - Screen::get()->render(); -} - -// Comprueba el manejador de eventos -void Ending::handleEvents() { - SDL_Event event; - while (SDL_PollEvent(&event)) { - GlobalEvents::handle(event); - } -} - -// Comprueba las entradas -void Ending::handleInput() { - Input::get()->update(); - GlobalInputs::handle(); -} - -// Transición entre estados -void Ending::transitionToState(State new_state) { - state_ = new_state; - state_time_ = 0.0F; - - // Al cambiar a una escena, resetear la cortinilla de salida y el contador de fade - if (new_state != State::WARMING_UP && new_state != State::ENDING) { - fadeout_time_ = 0.0F; - scene_cover_.reset(); - } -} - -// Lógica de fade común a los estados SCENE_N -void Ending::handleSceneFadeout(float scene_duration, float delta_time) { - if (state_time_ >= scene_duration - FADEOUT_START_OFFSET) { - fadeout_time_ += delta_time; - if (!scene_cover_) { - scene_cover_ = std::make_unique<PixelReveal>(Options::game.width, Options::game.height, COVER_PIXELS_PER_SECOND, STEP_DURATION, COVER_STEPS, true); - } - scene_cover_->update(fadeout_time_); - } -} - -// 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(); - handleSceneFadeout(SCENE_0_DURATION, delta_time); - break; - - case State::SCENE_1: - checkChangeScene(); - handleSceneFadeout(SCENE_1_DURATION, delta_time); - break; - - case State::SCENE_2: - checkChangeScene(); - handleSceneFadeout(SCENE_2_DURATION, delta_time); - break; - - case State::SCENE_3: - checkChangeScene(); - handleSceneFadeout(SCENE_3_DURATION, delta_time); - break; - - case State::SCENE_4: - checkChangeScene(); - handleSceneFadeout(SCENE_4_DURATION, delta_time); - break; - - case State::ENDING: - // Esperar ENDING_DURATION y luego transicionar a ENDING2 - if (state_time_ >= ENDING_DURATION) { - SceneManager::current = SceneManager::Scene::ENDING2; - } - break; - } -} - -// Inicializa los textos -void Ending::iniTexts() { // NOLINT(readability-convert-member-functions-to-static) - // Vector con los textos (traducidos según el idioma activo) - std::vector<TextAndPosition> texts; - auto* loc = Locale::get(); - - // Escena #0 - texts.push_back({.caption = loc->get("ending.t0"), .pos = 32}); - texts.push_back({.caption = loc->get("ending.t1"), .pos = 42}); - texts.push_back({.caption = loc->get("ending.t2"), .pos = 142}); - texts.push_back({.caption = loc->get("ending.t3"), .pos = 152}); - - // Escena #1 - texts.push_back({.caption = loc->get("ending.t4"), .pos = 1}); - texts.push_back({.caption = loc->get("ending.t5"), .pos = 11}); - texts.push_back({.caption = loc->get("ending.t6"), .pos = 21}); - - texts.push_back({.caption = loc->get("ending.t7"), .pos = 161}); - texts.push_back({.caption = loc->get("ending.t8"), .pos = 171}); - - texts.push_back({.caption = loc->get("ending.t9"), .pos = 181}); - - // Escena #2 - texts.push_back({.caption = loc->get("ending.t10"), .pos = 19}); - texts.push_back({.caption = loc->get("ending.t11"), .pos = 29}); - - // Escena #3 - texts.push_back({.caption = loc->get("ending.t12"), .pos = 36}); - texts.push_back({.caption = loc->get("ending.t13"), .pos = 46}); - - // Escena #4 - texts.push_back({.caption = loc->get("ending.t14"), .pos = 36}); - texts.push_back({.caption = loc->get("ending.t15"), .pos = 46}); - texts.push_back({.caption = loc->get("ending.t16"), .pos = 158}); - - // Crea los sprites - sprite_texts_.clear(); - - for (const auto& txt : texts) { - auto text = Resource::Cache::get()->getText("smb2"); - - const float WIDTH = text->length(txt.caption, 1) + 2 + 2; - const float HEIGHT = text->getCharacterSize() + 2 + 2; - auto text_color = 14; - auto shadow_color = 0; - - EndingSurface st; - - // Crea la textura - st.image_surface = std::make_shared<Surface>(WIDTH, HEIGHT); - auto previuos_renderer = Screen::get()->getRendererSurface(); - Screen::get()->setRendererSurface(st.image_surface); - text->writeDX(Text::STROKE_FLAG, 2, 2, txt.caption, 1, text_color, 2, shadow_color); - - // Crea el sprite - st.image_sprite = std::make_shared<Sprite>(st.image_surface, 0, 0, st.image_surface->getWidth(), st.image_surface->getHeight()); - st.pos_x = static_cast<int>((Options::game.width - st.image_surface->getWidth()) / 2); - st.pos_y = txt.pos; - st.image_sprite->setPosition(st.pos_x, st.pos_y); - - // Crea el efecto de revelado pixel a pixel - st.pixel_reveal = std::make_unique<PixelReveal>(static_cast<int>(WIDTH), static_cast<int>(HEIGHT), TEXT_PIXELS_PER_SECOND, STEP_DURATION, REVEAL_STEPS); - - sprite_texts_.push_back(std::move(st)); - Screen::get()->setRendererSurface(previuos_renderer); - } -} - -// Inicializa las imagenes -void Ending::iniPics() { - // Vector con las rutas y la posición - std::vector<TextAndPosition> pics; - - pics.push_back({.caption = "ending1.gif", .pos = 48}); - pics.push_back({.caption = "ending2.gif", .pos = 26}); - pics.push_back({.caption = "ending3.gif", .pos = 29}); - pics.push_back({.caption = "ending4.gif", .pos = 63}); - pics.push_back({.caption = "ending5.gif", .pos = 53}); - - // Crea los sprites - sprite_pics_.clear(); - - for (const auto& pic : pics) { - EndingSurface sp; - - // Crea la texture - sp.image_surface = Resource::Cache::get()->getSurface(pic.caption); - sp.image_surface->setTransparentColor(); - const float WIDTH = sp.image_surface->getWidth(); - const float HEIGHT = sp.image_surface->getHeight(); - - // Crea el sprite - sp.pos_x = static_cast<int>((Options::game.width - WIDTH) / 2); - sp.pos_y = pic.pos; - sp.image_sprite = std::make_shared<Sprite>(sp.image_surface, 0, 0, WIDTH, HEIGHT); - sp.image_sprite->setPosition(sp.pos_x, sp.pos_y); - - // Crea el efecto de revelado pixel a pixel - sp.pixel_reveal = std::make_unique<PixelReveal>(static_cast<int>(WIDTH), static_cast<int>(HEIGHT), IMAGE_PIXELS_PER_SECOND, STEP_DURATION, REVEAL_STEPS); - - sprite_pics_.push_back(std::move(sp)); - } -} - -// Inicializa las escenas -void Ending::iniScenes() { // NOLINT(readability-convert-member-functions-to-static) - // Variable para los tiempos - int trigger; - constexpr int LAPSE = 80; - - // Crea el contenedor - SceneData sc; - - // Inicializa el vector - scenes_.clear(); - - // Crea la escena #0 - sc.counter_end = 1000; - sc.picture_index = 0; - sc.text_index.clear(); - trigger = 85 * 2; - trigger += LAPSE; - sc.text_index.push_back({.index = 0, .trigger = trigger}); - trigger += LAPSE; - sc.text_index.push_back({.index = 1, .trigger = trigger}); - trigger += LAPSE * 3; - sc.text_index.push_back({.index = 2, .trigger = trigger}); - trigger += LAPSE; - sc.text_index.push_back({.index = 3, .trigger = trigger}); - scenes_.push_back(sc); - - // Crea la escena #1 - sc.counter_end = 1400; - sc.picture_index = 1; - sc.text_index.clear(); - trigger = 140 * 2; - trigger += LAPSE; - sc.text_index.push_back({.index = 4, .trigger = trigger}); - trigger += LAPSE; - sc.text_index.push_back({.index = 5, .trigger = trigger}); - trigger += LAPSE; - sc.text_index.push_back({.index = 6, .trigger = trigger}); - trigger += LAPSE * 3; - sc.text_index.push_back({.index = 7, .trigger = trigger}); - trigger += LAPSE; - sc.text_index.push_back({.index = 8, .trigger = trigger}); - trigger += LAPSE * 3; - sc.text_index.push_back({.index = 9, .trigger = trigger}); - scenes_.push_back(sc); - - // Crea la escena #2 - sc.counter_end = 1000; - sc.picture_index = 2; - sc.text_index.clear(); - trigger = 148 / 2; - trigger += LAPSE; - sc.text_index.push_back({.index = 10, .trigger = trigger}); - trigger += LAPSE; - sc.text_index.push_back({.index = 11, .trigger = trigger}); - scenes_.push_back(sc); - - // Crea la escena #3 - sc.counter_end = 800; - sc.picture_index = 3; - sc.text_index.clear(); - trigger = 87 / 2; - trigger += LAPSE; - sc.text_index.push_back({.index = 12, .trigger = trigger}); - trigger += LAPSE / 2; - sc.text_index.push_back({.index = 13, .trigger = trigger}); - scenes_.push_back(sc); - - // Crea la escena #4 - sc.counter_end = 1000; - sc.picture_index = 4; - sc.text_index.clear(); - trigger = 91 * 2; - trigger += LAPSE; - sc.text_index.push_back({.index = 14, .trigger = trigger}); - trigger += LAPSE * 2; - sc.text_index.push_back({.index = 15, .trigger = trigger}); - trigger += LAPSE * 3; - sc.text_index.push_back({.index = 16, .trigger = trigger}); - scenes_.push_back(sc); -} - -// Bucle principal -void Ending::run() { - Audio::get()->playMusic("574070_KUVO_Farewell_to_school.ogg"); - - while (SceneManager::current == SceneManager::Scene::ENDING) { - update(); - render(); - } - - Audio::get()->stopMusic(); -} - -// Actualiza las cortinillas de los elementos -void Ending::updateSpriteCovers() { - // Skip durante WARMING_UP - if (state_ == State::WARMING_UP) { - return; - } - - // Actualiza el revelado de los textos - for (const auto& ti : scenes_.at(current_scene_).text_index) { - const float TRIGGER_TIME = static_cast<float>(ti.trigger) / 60.0F; - - if (state_time_ > TRIGGER_TIME) { - const float TIME_SINCE_TRIGGER = state_time_ - TRIGGER_TIME; - sprite_texts_.at(ti.index).pixel_reveal->update(TIME_SINCE_TRIGGER); - } - } - - // Actualiza el revelado de la imagen (desde el inicio de la escena) - sprite_pics_.at(current_scene_).pixel_reveal->update(state_time_); -} - -// Comprueba si se ha de cambiar de escena -void Ending::checkChangeScene() { - // 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) { - // Transición al estado ENDING con fade de audio - transitionToState(State::ENDING); - Audio::get()->fadeOutMusic(MUSIC_FADE_DURATION); - } else { - // Transición a la siguiente escena - current_scene_++; - transitionToState(next_state); - } - } -} diff --git a/source/game/scenes/ending.hpp b/source/game/scenes/ending.hpp deleted file mode 100644 index b071084..0000000 --- a/source/game/scenes/ending.hpp +++ /dev/null @@ -1,106 +0,0 @@ -#pragma once - -#include <SDL3/SDL.h> - -#include <memory> // Para shared_ptr -#include <string> // Para string -#include <vector> // Para vector -class Sprite; // lines 8-8 -class Surface; // lines 9-9 -class PixelReveal; -class DeltaTimer; - -class Ending { - public: - // --- Constructor y Destructor --- - Ending(); - ~Ending(); // NOLINT(modernize-use-equals-default, performance-trivially-destructible) -- defined in .cpp for unique_ptr with forward declarations - - // --- Bucle principal --- - void run(); - - private: - // --- Enumeraciones --- - enum class State { - WARMING_UP, - SCENE_0, - SCENE_1, - SCENE_2, - SCENE_3, - SCENE_4, - ENDING - }; - - // --- Estructuras --- - struct EndingSurface { - std::shared_ptr<Surface> image_surface; // Surface a mostrar - std::shared_ptr<Sprite> image_sprite; // SSprite para mostrar la textura - std::unique_ptr<PixelReveal> pixel_reveal; // Efecto de revelado pixel a pixel - int pos_x{0}; // Posición X de renderizado - int pos_y{0}; // Posición Y de renderizado - }; - - struct TextAndPosition { - std::string caption; // Texto - int pos{0}; // Posición - }; - - struct TextIndex { - int index{0}; // Índice del texto - int trigger{0}; // Disparador temporal - }; - - struct SceneData { - std::vector<TextIndex> text_index; // Índices del vector de textos a mostrar y su disparador - int picture_index{0}; // Índice del vector de imágenes a mostrar - int counter_end{0}; // Valor del contador en el que finaliza la escena - }; - - // --- Constantes de tiempo (basado en 60 FPS) --- - static constexpr float WARMUP_DURATION = 3.333F; // 200 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_PIXELS_PER_SECOND = 30.0F; // Filas de texto reveladas por segundo - static constexpr float IMAGE_PIXELS_PER_SECOND = 60.0F; // Filas de imagen reveladas por segundo - static constexpr float STEP_DURATION = 2.0F / 60.0F; // Segundos por paso de revelado (2 frames @ 60fps) - static constexpr int REVEAL_STEPS = 4; // Pasos de revelado por fila - static constexpr float TEXT_LAPSE = 1.333F; // 80 frames @ 60fps - static constexpr float FADEOUT_START_OFFSET = 1.667F; // Inicio cortinilla 100 frames antes del fin - static constexpr float COVER_PIXELS_PER_SECOND = 120.0F; // Filas cubiertas por segundo - static constexpr int COVER_STEPS = 4; // Pasos por fila - static constexpr float ENDING_DURATION = 2.0F; // Duración del estado ENDING (2 segundos) - static constexpr int MUSIC_FADE_DURATION = 1800; // Fade de audio en milisegundos (1.8 segundos) - - // --- Métodos --- - void update(); // Actualiza el objeto - void render(); // Dibuja el final en pantalla - static void handleEvents(); // Comprueba el manejador de eventos - static void handleInput(); // Comprueba las entradas - void iniTexts(); // Inicializa los textos - void iniPics(); // Inicializa las imágenes - void iniScenes(); // Inicializa las escenas - void updateState(float delta_time); // Actualiza la máquina de estados - void handleSceneFadeout(float scene_duration, float delta_time); // Lógica de fade común a los estados SCENE_N - 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 updateMusicVolume() const; // Actualiza el volumen de la música - - // --- Variables miembro --- - // Objetos y punteros a recursos - std::unique_ptr<PixelReveal> scene_cover_; // Cortinilla de salida (negro sobre la escena) - std::unique_ptr<DeltaTimer> delta_timer_; // Timer para time-based update - std::vector<EndingSurface> sprite_texts_; // Vector con los sprites de texto con su cortinilla - std::vector<EndingSurface> sprite_pics_; // Vector con los sprites de imágenes con su cortinilla - std::vector<SceneData> scenes_; // Vector con los textos e imágenes de cada escena - - // Variables de estado - 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 la cortinilla de salida - int current_scene_{0}; // Escena actual (0-4) -}; \ No newline at end of file diff --git a/source/game/scenes/ending2.cpp b/source/game/scenes/ending2.cpp deleted file mode 100644 index 1327668..0000000 --- a/source/game/scenes/ending2.cpp +++ /dev/null @@ -1,502 +0,0 @@ -#include "game/scenes/ending2.hpp" - -#include <SDL3/SDL.h> - -#include <algorithm> // Para max, replace - -#include "core/audio/audio.hpp" // Para Audio -#include "core/input/global_inputs.hpp" // Para check -#include "core/input/input.hpp" // Para Input -#include "core/locale/locale.hpp" // Para Locale -#include "core/rendering/screen.hpp" // Para Screen -#include "core/rendering/sprite/dissolve_sprite.hpp" // Para SurfaceDissolveSprite -#include "core/rendering/sprite/moving_sprite.hpp" // Para SMovingSprite -#include "core/rendering/surface.hpp" // Para Surface -#include "core/rendering/text.hpp" // Para Text -#include "core/resources/resource_cache.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 GameCanvas::CENTER_X, GameCanvas::CENTER_Y -#include "utils/delta_timer.hpp" // Para DeltaTimer -#include "utils/utils.hpp" - -// Constructor -Ending2::Ending2() - : delta_timer_(std::make_unique<DeltaTimer>()), - state_{.state = EndingState::PRE_CREDITS, .duration = STATE_PRE_CREDITS_DURATION} { - // Establece la escena - SceneManager::current = SceneManager::Scene::ENDING2; - SceneManager::options = SceneManager::Options::NONE; - - // Inicializa el vector de colores - colors_ = {14, 12, 10, 8, 6, 4, 2, 0}; - - Screen::get()->setBorderColor(0); // Cambia el color del borde - iniSpriteList(); // Inicializa la lista de sprites - loadSprites(); // Carga todos los sprites desde una lista - placeSprites(); // Coloca los sprites en su sito - createSpriteTexts(); // Crea los sprites con las texturas con los textos - createTexts(); // Crea los sprites con las texturas con los textos del final -} - -// Actualiza el objeto -void Ending2::update() { - const float DELTA_TIME = delta_timer_->tick(); - - handleEvents(); // Comprueba los eventos - handleInput(); // Comprueba las entradas - - updateState(DELTA_TIME); // Actualiza el estado - - switch (state_.state) { - case EndingState::CREDITS: - // Actualiza los sprites, los textos y los textos del final - updateSprites(DELTA_TIME); - updateTextSprites(DELTA_TIME); - updateTexts(DELTA_TIME); - break; - - case EndingState::FADING: - // Actualiza el fade final - updateFinalFade(); - break; - - default: - // No hacer nada si el estado no corresponde a un caso manejado - break; - } - - Audio::update(); // Actualiza el objeto Audio - Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen -} - -// Dibuja el final en pantalla -void Ending2::render() { - // Prepara para empezar a dibujar en la surface de juego - Screen::get()->start(); - - // Limpia la pantalla - Screen::get()->clearSurface(0); - - // Dibuja los sprites - renderSprites(); - - // Dibuja los sprites con el texto - renderSpriteTexts(); - - // Dibuja los sprites con el texto del final - renderTexts(); - - // Vuelca el contenido del renderizador en pantalla - Screen::get()->render(); -} - -// Comprueba el manejador de eventos -void Ending2::handleEvents() { - SDL_Event event; - while (SDL_PollEvent(&event)) { - GlobalEvents::handle(event); - } -} - -// Comprueba las entradas -void Ending2::handleInput() { - Input::get()->update(); - GlobalInputs::handle(); -} - -// Bucle principal -void Ending2::run() { - Audio::get()->playMusic("574071_EA_DTV.ogg"); - - while (SceneManager::current == SceneManager::Scene::ENDING2) { - update(); - render(); - } - - Audio::get()->stopMusic(); -} - -// Actualiza el estado -void Ending2::updateState(float delta_time) { - state_time_ += delta_time; - - switch (state_.state) { - case EndingState::PRE_CREDITS: - if (state_time_ >= STATE_PRE_CREDITS_DURATION) { - transitionToState(EndingState::CREDITS); - } - break; - - case EndingState::CREDITS: - if (texts_.back()->getPosY() <= GameCanvas::CENTER_Y) { - transitionToState(EndingState::POST_CREDITS); - } - break; - - case EndingState::POST_CREDITS: - if (state_time_ >= STATE_POST_CREDITS_DURATION) { - transitionToState(EndingState::FADING); - } - break; - - case EndingState::FADING: - if (state_time_ >= STATE_FADE_DURATION) { - SceneManager::current = SceneManager::Scene::LOGO; - SceneManager::options = SceneManager::Options::LOGO_TO_TITLE; - } - break; - - default: - break; - } -} - -// 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 - sprite_list_.clear(); - - // Añade los valores - sprite_list_.emplace_back("bin"); - sprite_list_.emplace_back("floppy"); - sprite_list_.emplace_back("bird"); - sprite_list_.emplace_back("chip"); - sprite_list_.emplace_back("jeannine"); - sprite_list_.emplace_back("spark"); - sprite_list_.emplace_back("code"); - sprite_list_.emplace_back("paco"); - sprite_list_.emplace_back("elsa"); - sprite_list_.emplace_back("z80"); - - sprite_list_.emplace_back("bell"); - sprite_list_.emplace_back("dong"); - - sprite_list_.emplace_back("amstrad_cs"); - sprite_list_.emplace_back("breakout"); - - sprite_list_.emplace_back("flying_arounder"); - sprite_list_.emplace_back("stopped_arounder"); - sprite_list_.emplace_back("walking_arounder"); - sprite_list_.emplace_back("arounders_door"); - sprite_list_.emplace_back("arounders_machine"); - - sprite_list_.emplace_back("abad"); - sprite_list_.emplace_back("abad_bell"); - sprite_list_.emplace_back("lord_abad"); - - sprite_list_.emplace_back("bat"); - sprite_list_.emplace_back("batman_bell"); - sprite_list_.emplace_back("batman_fire"); - sprite_list_.emplace_back("batman"); - - sprite_list_.emplace_back("demon"); - sprite_list_.emplace_back("heavy"); - sprite_list_.emplace_back("dimallas"); - sprite_list_.emplace_back("guitar"); - - sprite_list_.emplace_back("jailbattle_alien"); - sprite_list_.emplace_back("jailbattle_human"); - - sprite_list_.emplace_back("jailer1"); - sprite_list_.emplace_back("jailer2"); - sprite_list_.emplace_back("jailer3"); - sprite_list_.emplace_back("bry"); - sprite_list_.emplace_back("upv_student"); - - sprite_list_.emplace_back("lamp"); - sprite_list_.emplace_back("robot"); - sprite_list_.emplace_back("congo"); - sprite_list_.emplace_back("crosshair"); - sprite_list_.emplace_back("tree_thing"); - - sprite_list_.emplace_back("matatunos"); - sprite_list_.emplace_back("tuno"); - - sprite_list_.emplace_back("mummy"); - sprite_list_.emplace_back("sam"); - - sprite_list_.emplace_back("qvoid"); - sprite_list_.emplace_back("sigmasua"); - - sprite_list_.emplace_back("tv_panel"); - sprite_list_.emplace_back("tv"); - - sprite_list_.emplace_back("spider"); - sprite_list_.emplace_back("shock"); - sprite_list_.emplace_back("wave"); - - sprite_list_.emplace_back("player"); -} - -// Carga todos los sprites desde una lista -void Ending2::loadSprites() { - // Inicializa variables - sprite_max_width_ = 0; - sprite_max_height_ = 0; - - // Carga los sprites - for (const auto& file : sprite_list_) { - const auto& animation_data = Resource::Cache::get()->getAnimationData(file + ".yaml"); - sprites_.emplace_back(std::make_shared<DissolveSprite>(animation_data)); - sprites_.back()->setColorReplace(1, 4); - sprites_.back()->setProgress(1.0F); // comença invisible - sprite_max_width_ = std::max(sprites_.back()->getWidth(), sprite_max_width_); - sprite_max_height_ = std::max(sprites_.back()->getHeight(), sprite_max_height_); - } - - // El último sprite (player) va en blanco, no en rojo - sprites_.back()->setColorReplace(1, 14); -} - -// Actualiza los sprites -void Ending2::updateSprites(float delta) { - for (const auto& sprite : sprites_) { - sprite->update(delta); - - const float Y = sprite->getPosY(); - const float H = sprite->getHeight(); - const auto CANVAS_H = Options::game.height; - - // Checkpoint inferior: sprite entra per baix → generar de dalt a baix - if (Y > static_cast<float>(ENTRY_EXIT_PADDING) && Y <= CANVAS_H - H - ENTRY_EXIT_PADDING && sprite->getProgress() >= 1.0F && sprite->isTransitionDone()) { - sprite->startGenerate(TRANSITION_DURATION_MS, DissolveDirection::UP); - } - - // Checkpoint superior: sprite surt per dalt → dissoldre de dalt a baix - if (Y <= static_cast<float>(ENTRY_EXIT_PADDING) && sprite->getProgress() <= 0.0F && sprite->isTransitionDone()) { - sprite->startDissolve(TRANSITION_DURATION_MS, DissolveDirection::DOWN); - } - } -} - -// Actualiza los sprites de texto -void Ending2::updateTextSprites(float delta) { - for (const auto& sprite : sprite_texts_) { - sprite->update(delta); - - const float Y = sprite->getPosY(); - const float H = sprite->getHeight(); - const auto CANVAS_H = Options::game.height; - - if (Y > static_cast<float>(ENTRY_EXIT_PADDING) && Y <= CANVAS_H - H - ENTRY_EXIT_PADDING && sprite->getProgress() >= 1.0F && sprite->isTransitionDone()) { - sprite->startGenerate(TRANSITION_DURATION_MS, DissolveDirection::UP); - } - - if (Y <= static_cast<float>(ENTRY_EXIT_PADDING) && sprite->getProgress() <= 0.0F && sprite->isTransitionDone()) { - sprite->startDissolve(TRANSITION_DURATION_MS, DissolveDirection::DOWN); - } - } -} - -// Actualiza los sprites de texto del final -void Ending2::updateTexts(float delta) { - for (const auto& sprite : texts_) { - sprite->update(delta); - - const float Y = sprite->getPosY(); - const float H = sprite->getHeight(); - const auto CANVAS_H = Options::game.height; - - // Checkpoint inferior: text entra per baix → generar de dalt a baix - if (Y > static_cast<float>(ENTRY_EXIT_PADDING) && Y <= CANVAS_H - H - ENTRY_EXIT_PADDING && sprite->getProgress() >= 1.0F && sprite->isTransitionDone()) { - sprite->startGenerate(TRANSITION_DURATION_MS, DissolveDirection::UP); - } - - // Checkpoint superior: text surt per dalt → dissoldre de dalt a baix - if (Y <= static_cast<float>(ENTRY_EXIT_PADDING) && sprite->getProgress() <= 0.0F && sprite->isTransitionDone()) { - sprite->startDissolve(TRANSITION_DURATION_MS, DissolveDirection::DOWN); - } - } -} - -// Dibuja los sprites -void Ending2::renderSprites() { - for (const auto& sprite : sprites_) { - const bool A = sprite->getRect().y + sprite->getRect().h > 0; - const bool B = sprite->getRect().y < Options::game.height; - if (A && B) { - sprite->render(); - } - } -} - -// Dibuja los sprites con el texto -void Ending2::renderSpriteTexts() { - for (const auto& sprite : sprite_texts_) { - const bool A = sprite->getRect().y + sprite->getRect().h > 0; - const bool B = sprite->getRect().y < Options::game.height; - if (A && B) { - sprite->render(); - } - } -} - -// Dibuja los sprites con el texto del final -void Ending2::renderTexts() { - for (const auto& sprite : texts_) { - const bool A = sprite->getRect().y + sprite->getRect().h > 0; - const bool B = sprite->getRect().y < Options::game.height; - if (A && B) { - sprite->render(); - } - } -} - -// Coloca los sprites en su sito -void Ending2::placeSprites() const { - 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::Cache::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); - const float DY = sprite_max_height_ - H; - - sprites_.at(i)->setPos({.x = X + DX, .y = Y + DY, .w = W, .h = H}); - sprites_.at(i)->setVelY(SPRITE_DESP_SPEED); - } - - // Recoloca el sprite del jugador, que es el último de la lista - const float X = (Options::game.width - sprites_.back()->getWidth()) / 2; - const float Y = sprites_.back()->getPosY() + (sprite_max_height_ * 2); - sprites_.back()->setPos(X, Y); - sprites_.back()->setCurrentAnimation("default"); -} - -// Crea los sprites con las texturas con los textos -void Ending2::createSpriteTexts() { // NOLINT(readability-convert-member-functions-to-static) - // Crea los sprites de texto a partir de la lista - for (size_t i = 0; i < sprite_list_.size(); ++i) { - auto text = Resource::Cache::get()->getText("smb2"); - - // Procesa y ajusta el texto del sprite actual - std::string txt = sprite_list_[i]; - std::ranges::replace(txt, '_', ' '); // Reemplaza '_' por ' ' - if (txt == "player") { - txt = Locale::get()->get("ending2.jaildoctor"); // NOLINT(readability-static-accessed-through-instance) Reemplaza "player" por nombre localizado - } - - // Calcula las dimensiones del texto - const float W = text->length(txt, 1); - const float H = text->getCharacterSize(); - - // Determina la columna y la posición X del texto - const float X = (i == sprite_list_.size() - 1) - ? (GameCanvas::CENTER_X - (W / 2)) - : ((i % 2 == 0 ? FIRST_COL : SECOND_COL) - (W / 2)); - - // Calcula la posición Y del texto en base a la posición y altura del sprite - const float Y = sprites_.at(i)->getPosY() + sprites_.at(i)->getHeight() + DIST_SPRITE_TEXT; - - // Crea la surface - auto surface = std::make_shared<Surface>(W, H); - auto previuos_renderer = Screen::get()->getRendererSurface(); - Screen::get()->setRendererSurface(surface); - text->write(0, 0, txt); - - // Crea el sprite - SDL_FRect pos = {.x = X, .y = Y, .w = W, .h = H}; - sprite_texts_.emplace_back(std::make_shared<DissolveSprite>(surface, pos)); - sprite_texts_.back()->setColorReplace(1, 14); - sprite_texts_.back()->setProgress(1.0F); // comença invisible - sprite_texts_.back()->setVelY(SPRITE_DESP_SPEED); - Screen::get()->setRendererSurface(previuos_renderer); - } -} - -// Crea los sprites con las texturas con los textos del final -void Ending2::createTexts() { // NOLINT(readability-convert-member-functions-to-static) - // Crea los primeros textos - std::vector<std::string> list; - list.emplace_back(Locale::get()->get("ending2.starring")); - - auto text = Resource::Cache::get()->getText("smb2"); - - // Crea los sprites de texto a partir de la lista - for (size_t i = 0; i < list.size(); ++i) { - // Calcula constantes - const float W = text->length(list[i], 1); - 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 * TEXT_SPACING_MULTIPLIER)); - - // Crea la surface - auto surface = std::make_shared<Surface>(W, H); - auto previuos_renderer = Screen::get()->getRendererSurface(); - Screen::get()->setRendererSurface(surface); - text->write(0, 0, list[i]); - - // Crea el sprite - SDL_FRect pos = {.x = X + DX, .y = Y, .w = W, .h = H}; - texts_.emplace_back(std::make_shared<DissolveSprite>(surface, pos)); - texts_.back()->setProgress(1.0F); // comença invisible - texts_.back()->setVelY(SPRITE_DESP_SPEED); - Screen::get()->setRendererSurface(previuos_renderer); - } - - // Crea los últimos textos - // El primer texto va a continuación del ultimo spriteText - const int START = sprite_texts_.back()->getPosY() + (text->getCharacterSize() * 15); - list.clear(); - list.emplace_back(Locale::get()->get("ending2.thank_you")); - list.emplace_back(Locale::get()->get("ending2.for_playing")); - - // Crea los sprites de texto a partir de la lista - for (size_t i = 0; i < list.size(); ++i) { - // Calcula constantes - const float W = text->length(list[i], 1); - const float H = text->getCharacterSize(); - const float X = GameCanvas::CENTER_X; - const float DX = -(W / 2); - const float Y = START + (text->getCharacterSize() * (i * TEXT_SPACING_MULTIPLIER)); - - // Crea la surface - auto surface = std::make_shared<Surface>(W, H); - auto previuos_renderer = Screen::get()->getRendererSurface(); - Screen::get()->setRendererSurface(surface); - text->write(0, 0, list[i]); - - // Crea el sprite - SDL_FRect pos = {.x = X + DX, .y = Y, .w = W, .h = H}; - texts_.emplace_back(std::make_shared<DissolveSprite>(surface, pos)); - texts_.back()->setProgress(1.0F); // comença invisible - texts_.back()->setVelY(SPRITE_DESP_SPEED); - Screen::get()->setRendererSurface(previuos_renderer); - } -} - -// Actualiza el fade final -void Ending2::updateFinalFade() { - for (const auto& sprite : texts_) { - sprite->getSurface()->fadeSubPalette(0); - } -} diff --git a/source/game/scenes/ending2.hpp b/source/game/scenes/ending2.hpp deleted file mode 100644 index ff8da99..0000000 --- a/source/game/scenes/ending2.hpp +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once - -#include <SDL3/SDL.h> - -#include <memory> // Para shared_ptr -#include <string> // Para string -#include <vector> // Para vector - -#include "core/rendering/sprite/dissolve_sprite.hpp" // Para SurfaceDissolveSprite -#include "utils/defines.hpp" // Para GameCanvas::WIDTH, GameCanvas::FIRST_QUAR... - -class MovingSprite; -class DeltaTimer; - -class Ending2 { - public: - // --- Constructor y Destructor --- - Ending2(); - ~Ending2() = default; - - // --- Bucle principal --- - void run(); - - private: - // --- Enumeraciones --- - enum class EndingState : int { - PRE_CREDITS, // Estado previo a los créditos - CREDITS, // Estado de los créditos - POST_CREDITS, // Estado posterior a los créditos - FADING, // Estado de fundido de los textos a negro - }; - - // --- Estructuras --- - struct State { - EndingState state{EndingState::PRE_CREDITS}; // Estado actual - float duration{0.0F}; // Duración en segundos para el estado actual - }; - - // --- Constantes --- - static constexpr int FIRST_COL = GameCanvas::FIRST_QUARTER_X + (GameCanvas::WIDTH / 16); // Primera columna por donde desfilan los sprites - 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 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 FADE_H = 24; // Alçada de la zona de dissolució als cantons (files) - static constexpr float TRANSITION_DURATION_MS = 500.0F; // ms per canviar d'estat (generar o dissoldre) - static constexpr int ENTRY_EXIT_PADDING = 2; // px de padding als bordes per activar dissolució/generació - 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) - - // --- Métodos --- - void update(); // Actualiza el objeto - void render(); // Dibuja el final en pantalla - static void handleEvents(); // Comprueba el manejador de eventos - static void handleInput(); // 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() const; // Coloca los sprites en su sitio - 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 - - // --- Variables miembro --- - // Objetos y punteros a recursos - std::vector<std::shared_ptr<DissolveSprite>> sprites_; // Vector con todos los sprites a dibujar - std::vector<std::shared_ptr<DissolveSprite>> sprite_texts_; // Vector con los sprites de texto de los sprites - std::vector<std::shared_ptr<DissolveSprite>> texts_; // Vector con los sprites de texto - std::unique_ptr<DeltaTimer> delta_timer_; // Timer para time-based update - - // Variables de estado - State state_; // Controla el estado de la clase - float state_time_{0.0F}; // Tiempo acumulado en el estado actual - - // Variables auxiliares - 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.0F}; // El valor de ancho del sprite más ancho - float sprite_max_height_{0.0F}; // El valor de alto del sprite más alto -}; diff --git a/source/game/scenes/game.cpp b/source/game/scenes/game.cpp index 8221967..c9b6e39 100644 --- a/source/game/scenes/game.cpp +++ b/source/game/scenes/game.cpp @@ -157,7 +157,7 @@ Game::Game(Mode mode) }; #endif - SceneManager::current = (mode_ == Mode::GAME) ? SceneManager::Scene::GAME : SceneManager::Scene::DEMO; + SceneManager::current = SceneManager::Scene::GAME; SceneManager::options = SceneManager::Options::NONE; } @@ -265,7 +265,7 @@ void Game::run() { Audio::get()->pauseMusic(); } - while (SceneManager::current == SceneManager::Scene::GAME || SceneManager::current == SceneManager::Scene::DEMO) { + while (SceneManager::current == SceneManager::Scene::GAME) { update(); render(); } @@ -375,7 +375,7 @@ void Game::updateGameOver(float delta_time) { // Pequeño delay antes de cambiar escena state_time_ += delta_time; if (state_time_ > 0.1F) { // 100ms de delay mínimo - SceneManager::current = SceneManager::Scene::GAME_OVER; + SceneManager::current = SceneManager::Scene::TITLE; } } @@ -409,7 +409,7 @@ void Game::updatePostFadeEnding(float delta_time) { // Después del delay, cambiar a la escena de ending if (state_time_ >= POST_FADE_DELAY) { - SceneManager::current = SceneManager::Scene::ENDING; + SceneManager::current = SceneManager::Scene::TITLE; } } diff --git a/source/game/scenes/game_over.cpp b/source/game/scenes/game_over.cpp deleted file mode 100644 index 18e72c1..0000000 --- a/source/game/scenes/game_over.cpp +++ /dev/null @@ -1,207 +0,0 @@ -#include "game/scenes/game_over.hpp" - -#include <SDL3/SDL.h> - -#include <algorithm> // Para min, max -#include <string> // Para basic_string, operator+, to_string - -#include "core/audio/audio.hpp" // Para Audio -#include "core/input/global_inputs.hpp" // Para check -#include "core/input/input.hpp" // Para Input -#include "core/locale/locale.hpp" // Para Locale -#include "core/rendering/screen.hpp" // Para Screen -#include "core/rendering/sprite/animated_sprite.hpp" // Para SAnimatedSprite -#include "core/rendering/text.hpp" // Para Text::CENTER_FLAG, Text::COLOR_FLAG, Text -#include "core/resources/resource_cache.hpp" // Para Resource -#include "core/system/global_events.hpp" // Para check -#include "game/options.hpp" // Para Options, options, OptionsStats, Secti... -#include "game/scene_manager.hpp" // Para SceneManager -#include "utils/defines.hpp" // Para GameCanvas::CENTER_X -#include "utils/delta_timer.hpp" // Para DeltaTimer -#include "utils/utils.hpp" - -// Constructor -GameOver::GameOver() - : player_sprite_(std::make_shared<AnimatedSprite>(Resource::Cache::get()->getAnimationData("player_game_over.yaml"))), - tv_sprite_(std::make_shared<AnimatedSprite>(Resource::Cache::get()->getAnimationData("tv.yaml"))), - delta_timer_(std::make_shared<DeltaTimer>()) { - SceneManager::current = SceneManager::Scene::GAME_OVER; - SceneManager::options = SceneManager::Options::NONE; - - // Inicializa las posiciones de los sprites usando las constantes - player_sprite_->setPosX(GameCanvas::CENTER_X + PLAYER_X_OFFSET); - player_sprite_->setPosY(TEXT_Y + SPRITE_Y_OFFSET); - tv_sprite_->setPosX(GameCanvas::CENTER_X - tv_sprite_->getWidth() - TV_X_OFFSET); - tv_sprite_->setPosY(TEXT_Y + SPRITE_Y_OFFSET); - - Screen::get()->setBorderColor(0); - - // Inicializa el vector de colores (de brillante a oscuro para fade) - colors_ = {14, 12, 10, 8, 6, 4, 2, 0}; - color_ = colors_.back(); // Empieza en black -} - -// Actualiza el objeto -void GameOver::update() { - const float DELTA_TIME = delta_timer_->tick(); - elapsed_time_ += DELTA_TIME; - - handleEvents(); // Comprueba los eventos - handleInput(); // Comprueba las entradas - - updateState(); // Actualiza el estado de la escena - updateColor(); // Actualiza el color usado para renderizar los textos e imagenes - player_sprite_->update(DELTA_TIME); // Actualiza el sprite - tv_sprite_->update(DELTA_TIME); // Actualiza el sprite - - Audio::update(); // Actualiza el objeto Audio - Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen -} - -// Dibuja el final en pantalla -void GameOver::render() { - Screen::get()->start(); - Screen::get()->clearSurface(0); - - auto text = Resource::Cache::get()->getText("smb2"); - - // Escribe el texto de GAME OVER - auto* loc = Locale::get(); - text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GameCanvas::CENTER_X, TEXT_Y, loc->get("game_over.title"), 1, color_); // NOLINT(readability-static-accessed-through-instance) - - // Dibuja los sprites (ya posicionados en el constructor, solo ajustamos Y) - player_sprite_->setPosY(TEXT_Y + SPRITE_Y_OFFSET); - tv_sprite_->setPosY(TEXT_Y + SPRITE_Y_OFFSET); - renderSprites(); - - // Escribe el texto con las habitaciones y los items - const std::string ITEMS_TEXT = std::to_string(Options::stats.items / 100) + std::to_string((Options::stats.items % 100) / 10) + std::to_string(Options::stats.items % 10); - const std::string ROOMS_TEXT = std::to_string(Options::stats.rooms / 100) + std::to_string((Options::stats.rooms % 100) / 10) + std::to_string(Options::stats.rooms % 10); - text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GameCanvas::CENTER_X, TEXT_Y + ITEMS_Y_OFFSET, loc->get("game_over.items") + ITEMS_TEXT, 1, color_); // NOLINT(readability-static-accessed-through-instance) - text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GameCanvas::CENTER_X, TEXT_Y + ROOMS_Y_OFFSET, loc->get("game_over.rooms") + ROOMS_TEXT, 1, color_); // NOLINT(readability-static-accessed-through-instance) - - // Vuelca el contenido del renderizador en pantalla - Screen::get()->render(); -} - -// Comprueba el manejador de eventos -void GameOver::handleEvents() { - SDL_Event event; - while (SDL_PollEvent(&event)) { - GlobalEvents::handle(event); - } -} - -// Comprueba las entradas -void GameOver::handleInput() { - Input::get()->update(); - GlobalInputs::handle(); -} - -// Bucle principal -void GameOver::run() { - while (SceneManager::current == SceneManager::Scene::GAME_OVER) { - update(); - render(); - } -} - -// Actualiza el color usado para renderizar los textos e imagenes -void GameOver::updateColor() { - // Calcula el color basado en el estado actual - switch (state_) { - case State::WAITING: - // Durante la espera, mantener en black - color_ = colors_.back(); // black - break; - - case State::FADE_IN: { - // Fade in: de black (último color) a white (primer color) - // Progreso: 0.0 (black) -> 1.0 (white) - const float PROGRESS = std::min(elapsed_time_ / FADE_IN_DURATION, 1.0F); - const int INDEX = (colors_.size() - 1) - static_cast<int>((colors_.size() - 1) * PROGRESS); - color_ = colors_[std::clamp(INDEX, 0, static_cast<int>(colors_.size() - 1))]; - break; - } - - case State::DISPLAY: - // Durante display, mantener el color más brillante - color_ = colors_[0]; // white - break; - - case State::FADE_OUT: { - // Fade out: de white (primer color) a black (último color) - // Progreso: 0.0 (white) -> 1.0 (black) - const float PROGRESS = std::min(elapsed_time_ / FADE_OUT_DURATION, 1.0F); - const int INDEX = static_cast<int>((colors_.size() - 1) * PROGRESS); - color_ = colors_[std::clamp(INDEX, 0, static_cast<int>(colors_.size() - 1))]; - break; - } - - case State::ENDING: - case State::TRANSITION: - // Al final, mantener en black - color_ = colors_.back(); // black - break; - } -} - -// Dibuja los sprites -void GameOver::renderSprites() { - player_sprite_->render(1, color_); - tv_sprite_->render(1, color_); -} - -// Actualiza el estado de la escena y gestiona transiciones -void GameOver::updateState() { - // Máquina de estados basada en tiempo transcurrido - switch (state_) { - case State::WAITING: - // Espera inicial antes de empezar - if (elapsed_time_ >= WAITING_DURATION) { - state_ = State::FADE_IN; - elapsed_time_ = 0.0F; - // Hace sonar la música cuando termina la espera - Audio::get()->playMusic("574070_KUVO_Farewell_to_school.ogg", 0); - } - break; - - case State::FADE_IN: - // Fade in de colores desde black - if (elapsed_time_ >= FADE_IN_DURATION) { - state_ = State::DISPLAY; - elapsed_time_ = 0.0F; - } - break; - - case State::DISPLAY: - // Mostrando contenido con color brillante - if (elapsed_time_ >= DISPLAY_DURATION) { - state_ = State::FADE_OUT; - elapsed_time_ = 0.0F; - } - break; - - case State::FADE_OUT: - // Fade out hacia black - if (elapsed_time_ >= FADE_OUT_DURATION) { - state_ = State::ENDING; - elapsed_time_ = 0.0F; - } - break; - - case State::ENDING: - // Pantalla en negro antes de salir - if (elapsed_time_ >= ENDING_DURATION) { - state_ = State::TRANSITION; - elapsed_time_ = 0.0F; - } - break; - - case State::TRANSITION: - // Transición a la escena de logo - SceneManager::current = SceneManager::Scene::LOGO; - SceneManager::options = SceneManager::Options::LOGO_TO_TITLE; - break; - } -} \ No newline at end of file diff --git a/source/game/scenes/game_over.hpp b/source/game/scenes/game_over.hpp deleted file mode 100644 index 5e2191e..0000000 --- a/source/game/scenes/game_over.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include <SDL3/SDL.h> - -#include <memory> // Para shared_ptr -#include <vector> // Para vector -class AnimatedSprite; // lines 7-7 -class DeltaTimer; // Forward declaration - -class GameOver { - public: - // Constructor y Destructor - GameOver(); - ~GameOver() = default; - - // Bucle principal - void run(); - - private: - // --- Enumeraciones --- - enum class State { - WAITING, // Espera inicial antes de empezar - FADE_IN, // Fade in de colores desde black - DISPLAY, // Mostrando contenido con color brillante - FADE_OUT, // Fade out hacia black - ENDING, // Pantalla en negro antes de salir - TRANSITION // Cambio a logo - }; - - // --- Constantes de duración (segundos) --- - static constexpr float WAITING_DURATION = 0.8F; // Espera inicial - static constexpr float FADE_IN_DURATION = 0.32F; // Duración del fade in - static constexpr float DISPLAY_DURATION = 4.64F; // Duración mostrando contenido - static constexpr float FADE_OUT_DURATION = 0.32F; // Duración del fade out - static constexpr float ENDING_DURATION = 1.12F; // Espera en negro antes de salir - - // --- Constantes de posición --- - static constexpr int TEXT_Y = 32; // Posición Y del texto principal - static constexpr int SPRITE_Y_OFFSET = 30; // Offset Y para sprites desde TEXT_Y - static constexpr int PLAYER_X_OFFSET = 10; // Offset X del jugador desde el centro - static constexpr int TV_X_OFFSET = 10; // Offset X del TV desde el centro - static constexpr int ITEMS_Y_OFFSET = 80; // Offset Y del texto de items desde TEXT_Y - static constexpr int ROOMS_Y_OFFSET = 90; // Offset Y del texto de rooms desde TEXT_Y - - // --- Métodos --- - void update(); // Actualiza el objeto - void render(); // Dibuja el final en pantalla - static void handleEvents(); // Comprueba el manejador de eventos - static void handleInput(); // Comprueba las entradas - void updateState(); // Actualiza el estado y transiciones - void updateColor(); // Actualiza el color usado para renderizar - void renderSprites(); // Dibuja los sprites - - // --- Variables miembro --- - // Objetos y punteros a recursos - std::shared_ptr<AnimatedSprite> player_sprite_; // Sprite con el jugador - std::shared_ptr<AnimatedSprite> tv_sprite_; // Sprite con el televisor - std::shared_ptr<DeltaTimer> delta_timer_; // Timer para time-based logic - - // Variables de estado de la escena - State state_{State::WAITING}; // Estado actual de la escena - float elapsed_time_{0.0F}; // Tiempo transcurrido en el estado actual - - // Variables de efectos visuales - std::vector<Uint8> colors_; // Vector con los colores para el fade - Uint8 color_{0}; // Color actual para texto y sprites -}; \ No newline at end of file diff --git a/source/game/scenes/loading_screen.cpp b/source/game/scenes/loading_screen.cpp deleted file mode 100644 index b5b754a..0000000 --- a/source/game/scenes/loading_screen.cpp +++ /dev/null @@ -1,498 +0,0 @@ -#include "game/scenes/loading_screen.hpp" - -#include <SDL3/SDL.h> - -#include <cmath> // Para std::sin -#include <cstdlib> // Para rand - -#include "core/audio/audio.hpp" // Para Audio -#include "core/input/global_inputs.hpp" // Para check -#include "core/input/input.hpp" // Para Input -#include "core/rendering/screen.hpp" // Para Screen -#include "core/rendering/sprite/sprite.hpp" // Para SSprite -#include "core/rendering/surface.hpp" // Para Surface -#include "core/resources/resource_cache.hpp" // Para Resource -#include "core/system/global_events.hpp" // Para check -#include "game/options.hpp" // Para Options, options, SectionState, Options... -#include "game/scene_manager.hpp" // Para SceneManager -#include "utils/defines.hpp" // Para GAME_SPEED -#include "utils/utils.hpp" - -// Constructor -LoadingScreen::LoadingScreen() - : mono_loading_screen_surface_(Resource::Cache::get()->getSurface("loading_screen_bn.gif")), - color_loading_screen_surface_(Resource::Cache::get()->getSurface("loading_screen_color.gif")), - mono_loading_screen_sprite_(std::make_unique<Sprite>(mono_loading_screen_surface_, 0, 0, mono_loading_screen_surface_->getWidth(), mono_loading_screen_surface_->getHeight())), - color_loading_screen_sprite_(std::make_unique<Sprite>(color_loading_screen_surface_, 0, 0, color_loading_screen_surface_->getWidth(), color_loading_screen_surface_->getHeight())), - program_sprite_(std::make_unique<Sprite>(Resource::Cache::get()->getSurface("program_jaildoc.gif"))), - screen_surface_(std::make_shared<Surface>(Options::game.width, Options::game.height)), - delta_timer_(std::make_unique<DeltaTimer>()) { - // Configura la superficie donde se van a pintar los sprites - screen_surface_->clear(14); - - // Inicializa variables - SceneManager::current = SceneManager::Scene::LOADING_SCREEN; - SceneManager::options = SceneManager::Options::NONE; - program_sprite_->setPosition(0.0F, 8.0F); - - // Inicializa el array de índices de líneas - initLineIndexArray(); - - // Cambia el color del borde - Screen::get()->setBorderColor(14); - transitionToState(State::SILENT1); -} - -// Destructor -LoadingScreen::~LoadingScreen() { - Audio::get()->stopMusic(); -} - -// Comprueba el manejador de eventos -void LoadingScreen::handleEvents() { - SDL_Event event; - while (SDL_PollEvent(&event)) { - GlobalEvents::handle(event); - } -} - -// Comprueba las entradas -void LoadingScreen::handleInput() { - Input::get()->update(); - GlobalInputs::handle(); -} - -// Inicializa el array de índices de líneas (imita el direccionamiento de memoria del Spectrum) -void LoadingScreen::initLineIndexArray() { // NOLINT(readability-convert-member-functions-to-static) - 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); - } - } -} - -// Transiciona a un nuevo estado -void LoadingScreen::transitionToState(State new_state) { - state_ = new_state; - state_time_ = 0.0F; - - // Acciones específicas al entrar en cada estado - switch (new_state) { - case State::SILENT1: - case State::SILENT2: - current_border_type_ = Border::RED; - Audio::get()->stopMusic(); - break; - - case State::HEADER1: - case State::HEADER2: - current_border_type_ = Border::RED_AND_CYAN; - Audio::get()->playMusic("574071_EA_DTV.ogg", 0); - break; - - case State::DATA1: - printProgramName(); - current_border_type_ = Border::YELLOW_AND_BLUE; - Audio::get()->playMusic("574071_EA_DTV.ogg", 0); - break; - case State::DATA2: - current_border_type_ = Border::YELLOW_AND_BLUE; - Audio::get()->playMusic("574070_KUVO_Farewell_to_school.ogg", 0); - break; - case State::LOADING_MONO: - current_border_type_ = Border::YELLOW_AND_BLUE; - Audio::get()->playMusic("574071_EA_DTV.ogg", 0); - last_mono_step_ = -1; // Resetear contador de pasos mono - break; - - case State::LOADING_COLOR: - current_border_type_ = Border::YELLOW_AND_BLUE; - Audio::get()->playMusic("574070_KUVO_Farewell_to_school.ogg", 0); - last_color_block_ = -1; // Resetear contador de bloques color - break; - - case State::COMPLETE: - current_border_type_ = Border::BLACK; - // Transicionar a la pantalla de título - SceneManager::current = SceneManager::Scene::TITLE; - SceneManager::options = SceneManager::Options::TITLE_WITH_LOADING_SCREEN; - Audio::get()->stopMusic(); - break; - } -} - -// Actualiza el estado actual -void LoadingScreen::updateState(float delta_time) { - state_time_ += delta_time; - - // Transiciones automáticas por tiempo para los estados iniciales - // LOADING_MONO y LOADING_COLOR transicionan en sus propias funciones - switch (state_) { - case State::SILENT1: - if (state_time_ >= SILENT1_DURATION) { - transitionToState(State::HEADER1); - } - break; - - case State::HEADER1: - if (state_time_ >= HEADER1_DURATION) { - transitionToState(State::DATA1); - } - break; - - case State::DATA1: - if (state_time_ >= DATA1_DURATION) { - transitionToState(State::SILENT2); - } - break; - - case State::SILENT2: - if (state_time_ >= SILENT2_DURATION) { - transitionToState(State::HEADER2); - } - break; - - case State::HEADER2: - if (state_time_ >= HEADER2_DURATION) { - transitionToState(State::LOADING_MONO); - } - break; - - case State::DATA2: - if (state_time_ >= DATA2_DURATION) { - transitionToState(State::COMPLETE); - } - break; - - case State::LOADING_MONO: - case State::LOADING_COLOR: - case State::COMPLETE: - // Estos estados se gestionan en updateMonoLoad/updateColorLoad - break; - } -} - -// 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); - - // Verificar si ha completado todas las líneas - if (CURRENT_STEP >= TOTAL_STEPS) { - transitionToState(State::LOADING_COLOR); - return; - } - - // Dibujar todos los pasos intermedios desde el último dibujado - const float TEXTURE_WIDTH = mono_loading_screen_surface_->getWidth(); - const float CLIP_WIDTH = TEXTURE_WIDTH / MONO_STEPS_PER_LINE; - - auto previous_renderer = Screen::get()->getRendererSurface(); - Screen::get()->setRendererSurface(screen_surface_); - - for (int step = last_mono_step_ + 1; step <= CURRENT_STEP; ++step) { - // Calcular línea y sub-paso para este paso - const int CURRENT_LINE = step / MONO_STEPS_PER_LINE; // 0-191 - const int CURRENT_SUBSTEP = step % MONO_STEPS_PER_LINE; // 0-4 - - // Saltar si excede el total de líneas - if (CURRENT_LINE >= MONO_TOTAL_LINES) { - break; - } - - // Calcular rectángulo de clip para este paso - 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_); - mono_loading_screen_sprite_->render(); - } - - Screen::get()->setRendererSurface(previous_renderer); - - // Actualizar el último paso dibujado - last_mono_step_ = CURRENT_STEP; -} - -// Gestiona la carga en color -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 bloque actual (0-767) - ahora pinta de 1 en 1 en lugar de 2 en 2 - const int CURRENT_BLOCK = static_cast<int>(progress * COLOR_TOTAL_BLOCKS); - - // Verificar si ha completado todos los bloques - if (CURRENT_BLOCK >= COLOR_TOTAL_BLOCKS) { - transitionToState(State::DATA2); - return; - } - - // Dibujar todos los bloques intermedios desde el último dibujado - auto previous_renderer = Screen::get()->getRendererSurface(); - Screen::get()->setRendererSurface(screen_surface_); - - // Iterar desde el último bloque + 1 hasta el bloque actual (de 1 en 1) - for (int block = last_color_block_ + 1; block <= CURRENT_BLOCK; ++block) { - // Saltar si excede el total de bloques - if (block >= COLOR_TOTAL_BLOCKS) { - break; - } - - // Calcular posición del bloque - load_rect_.x = static_cast<float>((block * COLOR_BLOCK_SPACING) % 256); - load_rect_.y = static_cast<float>((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_); - color_loading_screen_sprite_->render(); - } - - Screen::get()->setRendererSurface(previous_renderer); - - // Actualizar el último bloque dibujado - last_color_block_ = CURRENT_BLOCK; -} - -// Dibuja el efecto de carga amarillo y azul en el borde -void LoadingScreen::renderDataBorder() { - // Obtiene la Surface del borde - auto border = Screen::get()->getBorderSurface(); - - // Pinta el borde de color azul - border->clear(2); - - // Añade lineas amarillas - const auto COLOR = 12; - 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 = rand() % 2 == 0; - - int row = 0; - while (row < HEIGHT) { - const int ROW_HEIGHT = (rand() % 4) + 3; - 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 efecto de carga rojo y azul en el borde -void LoadingScreen::renderHeaderBorder() const { - // Obtiene la Surface del borde - auto border = Screen::get()->getBorderSurface(); - - // Pinta el borde de color azul o rojo - border->clear(carrier_.toggle ? 10 : 4); - - // Añade lineas rojas o azules - const auto COLOR = carrier_.toggle ? 4 : 10; - const int WIDTH = Options::game.width + (Options::video.border.width * 2); - const int HEIGHT = Options::game.height + (Options::video.border.height * 2); - - // Primera linea (con el color y tamaño de la portadora) - int row = 0; - const int FIRST_ROW_HEIGHT = static_cast<int>(carrier_.offset); - for (int i = row; i < row + FIRST_ROW_HEIGHT; ++i) { - border->drawLine(0, i, WIDTH, i, COLOR); - } - row += FIRST_ROW_HEIGHT; - - // Resto de lineas (siguen a la portadora) - bool draw_enabled = false; - while (row < HEIGHT) { - if (draw_enabled) { - for (int i = row; i < row + HEADER_DATAROW_HEIGHT; ++i) { - border->drawLine(0, i, WIDTH, i, COLOR); - } - } - row += HEADER_DATAROW_HEIGHT; - draw_enabled = !draw_enabled; - } -} - -// Dibuja el borde de color -void LoadingScreen::renderColoredBorder(Uint8 color) { - // Obtiene la Surface del borde - auto border = Screen::get()->getBorderSurface(); - - // Pinta el borde del color indicado - border->clear(color); -} - -// Actualiza las variables -void LoadingScreen::update() { - const float DELTA_TIME = delta_timer_->tick(); - - handleEvents(); // Comprueba los eventos - handleInput(); // Comprueba las entradas - - updateState(DELTA_TIME); // Actualiza el estado y gestiona transiciones - - // Actualizar la carga según el estado actual - switch (state_) { - case State::DATA1: - case State::DATA2: - // Por ahora no hacen nada específico - break; - case State::SILENT1: - case State::SILENT2: - updateSilent(DELTA_TIME); - break; - case State::HEADER1: - case State::HEADER2: - updateCarrier(DELTA_TIME); - break; - - case State::LOADING_MONO: - updateMonoLoad(DELTA_TIME); - break; - - case State::LOADING_COLOR: - updateColorLoad(DELTA_TIME); - break; - - case State::COMPLETE: - // No hay más actualizaciones - break; - } - - Audio::update(); // Actualiza el objeto Audio - Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen -} - -// Dibuja en pantalla -void LoadingScreen::render() { - // Pinta el borde - renderBorder(); - - // Prepara para empezar a dibujar en la textura de juego - Screen::get()->start(); - Screen::get()->clearSurface(14); - - // Copia la surface a la surface de Screen - screen_surface_->render(0, 0); - - // Vuelca el contenido del renderizador en pantalla - Screen::get()->render(); -} - -// Bucle para el logo del juego -void LoadingScreen::run() { - // Ajusta el volumen - Audio::get()->setMusicVolume(50); - - // Limpia la pantalla - Screen::get()->start(); - Screen::get()->clearRenderer(); - Screen::get()->render(); - - while (SceneManager::current == SceneManager::Scene::LOADING_SCREEN) { - update(); - render(); - } - - 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 Border::YELLOW_AND_BLUE: - renderDataBorder(); - break; - case Border::RED_AND_CYAN: - renderHeaderBorder(); - break; - case Border::WHITE: - renderColoredBorder(14); - break; - case Border::BLACK: - renderColoredBorder(0); - break; - case Border::RED: - renderColoredBorder(4); - break; - case Border::CYAN: - renderColoredBorder(10); - break; - case Border::NONE: - // No renderizar borde - break; - } - } -} - -// Escribe el nombre del programa -void LoadingScreen::printProgramName() { // NOLINT(readability-convert-member-functions-to-static) - auto previous_renderer = Screen::get()->getRendererSurface(); - Screen::get()->setRendererSurface(screen_surface_); - program_sprite_->render(); - Screen::get()->setRendererSurface(previous_renderer); -} - -// Actualiza la portadora -void LoadingScreen::updateCarrier(float delta_time) { - constexpr float CARRIER_BASE_SPEED = -250.0F; - constexpr float CARRIER_HEIGHT = HEADER_DATAROW_HEIGHT; - - // Oscilación compuesta: mezcla de dos frecuencias para evitar patrón predecible - const float MODULATION = std::sin(carrier_.total_time * 1.2F) * std::sin((carrier_.total_time * 0.35F) + 1.0F); - const float SPEED = CARRIER_BASE_SPEED * (0.5F + (0.5F * MODULATION)); // rango [-200, 0] - - carrier_.offset += SPEED * delta_time; - - if (carrier_.offset < 0.0F) { - carrier_.offset += CARRIER_HEIGHT; // reinicia al rango [0,HEADER_DATAROW_HEIGHT] - carrier_.toggle = !carrier_.toggle; - } - - carrier_.total_time += delta_time; -} - -// Actualiza el ruido durante el tiempo de silencio -void LoadingScreen::updateSilent(float delta_time) { - constexpr float NOISE_THRESHOLD = 0.35F; - - // Oscilación compuesta para simular picos de ruido - const float MODULATION = std::sin(noise_.total_time * 4.2F) * std::sin((noise_.total_time * 1.7F) + 0.5F); - noise_.value = std::fabs(MODULATION); // rango [0.0, 1.0] - - // Detecta cruce de umbral solo si venía de abajo - if (noise_.value > NOISE_THRESHOLD && !noise_.crossed) { - noise_.crossed = true; - current_border_type_ = (current_border_type_ == Border::RED) ? Border::CYAN : Border::RED; - } - - // Restablece el flag cuando baja del umbral - if (noise_.value < NOISE_THRESHOLD) { - noise_.crossed = false; - } - - noise_.total_time += delta_time; -} \ No newline at end of file diff --git a/source/game/scenes/loading_screen.hpp b/source/game/scenes/loading_screen.hpp deleted file mode 100644 index 71daf8a..0000000 --- a/source/game/scenes/loading_screen.hpp +++ /dev/null @@ -1,122 +0,0 @@ -#pragma once - -#include <SDL3/SDL.h> - -#include <array> // Para std::array -#include <memory> // Para shared_ptr - -#include "utils/delta_timer.hpp" // Para DeltaTimer -class Sprite; // Forward declaration -class Surface; // Forward declaration - -class LoadingScreen { - public: - // --- Constructor y Destructor --- - LoadingScreen(); - ~LoadingScreen(); - - // --- Bucle principal --- - void run(); - - private: - // --- Enumeraciones --- - // Estados de la secuencia de carga - enum class State { - SILENT1, // Pausa inicial antes de empezar - HEADER1, // Cabecera - DATA1, // Datos - SILENT2, // Segunda pausa - HEADER2, // Cabecera pantalla - LOADING_MONO, // Carga de pantalla monocromática (escaneo de líneas) - LOADING_COLOR, // Carga de pantalla en color (bloques) - DATA2, // Datos - COMPLETE // Carga completa - }; - - // Tipos de borde para la pantalla de carga - enum class Border { - NONE, - YELLOW_AND_BLUE, - RED_AND_CYAN, - WHITE, - BLACK, - RED, - CYAN - }; - - // --- Estructuras --- - struct Carrier { - float offset{0.0F}; // Offset para la carga de cabeceras - bool toggle{false}; // Para cambiar el color inicial - float total_time{0.0F}; // Tiempo acumulado para modulación de velocidad - }; - - struct Noise { - float value{0.0F}; // Nivel actual de ruido (0.0 a 1.0) - float total_time{0.0F}; // Tiempo acumulado para modulación - bool crossed{false}; // Flag para detectar cruce de umbral - }; - - // --- Constantes de tiempo (en segundos) --- - static constexpr float SILENT1_DURATION = 2.0F; // Pausa inicial - static constexpr float HEADER1_DURATION = 4.0F; // Cabecera - static constexpr float DATA1_DURATION = 0.18F; // Datos - static constexpr float SILENT2_DURATION = 1.6F; // 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_COLOR_DURATION = 4.0F; // Duración total de la carga en color - static constexpr float DATA2_DURATION = 5.0F; // Datos - - // --- Constantes de geometría --- - static constexpr int MONO_TOTAL_LINES = 192; // Total de líneas en carga monocromática - static constexpr int MONO_STEPS_PER_LINE = 5; // Pasos de animación por línea - static constexpr int COLOR_TOTAL_BLOCKS = 768; // Total de bloques en carga color - static constexpr int COLOR_BLOCK_WIDTH = 16; // Ancho del bloque de color - static constexpr int COLOR_BLOCK_HEIGHT = 8; // Alto del bloque de color - static constexpr int COLOR_BLOCKS_PER_ROW = 32; // Bloques por fila (256 / 8) - static constexpr int COLOR_BLOCK_SPACING = 8; // Espaciado entre bloques - static constexpr int HEADER_DATAROW_HEIGHT = 9.0F; // Alto de las barras del borde de la carga de las cabeceras - - // --- Métodos --- - void update(); // Actualiza las variables - void render(); // Dibuja en pantalla - static void handleEvents(); // Comprueba el manejador de eventos - static void handleInput(); // Comprueba las entradas - void updateState(float delta_time); // Actualiza el estado actual - void transitionToState(State new_state); // Transiciona a un nuevo estado - 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 renderBorder(); // Pinta el borde - static void renderDataBorder(); // Dibuja el efecto de carga amarillo y azul en el borde - void renderHeaderBorder() const; // Dibuja el efecto de carga rojo y azul en el borde - static void renderColoredBorder(Uint8 color); // Dibuja el borde de color - void initLineIndexArray(); // Inicializa el array de índices de líneas - void printProgramName(); // Escribe el nombre del programa - void updateCarrier(float delta_time); // Actualiza la portadora - void updateSilent(float delta_time); // Actualiza el ruido durante el tiempo de silencio - - // --- Variables miembro --- - // Objetos y punteros a recursos - std::shared_ptr<Surface> mono_loading_screen_surface_; // Surface con la pantalla de carga en blanco y negro - std::shared_ptr<Surface> color_loading_screen_surface_; // Surface con la pantalla de carga en color - std::unique_ptr<Sprite> mono_loading_screen_sprite_; // SurfaceSprite para manejar la textura mono_loading_screen_surface_ - std::unique_ptr<Sprite> color_loading_screen_sprite_; // SurfaceSprite para manejar la textura color_loading_screen_surface_ - std::unique_ptr<Sprite> program_sprite_; // SurfaceSprite para manejar la textura con el nombre del programa - std::shared_ptr<Surface> screen_surface_; // Surface para dibujar la pantalla de carga - std::unique_ptr<DeltaTimer> delta_timer_; // Timer para delta time - - // Variables de estado de la secuencia - State state_{State::SILENT1}; // Estado actual de la secuencia - float state_time_{0.0F}; // Tiempo acumulado en el estado actual - Border current_border_type_{Border::NONE}; // Tipo de borde actual - - // Arrays y estructuras auxiliares - 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_{.x = 0.0F, .y = 0.0F, .w = 0.0F, .h = 1.0F}; // Rectángulo para dibujar la pantalla de carga - Carrier carrier_; // Estructura para los efectos de la carga de cabeceras - Noise noise_; // Variaciones de ruido durante los silencios - - // Variables de seguimiento para evitar saltos de pasos/bloques - int last_mono_step_{-1}; // Último paso mono dibujado - int last_color_block_{-1}; // Último bloque color dibujado -}; \ No newline at end of file diff --git a/source/game/scenes/logo.cpp b/source/game/scenes/logo.cpp index 795d3ff..60b2e7a 100644 --- a/source/game/scenes/logo.cpp +++ b/source/game/scenes/logo.cpp @@ -238,19 +238,7 @@ void Logo::run() { // Termina la sección void Logo::endSection() { - switch (SceneManager::options) { - case SceneManager::Options::LOGO_TO_TITLE: - SceneManager::current = SceneManager::Scene::TITLE; - break; - - case SceneManager::Options::LOGO_TO_LOADING_SCREEN: - SceneManager::current = SceneManager::Scene::LOADING_SCREEN; - break; - - default: - SceneManager::current = SceneManager::Scene::LOADING_SCREEN; - break; - } + SceneManager::current = SceneManager::Scene::TITLE; } // Inicializa el vector de colores diff --git a/source/game/scenes/title.cpp b/source/game/scenes/title.cpp index 444ed34..9bd70e1 100644 --- a/source/game/scenes/title.cpp +++ b/source/game/scenes/title.cpp @@ -26,25 +26,21 @@ Title::Title() : game_logo_surface_(Resource::Cache::get()->getSurface("title_logo.gif")), game_logo_sprite_(std::make_unique<Sprite>(game_logo_surface_, 29, 9, game_logo_surface_->getWidth(), game_logo_surface_->getHeight())), - loading_screen_surface_(Resource::Cache::get()->getSurface("loading_screen_color.gif")), - loading_screen_sprite_(std::make_unique<Sprite>(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::Cache::get()->getText("gauntlet")), menu_text_(Resource::Cache::get()->getText("gauntlet")) { // Inicializa arrays con valores por defecto temp_keys_.fill(SDL_SCANCODE_UNKNOWN); temp_buttons_.fill(-1); - // Determina el estado inicial basado en opciones - state_ = SceneManager::options == SceneManager::Options::TITLE_WITH_LOADING_SCREEN ? State::SHOW_LOADING_SCREEN : State::MAIN_MENU; + // Estado inicial: menú principal + state_ = State::MAIN_MENU; // Establece SceneManager SceneManager::current = SceneManager::Scene::TITLE; SceneManager::options = SceneManager::Options::NONE; // Acciones iniciales - initMarquee(); // Inicializa la marquesina createCheevosTexture(); // Crea y rellena la textura para mostrar los logros Screen::get()->setBorderColor(0); // Cambia el color del borde Audio::get()->playMusic("574071_EA_DTV.ogg"); // Inicia la musica @@ -52,35 +48,9 @@ Title::Title() // Destructor Title::~Title() { // NOLINT(modernize-use-equals-default) - loading_screen_surface_->resetSubPalette(); title_surface_->resetSubPalette(); } -// Inicializa la marquesina -void Title::initMarquee() { - letters_.clear(); - long_text_ = Locale::get()->get("title.marquee"); - - // Pre-calcular anchos de caracteres para eficiencia (iteración por codepoints UTF-8) - size_t pos = 0; - while (pos < long_text_.size()) { - uint32_t cp = Text::nextCodepoint(long_text_, pos); - Glyph l; - l.codepoint = cp; - l.clip = marquee_text_->getGlyphClip(cp); // Pre-calcular clip rect (evita búsqueda por frame) - l.x = MARQUEE_START_X; - l.width = static_cast<float>(marquee_text_->glyphWidth(cp, 0)); // Pre-calcular ancho visual del glifo - l.enabled = false; - letters_.push_back(l); - } - - if (!letters_.empty()) { - letters_[0].enabled = true; - } - first_active_letter_ = 0; - last_active_letter_ = 0; -} - // Comprueba el manejador de eventos void Title::handleEvents() { SDL_Event event; @@ -170,12 +140,6 @@ void Title::handleInput(float delta_time) { } switch (state_) { - case State::SHOW_LOADING_SCREEN: - if (Input::get()->checkAction(InputAction::ACCEPT, Input::DO_NOT_ALLOW_REPEAT)) { - transitionToState(State::FADE_LOADING_SCREEN); - } - break; - case State::CHEEVOS_MENU: if (Input::get()->checkAction(InputAction::ACCEPT, Input::DO_NOT_ALLOW_REPEAT) || Input::get()->checkAction(InputAction::CANCEL, Input::DO_NOT_ALLOW_REPEAT)) { @@ -191,53 +155,6 @@ void Title::handleInput(float delta_time) { GlobalInputs::handle(); } -// Actualiza la marquesina -void Title::updateMarquee(float delta_time) { - const float DISPLACEMENT = MARQUEE_SPEED * delta_time; - - // Solo procesar letras en rango activo + 1 para poder activar la siguiente - for (int i = first_active_letter_; i <= last_active_letter_ + 1 && i < (int)letters_.size(); ++i) { - auto& letter = letters_[i]; - - if (letter.enabled) { - letter.x -= DISPLACEMENT; - - // Desactivar si sale de pantalla - if (letter.x < MARQUEE_EXIT_X) { - letter.enabled = false; - if (i == first_active_letter_) { - first_active_letter_++; // Avanzar inicio del rango - } - } - } else if (i > 0 && letters_[i - 1].x < MARQUEE_START_X && letters_[i - 1].enabled) { - // Activar siguiente letra usando ancho pre-calculado - letter.enabled = true; - letter.x = letters_[i - 1].x + letters_[i - 1].width + MARQUEE_LETTER_SPACING; - last_active_letter_ = i; // Expandir fin del rango - } - } - - // Comprueba si ha terminado la marquesina y la reinicia - if (letters_[letters_.size() - 1].x < MARQUEE_EXIT_X) { - initMarquee(); - } -} - -// Dibuja la marquesina -void Title::renderMarquee() const { - auto* sprite = marquee_text_->getSprite(); - sprite->setY(MARQUEE_Y); - // Solo renderizar letras activas (optimización: usa cache y rangos) - for (int i = first_active_letter_; i <= last_active_letter_ + 1 && i < (int)letters_.size(); ++i) { - const auto& letter = letters_[i]; - if (letter.enabled && letter.clip.w > 0.0F) { - sprite->setClip(letter.clip); - sprite->setX(letter.x); - sprite->render(1, 6); - } - } -} - // Actualiza las variables void Title::update() { const float DELTA_TIME = delta_timer_->tick(); @@ -254,14 +171,6 @@ void Title::update() { // Actualiza el estado actual void Title::updateState(float delta_time) { switch (state_) { - case State::SHOW_LOADING_SCREEN: - updateShowLoadingScreen(delta_time); - break; - - case State::FADE_LOADING_SCREEN: - updateFadeLoadingScreen(delta_time); - break; - case State::MAIN_MENU: updateMainMenu(delta_time); break; @@ -290,30 +199,8 @@ void Title::transitionToState(State new_state) { fade_accumulator_ = 0.0F; } -// Actualiza el estado SHOW_LOADING_SCREEN -void Title::updateShowLoadingScreen(float delta_time) { - state_time_ += delta_time; - if (state_time_ >= SHOW_LOADING_DURATION) { - transitionToState(State::FADE_LOADING_SCREEN); - } -} - -// Actualiza el estado FADE_LOADING_SCREEN -void Title::updateFadeLoadingScreen(float delta_time) { - fade_accumulator_ += delta_time; - if (fade_accumulator_ >= FADE_STEP_INTERVAL) { - fade_accumulator_ = 0.0F; - if (loading_screen_surface_->fadeSubPalette()) { - transitionToState(State::MAIN_MENU); - } - } -} - // Actualiza el estado MAIN_MENU void Title::updateMainMenu(float delta_time) { - // Actualiza la marquesina - updateMarquee(delta_time); - // Si estamos en modo remap, manejar la lógica específica if (is_remapping_keyboard_ || is_remapping_joystick_) { // Decrementar cooldown de ejes si estamos capturando botones de joystick @@ -341,19 +228,11 @@ void Title::updateMainMenu(float delta_time) { } else { // Incrementa el temporizador solo en el menú principal normal state_time_ += delta_time; - - // Si el tiempo alcanza el timeout, va a créditos con fade - if (state_time_ >= MAIN_MENU_IDLE_TIMEOUT) { - exit_scene_ = SceneManager::Scene::CREDITS; - transitionToState(State::FADE_MENU); - } } } // Actualiza el estado CHEEVOS_MENU void Title::updateCheevosMenu(float delta_time) { - // Actualiza la marquesina (sigue visible en fondo) - updateMarquee(delta_time); // Determina la velocidad objetivo basada en el input float target_velocity = 0.0F; @@ -405,8 +284,6 @@ void Title::updateFadeMenu(float delta_time) { transitionToState(State::POST_FADE_MENU); } } - // Actualiza la marquesina (sigue visible en fondo) - updateMarquee(delta_time); } // Actualiza el estado POST_FADE_MENU @@ -561,19 +438,13 @@ void Title::fillTitleSurface() { case State::FADE_MENU: renderGameLogo(); renderMainMenu(); - renderMarquee(); + break; case State::CHEEVOS_MENU: renderGameLogo(); renderCheevosMenu(); - renderMarquee(); - break; - case State::SHOW_LOADING_SCREEN: - case State::FADE_LOADING_SCREEN: - loading_screen_sprite_->render(); - renderGameLogo(); break; default: diff --git a/source/game/scenes/title.hpp b/source/game/scenes/title.hpp index d05b1d0..f915f09 100644 --- a/source/game/scenes/title.hpp +++ b/source/game/scenes/title.hpp @@ -5,8 +5,6 @@ #include <array> // Para std::array #include <memory> // Para shared_ptr #include <string> // Para string -#include <vector> // Para vector - #include "game/scene_manager.hpp" // Para SceneManager::Scene #include "utils/delta_timer.hpp" // Para DeltaTimer class Sprite; // Forward declaration @@ -24,17 +22,7 @@ class Title { private: // --- Estructuras y enumeraciones --- - struct Glyph { - uint32_t codepoint{0}; // Codepoint Unicode del carácter - SDL_FRect clip{}; // Clip rect pre-calculado en el bitmap de fuente - float x{0.0F}; // Posición en el eje x (float para precisión con delta time) - float width{0.0F}; // Ancho pre-calculado del carácter - bool enabled{false}; // Solo se escriben y mueven si estan habilitadas - }; - enum class State { - SHOW_LOADING_SCREEN, - FADE_LOADING_SCREEN, MAIN_MENU, CHEEVOS_MENU, FADE_MENU, @@ -42,22 +30,13 @@ class Title { }; // --- 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.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 MAIN_MENU_IDLE_TIMEOUT = 20.0F; // Timeout para ir a créditos (antes 2200 frames) static constexpr float KEYBOARD_REMAP_DISPLAY_DELAY = 2.0F; // Tiempo mostrando teclas definidas antes de guardar - static constexpr float MARQUEE_SPEED = 100.0F; // Velocidad de marquesina (pixels/segundo) static constexpr float CHEEVOS_SCROLL_MAX_SPEED = 180.0F; // Velocidad máxima de scroll de logros (pixels/segundo) static constexpr float CHEEVOS_SCROLL_ACCELERATION = 600.0F; // Aceleración del scroll (pixels/segundo²) static constexpr float CHEEVOS_SCROLL_DECELERATION = 800.0F; // Desaceleración del scroll (pixels/segundo²) - // --- Constantes de marquesina --- - static constexpr float MARQUEE_START_X = 256.0F; // Posición inicial (ancho pantalla) - static constexpr float MARQUEE_EXIT_X = -10.0F; // Cuando desaparece de pantalla - static constexpr float MARQUEE_Y = 184.0F; // Posición Y - static constexpr float MARQUEE_LETTER_SPACING = 1.0F; // Espaciado entre letras - // --- Métodos --- void update(); // Actualiza las variables void render(); // Dibuja en pantalla @@ -66,15 +45,10 @@ class Title { void handleInput(float delta_time); // Comprueba las entradas void updateState(float delta_time); // Actualiza el estado actual void transitionToState(State new_state); // Transiciona a un nuevo estado - void updateShowLoadingScreen(float delta_time); // Actualiza SHOW_LOADING_SCREEN - void updateFadeLoadingScreen(float delta_time); // Actualiza FADE_LOADING_SCREEN void updateMainMenu(float delta_time); // Actualiza MAIN_MENU void updateCheevosMenu(float delta_time); // Actualiza CHEEVOS_MENU void updateFadeMenu(float delta_time); // Actualiza FADE_MENU void updatePostFadeMenu(float delta_time); // Actualiza POST_FADE_MENU - void initMarquee(); // Inicializa la marquesina - void updateMarquee(float delta_time); // Actualiza la marquesina (time-based) - void renderMarquee() const; // 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 @@ -97,21 +71,12 @@ class Title { // Objetos y punteros std::shared_ptr<Surface> game_logo_surface_; // Textura con los graficos std::unique_ptr<Sprite> 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::unique_ptr<Sprite> 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::unique_ptr<Sprite> 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 de 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_{0}; // Primera letra activa (optimización) - int last_active_letter_{0}; // Última letra activa (optimización) - // Variables de estado del menú de logros SDL_FRect cheevos_surface_view_; // Zona visible de la surface con el listado de logros float cheevos_scroll_velocity_{0.0F}; // Velocidad actual del scroll de logros (pixels/segundo) diff --git a/source/game/ui/console_commands.cpp b/source/game/ui/console_commands.cpp index 38feff2..4ee4efb 100644 --- a/source/game/ui/console_commands.cpp +++ b/source/game/ui/console_commands.cpp @@ -494,21 +494,9 @@ static auto cmdDebug(const std::vector<std::string>& args) -> std::string { // } else if (args[2] == "LOGO") { target = SceneManager::Scene::LOGO; name = "logo"; - } else if (args[2] == "LOADING") { - target = SceneManager::Scene::LOADING_SCREEN; - name = "loading"; } else if (args[2] == "TITLE") { target = SceneManager::Scene::TITLE; name = "title"; - } else if (args[2] == "CREDITS") { - target = SceneManager::Scene::CREDITS; - name = "credits"; - } else if (args[2] == "ENDING") { - target = SceneManager::Scene::ENDING; - name = "ending"; - } else if (args[2] == "ENDING2") { - target = SceneManager::Scene::ENDING2; - name = "ending2"; } else { std::string scene_lower = args[2]; std::ranges::transform(scene_lower, scene_lower.begin(), ::tolower); @@ -651,7 +639,7 @@ static auto cmdItems(const std::vector<std::string>& args) -> std::string { return "Items: " + std::to_string(count); } -// SCENE [LOGO|LOADING|TITLE|CREDITS|GAME|ENDING|ENDING2|RESTART] +// SCENE [LOGO|TITLE|GAME|RESTART] static auto cmdScene(const std::vector<std::string>& args) -> std::string { if (Options::kiosk.enabled) { return "Not allowed in kiosk mode"; } if (args.empty()) { return "usage: scene [logo|loading|title|credits|game|ending|ending2|restart]"; } @@ -673,12 +661,8 @@ static auto cmdScene(const std::vector<std::string>& args) -> std::string { }; if (args[0] == "LOGO") { return GO_TO(SceneManager::Scene::LOGO, "Logo"); } - if (args[0] == "LOADING") { return GO_TO(SceneManager::Scene::LOADING_SCREEN, "Loading"); } if (args[0] == "TITLE") { return GO_TO(SceneManager::Scene::TITLE, "Title"); } - if (args[0] == "CREDITS") { return GO_TO(SceneManager::Scene::CREDITS, "Credits"); } if (args[0] == "GAME") { return GO_TO(SceneManager::Scene::GAME, "Game"); } - if (args[0] == "ENDING") { return GO_TO(SceneManager::Scene::ENDING, "Ending"); } - if (args[0] == "ENDING2") { return GO_TO(SceneManager::Scene::ENDING2, "Ending 2"); } return "Unknown scene: " + args[0]; }