From fe6e63e39f615c9580bb32b16cbdc0354f3f914b Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 6 Oct 2024 18:57:47 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20la=20classe=20Screen=20ja=20ha=20recuper?= =?UTF-8?q?at=20un=20poc=20del=20lustro=20que=20tenia=20shake=20effect=20j?= =?UTF-8?q?a=20no=20est=C3=A0=20fet=20"the=20torerous=20menner"=20shake=20?= =?UTF-8?q?effect=20ja=20va=20amb=20shaders?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/director.cpp | 5 ++-- source/game.cpp | 28 ++++++++++++++++---- source/screen.cpp | 64 +++++++++++++++++++++++++++++++++------------ source/screen.h | 17 +++++++----- 4 files changed, 83 insertions(+), 31 deletions(-) diff --git a/source/director.cpp b/source/director.cpp index d3c5f1d..ec17cc1 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -34,6 +34,7 @@ #include "section.h" // for name_e, name, options, options_e #include "title.h" // for Title #include "utils.h" // for music_file_t, sound_file_t, opt... +#include #ifndef _WIN32 #include // for getpwuid, passwd @@ -79,9 +80,8 @@ Director::Director(int argc, char *argv[]) loadParams(paramFilePath); // Carga el fichero de puntuaciones - ManageHiScoreTable *manager = new ManageHiScoreTable(&options.game.hiScoreTable); + auto manager = std::make_unique(&options.game.hiScoreTable); manager->loadFromFile(Asset::get()->get("score.bin")); - delete manager; // Inicializa SDL initSDL(); @@ -326,6 +326,7 @@ bool Director::initSDL() // Establece el tamaño del buffer de renderizado SDL_RenderSetLogicalSize(renderer, param.game.width, param.game.height); + SDL_RenderSetIntegerScale(renderer, SDL_TRUE); // Establece el modo de mezcla SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); diff --git a/source/game.cpp b/source/game.cpp index b3abad7..d7a6274 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -56,7 +56,7 @@ Game::Game(int playerID, int currentStage, bool demo, JA_Music_t *music) scoreboard = Scoreboard::get(); eventHandler = std::make_unique(); fade = std::make_unique(renderer); - + background = std::make_unique(renderer); explosions = std::make_unique(); enemyFormations = std::make_unique(); @@ -107,7 +107,7 @@ Game::~Game() unloadMedia(); Scoreboard::destroy(); - + SDL_DestroyTexture(canvas); } @@ -2655,12 +2655,14 @@ void Game::checkEvents() { switch (eventHandler->key.keysym.sym) { - // CREA UNA POWERBALL + // Crea una powerball case SDLK_1: + { createPowerBall(); break; + } - // CREA DOS BALLON4 + // Crea dos BALLON4 case SDLK_2: { const int set = 0; @@ -2678,11 +2680,27 @@ void Game::checkEvents() } break; - // ACTIVA EL MODO PARA PASAR EL JUEGO AUTOMATICAMENTE + // Activa el modo para pasar el juego automaticamente case SDLK_3: + { autoPopBalloons = !autoPopBalloons; screen->showNotification("autoPopBalloons " + boolToString(autoPopBalloons)); break; + } + + // Ralentiza mucho la lógica + case SDLK_4: + { + ticksSpeed *= 10; + break; + } + + // Acelera mucho la lógica + case SDLK_5: + { + ticksSpeed /= 10; + break; + } default: break; diff --git a/source/screen.cpp b/source/screen.cpp index 1d71d74..43aa9e4 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -56,12 +56,14 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) : window(window), ren flashEffect.counter = 0; flashEffect.lenght = 0; flashEffect.color = {0xFF, 0xFF, 0xFF}; - shakeEffect.desp = 1; + shakeEffect.enabled = false; + shakeEffect.desp = 2; shakeEffect.delay = 3; shakeEffect.counter = 0; shakeEffect.lenght = 8; shakeEffect.remaining = 0; - shakeEffect.origin = 0; + shakeEffect.originalPos = 0; + shakeEffect.originalWidth = param.game.width; attenuateEffect = false; fpsTicks = 0; fpsCounter = 0; @@ -81,8 +83,9 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) : window(window), ren // Define el color del borde para el modo de pantalla completa borderColor = {0x00, 0x00, 0x00}; - // Crea la textura donde se dibujan los graficos del juego + // Crea las textura donde se dibujan los graficos del juego gameCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height); + shaderCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height); // Establece el modo de video setVideoMode(options.video.mode); @@ -95,6 +98,7 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) : window(window), ren Screen::~Screen() { SDL_DestroyTexture(gameCanvas); + SDL_DestroyTexture(shaderCanvas); } // Limpia la pantalla @@ -140,13 +144,22 @@ void Screen::blit() SDL_RenderClear(renderer); // Copia la textura de juego en el renderizador en la posición adecuada - SDL_RenderCopy(renderer, gameCanvas, nullptr, nullptr); + if (shakeEffect.enabled) + SDL_RenderCopy(renderer, gameCanvas, nullptr, nullptr); + SDL_RenderCopy(renderer, gameCanvas, &srcrect, &dstrect); // Muestra por pantalla el renderizador SDL_RenderPresent(renderer); #else if (options.video.shaders) { + SDL_SetRenderTarget(renderer, shaderCanvas); + SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF); + SDL_RenderClear(renderer); + if (shakeEffect.enabled) + SDL_RenderCopy(renderer, gameCanvas, nullptr, nullptr); + SDL_RenderCopy(renderer, gameCanvas, &srcrect, &dstrect); + SDL_SetRenderTarget(renderer, nullptr); shader::render(); } else @@ -154,8 +167,14 @@ void Screen::blit() // Vuelve a dejar el renderizador en modo normal SDL_SetRenderTarget(renderer, nullptr); + // Borra el render + SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF); + SDL_RenderClear(renderer); + // Copia la textura de juego en el renderizador en la posición adecuada - SDL_RenderCopy(renderer, gameCanvas, &srcrect, nullptr); + if (shakeEffect.enabled) + SDL_RenderCopy(renderer, gameCanvas, nullptr, nullptr); + SDL_RenderCopy(renderer, gameCanvas, &srcrect, &dstrect); // Muestra por pantalla el renderizador SDL_RenderPresent(renderer); @@ -214,11 +233,12 @@ void Screen::setVideoMode(screenVideoMode videoMode) std::ifstream f(asset->get("crtpi.glsl").c_str()); std::string source((std::istreambuf_iterator(f)), std::istreambuf_iterator()); - shader::init(window, gameCanvas, source.c_str()); + shader::init(window, shaderCanvas, source.c_str()); } // Actualiza variables - shakeEffect.origin = srcrect.x; + // shakeEffect.originalPos = srcrect.x; + // shakeEffect.originalWidth = srcrect.w; } // Camibia entre pantalla completa y ventana @@ -341,12 +361,17 @@ void Screen::checkInput() // Agita la pantalla void Screen::shake() { - // Si ya hay un shake effect en marcha no se pilla el origen, solo se renuevan los contadores - if (shakeEffect.remaining == 0) + // Si no hay un shake effect activo, se guarda una copia de los valores actuales antes de modificarlos + if (!shakeEffect.enabled) { - shakeEffect.origin = srcrect.x; + shakeEffect.enabled = true; + shakeEffect.originalPos = srcrect.x; + shakeEffect.originalWidth = srcrect.w; + srcrect.w -= shakeEffect.desp; + dstrect.w = srcrect.w; } + // Si ya hay un shake effect en marcha no se pilla el origen, solo se renuevan los contadores shakeEffect.remaining = shakeEffect.lenght; shakeEffect.counter = shakeEffect.delay; } @@ -354,7 +379,7 @@ void Screen::shake() // Actualiza la logica para agitar la pantalla void Screen::updateShake() { - if (shakeEffect.remaining > 0) + if (shakeEffect.enabled) { if (shakeEffect.counter > 0) { @@ -363,15 +388,20 @@ void Screen::updateShake() else { shakeEffect.counter = shakeEffect.delay; - const auto desp = shakeEffect.remaining % 2 == 0 ? shakeEffect.desp * (-1) : shakeEffect.desp; - srcrect.x = shakeEffect.origin + desp; + const auto srcdesp = shakeEffect.remaining % 2 == 0 ? 0 : shakeEffect.desp; + const auto dstdesp = shakeEffect.remaining % 2 == 1 ? 0 : shakeEffect.desp; + srcrect.x = shakeEffect.originalPos + srcdesp; + dstrect.x = shakeEffect.originalPos + dstdesp; shakeEffect.remaining--; + shakeEffect.enabled = shakeEffect.remaining == -1 ? false : true; + if (!shakeEffect.enabled) + { + srcrect.x = shakeEffect.originalPos; + srcrect.w = shakeEffect.originalWidth; + dstrect = srcrect; + } } } - else - { - srcrect.x = shakeEffect.origin; - } } // Pone la pantalla de color diff --git a/source/screen.h b/source/screen.h index 98bcc9a..f673661 100644 --- a/source/screen.h +++ b/source/screen.h @@ -36,7 +36,8 @@ private: Asset *asset; // Objeto con el listado de recursos Input *input; // Objeto para leer las entradas de teclado o mando std::unique_ptr notify; // Pinta notificaciones en pantalla - SDL_Texture *gameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa + SDL_Texture *gameCanvas; // Textura donde se dibuja todo antes de volcarse al renderizador + SDL_Texture *shaderCanvas; // Textura para pasarle al shader desde gameCanvas // Variables SDL_Rect srcrect; // Coordenadas de donde va a pillar la textura del juego para dibujarla @@ -62,12 +63,14 @@ private: struct shake_t { - int desp; // Pixels de desplazamiento para agitar la pantalla en el eje x - int delay; // Retraso entre cada desplazamiento de la pantalla al agitarse - int counter; // Contador para el retraso - int lenght; // Cantidad de desplazamientos a realizar - int remaining; // Cantidad de desplazamientos pendientes a realizar - int origin; // Valor inicial de la pantalla para dejarla igual tras el desplazamiento + int desp; // Pixels de desplazamiento para agitar la pantalla en el eje x + int delay; // Retraso entre cada desplazamiento de la pantalla al agitarse + int counter; // Contador para el retraso + int lenght; // Cantidad de desplazamientos a realizar + int remaining; // Cantidad de desplazamientos pendientes a realizar + int originalPos; // Posición inicial de la pantalla para dejarla igual tras el desplazamiento + int originalWidth; // Anchura inicial de la pantalla para dejarla igual tras el desplazamiento + bool enabled; // Indica si el efecto está activo } shakeEffect; // Actualiza la logica para agitar la pantalla