#include "map.h" // Constructor Map::Map(std::string file, SDL_Renderer *renderer, Asset *asset) { // 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 == "tilemap") { // Se introducen los valores separados por comas en un vector std::stringstream ss(value); std::string tmp; while (getline(ss, tmp, ',')) { tilemap.push_back(std::stoi(tmp)); } } 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, 0x00); SDL_RenderClear(renderer); // Dibuja la textura de fondo SDL_Rect clip = {0, 0, 320, 240-32}; texture_bg->render(renderer, 0, 0, &clip); // Dibuja el mapeado de tiles const int tile_size = 16; const int tileset_width_in_tiles = 16; const int map_width_in_tiles = 20; const int map_height_in_tiles = 13; clip = {0, 0, tile_size, tile_size}; for (int y = 0; y < map_height_in_tiles; y++) for (int x = 0; x < map_width_in_tiles; x++) { clip.x = ((tilemap[(y * map_width_in_tiles) + x] - 1) % tileset_width_in_tiles) * tile_size; clip.y = ((tilemap[(y * map_width_in_tiles) + x] - 1) / tileset_width_in_tiles) * tile_size; texture_tile->render(renderer, x * tile_size, y * tile_size, &clip); } 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); }