From 2039b2f8db0aa736d30e626225ed1f72a25d7ff9 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Wed, 7 Sep 2022 14:00:02 +0200 Subject: [PATCH] Creando las superficies del mapa --- source/room.cpp | 154 +++++++++++++++++++++++++++++++++++++++++++++-- source/room.h | 59 ++++++++++++------ source/utils.cpp | 62 +++++++++++++++++++ source/utils.h | 20 +++++- 4 files changed, 268 insertions(+), 27 deletions(-) diff --git a/source/room.cpp b/source/room.cpp index e294400..e6711e1 100644 --- a/source/room.cpp +++ b/source/room.cpp @@ -6,6 +6,12 @@ // Constructor Room::Room(std::string file_path, SDL_Renderer *renderer, Screen *screen, Asset *asset, ItemTracker *itemTracker, int *items, Debug *debug) { + // Inicializa variables + tileSize = 8; + mapWidth = 32; + mapHeight = 16; + tilesetWidth = 20; + // Copia los punteros a objetos this->renderer = renderer; this->asset = asset; @@ -19,6 +25,12 @@ Room::Room(std::string file_path, SDL_Renderer *renderer, Screen *screen, Asset texture = new LTexture(renderer, asset->get(tileset)); itemSound = JA_LoadSound(asset->get("item.wav").c_str()); + // Calcula las superficies + setBottomSurfaces(); + setTopSurfaces(); + setLeftSurfaces(); + setRightSurfaces(); + // Crea la textura para el mapa de tiles de la habitación mapTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); if (mapTexture == NULL) @@ -29,12 +41,6 @@ Room::Room(std::string file_path, SDL_Renderer *renderer, Screen *screen, Asset // Establece el color del borde screen->setBorderColor(borderColor); - - // Inicializa variables - tileSize = 8; - mapWidth = 32; - mapHeight = 16; - tilesetWidth = 20; } // Destructor @@ -434,6 +440,32 @@ void Room::fillMapTexture() texture->render(renderer, x * 8, y * 8, &clip); } + // **** + SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF); + for (auto l : bottomSurfaces) + { + SDL_RenderDrawLine(renderer, l.x1, l.y, l.x2, l.y); + } + + SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF); + for (auto l : topSurfaces) + { + SDL_RenderDrawLine(renderer, l.x1, l.y, l.x2, l.y); + } + + SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF); + for (auto l : leftSurfaces) + { + SDL_RenderDrawLine(renderer, l.x, l.y1, l.x, l.y2); + } + + SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); + for (auto l : rightSurfaces) + { + SDL_RenderDrawLine(renderer, l.x, l.y1, l.x, l.y2); + } + + // **** SDL_SetRenderTarget(renderer, nullptr); } @@ -542,6 +574,42 @@ tile_e Room::getTile(SDL_Point point) return tile; } +// Devuelve el tipo de tile que hay en ese indice +tile_e Room::getTile(int index) +{ + const int maxTile = mapWidth * mapHeight; + tile_e tile = t_empty; + + if (index < maxTile) + { + // Las filas 0-7 son de tiles t_wall + if ((tilemap[index] > 0) && (tilemap[index] < 8 * tilesetWidth)) + { + return t_wall; + } + + // La fila 8 es de tiles t_slope_r + else if ((tilemap[index] >= 8 * tilesetWidth) && (tilemap[index] < 9 * tilesetWidth)) + { + return t_slope_r; + } + + // La fila 9 es de tiles t_slope_l + else if ((tilemap[index] >= 9 * tilesetWidth) && (tilemap[index] < 10 * tilesetWidth)) + { + return t_slope_l; + } + + // Las filas 10-14 son de tiles t_passable + if ((tilemap[index] >= 10 * tilesetWidth) && (tilemap[index] < 15 * tilesetWidth)) + { + return t_passable; + } + } + + return tile; +} + // Indica si hay colision con un enemigo a partir de un rectangulo bool Room::enemyCollision(SDL_Rect &rect) { @@ -625,4 +693,78 @@ int Room::getSlopeHeight(SDL_Point p, tile_e slope) } return base; +} + +// Calcula las superficies inferiores +void Room::setBottomSurfaces() +{ + std::vector tile; + + // Busca todos los tiles de tipo wall (excepto los de la última fila) que debajo + // tienen un tile de tipo vacio + for (int i = 0; i < tilemap.size() - mapWidth; i++) + { + if (getTile(i) == t_wall && getTile(i + mapWidth) == t_empty) + { + tile.push_back(i); + } + } + + // Recorre el vector de tiles buscando tiles consecutivos para localizar las superficies + int i = 0; + while (i < tile.size()) + { + h_line_t line; + line.x1 = (tile[i] % mapWidth) * tileSize; + line.y = ((tile[i] / mapWidth) * tileSize) + tileSize - 1; + while (tile[i] + 1 == tile[i + 1]) + { + i++; + } + line.x2 = ((tile[i] % mapWidth) * tileSize) + tileSize - 1; + bottomSurfaces.push_back(line); + i++; + } +} + +// Calcula las superficies superiores +void Room::setTopSurfaces() +{ + std::vector tile; + + // Busca todos los tiles de tipo wall (excepto los de la primera fila) que encima + // tienen un tile de tipo vacio + for (int i = mapWidth; i < tilemap.size(); i++) + { + if (getTile(i) == t_wall && getTile(i - mapWidth) == t_empty) + { + tile.push_back(i); + } + } + + // Recorre el vector de tiles buscando tiles consecutivos para localizar las superficies + int i = 0; + while (i < tile.size()) + { + h_line_t line; + line.x1 = (tile[i] % mapWidth) * tileSize; + line.y = ((tile[i] / mapWidth) * tileSize); + while (tile[i] + 1 == tile[i + 1]) + { + i++; + } + line.x2 = ((tile[i] % mapWidth) * tileSize) + tileSize - 1; + topSurfaces.push_back(line); + i++; + } +} + +// Calcula las superficies laterales izquierdas +void Room::setLeftSurfaces() +{ +} + +// Calcula las superficies laterales derechas +void Room::setRightSurfaces() +{ } \ No newline at end of file diff --git a/source/room.h b/source/room.h index 612b5f9..62dca68 100644 --- a/source/room.h +++ b/source/room.h @@ -44,26 +44,30 @@ enum tile_e class Room { private: - std::string name; // Nombre de la habitación - color_t bgColor; // Color de fondo de la habitación - color_t borderColor; // Color de fondo de la habitación - std::string roomUp; // Identificador de la habitación que se encuentra arriba - std::string roomDown; // Identificador de la habitación que se encuentra abajp - std::string roomLeft; // Identificador de la habitación que se encuentra a la izquierda - std::string roomRight; // 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 enemies; // Listado con los enemigos de la habitación - std::vector items; // 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 - Screen *screen; // Objeto encargado de dibujar en pantalla - ItemTracker *itemTracker; // Lleva el control de los objetos recogidos - SDL_Renderer *renderer; // El renderizador de la ventana - SDL_Texture *mapTexture; // Textura para dibujar el mapa de la habitación - JA_Sound itemSound; // Sonido producido al coger un objeto - int *itemsPicked; // Puntero a la cantidad de items recogidos que lleva el juego - Debug *debug; // Objeto para gestionar la información de debug + std::string name; // Nombre de la habitación + color_t bgColor; // Color de fondo de la habitación + color_t borderColor; // Color de fondo de la habitación + std::string roomUp; // Identificador de la habitación que se encuentra arriba + std::string roomDown; // Identificador de la habitación que se encuentra abajp + std::string roomLeft; // Identificador de la habitación que se encuentra a la izquierda + std::string roomRight; // 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 enemies; // Listado con los enemigos de la habitación + std::vector items; // 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 + Screen *screen; // Objeto encargado de dibujar en pantalla + ItemTracker *itemTracker; // Lleva el control de los objetos recogidos + SDL_Renderer *renderer; // El renderizador de la ventana + SDL_Texture *mapTexture; // Textura para dibujar el mapa de la habitación + JA_Sound itemSound; // Sonido producido al coger un objeto + int *itemsPicked; // Puntero a la cantidad de items recogidos que lleva el juego + Debug *debug; // Objeto para gestionar la información de debug + std::vector bottomSurfaces; // Lista con las superficies inferiores de la habitación + std::vector topSurfaces; // Lista con las superficies superiores de la habitación + std::vector leftSurfaces; // Lista con las superficies laterales de la parte izquierda de la habitación + std::vector rightSurfaces; // Lista con las superficies laterales de la parte derecha de la habitación int tileSize; // Ancho del tile en pixels int mapWidth; // Ancho del mapa en tiles @@ -85,6 +89,21 @@ private: // Pinta el mapa de la habitación en la textura void fillMapTexture(); + // Calcula las superficies inferiores + void setBottomSurfaces(); + + // Calcula las superficies superiores + void setTopSurfaces(); + + // Calcula las superficies laterales izquierdas + void setLeftSurfaces(); + + // Calcula las superficies laterales derechas + void setRightSurfaces(); + + // Devuelve el tipo de tile que hay en ese indice + tile_e getTile(int index); + public: // Constructor Room(std::string file_path, SDL_Renderer *renderer, Screen *screen, Asset *asset, ItemTracker *item_tracker, int *items, Debug *debug); diff --git a/source/utils.cpp b/source/utils.cpp index 8c36bb9..fe92176 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -140,6 +140,68 @@ bool checkCollision(SDL_Point &p, SDL_Rect &r) return true; } +// Detector de colisiones entre una linea horizontal y un rectangulo +bool checkCollision(h_line_t &l, SDL_Rect &r) +{ + // Comprueba si la linea esta por encima del rectangulo + if (l.y < r.y) + { + return false; + } + + // Comprueba si la linea esta por debajo del rectangulo + if (l.y > r.y + r.h) + { + return false; + } + + // Comprueba si el inicio de la linea esta a la derecha del rectangulo + if (l.x1 > r.x + r.w) + { + return false; + } + + // Comprueba si el final de la linea esta a la izquierda del rectangulo + if (l.x2 < r.x) + { + return false; + } + + // Si ha llegado hasta aquí, hay colisión + return true; +} + +// Detector de colisiones entre una linea vertical y un rectangulo +bool checkCollision(v_line_t &l, SDL_Rect &r) +{ + // Comprueba si la linea esta por la izquierda del rectangulo + if (l.x < r.x) + { + return false; + } + + // Comprueba si la linea esta por la derecha del rectangulo + if (l.x > r.x + r.w) + { + return false; + } + + // Comprueba si el inicio de la linea esta debajo del rectangulo + if (l.y1 > r.y + r.h) + { + return false; + } + + // Comprueba si el final de la linea esta encima del rectangulo + if (l.y2 < r.y) + { + return false; + } + + // Si ha llegado hasta aquí, hay colisión + return true; +} + // Devuelve un color_t a partir de un string color_t stringToColor(std::string str) { diff --git a/source/utils.h b/source/utils.h index e868235..b533957 100644 --- a/source/utils.h +++ b/source/utils.h @@ -34,6 +34,18 @@ struct circle_t int r; }; +// Estructura para definir una linea horizontal +struct h_line_t +{ + int x1, x2, y; +}; + +// Estructura para definir una linea vertical +struct v_line_t +{ + int x, y1, y2; +}; + // Estructura para definir un color struct color_t { @@ -74,9 +86,15 @@ bool checkCollision(circle_t &a, SDL_Rect &b); // Detector de colisiones entre un dos rectangulos bool checkCollision(SDL_Rect &a, SDL_Rect &b); -// Detector de colisiones entre un punto y u rectangulo +// Detector de colisiones entre un punto y un rectangulo bool checkCollision(SDL_Point &p, SDL_Rect &r); +// Detector de colisiones entre una linea horizontal y un rectangulo +bool checkCollision(h_line_t &l, SDL_Rect &r); + +// Detector de colisiones entre una linea vertical y un rectangulo +bool checkCollision(v_line_t &l, SDL_Rect &r); + // Devuelve un color_t a partir de un string color_t stringToColor(std::string str);