240 lines
7.3 KiB
C++
240 lines
7.3 KiB
C++
#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();
|
|
|
|
// Inicializa variables
|
|
tile_width = 16;
|
|
map_width = 20;
|
|
map_height = 13;
|
|
}
|
|
|
|
// 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 != "</data>")
|
|
{
|
|
std::stringstream ss(line);
|
|
std::string tmp;
|
|
while (getline(ss, tmp, ','))
|
|
{
|
|
tilemap.push_back(std::stoi(tmp));
|
|
}
|
|
}
|
|
} while (line != "</data>");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} 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);
|
|
}
|
|
|
|
// 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_width) * map_width) + (p.x / tile_width)];
|
|
|
|
if (tile > 0 && tile < 4 * map_width * tile_width)
|
|
{
|
|
return nothing;
|
|
}
|
|
else if (tile > (4 * map_width * tile_width) && tile < 8 * map_width * tile_width)
|
|
{
|
|
return wall;
|
|
}
|
|
else
|
|
{
|
|
return travessable;
|
|
}
|
|
} |