So I am loading a tiled map file using TinyXML but the only problem is, if I load the files in update the map is unplayable due to lag, yet if I wanted multiple levels, this is the only possible way to do it, I can't load the files in setup because it won't update to the new map. Any ideas on how to successfully do this?
Level.cpp
bool Level::LoadFromFile(std::string filename)
{
TiXmlDocument levelFile(filename.c_str());
if (!levelFile.LoadFile())
{
std::cout << "Loading level \"" << filename << "\" failed." << std::endl;
return false;
}
//Map element. This is the root element for the whole file.
TiXmlElement *map;
map = levelFile.FirstChildElement("map");
//Set up misc map properties.
width = atoi(map->Attribute("width"));
height = atoi(map->Attribute("height"));
tileWidth = atoi(map->Attribute("tilewidth"));
tileHeight = atoi(map->Attribute("tileheight"));
//Tileset stuff
TiXmlElement *tilesetElement;
tilesetElement = map->FirstChildElement("tileset");
firstTileID = atoi(tilesetElement->Attribute("firstgid"));
//Tileset image
TiXmlElement *image;
image = tilesetElement->FirstChildElement("image");
std::string imagepath = image->Attribute("source");
if (!tilesetImage.LoadFromFile(imagepath))//Load the tileset image
{
std::cout << "Failed to load tile sheet." << std::endl;
return false;
}
tilesetImage.CreateMaskFromColor(sf::Color(255, 0, 255));
tilesetImage.SetSmooth(false);
//Columns and rows (of tileset image)
int columns = tilesetImage.GetWidth() / tileWidth;
int rows = tilesetImage.GetHeight() / tileHeight;
std::vector <sf::Rect<int> > subRects;//container of subrects (to divide the tilesheet image up)
//tiles/subrects are counted from 0, left to right, top to bottom
for (int y = 0; y < rows; y++)
{
for (int x = 0; x < columns; x++)
{
sf::Rect <int> rect;
rect.Top = y * tileHeight;
rect.Bottom = y * tileHeight + tileHeight;
rect.Left = x * tileWidth;
rect.Right = x * tileWidth + tileWidth;
subRects.push_back(rect);
}
}
//Layers
TiXmlElement *layerElement;
layerElement = map->FirstChildElement("layer");
while (layerElement)
{
Layer layer;
if (layerElement->Attribute("opacity") != NULL)//check if opacity attribute exists
{
float opacity = strtod(layerElement->Attribute("opacity"), NULL);//convert the (string) opacity element to float
layer.opacity = 255 * opacity;
}
else
{
layer.opacity = 255;//if the attribute doesnt exist, default to full opacity
}
//Tiles
TiXmlElement *layerDataElement;
layerDataElement = layerElement->FirstChildElement("data");
if (layerDataElement == NULL)
{
std::cout << "Bad map. No layer information found." << std::endl;
}
TiXmlElement *tileElement;
tileElement = layerDataElement->FirstChildElement("tile");
if (tileElement == NULL)
{
std::cout << "Bad map. No tile information found." << std::endl;
return false;
}
int x = 0;
int y = 0;
while (tileElement)
{
int tileGID = atoi(tileElement->Attribute("gid"));
int subRectToUse = tileGID - firstTileID;//Work out the subrect ID to 'chop up' the tilesheet image.
if (subRectToUse >= 0)//we only need to (and only can) create a sprite/tile if there is one to display
{
sf::Sprite sprite;//sprite for the tile
sprite.SetImage(tilesetImage);
sprite.SetSubRect(subRects[subRectToUse]);
sprite.SetPosition(x * tileWidth, y * tileHeight);
sprite.SetColor(sf::Color(255, 255, 255, layer.opacity));//Set opacity of the tile.
//add tile to layer
layer.tiles.push_back(sprite);
}
tileElement = tileElement->NextSiblingElement("tile");
//increment x, y
x++;
if (x >= width)//if x has "hit" the end (right) of the map, reset it to the start (left)
{
x = 0;
y++;
if (y >= height)
{
y = 0;
}
}
}
layers.push_back(layer);
layerElement = layerElement->NextSiblingElement("layer");
}
//Objects
TiXmlElement *objectGroupElement;
if (map->FirstChildElement("objectgroup") != NULL)//Check that there is atleast one object layer
{
objectGroupElement = map->FirstChildElement("objectgroup");
while (objectGroupElement)//loop through object layers
{
TiXmlElement *objectElement;
objectElement = objectGroupElement->FirstChildElement("object");
while (objectElement)//loop through objects
{
std::string objectType;
if (objectElement->Attribute("type") != NULL)
{
objectType = objectElement->Attribute("type");
}
std::string objectName;
if (objectElement->Attribute("name") != NULL)
{
objectName = objectElement->Attribute("name");
}
int x = atoi(objectElement->Attribute("x"));
int y = atoi(objectElement->Attribute("y"));
int width = atoi(objectElement->Attribute("width"));
int height = atoi(objectElement->Attribute("height"));
Object object;
object.name = objectName;
object.type = objectType;
sf::Rect <int> objectRect;
objectRect.Top = y;
objectRect.Left = x;
objectRect.Bottom = y + height;
objectRect.Right = x + width;
if (objectType == "solid")
{
solidObjects.push_back(objectRect);
}
object.rect = objectRect;
TiXmlElement *properties;
properties = objectElement->FirstChildElement("properties");
if (properties != NULL)
{
TiXmlElement *prop;
prop = properties->FirstChildElement("property");
if (prop != NULL)
{
while(prop)
{
std::string propertyName = prop->Attribute("name");
std::string propertyValue = prop->Attribute("value");
object.properties[propertyName] = propertyValue;
prop = prop->NextSiblingElement("property");
}
}
}
objects.push_back(object);
objectElement = objectElement->NextSiblingElement("object");
}
objectGroupElement = objectGroupElement->NextSiblingElement("objectgroup");
}
}
else
{
std::cout << "No object layers found..." << std::endl;
}
return true;
}