#include "map.h" // Constructor Map::Map(std::string file, SDL_Renderer *renderer, Asset *asset) { // Inicializa variables tile_size = 8; map_width = 40; map_height = 26; tileset_width = 32; // Copia los punteros a objetos this->asset = asset; this->renderer = renderer; // Crea los objetos texture_tile = new LTexture(); texture_bg = new LTexture(); load(file); loadTextureFromFile(texture_tile, asset->get(tileset_img), renderer); loadTextureFromFile(texture_bg, asset->get(bg_img), renderer); // Crea la textura para el mapa de tiles de la habitación map_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); if (map_texture == NULL) printf("Error: map_texture could not be created!\nSDL Error: %s\n", SDL_GetError()); // Pinta el mapa de la habitación en la textura fillMapTexture(); } // Destructor Map::~Map() { // Reclama la memoria utilizada por los objetos texture_tile->unload(); delete texture_tile; texture_bg->unload(); delete texture_bg; SDL_DestroyTexture(map_texture); } // Carga las variables desde un fichero bool Map::load(std::string file_path) { // Indicador de éxito en la carga bool success = true; 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)) { // Si la linea contiene el texto [tilemap] se realiza el proceso de carga del fichero tmx if (line == "[tilemap]") { do { std::getline(file, line); if (line.find(".tmx") != std::string::npos) { std::ifstream file2(asset->get(line)); // Abre el fichero tmx if (file2.good()) { bool data_read = false; while (std::getline(file2, line)) // Lee el fichero linea a linea { if (!data_read) { // Lee lineas hasta que encuentre donde empiezan los datos del mapa int pos = 0; do { std::getline(file2, line); pos = line.find("data encoding"); } while (pos == std::string::npos); do { // Se introducen los valores separados por comas en un vector data_read = true; std::getline(file2, line); if (line != "") { std::stringstream ss(line); std::string tmp; while (getline(ss, tmp, ',')) { tilemap.push_back(std::stoi(tmp)); } } } while (line != ""); } } } } } while (line != "[tilemap-end]"); } // 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; } } } // Cierra el fichero printf("Closing file %s\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 Map::setVars(std::string var, std::string value) { // Indicador de éxito en la asignación bool success = true; if (var == "bg_img") { bg_img = value; } else if (var == "tileset_img") { tileset_img = value; } else if (var == "room_up") { room_up = value; } else if (var == "room_down") { room_down = value; } else if (var == "room_left") { room_left = value; } else if (var == "room_right") { room_right = value; } else if (var == "") { } else { success = false; } return success; } // Crea la textura con el mapeado de la habitación void Map::fillMapTexture() { SDL_SetRenderTarget(renderer, map_texture); SDL_SetTextureBlendMode(map_texture, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF); SDL_RenderClear(renderer); // Dibuja la textura de fondo SDL_Rect clip = {0, 0, 320, 208}; texture_bg->render(renderer, 0, 0, &clip); // Dibuja el mapeado de tiles clip = {0, 0, tile_size, tile_size}; for (int y = 0; y < map_height; y++) for (int x = 0; x < map_width; x++) { 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); } // Dibuja el degradado del marcador int color = 105; for (int i = 208; i < 240; i++) { SDL_SetRenderDrawColor(renderer, 0x69, color, 0x69, 0xFF); SDL_RenderDrawLine(renderer, 0, i, 320, i); color--; } // Dibuja el marco del marcador SDL_SetRenderDrawColor(renderer, 85, 50, 85, 0xFF); SDL_Rect rect = {0, 208, 320, 32}; SDL_RenderDrawRect(renderer, &rect); rect = {1, 209, 318, 30}; SDL_RenderDrawRect(renderer, &rect); SDL_SetRenderTarget(renderer, nullptr); } // Dibuja el mapa en pantalla void Map::render() { // Dibuja la textura con el mapa en pantalla SDL_Rect rect = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT}; SDL_RenderCopy(renderer, map_texture, &rect, NULL); } // Devuelve el tipo de tile que hay en un punto t_tile_map Map::getTile(SDL_Point p) { const int tile = tilemap[((p.y / tile_size) * map_width) + (p.x / tile_size)]; const int png_width = 32; if (tile >= 0 && tile < 8 * png_width) { return nothing; } else if (tile >= (8 * png_width) && tile < 16 * png_width) { return wall; } else { return passable; } } // Devuelve el valor de la variable int Map::getTileSize() { return tile_size; } // Devuelve el indice del tile correspondiente a un punto del mapa int Map::getTileIndex(SDL_Point p) { return tilemap[((p.y / tile_size) * map_width) + (p.x / tile_size)]; }