From 04d39c579a6056f314fbdf6d2ceefe5b569c405a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Valor=20Mart=C3=ADnez?= Date: Sat, 3 Sep 2022 07:40:11 +0200 Subject: [PATCH] Empezando a trabajar en el logo --- media/logo/jailgames.png | Bin 0 -> 717 bytes media/logo/seagull.png | Bin 0 -> 690 bytes media/logo/since_1998.png | Bin 0 -> 561 bytes source/director.cpp | 5 + source/logo.cpp | 137 ++++++ source/logo.h | 50 +++ source/menu.cpp | 896 -------------------------------------- source/menu.h | 217 --------- todo.txt | 10 + 9 files changed, 202 insertions(+), 1113 deletions(-) create mode 100644 media/logo/jailgames.png create mode 100644 media/logo/seagull.png create mode 100644 media/logo/since_1998.png create mode 100644 source/logo.cpp create mode 100644 source/logo.h delete mode 100644 source/menu.cpp delete mode 100644 source/menu.h diff --git a/media/logo/jailgames.png b/media/logo/jailgames.png new file mode 100644 index 0000000000000000000000000000000000000000..e85ceb9b60e25266d33d5ebbed58f1fd659c3eda GIT binary patch literal 717 zcmV;;0y6!HP)w^Sqf+^W*j2n>5)fTSbYD zUkm;Mw#r&5A|*RzO>EF}o|&3S=G^YNpZmS%obEjroZ*y`Hmdp{oiX*$M8Gp2S@6_6 zwlfuDOQ?q$nxK&9; zmxWJ-eY#vw_}12A1%9zPQQ$9|^>AnmoK3=>L>b4*SV`(>VR<=S=~PZB-p784Tg}YP z%GxQj9fJ@P1n@A$IAi$fXIQ+S9tP-@9ToEXe)FfvO0FVaBahAs36hxjM9oQcRo1xZ zs*DtQyZ?XtYQzTz3f0{KsD84nw{ED}g6~bs`aHC(?;~(M!bPT(pFMz~chNUXTGu`_ zuEW`7NsH~k`3AH-Xi+`-E4gGk<8gRBfrbdQTtnSrp=ZT&j_)D7CSP?0yL;f3_{OCl zO9W@xFFYao0003LNklptEi6MD^Mr@Bwqs5fJey6zU%Ik+};&8U}*6-M23tdYGg@dI*bYRH)yKd{cf zj6E{qlxmNBXW~f>IW#ro5I>BpM+sJW^Ug|byOO5HFugZ(K8~{=I37(6IaA}un{(VO ztWmps&B)Y;D1Cn4{nLEw{D>crLsLTzr}Q>6V~uv)H}}Mo8ggiA$hl670bVD^PFuGg zEow^Sqf+^W*j2n>5)fTSbYD zUkm;Mw#r&5A|*RzO>EF}o|&3S=G^YNpZmS%obEjroZ*y`Hmdp{oiX*$M8Gp2S@6_6 zwlfuDOQ?q$nxK&9; zmxWJ-eY#vw_}12A1%9zPQQ$9|^>AnmoK3=>L>b4*SV`(>VR<=S=~PZB-p784Tg}YP z%GxQj9fJ@P1n@A$IAi$fXIQ+S9tP-@9ToEXe)FfvO0FVaBahAs36hxjM9oQcRo1xZ zs*DtQyZ?XtYQzTz3f0{KsD84nw{ED}g6~bs`aHC(?;~(M!bPT(pFMz~chNUXTGu`_ zuEW`7NsH~k`3AH-Xi+`-E4gGk<8gRBfrbdQTtnSrp=ZT&j_)D7CSP?0yL;f3_{OCl zO9W@xFFYao0002_Nkl5pKfnte_FD+yu=b@|yE0Kx@S-t+Xr?VcotYkZZo`@VXGwbvE zzf=$eG9J8#X2Dh;prm9{4lR`~laMKw?kD}bBttW-%$4+z2Y(@IA|x;~w-O?1mLZ}e z)P-jC>cu( zy%kPB)a+Z&BQlY}|LxB+GND;?4Px!je+I6aq27~c%hc{&c7!~_jpsFQwzw^Sqf+^W*j2n>5)fTSbYD zUkm;Mw#r&5A|*RzO>EF}o|&3S=G^YNpZmS%obEjroZ*y`Hmdp{oiX*$M8Gp2S@6_6 zwlfuDOQ?q$nxK&9; zmxWJ-eY#vw_}12A1%9zPQQ$9|^>AnmoK3=>L>b4*SV`(>VR<=S=~PZB-p784Tg}YP z%GxQj9fJ@P1n@A$IAi$fXIQ+S9tP-@9ToEXe)FfvO0FVaBahAs36hxjM9oQcRo1xZ zs*DtQyZ?XtYQzTz3f0{KsD84nw{ED}g6~bs`aHC(?;~(M!bPT(pFMz~chNUXTGu`_ zuEW`7NsH~k`3AH-Xi+`-E4gGk<8gRBfrbdQTtnSrp=ZT&j_)D7CSP?0yL;f3_{OCl zO9W@xFFYao0001ZNkl&R|lsSA100000NkvXXu0mjfloSJg literal 0 HcmV?d00001 diff --git a/source/director.cpp b/source/director.cpp index 4e30f6c..e86624b 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -190,6 +190,11 @@ bool Director::setFileList() asset->add("/media/sound/item.wav", sound); + asset->add("/media/logo/jailgames.wav", bitmap); + asset->add("/media/logo/since_1998.wav", bitmap); + asset->add("/media/logo/seagull.wav", bitmap); + + return asset->check(); } diff --git a/source/logo.cpp b/source/logo.cpp new file mode 100644 index 0000000..92999ed --- /dev/null +++ b/source/logo.cpp @@ -0,0 +1,137 @@ +#include "logo.h" + +// Constructor +Logo::Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset) +{ + // Copia la dirección de los objetos + this->renderer = renderer; + this->screen = screen; + this->asset = asset; + + // Reserva memoria para los punteros + eventHandler = new SDL_Event(); + texture = new LTexture(); + loadTextureFromFile(texture, asset->get("logo.png"), renderer); + sprite = new Sprite(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, texture, renderer); + + // Crea un backbuffer para el renderizador + backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH, SCREEN_HEIGHT); + if (backbuffer == NULL) + printf("Backbuffer could not be created!\nSDL Error: %s\n", SDL_GetError()); + + // Inicializa variables + counter = 0; + section.name = SECTION_PROG_LOGO; + section.subsection = 0; + ticks = 0; + ticksSpeed = 15; + initFade = 100; + endLogo = 200; + postLogo = 20; +} + +// Destructor +Logo::~Logo() +{ + renderer = nullptr; + screen = nullptr; + asset = nullptr; + + texture->unload(); + delete texture; + texture = nullptr; + + delete sprite; + sprite = nullptr; + + delete eventHandler; + eventHandler = nullptr; + + SDL_DestroyTexture(backbuffer); + backbuffer = nullptr; +} + +// Actualiza las variables +void Logo::update() +{ + // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego + if (SDL_GetTicks() - ticks > ticksSpeed) + { + // Actualiza el contador de ticks + ticks = SDL_GetTicks(); + + // Comprueba los eventos que hay en la cola + while (SDL_PollEvent(eventHandler) != 0) + { + // Evento de salida de la aplicación + if (eventHandler->type == SDL_QUIT) + { + section.name = SECTION_PROG_QUIT; + break; + } + + // Cualquier tecla pulsada + if ((eventHandler->type == SDL_KEYDOWN) || (eventHandler->type == SDL_JOYBUTTONDOWN)) + { + section.name = SECTION_PROG_TITLE; + section.subsection = 0; + } + } + + counter++; + + // Comprueba si ha terminado el logo + if (counter == endLogo + postLogo) + { + section.name = SECTION_PROG_INTRO; + section.subsection = 0; + } + } +} + +// Dibuja en pantalla +void Logo::render() +{ + + // Prepara para empezar a dibujar en la textura de juego + screen->start(); + + // Limpia la pantalla + screen->clean(); + + // Dibuja los objetos + sprite->render(); + + // Dibuja el fade + if (counter >= initFade) + { + const SDL_Rect rect = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT}; + const color_t color = {0xFF, 0xFF, 0xFF}; + const int fadeLenght = endLogo - initFade; + + int alpha = (255 * (counter - initFade)) / fadeLenght; + if (alpha < 256) + SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, alpha); + else + SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 255); + SDL_RenderFillRect(renderer, &rect); + } + + // Vuelca el contenido del renderizador en pantalla + screen->blit(); +} + +// Bucle para el logo del juego +section_t Logo::run() +{ + // Detiene la música + JA_StopMusic(); + + while (section.name == SECTION_PROG_LOGO) + { + update(); + render(); + } + + return section; +} diff --git a/source/logo.h b/source/logo.h new file mode 100644 index 0000000..cee7c7c --- /dev/null +++ b/source/logo.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include "const.h" +#include "utils.h" +#include "sprite.h" +#include "screen.h" +#include "asset.h" +#include "jail_audio.h" + +#ifndef LOGO_H +#define LOGO_H + +// Clase Logo +class Logo +{ +private: + SDL_Renderer *renderer; // El renderizador de la ventana + Screen *screen; // Objeto encargado de dibujar en pantalla + Asset *asset; // Objeto con los ficheros de recursos + LTexture *texture; // Textura con los graficos + SDL_Event *eventHandler; // Manejador de eventos + SDL_Texture *backbuffer; // Textura para usar como backbuffer + Sprite *sprite; // Sprite con la textura del logo + int counter; // Contador + section_t section; // Estado del bucle principal para saber si continua o se sale + int ticks; // Contador de ticks para ajustar la velocidad del programa + int ticksSpeed; // Velocidad a la que se repiten los bucles del programa + int initFade; // Tiempo del contador cuando inicia el fade a negro + int endLogo; // Tiempo del contador para terminar el logo + int postLogo; // Tiempo que dura el logo con el fade al maximo + + // Actualiza las variables + void update(); + + // Dibuja en pantalla + void render(); + +public: + // Constructor + Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset); + + // Destructor + ~Logo(); + + // Bucle principal + section_t run(); +}; + +#endif diff --git a/source/menu.cpp b/source/menu.cpp deleted file mode 100644 index aa64abe..0000000 --- a/source/menu.cpp +++ /dev/null @@ -1,896 +0,0 @@ - -#include "menu.h" - -// Constructor -Menu::Menu(SDL_Renderer *renderer, Asset *asset, Input *input, std::string file) -{ - this->renderer = renderer; - this->asset = asset; - this->input = input; - - soundMove = nullptr; - soundAccept = nullptr; - soundCancel = nullptr; - - init(); - if (file != "") - { - load(file); - } - reorganize(); -} - -Menu::~Menu() -{ - renderer = nullptr; - asset = nullptr; - input = nullptr; - - if (soundMove) - { - JA_DeleteSound(soundMove); - } - - if (soundAccept) - { - JA_DeleteSound(soundAccept); - } - - if (soundCancel) - { - JA_DeleteSound(soundCancel); - } - - if (text != nullptr) - { - delete text; - } -} - -// Carga la configuración del menu desde un archivo de texto -bool Menu::load(std::string file_path) -{ - // Indicador de éxito en la carga - bool success = true; - - // Indica si se ha creado ya el objeto de texto - bool textAllocated = false; - - std::string filename = file_path.substr(file_path.find_last_of("\\/") + 1); - std::string line; - std::ifstream file(file_path); - - // El fichero se puede abrir - if (file.good()) - { - // Procesa el fichero linea a linea - printf("Reading file %s\n", filename.c_str()); - while (std::getline(file, line)) - { - if (line == "[item]") - { - item_t item; - item.label = ""; - item.hPaddingDown = 1; - item.selectable = true; - item.greyed = false; - item.linkedDown = false; - - do - { - - std::getline(file, line); - - // Encuentra la posición del caracter '=' - int pos = line.find("="); - - // Procesa las dos subcadenas - if (!setItem(&item, line.substr(0, pos), line.substr(pos + 1, line.length()))) - { - printf("Warning: file %s\n, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str()); - success = false; - } - - } while (line != "[/item]"); - - addItem(item.label, item.hPaddingDown, item.selectable, item.greyed, item.linkedDown); - } - - // En caso contrario se parsea el fichero para buscar las variables y los valores - else - { - // Encuentra la posición del caracter '=' - int pos = line.find("="); - // Procesa las dos subcadenas - if (!setVars(line.substr(0, pos), line.substr(pos + 1, line.length()))) - { - printf("Warning: file %s, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str()); - success = false; - } - - // Crea el objeto text tan pronto como se pueda. Necesario para añadir items - if (font_png != "" && font_txt != "" && !textAllocated) - { - text = new Text(asset->get(font_png), asset->get(font_txt), renderer); - textAllocated = true; - } - } - } - - // Cierra el fichero - printf("Closing file %s\n\n", filename.c_str()); - file.close(); - } - // El fichero no se puede abrir - else - { - printf("Warning: Unable to open %s file\n", filename.c_str()); - success = false; - } - - return success; -} - -// Asigna variables a partir de dos cadenas -bool Menu::setItem(item_t *item, std::string var, std::string value) -{ - // Indicador de éxito en la asignación - bool success = true; - - if (var == "text") - { - item->label = value; - } - - else if (var == "hPaddingDown") - { - item->hPaddingDown = std::stoi(value); - } - - else if (var == "selectable") - { - item->selectable = value == "true" ? true : false; - } - - else if (var == "greyed") - { - item->greyed = value == "true" ? true : false; - } - - else if (var == "linkedDown") - { - item->linkedDown = value == "true" ? true : false; - } - - else if ((var == "") || (var == "[/item]")) - { - } - else - { - success = false; - } - - return success; -} - -// Asigna variables a partir de dos cadenas -bool Menu::setVars(std::string var, std::string value) -{ - // Indicador de éxito en la asignación - bool success = true; - - if (var == "font_png") - { - font_png = value; - } - - else if (var == "font_txt") - { - font_txt = value; - } - - else if (var == "sound_cancel") - { - soundCancel = JA_LoadSound(asset->get(value).c_str()); - } - - else if (var == "sound_accept") - { - soundAccept = JA_LoadSound(asset->get(value).c_str()); - } - - else if (var == "sound_move") - { - soundMove = JA_LoadSound(asset->get(value).c_str()); - } - - else if (var == "name") - { - name = value; - } - - else if (var == "x") - { - x = std::stoi(value); - } - - else if (var == "centerX") - { - centerX = std::stoi(value); - } - - else if (var == "centerY") - { - centerY = std::stoi(value); - } - - else if (var == "y") - { - y = std::stoi(value); - } - - else if (var == "backgroundType") - { - backgroundType = std::stoi(value); - } - - else if (var == "backgroundColor") - { - // Se introducen los valores separados por comas en un vector - std::stringstream ss(value); - std::string tmp; - getline(ss, tmp, ','); - rectBG.color.r = std::stoi(tmp); - getline(ss, tmp, ','); - rectBG.color.g = std::stoi(tmp); - getline(ss, tmp, ','); - rectBG.color.b = std::stoi(tmp); - getline(ss, tmp, ','); - rectBG.a = std::stoi(tmp); - } - - else if (var == "selector_color") - { - // Se introducen los valores separados por comas en un vector - std::stringstream ss(value); - std::string tmp; - getline(ss, tmp, ','); - selector.color.r = std::stoi(tmp); - getline(ss, tmp, ','); - selector.color.g = std::stoi(tmp); - getline(ss, tmp, ','); - selector.color.b = std::stoi(tmp); - getline(ss, tmp, ','); - selector.a = std::stoi(tmp); - } - - else if (var == "selector_text_color") - { - // Se introducen los valores separados por comas en un vector - std::stringstream ss(value); - std::string tmp; - getline(ss, tmp, ','); - selector.itemColor.r = std::stoi(tmp); - getline(ss, tmp, ','); - selector.itemColor.g = std::stoi(tmp); - getline(ss, tmp, ','); - selector.itemColor.b = std::stoi(tmp); - } - - else if (var == "areElementsCenteredOnX") - { - areElementsCenteredOnX = value == "true" ? true : false; - } - - else if (var == "isCenteredOnX") - { - isCenteredOnX = value == "true" ? true : false; - } - - else if (var == "isCenteredOnY") - { - isCenteredOnY = value == "true" ? true : false; - } - - else if (var == "defaultActionWhenCancel") - { - defaultActionWhenCancel = std::stoi(value); - } - - else if (var == "") - { - } - - else - { - success = false; - } - - return success; -} - -// Inicializa las variables -void Menu::init() -{ - // Inicia variables - name = ""; - selector.index = 0; - itemSelected = MENU_NO_OPTION; - x = 0; - y = 0; - rectBG.rect = {0, 0, 0, 0}; - rectBG.color = {0, 0, 0}; - rectBG.a = 0; - backgroundType = MENU_BACKGROUND_SOLID; - isCenteredOnX = false; - isCenteredOnY = false; - areElementsCenteredOnX = false; - centerX = 0; - centerY = 0; - widestItem = 0; - colorGreyed = {128, 128, 128}; - defaultActionWhenCancel = 0; - font_png = ""; - font_txt = ""; - - // Selector - selector.originY = 0; - selector.targetY = 0; - selector.despY = 0; - selector.originH = 0; - selector.targetH = 0; - selector.incH = 0; - selector.y = 0.0f; - selector.h = 0.0f; - selector.numJumps = 8; - selector.moving = false; - selector.resizing = false; - selector.rect = {0, 0, 0, 0}; - selector.color = {0, 0, 0}; - selector.itemColor = {0, 0, 0}; - selector.a = 255; -} - -// Carga los ficheros de audio -void Menu::loadAudioFile(std::string file, int sound) -{ - switch (sound) - { - case SOUND_ACCEPT: - soundAccept = JA_LoadSound(file.c_str()); - break; - - case SOUND_CANCEL: - soundCancel = JA_LoadSound(file.c_str()); - break; - - case SOUND_MOVE: - soundMove = JA_LoadSound(file.c_str()); - break; - - default: - break; - } -} - -// Obtiene el nombre del menu -std::string Menu::getName() -{ - return name; -} - -// Obtiene el valor de la variable -int Menu::getItemSelected() -{ - // Al llamar a esta funcion, se obtiene el valor y se borra - const int temp = itemSelected; - itemSelected = MENU_NO_OPTION; - return temp; -} - -// Actualiza la posicion y el estado del selector -void Menu::updateSelector() -{ - if (selector.moving) - { - // Calcula el desplazamiento en Y - selector.y += selector.despY; - if (selector.despY > 0) // Va hacia abajo - { - if (selector.y > selector.targetY) // Ha llegado al destino - { - selector.originY = selector.y = selector.targetY; - selector.moving = false; - } - } - if (selector.despY < 0) // Va hacia arriba - { - if (selector.y < selector.targetY) // Ha llegado al destino - { - selector.originY = selector.y = selector.targetY; - selector.moving = false; - } - } - selector.rect.y = int(selector.y); - } - else - { - selector.rect.y = int(selector.y); - } - - if (selector.resizing) - { - // Calcula el incremento en H - selector.h += selector.incH; - if (selector.incH > 0) // Crece - { - if (selector.h > selector.targetH) // Ha llegado al destino - { - // selector.originH = selector.targetH = selector.rect.h = getSelectorHeight(selector.index); - selector.originH = selector.h = selector.targetH; - selector.resizing = false; - } - } - if (selector.incH < 0) // Decrece - { - if (selector.h < selector.targetH) // Ha llegado al destino - { - // selector.originH = selector.targetH = selector.rect.h = getSelectorHeight(selector.index); - selector.originH = selector.h = selector.targetH; - selector.resizing = false; - } - } - selector.rect.h = int(selector.h); - } - else - { - selector.rect.h = getSelectorHeight(selector.index); - } -} - -// Coloca el selector en una posición específica -void Menu::setSelectorPos(int index) -{ - if (index < item.size()) - { - selector.index = index; - selector.rect.y = selector.y = selector.originY = selector.targetY = item[selector.index].rect.y; - selector.rect.w = rectBG.rect.w; - selector.rect.x = rectBG.rect.x; - selector.originH = selector.targetH = selector.rect.h = getSelectorHeight(selector.index); - selector.moving = false; - selector.resizing = false; - } -} - -// Obtiene la anchura del elemento más ancho del menu -int Menu::getWidestItem() -{ - int result = 0; - - // Obtenemos la anchura del item mas ancho - for (auto &i : item) - { - result = std::max(result, i.rect.w); - } - - return result; -} - -// Deja el menu apuntando al primer elemento -void Menu::reset() -{ - itemSelected = MENU_NO_OPTION; - selector.index = 0; - selector.originY = selector.targetY = selector.y = item[0].rect.y; - selector.originH = selector.targetH = item[0].rect.h; - selector.moving = false; - selector.resizing = false; -} - -// Actualiza el menu para recolocarlo correctamente y establecer el tamaño -void Menu::reorganize() -{ - setRectSize(); - - if (isCenteredOnX) - { - centerMenuOnX(centerX); - } - - if (isCenteredOnY) - { - centerMenuOnY(centerY); - } - - if (areElementsCenteredOnX) - { - centerMenuElementsOnX(); - } -} - -// Deja el menu apuntando al siguiente elemento -bool Menu::increaseSelectorIndex() -{ - // Obten las coordenadas del elemento actual - selector.y = selector.originY = item[selector.index].rect.y; - selector.h = selector.originH = getSelectorHeight(selector.index); - - // Calcula cual es el siguiente elemento - ++selector.index %= item.size(); - while (!item[selector.index].selectable) - { - ++selector.index %= item.size(); - } - - // Establece las coordenadas y altura de destino - selector.targetY = item[selector.index].rect.y; - selector.despY = (selector.targetY - selector.originY) / selector.numJumps; - - selector.targetH = getSelectorHeight(selector.index); - selector.incH = (selector.targetH - selector.originH) / selector.numJumps; - - selector.moving = true; - if (selector.incH != 0) - { - selector.resizing = true; - } - - return true; -} - -// Deja el menu apuntando al elemento anterior -bool Menu::decreaseSelectorIndex() -{ - // Obten las coordenadas del elemento actual - selector.y = selector.originY = item[selector.index].rect.y; - selector.h = selector.originH = getSelectorHeight(selector.index); - - // Calcula cual es el siguiente elemento - if (selector.index == 0) - { - selector.index = item.size(); - } - else - { - selector.index--; - } - - while (!item[selector.index].selectable) - { - if (selector.index == 0) - { - selector.index = item.size(); - } - else - { - selector.index--; - } - } - - // Establece las coordenadas y altura de destino - selector.targetY = item[selector.index].rect.y; - selector.despY = (selector.targetY - selector.originY) / selector.numJumps; - - selector.targetH = getSelectorHeight(selector.index); - selector.incH = (selector.targetH - selector.originH) / selector.numJumps; - - selector.moving = true; - if (selector.incH != 0) - { - selector.resizing = true; - } - - return true; -} - -// Actualiza la logica del menu -void Menu::update() -{ - checkInput(); - updateSelector(); -} - -// Pinta el menu en pantalla -void Menu::render() -{ - // Rendereritza el fondo del menu - if (backgroundType == MENU_BACKGROUND_SOLID) - { - SDL_SetRenderDrawColor(renderer, rectBG.color.r, rectBG.color.g, rectBG.color.b, rectBG.a); - SDL_RenderFillRect(renderer, &rectBG.rect); - } - - // Renderiza el rectangulo del selector - const SDL_Rect temp = {selector.rect.x, selector.rect.y - 1, selector.rect.w, selector.rect.h + 1}; - // temp.y--; - // temp.h++; - SDL_SetRenderDrawColor(renderer, selector.color.r, selector.color.g, selector.color.b, selector.a); - SDL_RenderFillRect(renderer, &temp); - - // Renderiza el borde del fondo - if (backgroundType == MENU_BACKGROUND_SOLID) - { - SDL_SetRenderDrawColor(renderer, rectBG.color.r, rectBG.color.g, rectBG.color.b, 255); - SDL_RenderDrawRect(renderer, &rectBG.rect); - } - - // Renderitza el texto - for (int i = 0; i < item.size(); i++) - { - if (i == selector.index) - { - const color_t color = {selector.itemColor.r, selector.itemColor.g, selector.itemColor.b}; - text->writeColored(item[i].rect.x, item[i].rect.y, item[i].label, color); - } - else if (item[i].selectable) - { - text->write(item[i].rect.x, item[i].rect.y, item[i].label); - } - else if (item[i].greyed) - { - text->writeColored(item[i].rect.x, item[i].rect.y, item[i].label, colorGreyed); - } - else - // No seleccionable - { - if ((item[i].linkedUp) && (i == selector.index + 1)) - { - const color_t color = {selector.itemColor.r, selector.itemColor.g, selector.itemColor.b}; - text->writeColored(item[i].rect.x, item[i].rect.y, item[i].label, color); - } - else // No enlazado con el de arriba - { - text->write(item[i].rect.x, item[i].rect.y, item[i].label); - } - } - } -} - -// Establece el rectangulo de fondo del menu y el selector -void Menu::setRectSize() -{ - rectBG.rect.w = findWidth() + text->getCharacterWidth(); - rectBG.rect.h = findHeight() + text->getCharacterWidth(); - - // La posición X es la del menú menos medio caracter - rectBG.rect.x = x - (text->getCharacterWidth() / 2); - - // La posición Y es la del menu menos la altura de medio caracter - rectBG.rect.y = y - (text->getCharacterWidth() / 2); - - // Establecemos los valores del rectangulo del selector a partir de los valores del rectangulo de fondo - setSelectorPos(selector.index); -} - -// Establece el color del rectangulo de fondo -void Menu::setBackgroundColor(color_t color, int alpha) -{ - rectBG.color = color; - rectBG.a = alpha; -} - -// Establece el color del rectangulo del selector -void Menu::setSelectorColor(color_t color, int alpha) -{ - selector.color = color; - selector.a = alpha; -} - -// Establece el color del texto del selector -void Menu::setSelectorTextColor(color_t color) -{ - selector.itemColor = color; -} - -// Centra el menu respecto un punto en el eje X -void Menu::centerMenuOnX(int value) -{ - isCenteredOnX = true; - centerX = value; - - // Establece la nueva posición centrada en funcion del elemento más ancho - x = (value) - (findWidth() / 2); - - // Reposiciona los elementos del menu - for (auto &i : item) - { - i.rect.x = x; - } - - // Recalcula el rectangulo de fondo - setRectSize(); -} - -// Centra el menu respecto un punto en el eje Y -void Menu::centerMenuOnY(int value) -{ - isCenteredOnY = true; - centerY = value; - - // Establece la nueva posición centrada en funcion del elemento más ancho - y = (value) - (findHeight() / 2); - - // Reposiciona los elementos del menu - replaceElementsOnY(); - - // Recalcula el rectangulo de fondo - setRectSize(); -} - -// Centra los elementos del menu en el eje X -void Menu::centerMenuElementsOnX() -{ - areElementsCenteredOnX = true; - - for (auto &i : item) - { - i.rect.x = (centerX - (i.rect.w / 2)); - } -} - -// Añade un item al menu -void Menu::addItem(std::string text, int hPaddingDown, bool selectable, bool greyed, bool linkedDown) -{ - item_t temp; - // Si es el primer item coge la posición en el eje Y del propio menu - if (item.size() == 0) - { - temp.rect.y = y; - } - else - // En caso contrario, coge la posición en el eje Y a partir del elemento anterior - { - temp.rect.y = item.back().rect.y + item.back().rect.h + item.back().hPaddingDown; - } - - temp.rect.x = x; - temp.hPaddingDown = hPaddingDown; - temp.selectable = selectable; - temp.greyed = greyed; - temp.linkedDown = linkedDown; - - item.push_back(temp); - setItemCaption(item.size() - 1, text); - - if (item.size() > 0) - { - if (item[item.size() - 1].linkedDown) - { - item[item.size()].linkedUp = true; - } - } - - centerX = x + (findWidth() / 2); - reorganize(); -} - -// Cambia el texto de un item -void Menu::setItemCaption(int index, std::string text) -{ - item[index].label = text; - item[index].rect.w = this->text->lenght(item[index].label); - item[index].rect.h = this->text->getCharacterWidth(); - reorganize(); - - const std::string texto = item[index].label + ":" + std::to_string(item[index].rect.w); - printf("Adding menu item -> %s\n", texto.c_str()); -} - -// Establece el indice del itemm que se usará por defecto al cancelar el menu -void Menu::setDefaultActionWhenCancel(int item) -{ - defaultActionWhenCancel = item; -} - -// Gestiona la entrada de teclado y mando durante el menu -void Menu::checkInput() -{ - if (input->checkInput(INPUT_UP, REPEAT_FALSE)) - { - if (decreaseSelectorIndex()) - { - if (soundMove) - { - JA_PlaySound(soundMove); - } - } - } - - if (input->checkInput(INPUT_DOWN, REPEAT_FALSE)) - { - if (increaseSelectorIndex()) - { - if (soundMove) - { - JA_PlaySound(soundMove); - } - } - } - - if (input->checkInput(INPUT_ACCEPT, REPEAT_FALSE)) - { - itemSelected = selector.index; - if (soundAccept) - { - JA_PlaySound(soundAccept); - } - } - - if (input->checkInput(INPUT_CANCEL, REPEAT_FALSE)) - { - itemSelected = defaultActionWhenCancel; - if (soundCancel) - { - JA_PlaySound(soundCancel); - } - } -} - -// Calcula el ancho del menu -int Menu::findWidth() -{ - return getWidestItem(); -} - -// Calcula el alto del menu -int Menu::findHeight() -{ - int height = 0; - - // Obtenemos la altura de la suma de alturas de los items - for (auto &i : item) - { - height += i.rect.h + i.hPaddingDown; - } - - return height - item.back().hPaddingDown; -} - -// Recoloca los elementos del menu en el eje Y -void Menu::replaceElementsOnY() -{ - item[0].rect.y = y; - - for (int i = 1; i < item.size(); i++) - { - item[i].rect.y = item[i - 1].rect.y + item[i - 1].rect.h + item[i - 1].hPaddingDown; - } -} - -// Establece el estado seleccionable de un item -void Menu::setSelectable(int index, bool value) -{ - item[index].selectable = value; -} - -// Establece el estado agrisado de un item -void Menu::setGreyed(int index, bool value) -{ - item[index].greyed = value; -} - -// Establece el estado de enlace de un item -void Menu::setLinkedDown(int index, bool value) -{ - item[index].linkedDown = value; -} - -// Calcula la altura del selector -int Menu::getSelectorHeight(int value) -{ - if (item[value].linkedDown) - { - return item[value].rect.h + item[value].hPaddingDown + item[value + 1].rect.h; - } - else - { - return item[value].rect.h; - } -} - -// Recarga la textura -void Menu::reLoadTexture() -{ - text->reLoadTexture(); -} \ No newline at end of file diff --git a/source/menu.h b/source/menu.h deleted file mode 100644 index bcbf130..0000000 --- a/source/menu.h +++ /dev/null @@ -1,217 +0,0 @@ -#pragma once - -#include -#include -#include "sprite.h" -#include "text.h" -#include "asset.h" -#include "input.h" -#include "utils.h" -#include "jail_audio.h" -#include -#include - -#ifndef MENU_H -#define MENU_H - -// Tipos de fondos para el menu -#define MENU_BACKGROUND_TRANSPARENT 0 -#define MENU_BACKGROUND_SOLID 1 - -// Tipos de archivos de audio -#define SOUND_ACCEPT 0 -#define SOUND_MOVE 1 -#define SOUND_CANCEL 2 - -// Opciones de menu -#define MENU_NO_OPTION -1 - -// Clase Menu -class Menu -{ -private: - struct rectangle_t - { - SDL_Rect rect; // Rectangulo - color_t color; // Color - int a; // Transparencia - }; - - struct item_t - { - std::string label; // Texto - SDL_Rect rect; // Rectangulo que delimita el elemento - int hPaddingDown; // Espaciado bajo el elemento - bool selectable; // Indica si se puede seleccionar - bool greyed; // Indica si ha de aparecer con otro color mas oscuro - bool linkedDown; // Indica si el elemento actual y el siguiente se tratan como uno solo. Afecta al selector - bool linkedUp; // Indica si el elemento actual y el anterior se tratan como uno solo. Afecta al selector - }; - - struct selector_t - { - float originY; // Coordenada de origen - float targetY; // Coordenada de destino - float despY; // Cantidad de pixeles que se desplaza el selector en cada salto: (target - origin) / numJumps - bool moving; // Indica si el selector está avanzando hacia el destino - float originH; // Altura de origen - float targetH; // Altura de destino - float incH; // Cantidad de pixels que debe incrementar o decrementar el selector en cada salto - bool resizing; // Indica si el selector está cambiando de tamaño - float y; // Coordenada actual, usado para el desplazamiento - float h; // Altura actual, usado para el cambio de tamaño - int numJumps; // Numero de pasos preestablecido para llegar al destino - int index; // Elemento del menu que tiene el foco - SDL_Rect rect; // Rectangulo del selector - color_t color; // Color del selector - color_t itemColor; // Color del item - int a; // Cantidad de transparencia para el rectangulo del selector - }; - - std::string name; // Nombre del menu - int x; // Posición en el eje X de la primera letra del primer elemento - int y; // Posición en el eje Y de la primera letra del primer elemento - int h; // Altura del menu - int w; // Anchura del menu - int itemSelected; // Índice del item del menu que ha sido seleccionado - int defaultActionWhenCancel; // Indice del item del menu que se selecciona cuando se cancela el menu - int backgroundType; // Tipo de fondo para el menu - int centerX; // Centro del menu en el eje X - int centerY; // Centro del menu en el eje Y - bool isCenteredOnX; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje X - bool isCenteredOnY; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje Y - bool areElementsCenteredOnX; // Variable para saber si los elementos van centrados en el eje X - int widestItem; // Anchura del elemento más ancho - JA_Sound soundAccept; // Sonido al aceptar o elegir una opción del menu - JA_Sound soundCancel; // Sonido al cancelar el menu - JA_Sound soundMove; // Sonido al mover el selector - SDL_Renderer *renderer; // Puntero al renderizador de la ventana - Text *text; // Texto para poder escribir los items del menu - Input *input; // Gestor de eventos de entrada de teclado o gamepad - Asset *asset; // Objeto para gestionar los ficheros de recursos - color_t colorGreyed; // Color para los elementos agrisados - rectangle_t rectBG; // Rectangulo de fondo del menu - std::vector item; // Estructura para cada elemento del menu - selector_t selector; // Variables para pintar el selector del menu - std::string font_png; - std::string font_txt; - - // Carga la configuración del menu desde un archivo de texto - bool load(std::string file_path); - - // Asigna variables a partir de dos cadenas - bool setVars(std::string var, std::string value); - - // Asigna variables a partir de dos cadenas - bool setItem(item_t *item, std::string var, std::string value); - - // Inicializa las variables - void init(); - - // Establece el rectangulo de fondo del menu - void setRectSize(); - - // Actualiza el menu para recolocarlo correctamente y establecer el tamaño - void reorganize(); - - // Deja el menu apuntando al siguiente elemento - bool increaseSelectorIndex(); - - // Deja el menu apuntando al elemento anterior - bool decreaseSelectorIndex(); - - // Actualiza la posicion y el estado del selector - void updateSelector(); - - // Obtiene la anchura del elemento más ancho del menu - int getWidestItem(); - - // Gestiona la entrada de teclado y mando durante el menu - void checkMenuInput(Menu *menu); - - // Calcula el ancho del menu - int findWidth(); - - // Calcula el alto del menu - int findHeight(); - - // Recoloca los elementos del menu en el eje Y - void replaceElementsOnY(); - - // Calcula la altura del selector - int getSelectorHeight(int value); - -public: - // Constructor - Menu(SDL_Renderer *renderer, Asset *asset, Input *input, std::string file = ""); - - // Destructor - ~Menu(); - - // Carga los ficheros de audio - void loadAudioFile(std::string file, int sound); - - // Obtiene el nombre del menu - std::string getName(); - - // Obtiene el valor de la variable - int getItemSelected(); - - // Deja el menu apuntando al primer elemento - void reset(); - - // Gestiona la entrada de teclado y mando durante el menu - void checkInput(); - - // Actualiza la logica del menu - void update(); - - // Pinta el menu en pantalla - void render(); - - // Establece el color del rectangulo de fondo - void setBackgroundColor(color_t color, int alpha); - - // Establece el color del rectangulo del selector - void setSelectorColor(color_t color, int alpha); - - // Establece el color del texto del selector - void setSelectorTextColor(color_t color); - - // Centra el menu respecto a un punto en el eje X - void centerMenuOnX(int value); - - // Centra el menu respecto a un punto en el eje Y - void centerMenuOnY(int value); - - // Centra los elementos del menu en el eje X - void centerMenuElementsOnX(); - - // Añade un item al menu - void addItem(std::string text, int hPaddingDown = 1, bool selectable = true, bool greyed = false, bool linkedDown = false); - - // Cambia el texto de un item - void setItemCaption(int index, std::string text); - - // Establece el indice del item que se usará por defecto al cancelar el menu - void setDefaultActionWhenCancel(int item); - - // Coloca el selector en una posición específica - void setSelectorPos(int index); - - // Establece el estado seleccionable de un item - void setSelectable(int index, bool value); - - // Establece el estado agrisado de un item - void setGreyed(int index, bool value); - - // Establece el estado de enlace de un item - void setLinkedDown(int index, bool value); - - // Recarga la textura - void reLoadTexture(); - - // hacer procedimientos para establecer el titulo, la x, la y, la tipografia y el tipo de fondo -}; - -#endif diff --git a/todo.txt b/todo.txt index 590e93f..3827747 100644 --- a/todo.txt +++ b/todo.txt @@ -7,6 +7,7 @@ x (A) Colisiones con los enemigos {cm:2022-08-29} x (A) Decidir un diseño para qué sucede en caso de morir: Recordar el punto por donde se entró al mapa y la velocidad en el eje X/Y que llevaba el personaje, crear puntos de reaparicion en las habitaciones, etc {cm:2022-08-29} x En el Jet Set Willy el juego recuerda la posicion y el momento. En las Tres Luces de Glaurung solo la posición. Se va a optar por seguir el diseño del Jet Set Willy {cm:2022-08-29} x (A) Crear tiles que maten {cm:2022-08-29} +(A) Modificar el salto para que coincida con el del JSW, no ha de colisionar lateralmente (A) Crear tiles que deslicen, (no tipo hielo sino cinta) (A) Tiles animados @@ -14,6 +15,7 @@ x (A) Crear tiles que maten {cm:2022-08-29} x (A) Enemigos de diferente tamaño {cm:2022-08-30} (A) Color de los items al estilo jet set willy de amstrad, que brillan con dos colores x (A) Temporizador de inicio de los items, para poder hacer que brillen a distinto ritmo. Esto es incompatible con lo anterior {cm:2022-08-30} +(A) Crear efecto de fade estilo spectrum, cambiando el color de las cosas a rojo, morado, azul, negro x (A) Poner la info de debug con la tipografia adecuada {cm:2022-08-30} x (A) El modo debug debe pintar la rejilla {cm:2022-08-30} @@ -24,6 +26,14 @@ x (A) Tecla + y - para cambiar tamaño de ventana. O control F1 a F4 {cm:2022-08 (A) Añadir a cada habitación el color del borde (A) Añadir a cada habitación el color del nombre de la habitación +(A) Crear el logo al estilo del logo de ERBE o TOPO, con lineas que lo formen +(A) El titulo del juego hacerlo parecido al del Jet Set Willy in Paris + - Ha de generarse como las cargas de pantalla de spectrum + - Luego se colorea + - Finalmente, cada elemento cambia de color como si fueran luces de neon +(A) En el titulo del juego, por la parte inferior ha de aparecer una marquesina con texto, al estilo demoscene +(A) La pantalla de titulo no tiene menu, solo un PRESS ENTER TO PLAY + ## TEMAS arounders