fix: la classe Screen ja ha recuperat un poc del lustro que tenia

shake effect ja no està fet "the torerous menner"
shake effect ja va amb shaders
This commit is contained in:
2024-10-06 18:57:47 +02:00
parent afe092c742
commit fe6e63e39f
4 changed files with 83 additions and 31 deletions

View File

@@ -34,6 +34,7 @@
#include "section.h" // for name_e, name, options, options_e #include "section.h" // for name_e, name, options, options_e
#include "title.h" // for Title #include "title.h" // for Title
#include "utils.h" // for music_file_t, sound_file_t, opt... #include "utils.h" // for music_file_t, sound_file_t, opt...
#include <memory>
#ifndef _WIN32 #ifndef _WIN32
#include <pwd.h> // for getpwuid, passwd #include <pwd.h> // for getpwuid, passwd
@@ -79,9 +80,8 @@ Director::Director(int argc, char *argv[])
loadParams(paramFilePath); loadParams(paramFilePath);
// Carga el fichero de puntuaciones // Carga el fichero de puntuaciones
ManageHiScoreTable *manager = new ManageHiScoreTable(&options.game.hiScoreTable); auto manager = std::make_unique<ManageHiScoreTable>(&options.game.hiScoreTable);
manager->loadFromFile(Asset::get()->get("score.bin")); manager->loadFromFile(Asset::get()->get("score.bin"));
delete manager;
// Inicializa SDL // Inicializa SDL
initSDL(); initSDL();
@@ -326,6 +326,7 @@ bool Director::initSDL()
// Establece el tamaño del buffer de renderizado // Establece el tamaño del buffer de renderizado
SDL_RenderSetLogicalSize(renderer, param.game.width, param.game.height); SDL_RenderSetLogicalSize(renderer, param.game.width, param.game.height);
SDL_RenderSetIntegerScale(renderer, SDL_TRUE);
// Establece el modo de mezcla // Establece el modo de mezcla
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);

View File

@@ -56,7 +56,7 @@ Game::Game(int playerID, int currentStage, bool demo, JA_Music_t *music)
scoreboard = Scoreboard::get(); scoreboard = Scoreboard::get();
eventHandler = std::make_unique<SDL_Event>(); eventHandler = std::make_unique<SDL_Event>();
fade = std::make_unique<Fade>(renderer); fade = std::make_unique<Fade>(renderer);
background = std::make_unique<Background>(renderer); background = std::make_unique<Background>(renderer);
explosions = std::make_unique<Explosions>(); explosions = std::make_unique<Explosions>();
enemyFormations = std::make_unique<EnemyFormations>(); enemyFormations = std::make_unique<EnemyFormations>();
@@ -107,7 +107,7 @@ Game::~Game()
unloadMedia(); unloadMedia();
Scoreboard::destroy(); Scoreboard::destroy();
SDL_DestroyTexture(canvas); SDL_DestroyTexture(canvas);
} }
@@ -2655,12 +2655,14 @@ void Game::checkEvents()
{ {
switch (eventHandler->key.keysym.sym) switch (eventHandler->key.keysym.sym)
{ {
// CREA UNA POWERBALL // Crea una powerball
case SDLK_1: case SDLK_1:
{
createPowerBall(); createPowerBall();
break; break;
}
// CREA DOS BALLON4 // Crea dos BALLON4
case SDLK_2: case SDLK_2:
{ {
const int set = 0; const int set = 0;
@@ -2678,11 +2680,27 @@ void Game::checkEvents()
} }
break; break;
// ACTIVA EL MODO PARA PASAR EL JUEGO AUTOMATICAMENTE // Activa el modo para pasar el juego automaticamente
case SDLK_3: case SDLK_3:
{
autoPopBalloons = !autoPopBalloons; autoPopBalloons = !autoPopBalloons;
screen->showNotification("autoPopBalloons " + boolToString(autoPopBalloons)); screen->showNotification("autoPopBalloons " + boolToString(autoPopBalloons));
break; break;
}
// Ralentiza mucho la lógica
case SDLK_4:
{
ticksSpeed *= 10;
break;
}
// Acelera mucho la lógica
case SDLK_5:
{
ticksSpeed /= 10;
break;
}
default: default:
break; break;

View File

@@ -56,12 +56,14 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) : window(window), ren
flashEffect.counter = 0; flashEffect.counter = 0;
flashEffect.lenght = 0; flashEffect.lenght = 0;
flashEffect.color = {0xFF, 0xFF, 0xFF}; flashEffect.color = {0xFF, 0xFF, 0xFF};
shakeEffect.desp = 1; shakeEffect.enabled = false;
shakeEffect.desp = 2;
shakeEffect.delay = 3; shakeEffect.delay = 3;
shakeEffect.counter = 0; shakeEffect.counter = 0;
shakeEffect.lenght = 8; shakeEffect.lenght = 8;
shakeEffect.remaining = 0; shakeEffect.remaining = 0;
shakeEffect.origin = 0; shakeEffect.originalPos = 0;
shakeEffect.originalWidth = param.game.width;
attenuateEffect = false; attenuateEffect = false;
fpsTicks = 0; fpsTicks = 0;
fpsCounter = 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 // Define el color del borde para el modo de pantalla completa
borderColor = {0x00, 0x00, 0x00}; 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); 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 // Establece el modo de video
setVideoMode(options.video.mode); setVideoMode(options.video.mode);
@@ -95,6 +98,7 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) : window(window), ren
Screen::~Screen() Screen::~Screen()
{ {
SDL_DestroyTexture(gameCanvas); SDL_DestroyTexture(gameCanvas);
SDL_DestroyTexture(shaderCanvas);
} }
// Limpia la pantalla // Limpia la pantalla
@@ -140,13 +144,22 @@ void Screen::blit()
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
// Copia la textura de juego en el renderizador en la posición adecuada // 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 // Muestra por pantalla el renderizador
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
#else #else
if (options.video.shaders) 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(); shader::render();
} }
else else
@@ -154,8 +167,14 @@ void Screen::blit()
// Vuelve a dejar el renderizador en modo normal // Vuelve a dejar el renderizador en modo normal
SDL_SetRenderTarget(renderer, nullptr); 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 // 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 // Muestra por pantalla el renderizador
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
@@ -214,11 +233,12 @@ void Screen::setVideoMode(screenVideoMode videoMode)
std::ifstream f(asset->get("crtpi.glsl").c_str()); std::ifstream f(asset->get("crtpi.glsl").c_str());
std::string source((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>()); std::string source((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
shader::init(window, gameCanvas, source.c_str()); shader::init(window, shaderCanvas, source.c_str());
} }
// Actualiza variables // Actualiza variables
shakeEffect.origin = srcrect.x; // shakeEffect.originalPos = srcrect.x;
// shakeEffect.originalWidth = srcrect.w;
} }
// Camibia entre pantalla completa y ventana // Camibia entre pantalla completa y ventana
@@ -341,12 +361,17 @@ void Screen::checkInput()
// Agita la pantalla // Agita la pantalla
void Screen::shake() void Screen::shake()
{ {
// Si ya hay un shake effect en marcha no se pilla el origen, solo se renuevan los contadores // Si no hay un shake effect activo, se guarda una copia de los valores actuales antes de modificarlos
if (shakeEffect.remaining == 0) 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.remaining = shakeEffect.lenght;
shakeEffect.counter = shakeEffect.delay; shakeEffect.counter = shakeEffect.delay;
} }
@@ -354,7 +379,7 @@ void Screen::shake()
// Actualiza la logica para agitar la pantalla // Actualiza la logica para agitar la pantalla
void Screen::updateShake() void Screen::updateShake()
{ {
if (shakeEffect.remaining > 0) if (shakeEffect.enabled)
{ {
if (shakeEffect.counter > 0) if (shakeEffect.counter > 0)
{ {
@@ -363,15 +388,20 @@ void Screen::updateShake()
else else
{ {
shakeEffect.counter = shakeEffect.delay; shakeEffect.counter = shakeEffect.delay;
const auto desp = shakeEffect.remaining % 2 == 0 ? shakeEffect.desp * (-1) : shakeEffect.desp; const auto srcdesp = shakeEffect.remaining % 2 == 0 ? 0 : shakeEffect.desp;
srcrect.x = shakeEffect.origin + desp; const auto dstdesp = shakeEffect.remaining % 2 == 1 ? 0 : shakeEffect.desp;
srcrect.x = shakeEffect.originalPos + srcdesp;
dstrect.x = shakeEffect.originalPos + dstdesp;
shakeEffect.remaining--; 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 // Pone la pantalla de color

View File

@@ -36,7 +36,8 @@ private:
Asset *asset; // Objeto con el listado de recursos Asset *asset; // Objeto con el listado de recursos
Input *input; // Objeto para leer las entradas de teclado o mando Input *input; // Objeto para leer las entradas de teclado o mando
std::unique_ptr<Notify> notify; // Pinta notificaciones en pantalla std::unique_ptr<Notify> 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 // Variables
SDL_Rect srcrect; // Coordenadas de donde va a pillar la textura del juego para dibujarla SDL_Rect srcrect; // Coordenadas de donde va a pillar la textura del juego para dibujarla
@@ -62,12 +63,14 @@ private:
struct shake_t struct shake_t
{ {
int desp; // Pixels de desplazamiento para agitar la pantalla en el eje x 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 delay; // Retraso entre cada desplazamiento de la pantalla al agitarse
int counter; // Contador para el retraso int counter; // Contador para el retraso
int lenght; // Cantidad de desplazamientos a realizar int lenght; // Cantidad de desplazamientos a realizar
int remaining; // Cantidad de desplazamientos pendientes a realizar int remaining; // Cantidad de desplazamientos pendientes a realizar
int origin; // Valor inicial de la pantalla para dejarla igual tras el desplazamiento 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; } shakeEffect;
// Actualiza la logica para agitar la pantalla // Actualiza la logica para agitar la pantalla