Rediseñada y optimizada la clase Instructions

This commit is contained in:
2024-07-05 11:34:55 +02:00
parent 2b628d2d61
commit 5e7212dfaa
5 changed files with 223 additions and 113 deletions

View File

@@ -74,5 +74,6 @@ const color_t difficultyNormalColor = {255, 122, 0};
const color_t difficultyHardColor = {118, 66, 138};
const color_t flashColor = {0xFF, 0xFF, 0xFF};
const color_t fadeColor = {0x27, 0x27, 0x36};
const color_t orangeColor = {0xFF, 0x7A, 0x00};
#endif

View File

@@ -16,7 +16,7 @@ Director::Director(int argc, char *argv[])
{
// Inicializa variables
section = new section_t();
section->name = SECTION_PROG_TITLE;
section->name = SECTION_PROG_HI_SCORE_TABLE;
// Comprueba los parametros del programa
checkProgramArguments(argc, argv);

View File

@@ -86,11 +86,10 @@ void HiScoreTable::update()
void HiScoreTable::fillTexture()
{
// hay 27 letras - 7 de puntos quedan 20 caracteres 20 - nameLenght 0 numDots
const color_t orangeColor = {0xFF, 0x7A, 0x00};
const int maxNames = 10;
const int spaceBetweenHeader = 32;
const int spaceBetweenLines = text->getCharacterSize() * 2.0f;
const int size = spaceBetweenHeader + spaceBetweenLines * maxNames;
const int size = spaceBetweenHeader + spaceBetweenLines * (maxNames - 1) + text->getCharacterSize();
const int firstLine = (param->gameHeight - size) / 2;
// Pinta en el backbuffer el texto y los sprites

View File

@@ -13,7 +13,65 @@ Instructions::Instructions(SDL_Renderer *renderer, Screen *screen, Asset *asset,
this->param = param;
this->section = section;
// Reserva memoria para los punteros
// Creao objetos
eventHandler = new SDL_Event();
text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);
tiledbg = new Tiledbg(renderer, screen, asset, {0, 0, param->gameWidth, param->gameHeight});
// Crea un backbuffer para el renderizador
backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param->gameWidth, param->gameHeight);
SDL_SetTextureBlendMode(backbuffer, SDL_BLENDMODE_BLEND);
// Crea una textura para el texto fijo
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param->gameWidth, param->gameHeight);
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
// Inicializa variables
section->name = SECTION_PROG_INSTRUCTIONS;
ticks = 0;
ticksSpeed = 15;
counter = 0;
counterEnd = 700;
view = {0, 0, param->gameWidth, param->gameHeight};
spritePos = {0,0};
// Rellena la textura de texto
fillTexture();
// Inicializa los sprites de los items
iniSprites();
}
// Destructor
Instructions::~Instructions()
{
for (auto texture : itemTextures)
{
texture->unload();
delete texture;
}
itemTextures.clear();
for (auto sprite : sprites)
{
delete sprite;
}
sprites.clear();
delete eventHandler;
delete text;
delete tiledbg;
SDL_DestroyTexture(backbuffer);
SDL_DestroyTexture(texture);
}
// Inicializa los sprites de los items
void Instructions::iniSprites()
{
// Inicializa las texturas
Texture *item1 = new Texture(renderer, asset->get("item_points1_disk.png"));
itemTextures.push_back(item1);
@@ -29,42 +87,134 @@ Instructions::Instructions(SDL_Renderer *renderer, Screen *screen, Asset *asset,
Texture *item5 = new Texture(renderer, asset->get("item_coffee.png"));
itemTextures.push_back(item5);
Texture *item6 = new Texture(renderer, asset->get("item_coffee_machine.png"));
itemTextures.push_back(item6);
// Inicializa los sprites
const int itemSize = 16;
const int desp = spritePos.y - 4;
eventHandler = new SDL_Event();
sprite = new Sprite(0, 0, 16, 16, itemTextures[0], renderer);
text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);
// Crea un backbuffer para el renderizador
backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param->gameWidth, param->gameHeight);
SDL_SetTextureBlendMode(backbuffer, SDL_BLENDMODE_BLEND);
// Inicializa variables
section->name = SECTION_PROG_INSTRUCTIONS;
ticks = 0;
ticksSpeed = 15;
manualQuit = false;
counter = 0;
counterEnd = 600;
for (int i = 0; i < (int)itemTextures.size(); ++i)
{
Sprite *sprite = new Sprite(0, 0, itemSize, itemSize, itemTextures[i], renderer);
sprite->setPos({spritePos.x, desp + ((itemSize + 2) * i), itemSize, itemSize});
sprites.push_back(sprite);
}
}
// Destructor
Instructions::~Instructions()
// Actualiza los sprites
void Instructions::updateSprites()
{
for (auto texture : itemTextures)
SDL_Rect srcRect = {0, 0, 16, 16};
// Disquito
srcRect.y = 16 * (((counter + 12) / 36) % 2);
sprites[0]->setSpriteClip(srcRect);
// Gavineixon
srcRect.y = 16 * (((counter + 9) / 36) % 2);
sprites[1]->setSpriteClip(srcRect);
// Pacmar
srcRect.y = 16 * (((counter + 6) / 36) % 2);
sprites[2]->setSpriteClip(srcRect);
// Time Stopper
srcRect.y = 16 * (((counter + 3) / 36) % 2);
sprites[3]->setSpriteClip(srcRect);
// Coffee
srcRect.y = 16 * (((counter + 0) / 36) % 2);
sprites[4]->setSpriteClip(srcRect);
}
// Rellena la textura de texto
void Instructions::fillTexture()
{
// Modifica el renderizador para pintar en la textura
SDL_Texture *temp = SDL_GetRenderTarget(renderer);
SDL_SetRenderTarget(renderer, texture);
// Limpia la textura
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
// Constantes
const int numLines = 4;
const int numItemLines = 4;
const int numPostHeaders = 2;
const int numPreHeaders = 1;
const int spacePostHeader = 20;
const int spacePreHeader = 28;
const int spaceBetweenLines = text->getCharacterSize() * 1.5f;
const int spaceBetweenItemLines = 18;
const int spaceNewParagraph = spaceBetweenLines * 0.5f;
const int size = (numLines * spaceBetweenLines) + (numItemLines * spaceBetweenItemLines) + (numPostHeaders * spacePostHeader) + (numPreHeaders * spacePreHeader) + (spaceNewParagraph);
const int firstLine = (param->gameHeight - size) / 2;
// Calcula cual es el texto más largo de las descripciones de los items
int lenght = 0;
for (int i= 17; i <=21;++i)
{
texture->unload();
delete texture;
const int l = text->lenght(lang->getText(i));
lenght = l > lenght? l : lenght;
}
itemTextures.clear();
const int anchorItem = (param->gameWidth - (lenght + 24)) / 2;
delete sprite;
delete eventHandler;
delete text;
// BORRAR ESTO
//SDL_SetRenderDrawColor(renderer, 255, 255, 255, 32);
//SDL_Rect rect = {10, firstLine, param->gameWidth - 20, size};
//SDL_RenderFillRect(renderer, &rect);
SDL_DestroyTexture(backbuffer);
// Escribe el texto de las instrucciones
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, firstLine, lang->getText(11), 1, orangeColor, 1, shdwTxtColor);
const int anchor1 = firstLine + spacePostHeader;
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, anchor1 + spaceBetweenLines * 0, lang->getText(12), 1, noColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, anchor1 + spaceBetweenLines * 1, lang->getText(13), 1, noColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, anchor1 + spaceNewParagraph + spaceBetweenLines * 2, lang->getText(14), 1, noColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, anchor1 + spaceNewParagraph + spaceBetweenLines * 3, lang->getText(15), 1, noColor, 1, shdwTxtColor);
// Escribe el texto de los objetos y sus puntos
const int anchor2 = anchor1 + spacePreHeader + spaceNewParagraph + spaceBetweenLines * 3;
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, anchor2, lang->getText(16), 1, orangeColor, 1, shdwTxtColor);
const int anchor3 = anchor2 + spacePostHeader;
text->writeShadowed(anchorItem+24, anchor3 + spaceBetweenItemLines * 0, lang->getText(17), shdwTxtColor);
text->writeShadowed(anchorItem+24, anchor3 + spaceBetweenItemLines * 1, lang->getText(18), shdwTxtColor);
text->writeShadowed(anchorItem+24, anchor3 + spaceBetweenItemLines * 2, lang->getText(19), shdwTxtColor);
text->writeShadowed(anchorItem+24, anchor3 + spaceBetweenItemLines * 3, lang->getText(20), shdwTxtColor);
text->writeShadowed(anchorItem+24, anchor3 + spaceBetweenItemLines * 4, lang->getText(21), shdwTxtColor);
// Deja el renderizador como estaba
SDL_SetRenderTarget(renderer, temp);
// Da valor a la variable
spritePos.x = anchorItem;
spritePos.y = anchor3;
}
// Rellena el backbuffer
void Instructions::fillBackbuffer()
{
// Modifica el renderizador para pintar en la textura
SDL_Texture *temp = SDL_GetRenderTarget(renderer);
SDL_SetRenderTarget(renderer, backbuffer);
// Limpia la textura
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
// Coloca el texto de fondo
SDL_RenderCopy(renderer, texture, nullptr, nullptr);
// Dibuja los sprites
for (auto sprite : sprites)
{
sprite->render();
}
// Deja el renderizador como estaba
SDL_SetRenderTarget(renderer, temp);
}
// Actualiza las variables
@@ -79,8 +229,15 @@ void Instructions::update()
// Actualiza el contador de ticks
ticks = SDL_GetTicks();
// Incrementa el contador
counter++;
// Actualiza los sprites
updateSprites();
// Actualiza el mosaico de fondo
tiledbg->update();
if (counter == counterEnd)
{
section->name = SECTION_PROG_TITLE;
@@ -92,74 +249,8 @@ void Instructions::update()
// Pinta en pantalla
void Instructions::render()
{
// Pinta en pantalla
SDL_Rect window = {0, 0, param->gameWidth, param->gameHeight};
SDL_Rect srcRect = {0, 0, 16, 16};
const color_t orangeColor = {0xFF, 0x7A, 0x00};
const SDL_Rect destRect1 = {60, 88 + (16 * 0), 16, 16}; // Disquito
const SDL_Rect destRect2 = {60, 88 + (16 * 1), 16, 16}; // Gavineixon
const SDL_Rect destRect3 = {60, 88 + (16 * 2), 16, 16}; // Pacmar
const SDL_Rect destRect4 = {60, 88 + (16 * 3), 16, 16}; // Time Stopper
const SDL_Rect destRect5 = {60, 88 + (16 * 4), 16, 16}; // Coffee
// Pinta en el backbuffer el texto y los sprites
SDL_SetRenderTarget(renderer, backbuffer);
SDL_SetRenderDrawColor(renderer, 255, bgColor.g, bgColor.b, 255);
SDL_RenderClear(renderer);
// Escribe el texto
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 8, lang->getText(11), 1, orangeColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 24, lang->getText(12), 1, noColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 34, lang->getText(13), 1, noColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 48, lang->getText(14), 1, noColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 58, lang->getText(15), 1, noColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 75, lang->getText(16), 1, orangeColor, 1, shdwTxtColor);
text->writeShadowed(84, 92, lang->getText(17), shdwTxtColor);
text->writeShadowed(84, 108, lang->getText(18), shdwTxtColor);
text->writeShadowed(84, 124, lang->getText(19), shdwTxtColor);
text->writeShadowed(84, 140, lang->getText(20), shdwTxtColor);
text->writeShadowed(84, 156, lang->getText(21), shdwTxtColor);
// Disquito
sprite->setTexture(itemTextures[0]);
sprite->setPos(destRect1);
srcRect.y = 16 * (((counter + 12) / 36) % 2);
sprite->setSpriteClip(srcRect);
sprite->render();
// Gavineixon
sprite->setTexture(itemTextures[1]);
sprite->setPos(destRect2);
srcRect.y = 16 * (((counter + 9) / 36) % 2);
sprite->setSpriteClip(srcRect);
sprite->render();
// Pacmar
sprite->setTexture(itemTextures[2]);
sprite->setPos(destRect3);
srcRect.y = 16 * (((counter + 6) / 36) % 2);
sprite->setSpriteClip(srcRect);
sprite->render();
// Time Stopper
sprite->setTexture(itemTextures[3]);
sprite->setPos(destRect4);
srcRect.y = 16 * (((counter + 3) / 36) % 2);
sprite->setSpriteClip(srcRect);
sprite->render();
// Coffee
sprite->setTexture(itemTextures[4]);
sprite->setPos(destRect5);
srcRect.y = 16 * (((counter + 0) / 36) % 2);
sprite->setSpriteClip(srcRect);
sprite->render();
// Cambia el destino de renderizado
SDL_SetRenderTarget(renderer, nullptr);
// Rellena el backbuffer
fillBackbuffer();
// Prepara para empezar a dibujar en la textura de juego
screen->start();
@@ -167,11 +258,14 @@ void Instructions::render()
// Limpia la pantalla
screen->clean(bgColor);
// Establece la ventana del backbuffer
window.y = std::max(0, param->gameHeight - counter + 100);
// Dibuja el mosacico de fondo
tiledbg->render();
// Copia el backbuffer al renderizador
SDL_RenderCopy(renderer, backbuffer, nullptr, &window);
// Establece la ventana del backbuffer
view.y = std::max(0, param->gameHeight - counter + 100);
// Copia la textura y el backbuffer al renderizador
SDL_RenderCopy(renderer, backbuffer, nullptr, &view);
// Vuelca el contenido del renderizador en pantalla
screen->blit();
@@ -217,9 +311,9 @@ void Instructions::checkInput()
else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE))
{
JA_StopMusic();
section->name = SECTION_PROG_TITLE;
section->subsection = SUBSECTION_TITLE_1;
JA_StopMusic();
section->name = SECTION_PROG_TITLE;
section->subsection = SUBSECTION_TITLE_1;
}
}

View File

@@ -10,6 +10,7 @@
#include "common/utils.h"
#include "const.h"
#include "lang.h"
#include "tiledbg.h"
#ifndef INSTRUCTIONS_H
#define INSTRUCTIONS_H
@@ -22,22 +23,25 @@ private:
SDL_Renderer *renderer; // El renderizador de la ventana
Screen *screen; // Objeto encargado de dibujar en pantalla
std::vector<Texture *> itemTextures; // Vector con las texturas de los items
std::vector<Sprite *> sprites; // Vector con los sprites de los items
SDL_Event *eventHandler; // Manejador de eventos
SDL_Texture *backbuffer; // Textura para usar como backbuffer
Sprite *sprite; // Sprite con la textura de las instrucciones
SDL_Texture *texture; // Textura fija con el texto
Asset *asset; // Objeto que gestiona todos los ficheros de recursos
Input *input; // Objeto pata gestionar la entrada
Lang *lang; // Objeto para gestionar los textos en diferentes idiomas
Text *text; // Objeto para escribir texto
Tiledbg *tiledbg; // Objeto para dibujar el mosaico animado de fondo
section_t *section; // Estado del bucle principal para saber si continua o se sale
param_t *param; // Puntero con todos los parametros del programa
// Variables
Uint16 counter; // Contador
Uint16 counterEnd; // Valor final para el contador
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
bool manualQuit; // Indica si se quiere salir del modo manual
int counter; // Contador
int counterEnd; // Valor final para el contador
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
SDL_Rect view; // Vista del backbuffer que se va amostrar por pantalla
SDL_Point spritePos; // Posición del primer sprite
// Actualiza las variables
void update();
@@ -51,6 +55,18 @@ private:
// Comprueba las entradas
void checkInput();
// Rellena la textura de texto
void fillTexture();
// Rellena el backbuffer
void fillBackbuffer();
// Inicializa los sprites de los items
void iniSprites();
// Actualiza los sprites
void updateSprites();
public:
// Constructor
Instructions(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Lang *lang, param_t *param, section_t *section);