diff --git a/source/const.h b/source/const.h index 8c57b37..8f03f67 100644 --- a/source/const.h +++ b/source/const.h @@ -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 \ No newline at end of file diff --git a/source/director.cpp b/source/director.cpp index 344e3b5..d1a6fa2 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -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); diff --git a/source/hiscore_table.cpp b/source/hiscore_table.cpp index 1f9129d..eb9f139 100644 --- a/source/hiscore_table.cpp +++ b/source/hiscore_table.cpp @@ -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 diff --git a/source/instructions.cpp b/source/instructions.cpp index 43d2a7e..783fbd7 100644 --- a/source/instructions.cpp +++ b/source/instructions.cpp @@ -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; } } diff --git a/source/instructions.h b/source/instructions.h index d777ac6..24a0ca8 100644 --- a/source/instructions.h +++ b/source/instructions.h @@ -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 itemTextures; // Vector con las texturas de los items + std::vector 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);