From d5a069b8db354f1d129f233c1b86cdcd6f0a173c Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 28 Aug 2022 19:59:03 +0200 Subject: [PATCH] Trabajando en la carga de menus desde fichero --- data/map/05.tmx | 5 +- data/menu/title.men | 35 ++++++ source/map.cpp | 3 + source/menu.cpp | 285 ++++++++++++++++++++++++++++++++++++++++++-- source/menu.h | 25 +++- source/prog.cpp | 5 +- source/text.cpp | 13 +- source/title.cpp | 30 +---- source/title.h | 4 - 9 files changed, 352 insertions(+), 53 deletions(-) create mode 100644 data/menu/title.men diff --git a/data/map/05.tmx b/data/map/05.tmx index 59838ba..9bd8cc8 100644 --- a/data/map/05.tmx +++ b/data/map/05.tmx @@ -1,5 +1,8 @@ - + + + + diff --git a/data/menu/title.men b/data/menu/title.men new file mode 100644 index 0000000..a9a7586 --- /dev/null +++ b/data/menu/title.men @@ -0,0 +1,35 @@ +font_png=dogica.png +font_txt=dogica.txt + +sound_cancel=sound_menu_cancel.wav +sound_accept=sound_menu_select.wav +sound_move=sound_menu_move.wav + +name=TITLE +x=0 +y=150 +backgroundType=0 +backgroundColor=48,48,64,192 + +areElementsCenteredOnX=true +isCenteredOnX=true +isCenteredOnY=false + +selector_color=229,28,35,0 +selector_text_color=255,180,0 + +defaultActionWhenCancel=2 + +[item] +text=START +hPaddingDown=2 +[/item] + +[item] +text=OPTIONS +hPaddingDown=5 +[/item] + +[item] +text=EXIT +[/item] \ No newline at end of file diff --git a/source/map.cpp b/source/map.cpp index 8da8c8a..4d35e07 100644 --- a/source/map.cpp +++ b/source/map.cpp @@ -365,6 +365,9 @@ void Map::fillMapTexture() for (int y = 0; y < map_height; y++) for (int x = 0; x < map_width; x++) { + // Resta uno porque Tiled almacena los indices empezando de 1 en vez de 0. + // El problema es que los tiles vacios los pone como 0 y aqui pasan a ser -1 + // con lo que esta pintando desde fuera de la textura clip.x = ((tilemap[(y * map_width) + x] - 1) % tileset_width) * tile_size; clip.y = ((tilemap[(y * map_width) + x] - 1) / tileset_width) * tile_size; texture_tile->render(renderer, x * tile_size, y * tile_size, &clip); diff --git a/source/menu.cpp b/source/menu.cpp index 4deb7cb..029583e 100644 --- a/source/menu.cpp +++ b/source/menu.cpp @@ -2,21 +2,28 @@ #include "menu.h" // Constructor -Menu::Menu(SDL_Renderer *renderer, Text *text, Input *input) +Menu::Menu(SDL_Renderer *renderer, Asset *asset, Input *input, std::string file) { this->renderer = renderer; - this->text = text; + this->asset = asset; this->input = input; soundMove = nullptr; soundAccept = nullptr; soundCancel = nullptr; + + init(); + if (file != "") + { + load(file); + } + reorganize(); } Menu::~Menu() { renderer = nullptr; - text = nullptr; + asset = nullptr; input = nullptr; if (soundMove) @@ -33,21 +40,278 @@ Menu::~Menu() { JA_DeleteSound(soundCancel); } + + if (text != nullptr) + { + delete text; + } } -// Inicializador -void Menu::init(std::string name, int x, int y, int backgroundType) +// 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 == "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 - this->name = name; + name = ""; selector.index = 0; itemSelected = MENU_NO_OPTION; - this->x = x; - this->y = y; + x = 0; + y = 0; rectBG.rect = {0, 0, 0, 0}; rectBG.color = {0, 0, 0}; rectBG.a = 0; - this->backgroundType = backgroundType; + backgroundType = MENU_BACKGROUND_SOLID; isCenteredOnX = false; isCenteredOnY = false; areElementsCenteredOnX = false; @@ -55,6 +319,9 @@ void Menu::init(std::string name, int x, int y, int backgroundType) centerY = 0; widestItem = 0; colorGreyed = {128, 128, 128}; + defaultActionWhenCancel = 0; + font_png = ""; + font_txt = ""; // Selector selector.originY = 0; diff --git a/source/menu.h b/source/menu.h index c0731e6..09a001c 100644 --- a/source/menu.h +++ b/source/menu.h @@ -4,9 +4,12 @@ #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 @@ -85,10 +88,25 @@ private: 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(); @@ -125,14 +143,11 @@ private: public: // Constructor - Menu(SDL_Renderer *renderer, Text *text, Input *input); + Menu(SDL_Renderer *renderer, Asset *asset, Input *input, std::string file=""); // Destructor ~Menu(); - // Inicializador - void init(std::string name, int x, int y, int backgroundType); - // Carga los ficheros de audio void loadAudioFile(std::string file, int sound); @@ -192,6 +207,8 @@ public: // Establece el estado de enlace de un item void setLinkedDown(int index, bool value); + + // hacer procedimientos para establecer el titulo, la x, la y, la tipografia y el tipo de fondo }; #endif diff --git a/source/prog.cpp b/source/prog.cpp index d256555..8f16a8a 100644 --- a/source/prog.cpp +++ b/source/prog.cpp @@ -26,7 +26,7 @@ Prog::Prog(std::string executablePath) } else { - section.name = SECTION_PROG_GAME; + section.name = SECTION_PROG_TITLE; } input = new Input(asset->get("gamecontrollerdb.txt")); screen = new Screen(window, renderer, options); @@ -217,6 +217,9 @@ bool Prog::setFileList() asset->add("/data/intro/intro.png", bitmap); asset->add("/data/intro/intro.ani", data); + // Ficheros de menu + asset->add("/data/menu/title.men", data); + return asset->check(); } diff --git a/source/text.cpp b/source/text.cpp index aa975c8..57695d8 100644 --- a/source/text.cpp +++ b/source/text.cpp @@ -9,8 +9,7 @@ Text::Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer) texture = new LTexture(); loadTextureFromFile(texture, bitmapFile, renderer); - SDL_Rect rect = {0,0,0,0}; - mSprite = new Sprite(rect, texture, renderer); + mSprite = new Sprite({0, 0, 0, 0}, texture, renderer); mSprite->setTexture(texture); mSprite->setRenderer(renderer); file = textFile; @@ -57,9 +56,9 @@ void Text::init() offset[i].y = ((i - 32) / 15) * boxHeight; } - //printf("Cargando %s\n", file.c_str()); - //const std::string texto = "w = "+ std::to_string(boxWidth) + ", h = " + std::to_string(boxHeight); - //printf("%s\n",texto.c_str()); + // printf("Cargando %s\n", file.c_str()); + // const std::string texto = "w = "+ std::to_string(boxWidth) + ", h = " + std::to_string(boxHeight); + // printf("%s\n",texto.c_str()); } // Escribe texto en pantalla @@ -124,7 +123,7 @@ void Text::writeDX(Uint8 flags, int x, int y, std::string text, int kerning, col writeColored(x - shadowDistance, y + shadowDistance, text, shadowColor, kerning, lenght); writeColored(x + shadowDistance, y - shadowDistance, text, shadowColor, kerning, lenght); writeColored(x - shadowDistance, y - shadowDistance, text, shadowColor, kerning, lenght); - + writeColored(x, y + shadowDistance, text, shadowColor, kerning, lenght); writeColored(x, y - shadowDistance, text, shadowColor, kerning, lenght); writeColored(x + shadowDistance, y, text, shadowColor, kerning, lenght); @@ -174,7 +173,7 @@ void Text::initOffsetFromFile() // Almacena solo las lineas impares if (line_read % 2 == 1) offset[index++].w = std::stoi(buffer); - + // Limpia el buffer buffer.clear(); line_read++; diff --git a/source/title.cpp b/source/title.cpp index 6e70a57..bd8961f 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -15,11 +15,9 @@ Title::Title(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input) loadTextureFromFile(texture, asset->get("intro.png"), renderer); sprite = new AnimatedSprite(texture, renderer, asset->get("intro.ani")); sprite->setCurrentAnimation("menu"); - text = new Text(asset->get("dogica.png"), asset->get("dogica.txt"), renderer); - text2 = new Text(asset->get("debug.png"), asset->get("debug.txt"), renderer); + text = new Text(asset->get("debug.png"), asset->get("debug.txt"), renderer); music = JA_LoadMusic(asset->get("music_title.ogg").c_str()); - menu = new Menu(renderer, text, input); - initMenu(); + menu = new Menu(renderer, asset, input, asset->get("title.men")); // Inicializa variables section = {SECTION_PROG_TITLE, 0}; @@ -47,34 +45,12 @@ Title::~Title() delete text; text = nullptr; - delete text2; - text2 = nullptr; - delete menu; menu = nullptr; JA_DeleteMusic(music); } -// Crea el menu -void Title::initMenu() -{ - menu->loadAudioFile(asset->get("sound_menu_cancel.wav"), SOUND_CANCEL); - menu->loadAudioFile(asset->get("sound_menu_select.wav"), SOUND_ACCEPT); - menu->loadAudioFile(asset->get("sound_menu_move.wav"), SOUND_MOVE); - - menu->init("TITLE", 0, 150, MENU_BACKGROUND_TRANSPARENT); - menu->addItem("START", 2); - menu->addItem("OPTIONS", 5); - menu->addItem("EXIT"); - menu->setDefaultActionWhenCancel(2); - menu->setBackgroundColor({0x30, 0x30, 0x40}, 192); - menu->setSelectorColor({0xe5, 0x1c, 0x23}, 0); - menu->setSelectorTextColor({0xFF, 0xB4, 0x00}); - menu->centerMenuOnX(160); - menu->centerMenuElementsOnX(); -} - // Actualiza las variables void Title::update() { @@ -118,7 +94,7 @@ void Title::render() // Dibuja los objetos sprite->render(); - text2->writeDX(TXT_CENTER | TXT_COLOR, 160, 205, "@2016,2022 JAILDESIGNER & JAILBROTHER (v0.4)", 0, {255, 93, 4}); + text->writeDX(TXT_CENTER | TXT_COLOR, 160, 205, "@2016,2022 JAILDESIGNER & JAILBROTHER (v0.4)", 0, {255, 93, 4}); menu->render(); // Vuelca el contenido del renderizador en pantalla diff --git a/source/title.h b/source/title.h index 7af44ca..d9cccc9 100644 --- a/source/title.h +++ b/source/title.h @@ -25,7 +25,6 @@ private: Asset *asset; // Objeto con los ficheros de recurso Input *input; // Objeto para gestionar las entradas Text *text; // Objeto para escribir texto en pantalla - Text *text2; // Objeto para escribir texto en pantalla Menu *menu; // Objeto para gestionar el menu del titulo AnimatedSprite *sprite; // Sprite para dibujar los graficos de la intro JA_Music music; // Musica del titulo del juego @@ -39,9 +38,6 @@ private: // Dibuja en pantalla void render(); - // Crea el menu - void initMenu(); - // Comprueba el menu void checkMenu();