From b65c425c841382d0f5c9108f53b9af820ef665c3 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Mon, 4 Jul 2022 18:01:21 +0200 Subject: [PATCH] ERROR: no pinta los enemigos --- data/enemies/01.enemy | 10 +++ data/room/01.room | 26 +++++++- source/director.cpp | 1 + source/enemy.cpp | 57 +++++++++++++++- source/enemy.h | 53 ++++++++++++++- source/game.cpp | 5 +- source/room.cpp | 148 +++++++++++++++++++++++++++++++----------- source/room.h | 39 ++++++----- source/utils.cpp | 105 +++++++++++++++++++++++++----- source/utils.h | 3 + 10 files changed, 367 insertions(+), 80 deletions(-) create mode 100644 data/enemies/01.enemy diff --git a/data/enemies/01.enemy b/data/enemies/01.enemy new file mode 100644 index 0000000..9a7fc44 --- /dev/null +++ b/data/enemies/01.enemy @@ -0,0 +1,10 @@ +tileset=enemy01.png +x=8 +y=8 +vx=0.1 +vy=0 +x1=8 +x2=200 +y1=8 +y2=8 +color=red \ No newline at end of file diff --git a/data/room/01.room b/data/room/01.room index 9ea9721..54b9fbe 100644 --- a/data/room/01.room +++ b/data/room/01.room @@ -7,6 +7,28 @@ room_down=0 room_left=0 room_right=02.room tilemap=41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,81,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,41,41,41,41,41,41,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,41,41,41,41,41,41,41,41,41,41,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,0,0,0,0,0,0,0,0,0,41,0,0,0,0,0,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41 -enemy=1,0,0,0,1 -enemy=2,10,0,0,1 +[enemy] +tileset=enemy01.png +x=8 +y=8 +vx=0.1 +vy=0 +x1=8 +x2=200 +y1=8 +y2=8 +color=red +[enemy-end] +[enemy] +tileset=enemy01.png +x=20 +y=40 +vx=0.1 +vy=0 +x1=8 +x2=200 +y1=40 +y2=40 +color=yellow +[enemy-end] item=1,10,10 \ No newline at end of file diff --git a/source/director.cpp b/source/director.cpp index 106564c..8b8357c 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -199,6 +199,7 @@ void Director::setFileList() mAsset->add("/data/room/01.room", room); mAsset->add("/data/room/02.room", room); mAsset->add("/media/tilesets/room1.png", bitmap); + mAsset->add("/media/enemies/enemy01.png", bitmap); } // Carga el fichero de configuración diff --git a/source/enemy.cpp b/source/enemy.cpp index 30550d9..7b3773b 100644 --- a/source/enemy.cpp +++ b/source/enemy.cpp @@ -1,11 +1,66 @@ #include "enemy.h" +#include +#include // Constructor -Enemy::Enemy() +Enemy::Enemy(enemy_t enemy) { + // Obten punteros a objetos + asset = enemy.asset; + renderer = enemy.renderer; + + // Crea objetos + texture = new LTexture(); + sprite = new AnimatedSprite(); + + // Carga la textura + loadTextureFromFile(texture, asset->get(enemy.tileset), renderer); + + // Obten el resto de valores + x1 = enemy.x1; + x2 = enemy.x2; + y1 = enemy.y1; + y2 = enemy.y2; + color = enemy.color; + sprite->setPosX(enemy.x); + sprite->setPosY(enemy.y); + sprite->setVelX(enemy.vx); + sprite->setVelY(enemy.vy); + + // Inicializa el sprite con el resto de parametros comunes + sprite->setWidth(16); + sprite->setHeight(16); + sprite->setCurrentFrame(0); + sprite->setAnimationCounter(0); + sprite->setAnimationNumFrames(0, 4); + sprite->setAnimationSpeed(0, 10); + sprite->setAnimationLoop(0, true); + sprite->setAnimationFrames(0, 0, 16 * 0, 0, 16, 16); + sprite->setAnimationFrames(0, 1, 16 * 1, 0, 16, 16); + sprite->setAnimationFrames(0, 2, 16 * 2, 0, 16, 16); + sprite->setAnimationFrames(0, 3, 16 * 3, 0, 16, 16); + sprite->setSpriteClip(sprite->getAnimationClip(0, 0)); } // Destructor Enemy::~Enemy() { + texture->unload(); + delete texture; + texture = nullptr; + + delete sprite; + sprite = nullptr; } + +// Pinta el enemigo en pantalla +void Enemy::draw() +{ + sprite->render(); +} + +// Actualiza las variables del objeto +void Enemy::update() +{ + sprite->update(); +} \ No newline at end of file diff --git a/source/enemy.h b/source/enemy.h index 78b7633..f23c37c 100644 --- a/source/enemy.h +++ b/source/enemy.h @@ -1,21 +1,72 @@ #pragma once #include "ifdefs.h" +#include "utils.h" +#include "asset.h" +#include "animatedsprite.h" #include #ifndef ENEMY_H #define ENEMY_H +/* +Un enemigo deberia tener la siguiente informacion: +POSICION INICIAL +VELOCIDAD EN X +VELOCIDAD EN Y +PUNTO X1 Y PUNTO X2 DEL RECORRIDO +PUNTO Y1 Y PUNTO Y2 DEL RECORRIDO +COLOR +PNG ASOCIADO +FICHERO descriptor del enemigo + +Por convención, todos los enemigos dispondran de 4 frames de animacion +Se invertirá el sprite en funcion de la velocidad de X +*/ + +// Estructura para pasar los datos de un enemigo +struct enemy_t +{ + SDL_Renderer *renderer; // El renderizador de la ventana + Asset *asset; // Objeto con la ruta a todos los ficheros de recursos + std::string tileset; // Fichero con los graficos del enemigo + float x; // Posición inicial en el eje X + float y; // Posición inicial en el eje Y + float vx; // Velocidad en el eje X + float vy; // Velocidad en el eje Y + int x1; // Limite izquierdo de la ruta en el eje X + int x2; // Limite derecho de la ruta en el eje X + int y1; // Limite superior de la ruta en el eje Y + int y2; // Limite inferior de la ruta en el eje Y + color_t color; // Color del enemigo +}; + // Clase Enemy class Enemy { private: + LTexture *texture; // Textura con los graficos del enemigo + AnimatedSprite *sprite; // Sprite del enemigo + + SDL_Renderer *renderer; // El renderizador de la ventana + Asset *asset; // Objeto con la ruta a todos los ficheros de recursos + color_t color; // Color del enemigo + int x1; // Limite izquierdo de la ruta en el eje X + int x2; // Limite derecho de la ruta en el eje X + int y1; // Limite superior de la ruta en el eje Y + int y2; // Limite inferior de la ruta en el eje Y public: // Constructor - Enemy(); + Enemy(enemy_t enemy); // Destructor ~Enemy(); + + // Pinta el enemigo en pantalla + void draw(); + + // Actualiza las variables del objeto + void update(); }; #endif diff --git a/source/game.cpp b/source/game.cpp index 4cd5fee..ad6769d 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -120,10 +120,7 @@ void Game::draw() mScreen->clean(mRoom->getBGColor()); mRoom->drawMap(); - - // Escribe las medidas de ancho y alto de la pantalla - // mText->writeCentered(GAMECANVAS_CENTER_X, 0, std::to_string(GAMECANVAS_WIDTH), -1); - // mText->write(0, GAMECANVAS_CENTER_Y - (mText->getCharacterWidth() / 2), std::to_string(GAMECANVAS_HEIGHT), -1); + mRoom->drawEnemies(); // Texto en el centro de la pantalla mText->writeCentered(GAMECANVAS_CENTER_X, 18 * 8, mRoom->getName()); diff --git a/source/room.cpp b/source/room.cpp index e3f94fd..7962aa0 100644 --- a/source/room.cpp +++ b/source/room.cpp @@ -24,15 +24,22 @@ Room::Room(std::string _file_path, SDL_Renderer *_renderer, Asset *_asset) // Destructor Room::~Room() { + // Reclama la memoria utilizada por los objetos texture->unload(); delete texture; texture = nullptr; SDL_DestroyTexture(map_texture); map_texture = nullptr; + + for (auto enemy : enemy_list) + { + delete enemy; + } + enemy_list.clear(); } -// Carga una habitación desde un fichero +// Carga las variables desde un fichero bool Room::load(std::string _file_path) { // Indicador de éxito en la carga @@ -45,15 +52,45 @@ bool Room::load(std::string _file_path) // El fichero se puede abrir if (file.good()) { - // Carga los datos + // Procesa el fichero linea a linea printf("Reading file %s\n", filename.c_str()); while (std::getline(file, line)) { - int pos = line.find("="); - if (!setVars(line.substr(0, pos), line.substr(pos + 1, line.length()))) + // Si la linea contiene el texto [enemy] se realiza un proceso distinto + if (line == "[enemy]") { - printf("Warning: file %s, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str()); - success = false; + enemy_t enemy; + enemy.asset = asset; + enemy.renderer = renderer; + + do + { + std::getline(file, line); + + // Encuentra la posición del caracter '=' + int pos = line.find("="); + // Procesa las dos subcadenas + if (!setEnemy(&enemy, 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 != "[enemy-end]"); + + // Añade el enemigo al vector de enemigos + enemy_list.push_back(new Enemy(enemy)); + } + // 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; + } } } @@ -87,7 +124,7 @@ bool Room::setVars(std::string _var, std::string _value) } else if (_var == "bg_color") { - bg_color = _value; + bg_color = stringToColor(_value); } else if (_var == "tileset") { @@ -111,13 +148,12 @@ bool Room::setVars(std::string _var, std::string _value) } else if (_var == "tilemap") { + // Se introducen los valores separados por comas en un vector std::stringstream ss(_value); std::string tmp; while (getline(ss, tmp, ',')) { - // printf("text - %s\n",tmp.c_str()); tilemap.push_back(std::stoi(tmp)); - // printf("int - %i\n",std::stoi(tmp)); } } else @@ -128,6 +164,60 @@ bool Room::setVars(std::string _var, std::string _value) return success; } +// Asigna variables a una estructura enemy_t +bool Room::setEnemy(enemy_t *enemy, std::string _var, std::string _value) +{ + // Indicador de éxito en la asignación + bool success = true; + + if (_var == "tileset") + { + enemy->tileset = _value; + } + else if (_var == "x") + { + enemy->x = std::stof(_value); + } + else if (_var == "y") + { + enemy->y = std::stof(_value); + } + else if (_var == "vx") + { + enemy->vx = std::stof(_value); + } + else if (_var == "vy") + { + enemy->vy = std::stof(_value); + } + else if (_var == "x1") + { + enemy->x1 = std::stoi(_value); + } + else if (_var == "x2") + { + enemy->x2 = std::stoi(_value); + } + else if (_var == "y1") + { + enemy->y1 = std::stoi(_value); + } + else if (_var == "y2") + { + enemy->y2 = std::stoi(_value); + } + else if (_var == "color") + { + enemy->color = stringToColor(_value); + } + else + { + success = false; + } + + return success; +} + // Devuelve el nombre de la habitación std::string Room::getName() { @@ -137,36 +227,7 @@ std::string Room::getName() // Devuelve el color de la habitación color_t Room::getBGColor() { - color_t color = {0x00, 0x00, 0x00}; - if (bg_color == "white") - { - color = {0xFF, 0xFF, 0xFF}; - } - else if (bg_color == "red") - { - color = {0xFF, 0x00, 0x00}; - } - else if (bg_color == "green") - { - color = {0x00, 0xFF, 0x00}; - } - else if (bg_color == "blue") - { - color = {0x00, 0x00, 0xFF}; - } - else if (bg_color == "yellow") - { - color = {0xFF, 0xFF, 0x00}; - } - else if (bg_color == "cyan") - { - color = {0x00, 0xFF, 0xFF}; - } - else if (bg_color == "purple") - { - color = {0xFF, 0x00, 0xFF}; - } - return color; + return bg_color; } // Crea la textura con el mapeado de la habitación @@ -202,6 +263,15 @@ void Room::drawMap() SDL_RenderCopy(renderer, map_texture, &rect, NULL); } +// Dibuja los enemigos en pantalla +void Room::drawEnemies() +{ + for (auto enemy : enemy_list) + { + //enemy->draw(); + } +} + // Devuelve el valor de la variable std::string Room::getRoomUp() { diff --git a/source/room.h b/source/room.h index 4cec5f7..efd812e 100644 --- a/source/room.h +++ b/source/room.h @@ -3,6 +3,7 @@ #include "const.h" #include "utils.h" #include "asset.h" +#include "enemy.h" #include #include @@ -27,28 +28,31 @@ LISTADO DE ITEMS (tipo, posicion) class Room { private: - std::string id; // Identificador - std::string name; // Nombre de la habitación - std::string bg_color; // Color de fondo de la habitación - std::string room_up; // Identificador de la habitación que se encuentra arriba - std::string room_down; // Identificador de la habitación que se encuentra abajp - std::string room_left; // Identificador de la habitación que se encuentra a la izquierda - std::string room_right; // Identificador de la habitación que se encuentra a la derecha - std::string tileset; // Imagen con los graficos para la habitación - std::vector tilemap; // Indice de los tiles a dibujar en la habitación - std::vector enemy_list; // Listado con los enemigos de la habitación - std::vector item_list; // Listado con los items que hay en la habitación - LTexture *texture; // Textura con los graficos de la habitación - Asset *asset; // Objeto con la ruta a todos los ficheros de recursos - SDL_Renderer *renderer; // El renderizador de la ventana - SDL_Texture *map_texture; // Textura para dibujar el mapa de la habitación + std::string id; // Identificador + std::string name; // Nombre de la habitación + color_t bg_color; // Color de fondo de la habitación + std::string room_up; // Identificador de la habitación que se encuentra arriba + std::string room_down; // Identificador de la habitación que se encuentra abajp + std::string room_left; // Identificador de la habitación que se encuentra a la izquierda + std::string room_right; // Identificador de la habitación que se encuentra a la derecha + std::string tileset; // Imagen con los graficos para la habitación + std::vector tilemap; // Indice de los tiles a dibujar en la habitación + std::vector enemy_list; // Listado con los enemigos de la habitación + std::vector item_list; // Listado con los items que hay en la habitación + LTexture *texture; // Textura con los graficos de la habitación + Asset *asset; // Objeto con la ruta a todos los ficheros de recursos + SDL_Renderer *renderer; // El renderizador de la ventana + SDL_Texture *map_texture; // Textura para dibujar el mapa de la habitación - // Carga una habitación desde un fichero + // Carga las variables desde un fichero bool load(std::string _file_path); // Asigna variables a partir de dos cadenas bool setVars(std::string _var, std::string _value); + // Asigna variables a una estructura enemy_t + bool setEnemy(enemy_t *enemy, std::string _var, std::string _value); + // Pinta el mapa de la habitación en la textura void fillMapTexture(); @@ -68,6 +72,9 @@ public: // Dibuja el mapa en pantalla void drawMap(); + // Dibuja los enemigos en pantalla + void drawEnemies(); + // Devuelve el valor de la variable std::string getRoomUp(); diff --git a/source/utils.cpp b/source/utils.cpp index 2b28c40..a90cf2d 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -29,10 +29,10 @@ bool checkCollision(circle_t &a, circle_t &b) // Detector de colisiones entre un circulo y un rectangulo bool checkCollision(circle_t &a, SDL_Rect &b) { - //Closest point on collision box + // Closest point on collision box int cX, cY; - //Find closest x offset + // Find closest x offset if (a.x < b.x) { cX = b.x; @@ -46,7 +46,7 @@ bool checkCollision(circle_t &a, SDL_Rect &b) cX = a.x; } - //Find closest y offset + // Find closest y offset if (a.y < b.y) { cY = b.y; @@ -60,33 +60,33 @@ bool checkCollision(circle_t &a, SDL_Rect &b) cY = a.y; } - //If the closest point is inside the circle_t + // If the closest point is inside the circle_t if (distanceSquared(a.x, a.y, cX, cY) < a.r * a.r) { - //This box and the circle_t have collided + // This box and the circle_t have collided return true; } - //If the shapes have not collided + // If the shapes have not collided return false; } // Detector de colisiones entre un dos rectangulos bool checkCollision(SDL_Rect &a, SDL_Rect &b) { - //Calculate the sides of rect A + // Calculate the sides of rect A int leftA = a.x; int rightA = a.x + a.w; int topA = a.y; int bottomA = a.y + a.h; - //Calculate the sides of rect B + // Calculate the sides of rect B int leftB = b.x; int rightB = b.x + b.w; int topB = b.y; int bottomB = b.y + b.h; - //If any of the sides from A are outside of B + // If any of the sides from A are outside of B if (bottomA <= topB) { return false; @@ -107,18 +107,89 @@ bool checkCollision(SDL_Rect &a, SDL_Rect &b) return false; } - //If none of the sides from A are outside B + // If none of the sides from A are outside B return true; } // Carga un archivo de imagen en una textura bool loadTextureFromFile(LTexture *texture, std::string path, SDL_Renderer *renderer) { - bool success = true; - if (!texture->loadFromFile(path, renderer)) - { - printf("Failed to load %s texture!\n", path.c_str()); - success = false; - } - return success; + bool success = true; + if (!texture->loadFromFile(path, renderer)) + { + printf("Failed to load %s texture!\n", path.c_str()); + success = false; + } + return success; +} + +// Devuelve un color_t a partir de un string +color_t stringToColor(std::string str) +{ + color_t color = {0x00, 0x00, 0x00}; + if (str == "black") + { + color = {0x00, 0x00, 0x00}; + } + else if (str == "light_black") + { + color = {0x3C, 0x35, 0x1F}; + } + else if (str == "blue") + { + color = {0x31, 0x33, 0x90}; + } + else if (str == "light_blue") + { + color = {0x15, 0x59, 0xDB}; + } + else if (str == "red") + { + color = {0xA7, 0x32, 0x11}; + } + else if (str == "light_red") + { + color = {0xD8, 0x55, 0x25}; + } + else if (str == "purple") + { + color = {0xA1, 0x55, 0x89}; + } + else if (str == "light_purple") + { + color = {0xCD, 0x7A, 0x50}; + } + else if (str == "green") + { + color = {0x62, 0x9A, 0x31}; + } + else if (str == "light_green") + { + color = {0x9C, 0xD3, 0x3C}; + } + else if (str == "cyan") + { + color = {0x28, 0xA4, 0xCB}; + } + else if (str == "light_cyan") + { + color = {0x65, 0xDC, 0xD6}; + } + else if (str == "yellow") + { + color = {0xE8, 0xBC, 0x50}; + } + else if (str == "light_yellow") + { + color = {0xF1, 0xE7, 0x82}; + } + else if (str == "white") + { + color = {0xBF, 0xBF, 0xBD}; + } + else if (str == "light_white") + { + color = {0xF2, 0xF1, 0xED}; + } + return color; } \ No newline at end of file diff --git a/source/utils.h b/source/utils.h index 9046dc5..b403e70 100644 --- a/source/utils.h +++ b/source/utils.h @@ -79,4 +79,7 @@ bool checkCollision(SDL_Rect a, SDL_Rect b); // Carga un archivo de imagen en una textura bool loadTextureFromFile(LTexture *texture, std::string path, SDL_Renderer *renderer); +// Devuelve un color_t a partir de un string +color_t stringToColor(std::string str); + #endif \ No newline at end of file