-
Hi guys, I've been using the Tiled (http://www.mapeditor.org/) map format in a game I've been working on and thought I would share the love around.
I've basically rewritten it, as I was using it with Box2D. This new version is more general purpose.
It should work with any size level you throw at it. You can have as many tile layers as you want (and transparency works).
Any objects you place in the editor will be picked up and stored and can be accessed.
You should be able to get going just from looking at the header file and reading the README.txt.
Download: https://sourceforge.net/projects/tiledsfmlloader/files/TiledMapLoader0.1.zip/download
Note that I'm not affiliated with Tiled or it's author.
Suggestions, bug reports etc are more than welcome!
Don't forget to read the README.txt!!!
-
Really great work thank you! :)
I just wanted to say, I extended it a little bit to support multiple tilesets, and properties for layers, tiles and objects.
NOTE: this could probably be done a bit more "pro", as I used this to teach myself c++. I could not quite get templates working, so get properties methods are pretty much copied, for each object.
its still in a long thread and still only supports XML. (I like to be able to manually read the maps anyway)
--I removed some stuff that's useless TO ME,
and I am about to change it to just render a single background, (no tiles), (I KNOW??) so it will be faster for me. So I have not finished playing with it, posting as before I edit it for me, (which would make it useless for others).
I don't plan on using objects for collision, but might.
I think in tild you can do object layers? I don't have support for that? just same as above, objects...
be glad to see further feedback.
no idea about uploading, so ill just post code, sorry.
Compare with above for feature sets.
I mainly just use tiles to get info, ...ie......map.getproperyat(layer, x, y). ...I can then find certain things on maps...
getobjectat(x,y)
also reworked the objects , as not all objects have width, height.
apart from other optimizations..things to do.
somehow work out how to link or make a list of the objects which point to their objects in the multi - [y] layer. So easier to loop through...
/*********************************************************************
Quinn Schwab
16/08/2010
SFML Tiled Map Loader
The zlib license has been used to make this software fully compatible
with SFML. See http://www.sfml-dev.org/license.php
This software is provided 'as-is', without any express or
implied warranty. In no event will the authors be held
liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute
it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but
is not required.
2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any
source distribution.
*********************************************************************/
#ifndef MAP_H
#define Map_H
#include <string>
#include <vector>
#include <map>
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
//Object class. Everything is kept public in case you want to get a different type to the supported ones.
//Also you will be able to modify things. For example doors/changing walls etc (Just give the door a static type and a unique name)
//Kept in same files as Map just for convenience. (only have to add two files to your project)
class Object{
public:
int GetPropertyInt(std::string name);
float GetPropertyFloat(std::string name);
std::string GetPropertyString(std::string name);
std::string name;
std::string type;
sf::Rect <int> rect;
//All properties of the object. Values are stored as strings and mapped by strings(names provided in editor).
std::map <std::string, std::string> properties;
};
class TileSet{
public:
int GetPropertyInt(std::string name);
float GetPropertyFloat(std::string name);
std::string GetPropertyString(std::string name);
int rows;
int columns;
int firstTileID;
sf::String name;
std::string ImgSource;
//The tileset image.
sf::Image TilesetImage;
int width;
int height;
int tileHeight;
int tileWidth;
int spacing;
int margin;
std::map <std::string, std::string> properties;//All properties of the object. Values are stored as strings and mapped by strings(names provided in editor).
};
class Tile{
public:
int GetPropertyInt(std::string name);
float GetPropertyFloat(std::string name);
std::string GetPropertyString(std::string name);
bool drawable;
//the id in the tileset
int tilesettileid;
sf::Vector2i position;
sf::Vector2f coords;
sf::Sprite sprite;
int id;
TileSet *tileset;
//All properties of the object. Values are stored as strings and mapped by strings(names provided in editor).
std::map <std::string, std::string> properties;
};
class Layer{
public:
int GetPropertyInt(std::string name);
float GetPropertyFloat(std::string name);
std::string GetPropertyString(std::string name);
int rows;
int columns;
std::map <int , std::map <int , Tile> > XYTiles;
std::map <int , Tile > YTiles;
std::vector <Tile> tiles;
int visible;
int opacity;
std::map <std::string, std::string> properties;//All properties of the object. Values are stored as strings and mapped by strings(names provided in editor).
};
typedef std::map <int, TileSet> Tilesets;
class Map
{
public:
Map();
virtual ~Map();
//Loads the map. Returns false if it fails.
bool LoadFromFile(std::string filename);
//Returns true if the given tile is solid.
bool IsSolidTile(int x, int y);
//Set the area to draw. This rect is usually provided directly from the view you are using.
void SetDrawingBounds(sf::Rect<float> bounds);
//Draws the map to the provided window.
void Draw(sf::RenderWindow &window);
//Width(tiles), height(tiles), tile width(pixels), tile height(pixels) of the map.
int width, height, tileWidth, tileHeight;
int rows;
int columns;
std::string GetTilePropertyStringAt(int layer, int x, int y, std::string );
float GetTilePropertyFloatAt(int layer, int x, int y, std::string );
int GetTilePropertyIntAt(int layer, int x, int y, std::string );
std::string GetObjectPropertyStringAt(int x, int y,std::string name);
float GetObjectPropertyFloatAt( int x, int y, std::string name);
int GetObjectPropertyIntAt(int x, int y, std::string name);
private:
bool GetTileSetFromGID(int tileGid, Tile &Tile);
//Used to offset the t ile number.
int firstTileID;
//Used to clip anything off screen.
sf::Rect <float> drawingBounds;
sf::Image TilesetImage;
//This stores all the solid areas (objects with type 'solid'). This gets checked by the IsSolid function.
std::vector <sf::Rect <int> > solidObjects;
//This stores all objects (including 'solid' types)
// std::vector <Object> objects;
std::map <int , std::map <int , Object> > XYObjects;
//This stores each layer of sprites/tiles so they can be drawn in order.
std::vector <Layer> layers;
//tilesets
//std::vector <TileSet> TileSets;
Tilesets m_Tilesets;
};
#endif // Map_H
/*********************************************************************
Quinn Schwab
16/08/2010
SFML Tiled Map Loader
The zlib license has been used to make this software fully compatible
with SFML. See http://www.sfml-dev.org/license.php
This software is provided 'as-is', without any express or
implied warranty. In no event will the authors be held
liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute
it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but
is not required.
2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any
source distribution.
*********************************************************************/
#include "MapLoader.h"
#include <iostream>
#include "tinyxml/tinyxml.h"
std::string Map::GetTilePropertyStringAt(int layer, int x, int y, std::string name)
{
return layers[layer].XYTiles[x][y].GetPropertyString(name);
}
float Map::GetTilePropertyFloatAt(int layer, int x, int y, std::string name)
{
return layers[layer].XYTiles[x][y].GetPropertyFloat(name);
}
int Map::GetTilePropertyIntAt(int layer, int x, int y, std::string name)
{
return layers[layer].XYTiles[x][y].GetPropertyInt(name);
}
std::string Map::GetObjectPropertyStringAt(int x, int y, std::string name)
{
return XYObjects[x][y].GetPropertyString(name);
}
float Map::GetObjectPropertyFloatAt(int x, int y, std::string name)
{
return XYObjects[x][y].GetPropertyFloat(name);
}
int Map::GetObjectPropertyIntAt(int x, int y, std::string name)
{
return XYObjects[x][y].GetPropertyInt(name);
}
int Object::GetPropertyInt(std::string name)
{
int i;
i = atoi(properties[name].c_str());
return i;
}
float Object::GetPropertyFloat(std::string name)
{
float f;
f = (float)strtod(properties[name].c_str(), NULL);
return f;
}
std::string Object::GetPropertyString(std::string name)
{
return properties[name];
}
int Layer::GetPropertyInt(std::string name)
{
int i;
i = atoi(properties[name].c_str());
return i;
}
float Layer::GetPropertyFloat(std::string name)
{
float f;
f = (float)strtod(properties[name].c_str(), NULL);
return f;
}
std::string Layer::GetPropertyString(std::string name)
{
return properties[name];
}
int Tile::GetPropertyInt(std::string name)
{
int i;
i = atoi(properties[name].c_str());
return i;
}
float Tile::GetPropertyFloat(std::string name)
{
float f;
f = (float)strtod(properties[name].c_str(), NULL);
return f;
}
std::string Tile::GetPropertyString(std::string name)
{
return properties[name];
}
int TileSet::GetPropertyInt(std::string name)
{
int i;
i = atoi(properties[name].c_str());
return i;
}
float TileSet::GetPropertyFloat(std::string name)
{
float f;
f = (float)strtod(properties[name].c_str(), NULL);
return f;
}
std::string TileSet::GetPropertyString(std::string name)
{
return properties[name];
}
Map::Map()
{
//ctor
}
Map::~Map()
{
//dtor
}
bool Map::LoadFromFile(std::string filename)
{
TiXmlDocument MapFile(filename.c_str());
if (!MapFile.LoadFile())
{
std::cout << "Loading Map \"" << filename << "\" failed." << std::endl;
return false;
}
//Map element. This is the root element for the whole file.
TiXmlElement *map;
map = MapFile.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"));
columns = width / tileWidth;
rows = height / tileHeight;
//Tileset stuff
TiXmlElement *tilesetElement;
tilesetElement = map->FirstChildElement("tileset");
//while we want tilesets
while(tilesetElement)
{
TileSet TileSet;
TileSet.firstTileID = atoi(tilesetElement->Attribute("firstgid"));
//Tileset image
TiXmlElement *image;
image = tilesetElement->FirstChildElement("image");
TileSet.ImgSource = image->Attribute("source");
if (!TileSet.TilesetImage.LoadFromFile(TileSet.ImgSource))//Load the tileset image
{
std::cout << "Failed to load tile sheet." << std::endl;
return false;
}
TileSet.TilesetImage.CreateMaskFromColor(sf::Color(255, 0, 255));
TileSet.TilesetImage.SetSmooth(false);
if (tilesetElement->Attribute("spacing") != NULL)
{
TileSet.spacing = atoi(tilesetElement->Attribute("spacing"));
}
else
{
TileSet.spacing = 0;
}
if (tilesetElement->Attribute("margin") != NULL)
{
TileSet.margin = atoi(tilesetElement->Attribute("margin"));
}
else
{
TileSet.margin = 0;
}
if (tilesetElement->Attribute("tilewidth") != NULL)
{
TileSet.tileWidth = atoi(tilesetElement->Attribute("tilewidth"));
}
else
{
TileSet.tileWidth = 0;
}
if (tilesetElement->Attribute("tileheight") != NULL)
{
TileSet.tileHeight = atoi(tilesetElement->Attribute("tileheight"));
}
else
{
TileSet.tileHeight = 0;
}
//Columns and rows (of tileset image)
TileSet.width = TileSet.TilesetImage.GetWidth();
TileSet.height = TileSet.TilesetImage.GetHeight();
TileSet.columns = TileSet.width / TileSet.tileWidth;
TileSet.rows = TileSet.height / TileSet.tileHeight;
//do layer properties
TiXmlElement *properties;
properties = tilesetElement->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");
TileSet.properties[propertyName] = propertyValue;
prop = prop->NextSiblingElement("property");
}
}
}
tilesetElement = tilesetElement->NextSiblingElement("tileset");
//set by tile first id
m_Tilesets[TileSet.firstTileID] = TileSet;
}
//Layers
TiXmlElement *layerElement;
layerElement = map->FirstChildElement("layer");
while (layerElement)
{
Layer layer;
if (layerElement->Attribute("opacity") != NULL)//check if opacity attribute exists
{
float opacity = (int)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
}
//is visible
if (layerElement->Attribute("visible") != NULL)
{
layer.visible = atoi(layerElement->Attribute("opacity"));
}
else
{
layer.visible = 1;
}
//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;
bool GotTileSet = false;
while (tileElement)
{
int tileGID = atoi(tileElement->Attribute("gid"));
Tile CurrentTile;
sf::Rect <int> rect;
CurrentTile.id = tileGID;
if(!GotTileSet)
{
GotTileSet = GetTileSetFromGID(tileGID, CurrentTile);
if(!GotTileSet)
{
std::cout << "Could not find tileset for tile." << std::endl;
return false;
}
//get the layers rows, They should really match the tileset.
//unless someone used half size tileset..EEK? but I won so I'm not worried! ha
layer.rows = CurrentTile.tileset->rows;
layer.columns = CurrentTile.tileset->columns;
}
//Work out the subrect ID to 'chop up' the tilesheet image.
CurrentTile.tilesettileid = tileGID - CurrentTile.tileset->firstTileID;
if(CurrentTile.tilesettileid >= 0)//we only need to (and only can) create a sprite/tile if there is one to display
{
CurrentTile.drawable = true;
CurrentTile.sprite.SetImage(CurrentTile.tileset->TilesetImage);
rect.Top = y * CurrentTile.tileset->tileHeight;
rect.Bottom = y * CurrentTile.tileset->tileHeight + CurrentTile.tileset->tileHeight;
rect.Left = x * CurrentTile.tileset->tileWidth;
rect.Right = x * CurrentTile.tileset->tileWidth + CurrentTile.tileset->tileWidth;
CurrentTile.sprite.SetSubRect( rect );
CurrentTile.sprite.SetPosition(x * CurrentTile.tileset->tileWidth, y * CurrentTile.tileset->tileHeight);
CurrentTile.sprite.SetColor(sf::Color(255, 255, 255, layer.opacity));//Set opacity of the tile.
}
else
{
CurrentTile.drawable = false;
}
//set the position
sf::Vector2i position;
position.x = x;
position.y = x;
CurrentTile.position = position;
sf::Vector2f coords;
coords.x = x * CurrentTile.tileset->tileWidth;
coords.y = x * CurrentTile.tileset->tileHeight;
CurrentTile.coords = coords;
//do tiles properties
TiXmlElement *properties;
properties = tileElement->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");
CurrentTile.properties[propertyName] = propertyValue;
prop = prop->NextSiblingElement("property");
}
}
}
//Link tile x, y to this tile
layer.XYTiles[x].insert(std::pair<int, Tile>(y, CurrentTile));
//add tile to layer
// layer.tiles.push_back(layer.XYTiles);
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;
}
}
}
//do layer properties
TiXmlElement *properties;
properties = layerElement->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");
layer.properties[propertyName] = propertyValue;
prop = prop->NextSiblingElement("property");
}
}
}
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;
int width = 0;
int height = 0;
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"));
if (objectElement->Attribute("width") != NULL)
{
width = atoi(objectElement->Attribute("width"));
}
if (objectElement->Attribute("height") != NULL)
{
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;
x = x / tileWidth;
y = y / tileHeight;
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);
XYObjects[x][y] = object;
objectElement = objectElement->NextSiblingElement("object");
}
objectGroupElement = objectGroupElement->NextSiblingElement("objectgroup");
}
}
else
{
std::cout << "No object layers found..." << std::endl;
}
return true;
}
void Map::SetDrawingBounds(sf::Rect<float> bounds)
{
drawingBounds = bounds;
//Adjust the rect so that tiles are drawn just off screen, so you don't see them disappearing.
drawingBounds.Top -= tileHeight;
drawingBounds.Left -= tileWidth;
}
bool Map::GetTileSetFromGID(int tileGid, Tile &Tile)
{
//sort the tile sets by their first id
//std::sort(TileSets.begin(), TileSets.end(), comp_hungarian_strings);
//Tilesets, loop through and find
// if the ID (I) if bigger than tilegid, its not the one we want.
// if its lower, its the first lowest.
Tilesets::reverse_iterator iter;
for ( iter = m_Tilesets.rbegin();
iter != m_Tilesets.rend(); iter++)
{
//if the tileset ID is bigger
if(iter->first > tileGid)
{
continue;
}
//this is the highest ID, lower than our ID
Tile.tileset = &m_Tilesets[1];
return true;
}
return false;
}
void Map::Draw(sf::RenderWindow &window)
{
for (int layer = 0; layer < layers.size(); layer++)
{
for (int x = 0; x < layers[layer].columns; x++)
{
for (int y = 0; y < layers[layer].rows; y++)
{
window.Draw(layers[layer].XYTiles[x][y].sprite);
}
}
}
return;
/*
for (int x = 0; x < layers[layer].columns; x++)
{
for (int y = 0; y < layers[layer].rows; y++)
{
std::map <int , std::map <int , Tile> >::iterator XTile;
std::map <int , Tile>::const_iterator YTile;
XTile = layers[layer].XYTiles.find(x);
window.Draw(YTile->second.sprite);
}
}
std::map <int , std::map <int , Tile> >::const_iterator iter;
for ( iter = layers[layer].XYTiles.begin(); iter != layers[layer].XYTiles.end(); iter++)
{
std::map <int , Tile>::const_iterator tilesy;
for (tilesy = iter->second.begin(); tilesy != iter->second.end(); tilesy++)
{
window.Draw(tilesy->second.sprite);
}
}
for (int tile = 0; tile < layers[layer].tiles.size(); tile++)
{
// if( drawingBounds.Contains(layers[layer].tiles[tile].position.x, layers[layer].tiles[tile].position.y) )
{
if(layers[layer].tiles[tile].drawable)
{
window.Draw(layers[layer].tiles[tile].sprite);
}
}
}
*/
sf::Sprite sprite;
sf::Rect <int> rect;
rect.Top = 0 * m_Tilesets[1].tileHeight;
rect.Bottom = 0 * m_Tilesets[1].tileHeight + m_Tilesets[1].tileHeight;
rect.Left = 0 * m_Tilesets[1].tileWidth;
rect.Right = 0 * m_Tilesets[1].tileWidth + m_Tilesets[1].tileWidth;
sprite.SetImage(m_Tilesets[1].TilesetImage);
sprite.SetSubRect( rect );
sprite.SetPosition(0, 0);
window.Draw(sprite);
}
-
hello,
I get errors when i use it with sfml 2.
i tried to fix it myself but with no luck.
i get black screen.
Could you update it please to sfml 2?
thanks,
Jordan
Sorry for my bad english
-
Yeah , i would love to see this for SFML 2.0
-
Here is the SFML 2 version, works just like the 1.6.
level.h
http://pastebin.com/gwasT3hR (http://pastebin.com/gwasT3hR)
level.cpp
http://pastebin.com/U1NG8eKD (http://pastebin.com/U1NG8eKD)
-
I've been working on this for one of my own projects, so I thought I'd share what I've done:
Things it now does:
Works with SFML 2.0
Supports base64 and CSV encoded maps
Supports zlib and gzip compressed maps
Error handling when trying to find a non-existent object property
Error handling when trying to find a non-existent object
Support for *almost* all attribute tags in the latest version of the tmx format (https://github.com/bjorn/tiled/wiki/TMX-Map-Format), including transparency colour, layer visibilty, margin and spacing (tested to work with the desert map example which comes with Tiled)
Object class now stores polygon and polyline objects as a vector of sf::vector2i points
Previously loaded maps are automatically cleared when loading a new map so a single instance of the class can be used to load multiple maps (successively, not at the same time)
What it still doesnt do:
No isometric map support - I'm not interested in this for my current project so unlikely I'll add it
No tsx tilemap support, only image file support - images must be in the same directory as the tmx file
Still only one tilemap currently supported
Not completely error safe because I haven't tested every outcome - missing attributes or corrupt tmx files may cause an assertion error.
To use zlib and gzip compressed maps you need to link the zlib library to your project. On debian you can apt-get install zlib1g-dev or download the source and configure/make/install (tested on Ubuntu 11.04 with zlib 1.2.7). Using VC on windows is a bit trickier but you can find a tutorial here (http://www.helyar.net/2010/compiling-zlib-lib-on-windows/) (tested with VC10 on XP and Vista to work with static lib using 1.2.7). Presumably you can also do a configure/make/install with MinGW but I haven't tried.
You can download the files here (http://djfallen.com/TmxLoader.zip).
-
Will this display objects that contain pictures ?
Im not sure how to use the objects.
Thanks man, this is a lot better than mine.
-
The object class just stores the data parsed from the object tags in the tmx file. All I've added to the original class is parsing of polygon and polyline points and storing them as sf::vector2i so you can draw out shapes or whatever you need using sfml. Now you mention it, no, it won't draw objects that contain pictures, although I did add parsing of objects with tile GIDs, so it wouldn't take much to update the draw method to draw the corresponding tile. This would probably be more useful if the class supported multiple tilemaps I guess. There is still much which could be added but I'm not sure if I'll do it myself unless I need something for a specific reason. I really just wanted to share the zlib compatibility as it was quite tricky to work out, and it's about time I gave something back to a very helpful community :)
-
I am Having an issue where it is printing the tileset instead of the map.
I am using SFML 1.6.
Does anyone know how to fix this
-
When you save a map with tiled its location of the tileset picture in the map is "../blabbal/mypicture"
so you have to open the map with notepad(text editor) and remove "../" and it will load corrently then, and when editing it back to edit the map with tiled
check paths if they are correct
-
Okay I got it working thanks for all of the help.
How do I instantiate the objects I create in the Object layer. I want to use them for collisions and such. How would I call them. i have classes like class player. What should I have to make them functional.
-
Im not sure that myself, but i know you can add object property in tiled e.g. "collision" and set it true for certain tiles which you can identify within the script later on. If someone could show us, would be nice :D
-
So I understand Bassically how the collisions work, I can set certain collision variables and pass those into the World from box2D and that will take care of it, but How do I instatiate the tiles to objects from the XML. So I did the forground on one layer and made certain players on other layers, but how do I make it so that when I read my forground layer I can set them as fixtures?
-
In the version I posted you can create 'solid' objects by going to edit->preferences->object types in Tiled and adding a new type called 'solid'. Then if you create a rectangular object in Tiled you can right click on it, go to properties and set its type to 'solid'. The map loader will then find any objects with this type and create a sf::rect with the object's dimensions and add it to a vector named m_solidObjects (this is all existing functionality, not anything I added and so should be valid in the 1.6 version). This you can iterate over and call each rectangle's contains() function passing a vector2f (player position or whatever) as a parameter to check for collision. I've more recently added a contains() function to the object class too, which will let you check any objects in the m_objects vector which contain a list of poly points to see if the polygonal shape contains a point specified via a vector2f:
bool Object::Contains(const sf::Vector2f point)
{
//only test if we have enough points to create at least a triangle
if(polypoints.size() < 3) return false;
//else see if the point is inside the poly
unsigned int i, j;
bool result = false;
for (i = 0, j = polypoints.size() - 1; i < polypoints.size(); j = i++)
{
if (((polypoints[i].y > point.y) != (polypoints[j].y > point.y)) &&
(point.x < (polypoints[j].x - polypoints[i].x) * (point.y - polypoints[i].y) / (polypoints[j].y - polypoints[i].y) + polypoints[i].x))
result = !result;
}
return result;
}
which works by casting a ray through the polygon and counting the number of times it enters and exits it. If the number is odd then the point is inside, even it's outside.
-
Sorry for writing in a old post but, i've used this code to try get a map loader up and running. But when I try to run it I get an Assertion failure. It says:
File: f:\dd\vctools\crt_bld\self_x86\crt\src\strtol.c
Line: 94
Expression: nptr != NULL
anyone know what this might be?
Thanks
-
I have not long time ago such problems too. What i see make sure that tmx maps are readed good. There is 3 whitespaces on begining of each data tag- make sure not to read this. And sometimes there is no '=' character on end of base64 encoded maps.
-
Well, I dont know what it is. I've notice that each time that I have any kind of tile information in the TMX file I get an Assertion Error and when I dont have any tile information I get a "Bad map. No tile information found" but the program is running. Not quite sure how to load the tile information then. Btw I'm using the SFML 2.0, and the tile information that don't work is all the
"<tile gid="7"/>" that is in the file.
Anyone that might have a suggestion ?
-
I couldn't really suggest anything without looking at your map file and/or your code. Try downloading this (http://djfallen.com/TmxTest.zip) sample project for VS10 which uses the map loader in its most basic way. It includes a test map made in Tiled 0.9.0 and stored with gzip compression. You can narrow down your problem by seeing if it will load your map (either by renaming your map and over writing the map in the archive, or by modifying the source to load your file) and try comparing the example source with your own. HTH
-
Thanks! Looks like I had some problem loading the objects. The program never really accepted that some objects had GID and some did not. But looks like it works now with the help of your:
int gid = (objectElement->Attribute("gid")) ? atoi(objectElement->Attribute("gid")): 0;
EDIT*
I've been thinking, after a lot of searching in the code example you posted, I only see that you can draw the "normal" layers, but if I wanna draw the object tile (if I have one) can I like put it all in a if/else to have the code go one way if there is a "normal" layer or the other if there is a object layer.
Really been stuck on this today.
Thanks
-
When parsing the object layer you can do something like this:
if(gid) m_SetTile(subrects, layer, x, y, gid);
which will add a sprite to the rendering layers based on the object gid and x/y coords if the gid is non-zero.
-
How would you use the 2.0 version with an sf::View. Is that the best way to do it for something involving a 2d platforming game with a player moving?
-
Just move the sf::view around your world as you normally would then use TileMap::SetDrawingBounds() to set the drawing rectangle to that of your current view
-
This may be a stupid question but SetDrawingBounds does that limit the tilemap to only be drawn on those specific sections of the tilemap itself or with regards to how it is drawn on the screen?
-
Wasn't really sure if I should drag up this old topic or start a new one, but I've completely rewritten this class. I decided to post here to make sure the original author gets credit for his work which started the whole thing in the first place. I've written a post about it here (http://trederia.blogspot.co.uk/2013/05/tiled-map-loader-for-sfml.html) which includes a download with some examples but for brevity here's the readme:
This class is designed to load TILED .tmx format maps, compatible with
TILED up to version 0.9.0
http://trederia.blogspot.co.uk/2013/05/tiled-map-loader-for-sfml.html
What's Supported
----------------
Uses pugixml (included) to parse xml
Supports orthogonal maps
Supports isometric maps
Supports conversion between orthogonal and isometric world coords
Parses all types of layers (normal, object and image), layer properties
Parses all type of object, object shapes, types, properties
Option to draw debug output of objects, grid and object names
Supports multiple tile sets, including tsx files
Supports all layer encoding and compression: base64, csv, zlib, gzip and xml (requires zlib library, see /lib directory)
What's not supported / limitations
----------------------------------
Parsing of individual tile properties
Flipping / rotation of sprites
Staggered isometric maps
Tile set images must be in the same directory as tmx/tsx files
To display object names when drawing object debug shapes then you must provide a font
and update MapObject.h
Usage
-----
To quickly get up and running create an instance of the MapLoader class
tmx::MapLoader ml("path/to/maps");
load a map file
ml.Load("map.tmx");
and draw it in your main loop
ml.Draw(renderTarget);
Note that the constructor takes a path to the directory containing the map files as a parameter (with
or without the trailing '/') so that you only need pass the map name to MapLoader::Load(). Currently
all map files (tmx, tsx, images etc) must be in the diretory passed to the constructor.
New maps can be loaded simply by calling the load function again, existing maps will be automatically
unloaded. MapLoader::Load() also returns true on success and false on failure, to aid running the function
in its own thread for example. Conversion functions are provided for converting coordinate spaces between
orthogonal and isometric. For instance MapLoader::OthogonalToIsometric will convert mouse coordinates from
screen space:
0--------X
|
|
|
|
|
Y
to Isometric space:
0
/ \
/ \
/ \
/ \
Y X
Layer information can be accessed through MapLoader::GetLayers()
bool collision;
for(auto layer = ml.GetLayers().begin(); layer != ml.GetLayers().end(); ++layer)
{
if(layer->name == "Collision")
{
for(auto object = layer->objects.begin(); object != layer->objects.end(); ++object)
{
collision = object->Contains(point);
}
}
}
For more detailed examples see the source for the demos.
Requirements
------------
pugixml (included)
zlib (http://zlib.net/)
SFML 2.0 (http://sfml-dev.org)
as well as being a rewrite, it contains quite a few enhancements / new features.
This may be a stupid question but SetDrawingBounds does that limit the tilemap to only be drawn on those specific sections of the tilemap itself or with regards to how it is drawn on the screen?
SetDrawingBounds is used to define which tiles are visible, to save drawing tiles which don't need to be drawn. In the new version it is called automatically by Draw using the view of the supplied renderTarget.
-
I think it is the more advanced tmx parser 'released' for SFML in this moment. Thank you for your contribution fallahn!
I propose you open your own thread in SFML projects for more and better visibility and feedbacking with a feature list and so... Your work deserves it!
A git repository will be welcomed too. :-*
Thanks again!
DJuego
-
I am having issues using this loader.
The following code compiles, but seems to do nothing. Please help :) Thank you :D.
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <level.h>
int main(){
sf::RenderWindow window(sf::VideoMode(640, 480), "");
sf::View view;
view.setCenter(player_x, player_y);
view.setSize(640, 480);
Level sample_map;
sample_map.LoadFromFile("c:/gfx/sample_map.tmx");
sample_map.SetDrawingBounds(view.getViewport());
while (window.isOpen()){
sf::Event event;
while(window.pollEvent(event)){
if (event.type == sf::Event::Closed)
window.close();
}
window.clear(sf::Color::Green);
window.setView(view);
sample_map.Draw(window);
window.display();
}
return 0;
}
-
If I were to hazard a guess its because you are using the full path to the map file when the loader expects a path relative to your executable. That being said it also looks like you are using the older version of the map loader - there is a much updated version here (http://en.sfml-dev.org/forums/index.php?topic=3023.msg81195#msg81195) which allows you to construct the loader with a path to your map directory, so you only have to pass the map name to the Load function.
-
Thank you very much :), but I am getting a few error messages when trying to use your loader.
32 0 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapLoader.h In file included from C:/Users/Natha_000/Desktop/Blood of Tyr Prototype/inc/map_loader/MapLoader.h
29 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp from src/map_loader/MapLoaderPrivate.cpp
C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h In member function 'const bool tmx::MapObject::Intersects(tmx::MapObject&)':
159 13 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] 'i' does not name a type
159 47 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] expected ';' before 'i'
159 47 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] 'i' was not declared in this scope
159 65 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] 'class std::vector<sf::Vector2<float> >' has no member named 'cend'
162 13 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] 'i' does not name a type
162 40 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] expected ';' before 'i'
162 40 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] 'i' was not declared in this scope
162 58 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] 'class std::vector<sf::Vector2<float> >' has no member named 'cend'
C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h In member function 'void tmx::MapObject::CreateDebugShape(sf::Color)':
172 13 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] 'i' does not name a type
172 40 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] expected ';' before 'i'
172 40 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] 'i' was not declared in this scope
172 58 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] 'class std::vector<sf::Vector2<float> >' has no member named 'cend'
C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h In member function 'void tmx::MapObject::m_CalcTestValues()':
264 13 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] 'i' does not name a type
264 40 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] expected ';' before 'i'
264 40 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] 'i' was not declared in this scope
264 58 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h [Error] 'class std::vector<sf::Vector2<float> >' has no member named 'cend'
C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp In member function 'const bool tmx::MapLoader::m_ParseMapNode(const pugi::xml_node&)':
71 14 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected unqualified-id before 'or' token
73 5 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected primary-expression before 'or' token
73 8 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected primary-expression before '==' token
77 10 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected primary-expression before 'or' token
77 13 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected primary-expression before '==' token
84 38 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected primary-expression before 'or' token
84 41 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected primary-expression before '<<' token
C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp In member function 'const bool tmx::MapLoader::m_ParseLayer(const pugi::xml_node&)':
272 14 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] 'i' does not name a type
272 33 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected ';' before 'i'
272 33 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] 'i' was not declared in this scope
272 43 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] 'std::string' has no member named 'cend'
C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp In member function 'const bool tmx::MapLoader::m_ParseObjectgroup(const pugi::xml_node&)':
548 11 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] 'std::string' has no member named 'pop_back'
C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp In member function 'void tmx::MapLoader::m_SetIsometricCoords(tmx::MapLayer&)':
666 11 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] 'tile' does not name a type
666 39 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected ';' before 'tile'
666 39 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] 'tile' was not declared in this scope
C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp In member function 'const bool tmx::MapLoader::m_Decompress(const char*, std::vector<unsigned char>&, int, int)':
736 4 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] 'memcpy' is not a member of 'std'
736 4 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Note] suggested alternative:
46 0 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\cwchar In file included from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/cwchar
42 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\bits\postypes.h from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/bits/postypes.h
42 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\bits\char_traits.h from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/bits/char_traits.h
42 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\string from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/string
32 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h from C:/Users/Natha_000/Desktop/Blood of Tyr Prototype/inc/map_loader/MapObject.h
32 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapLoader.h from C:/Users/Natha_000/Desktop/Blood of Tyr Prototype/inc/map_loader/MapLoader.h
29 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp from src/map_loader/MapLoaderPrivate.cpp
961 17 c:\program files (x86)\dev-cpp\mingw64\x86_64-w64-mingw32\include\wchar.h [Note] 'memcpy'
758 2 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] 'memcpy' is not a member of 'std'
758 2 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Note] suggested alternative:
46 0 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\cwchar In file included from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/cwchar
42 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\bits\postypes.h from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/bits/postypes.h
42 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\bits\char_traits.h from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/bits/char_traits.h
42 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\string from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/string
32 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h from C:/Users/Natha_000/Desktop/Blood of Tyr Prototype/inc/map_loader/MapObject.h
32 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapLoader.h from C:/Users/Natha_000/Desktop/Blood of Tyr Prototype/inc/map_loader/MapLoader.h
29 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp from src/map_loader/MapLoaderPrivate.cpp
961 17 c:\program files (x86)\dev-cpp\mingw64\x86_64-w64-mingw32\include\wchar.h [Note] 'memcpy'
-
Ah I forgot to mention it uses C++11 features, particularly the auto keyword. In g++ you need to add
-std=c++0x
or
-std=c++11
to the compiler options (I think - I haven't actually tried compiling with anything other than VS10 :-[)
-
Ahhhh ty :)))
Edit: Still not compiling correctly :/
C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp In member function 'const bool tmx::MapLoader::m_ParseMapNode(const pugi::xml_node&)':
71 14 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected unqualified-id before 'or' token
73 5 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected primary-expression before 'or' token
73 8 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected primary-expression before '==' token
77 10 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected primary-expression before 'or' token
77 13 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected primary-expression before '==' token
84 38 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected primary-expression before 'or' token
84 41 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] expected primary-expression before '<<' token
C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp In member function 'const bool tmx::MapLoader::m_Decompress(const char*, std::vector<unsigned char>&, int, int)':
736 4 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] 'memcpy' is not a member of 'std'
736 4 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Note] suggested alternative:
46 0 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\cwchar In file included from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/cwchar
42 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\bits\postypes.h from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/bits/postypes.h
42 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\bits\char_traits.h from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/bits/char_traits.h
42 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\string from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/string
32 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h from C:/Users/Natha_000/Desktop/Blood of Tyr Prototype/inc/map_loader/MapObject.h
32 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapLoader.h from C:/Users/Natha_000/Desktop/Blood of Tyr Prototype/inc/map_loader/MapLoader.h
29 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp from src/map_loader/MapLoaderPrivate.cpp
961 17 c:\program files (x86)\dev-cpp\mingw64\x86_64-w64-mingw32\include\wchar.h [Note] 'memcpy'
758 2 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Error] 'memcpy' is not a member of 'std'
758 2 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp [Note] suggested alternative:
46 0 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\cwchar In file included from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/cwchar
42 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\bits\postypes.h from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/bits/postypes.h
42 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\bits\char_traits.h from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/bits/char_traits.h
42 c:\program files (x86)\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\string from c:\program files (x86)\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/string
32 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapObject.h from C:/Users/Natha_000/Desktop/Blood of Tyr Prototype/inc/map_loader/MapObject.h
32 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\inc\map_loader\MapLoader.h from C:/Users/Natha_000/Desktop/Blood of Tyr Prototype/inc/map_loader/MapLoader.h
29 C:\Users\Natha_000\Desktop\Blood of Tyr Prototype\src\map_loader\MapLoaderPrivate.cpp from src/map_loader/MapLoaderPrivate.cpp
961 17 c:\program files (x86)\dev-cpp\mingw64\x86_64-w64-mingw32\include\wchar.h [Note] 'memcpy'
-
Ok so it looks like I made the silly mistake of naming a variable 'or', and there are some missing includes presumably because of VC's precompiled headers or somesuch. If I get time this weekend I'll take a look - I've been planning an update with a quadtree anyway. For now you can try renaming the variable and including cstring (I think, you'll have to look up memcpy)
EDIT: after taking a look this morning I've managed to get this working properly with MinGW / Code::Blocks. To fix it manually simply rename the variable
or
to something else like
orientation
and add
#include <cstring>
in MapLoaderPrivate.cpp. I've also updated the download file so if in doubt just re-downloaded it from my blog post (http://trederia.blogspot.co.uk/2013/05/tiled-map-loader-for-sfml.html).
-
Thank you ever so much :D, and sorry for the late reply, been a little busy.
-
No problem, hope it helps. I've updated it with quadtree partitioning for map objects
http://youtu.be/Y0tr76hqpzs
Which you can read about here (http://trederia.blogspot.co.uk/2013/06/optimising-collision-testing.html) 8)
-
I've updated (http://trederia.blogspot.co.uk/2013/07/update-to-sfml-tiled-map-loader.html) this again so now it draws maps using vertex arrays, and is nice and speedy! :D
-
I'm using window.mapPixelToCoords(sf::Mouse::getPosition(window)) to map world coordinates to map coordinates. Is this the best route to take?
-
Yup, assuming you're passing the same window to the Draw function (ie you're not drawing to a render texture then drawing that texture to the window or something). Take a look at the isometric demo in the archive for an example.
-
Okay great thanks.
I'm not very familiar to Tiled so sorry if these questions have obvious answers.
My goal is to be able to manipulate the loaded in Tiled Map. Be able to add new things (flowers, monsters) and destroy these things as well.
Is there a way to go about this? From what I can see I can delete Objects, but Objects don't have any images associated with them.
Let me know if you have any ideas on this, thanks!
-
You can insert tiles on object layers and add all the associated properties which objects have using the tile tool (shortcut T iirc) in Tiled. These will be drawn by the map loader no problem. Currently there is a bug, however, when moving objects about where the associated debug graphic and AABB for the quad tree are not updated which I plan to fix in the near future. Personally speaking (I'm sure there are other and probably better ways to do this) I only use the map objects as static geometry for things such as solid objects or transition triggers. I usually create dynamic objects such as collectables, players or enemies as separate entities which can interact with each other and are drawn over the top of the map. It depends on what kind of game you are making, of course, but having the dynamic entities separate can also help with things like z-ordering when sprites need to move behind and in front of other objects. All dynamic objects can be made to interact with the loaded map by querying the quad tree (see the included example in the archive). If you want to place something like collectables in the map with Tiled you can do so with placeholder objects on their own layer, then when loading the map check that layer and use each object's position to spawn your collectable entity (or any other entity for that matter).
-
I've decided to go with the last method you posted. I'm creating objects as placeholders for items. However, it would be nice to have a function to add an Object to the map. I know there is an addTile function, but it'd be much nicer to have the addObject function. Any chance that this would be a possibility in a future update?
-
I'm not entirely sure what you mean by an addObject function. Tiled objects contain a position and a shape as well as, optionally, user data and a tile from one of the tile sets. The map loader uses a MapObject class which just reflects these properties as well as adding a few utility functions for things like collision testing or drawing debug output. If you want to create a new MapObject programmatically you can by using the MapObject class just like any other C++ class, then use layer.objects.push_back(myObj) as all the objects are stored in a vector belonging to the object layer (see the MapLayer class). If you want extended functionality you'll need to create your own entities which you can compose from sf::Sprite or an animated sprite class, along with a reference to a MapObject, for example:
class MyEnt
{
public:
MyEnt(tmx::MapObject& mo) : m_mapObj(mo){};
void Update(float dt){//do ent logic here};
//so we can draw with rt.draw(myEnt.GetSprite());
const sf::Sprite& GetSprite(void) const{return m_sprite;};
private:
sf::Sprite m_sprite;
tmx::MapObject& m_mapObj;
};
Then your entity will have direct access to the map object to which it is bound, including its collision testing and debug drawing abilities. I've recently updated the MapObject class with a Move() function, as someone else has also requested it, but it's not generally the approach I take so I can't vouch for its effectiveness.
-
Matt, first of all thanks for your code. It works really well!
I've just found a little bug when you compute the number of rows and columns in MapLoader::m_ProcessTiles:
const bool MapLoader::m_ProcessTiles(const pugi::xml_node& tilesetNode)
{
sf::Uint16 tileWidth, tileHeight, spacing, margin;
...
//slice into tiles
int columns = sourceImage->getSize().x / tileWidth;
int rows = sourceImage->getSize().y / tileHeight;
This won't take into account the spacing and margin of the tileset, if any. I've discovered by accident, trying to load a map with the blocks1.png tileset (attached below). That tileset requires a margin and spacing of 2 pixels.
The fix is easy:
const bool MapLoader::m_ProcessTiles(const pugi::xml_node& tilesetNode)
{
sf::Uint16 tileWidth, tileHeight, spacing, margin;
...
//slice into tiles
int columns = (sourceImage->getSize().x-margin) / (tileWidth+spacing);
int rows = (sourceImage->getSize().y-margin) / (tileHeight+spacing);
Hope it helps :)
Cheers!
-
Oh! Thanks, I shall add your fix as soon as I can :D
-
Glad to be of help :)
I have another quick question for you: I'm trying to check for collisions between a sprite and a collision layer of tiles, but your MapTile struct doesn't store the GID of a tile. Hence I added a gid field to the struct as follows:
struct MapTile
{
//returns the base centre point of sprite / tile
const sf::Vector2f GetBase(void) const
{
return sf::Vector2f(sprite.getPosition().x + (sprite.getLocalBounds().width / 2.f),
sprite.getPosition().y + sprite.getLocalBounds().height);
}
sf::Sprite sprite;
sf::Vector2i gridCoord;
sf::Uint16 gid; // need gid to check contents
sf::RenderStates renderStates; //used to perform any rendering with custom shaders or blend mode
};
What do you reckon? Is that a sensible approach?
Cheers!
-
Honestly? I couldn't say without knowing more about what you're trying to do. I've tried to make the loader as generic as possible but there is bound to be some need for customisation for any project. If it works for you, then it's good I guess :) I've personally always handled collisions by drawing data on an object layer then using the quadtree to query objects near the sprite but, like I say, I don't really know what fits your particular project :)
-
RE your quadtree implementation... Would it not be more effecient to add a 'remove' function rather than recreating the tree each frame? That way, any object that has moved is removed from the tree and re-added in the new position.
For myself I made a simple spacial partitioning system with a fixed-size grid that implemented the remove/add technique, it's only created once.
BTW, that car game would look awesome with a rotating view! :)
-
I guess it depends on how you use the quad tree. if you had a large world which needed to maintain the position of all the objects within it then building the tree once and adding/removing objects would probably be more efficient. In my racing game both the vehicle and the view move, however, and most of the initial culling is done simply by ignoring everything which isn't visible (as there is no way the car will collide with anything outside the view). Because the view is moving it effectively moves the root node and therefore necessitates rebuilding each time. It's no real performance hit anyway, I can render over 3000fps on my machine at work :) The quad tree node class is pretty flexible and I'm sure it wouldn't take much to modify it to allow for adding / removing objects as they move if anyone needed it. FWIW the quad tree code is based on this (http://gamedev.tutsplus.com/tutorials/implementation/quick-tip-use-quadtrees-to-detect-likely-collisions-in-2d-space/) article.
The car game itself has come a long way since (it doesn't even have cars any more...) and won't have a rotating view as I have very specific ideas for it. I'm glad you like what you see, however ;) Eventually I will post something about it in the projects forum.
-
That's fair comment. My world simulation is quite large with stuff interacting off-screen, so yeah.
-
Well, in fact I'm trying to get an undergraduate class to understand the basic principles of collision detection in games, so a tile layer with collision info seemed to be the easiest way. It's also very quick to put it together in Tiled, for instance. But of course you're right: it depends on the particular application. A quadtree is usually a sensible idea, but it just seemed overkill in my case :)
-
I'm trying to use your code, which looks great by the way. Whenever I call a function, I get an unresolved external symbol error message. My guess would be I didn't set it up correctly. I'm using visual studio 2012. I went into the project properties and added the "include" directory to the additional includes field. Is there anything else I need to do? Thanks!
-
I went into the project properties and added the "include" directory to the additional includes field. Is there anything else I need to do? Thanks!
Well ever consider that even 'Tiled' needs libs?
-
Well you don't say what the errors actually are, but at a guess I would say you need to link zlib 1.2.7 or higher, as mentioned in the included readme
-
Okay, I have linked zlib, and I am still getting the errors. Here's my code:
#include <MapLoader.h>
#include <SFML/Graphics.hpp>
int main()
{
tmx::MapLoader myLoader("resources/maps/");
myLoader.Load("rpgtest.tmx");
sf::RenderWindow window(sf::VideoMode(300, 300), "TEST");
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window.close();
}
}
window.clear();
myLoader.Draw(window);
window.display();
}
}
And the error messages:
1>------ Build started: Project: RPGengine, Configuration: Debug Win32 ------
1> main.cpp
1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall tmx::MapLoader::MapLoader(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0MapLoader@tmx@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall tmx::MapLoader::~MapLoader(void)" (??1MapLoader@tmx@@QAE@XZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: bool const __thiscall tmx::MapLoader::Load(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?Load@MapLoader@tmx@@QAE?B_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall tmx::MapLoader::Draw(class sf::RenderTarget &)" (?Draw@MapLoader@tmx@@QAEXAAVRenderTarget@sf@@@Z) referenced in function _main
1>D:\Documents\Programming\C++\SFML Games\RPGengine\Debug\RPGengine.exe : fatal error LNK1120: 4 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
-
hmm. Sounds like you haven't added the cpp files to your project
-
Good lord, I am a moron. It's working beautifully. Thanks!
-
Hi!
Is it possible to compile it to a .dll? Any instructions on how I can achieve that?
I'm trying to use it on a C# project.
-
The broad answer is 'probably, yes' - but I wouldn't know how to. I think it would work better as a straight port to the C# binding of SFML as I believe there is also a C# binding for zlib (which the class relies on) and the pugixml stuff can be replaced as .net/mono has direct support for XML.
-
Hi!
Is it possible to compile it to a .dll? Any instructions on how I can achieve that?
I'm trying to use it on a C# project.
You have two options here, either do a native port of 'Tiled' directly in C# or write a C function style interface and then use P/Invoke to call the C functions which will then call the C++ code. If are serious about having 'Tiled' in .NET I would recommend you go with the first option since it seems you are probably not familiar with writing C code and manual memory management with everything that entails.
-
do a native port of 'Tiled' directly in C#
Well, it seems the best option then. I know dynamic memory allocation in C, but it's a lot of work for now.
So I've already started a native C# project and hope to see it functioning in a few days. :)
Thanks!
-
Well, it seems the best option then. I know dynamic memory allocation in C, but it's a lot of work for now.
So I've already started a native C# project and hope to see it functioning in a few days. :)
That sounds great, I am sure your port will be used :)
-
ive linked everything and i get this compile error complaining about what i assume is zlib...
\TmxMapLoader\src\MapLoaderPrivate.cpp|830|undefined reference to `inflateInit2_'
could i be because im using zlib 1.2.8 ?
-
That is indeed a linker error referring to zlib - although I've tried the loader with 1.2.8 and it works fine using the static build / VS11. Did you make sure to replace the zlib.h and zconf.h file included with the map loader with the ones from the newer version of zlib? (I really shouldn't have included the headers with the distribution, my bad)
-
Hate to bring up an old thread, but I keep getting this error and I can't find the source of it. I have everything linked properly and I've tried adding all of the files to the project. I'm using fallahn's code btw. And it seems that someone else had this problem but their fix didn't fix mine.
Error 2 error LNK2019: unresolved external symbol "public: virtual __thiscall tmx::MapLoader::~MapLoader(void)" (??1MapLoader@tmx@@UAE@XZ) referenced in function _main C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\main.obj FFF
Error 3 error LNK2019: unresolved external symbol "public: bool const __thiscall tmx::MapLoader::Load(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?Load@MapLoader@tmx@@QAE?B_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function _main C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\main.obj FFF
Error 4 error LNK2019: unresolved external symbol "public: void __thiscall tmx::MapLoader::Draw(class sf::RenderTarget &,enum tmx::MapLayer::DrawType)" (?Draw@MapLoader@tmx@@QAEXAAVRenderTarget@sf@@W4DrawType@MapLayer@2@@Z) referenced in function _main C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\main.obj FFF
Error 5 error LNK1120: 4 unresolved externals C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\Debug\FFF.exe 1 1 FFF
-
You've tried this (http://en.sfml-dev.org/forums/index.php?topic=3023.msg91410#msg91410)? The linker can't find the symbols most likely because the correct obj file (MapLoaderPublic.obj) has not been compiled as the corresponding cpp file(s) are missing.
-
I have those added now, but I am getting even more errors.
Error 36 error LNK1120: 26 unresolved externals C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\Debug\FFF.exe FFF
Error 28 error LNK2001: unresolved external symbol "public: __thiscall pugi::xml_document::~xml_document(void)" (??1xml_document@pugi@@QAE@XZ) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPublic.obj FFF
Error 26 error LNK2001: unresolved external symbol "public: __thiscall pugi::xml_document::xml_document(void)" (??0xml_document@pugi@@QAE@XZ) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPublic.obj FFF
Error 10 error LNK2001: unresolved external symbol "public: __thiscall pugi::xml_node::operator void (__cdecl*)(class pugi::xml_node * * *)(void)const " (??Bxml_node@pugi@@QBEP6AXPAPAPAV01@@ZXZ) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPublic.obj FFF
Error 22 error LNK2001: unresolved external symbol "public: __thiscall pugi::xml_parse_result::operator bool(void)const " (??Bxml_parse_result@pugi@@QBE_NXZ) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPublic.obj FFF
Error 12 error LNK2001: unresolved external symbol "public: bool __thiscall pugi::xml_node::operator!(void)const " (??7xml_node@pugi@@QBE_NXZ) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPublic.obj FFF
Error 24 error LNK2001: unresolved external symbol "public: char const * __thiscall pugi::xml_parse_result::description(void)const " (?description@xml_parse_result@pugi@@QBEPBDXZ) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPublic.obj FFF
Error 17 error LNK2001: unresolved external symbol "public: class pugi::xml_node __thiscall pugi::xml_node::child(char const *)const " (?child@xml_node@pugi@@QBE?AV12@PBD@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPublic.obj FFF
Error 14 error LNK2001: unresolved external symbol "public: class pugi::xml_node __thiscall pugi::xml_node::first_child(void)const " (?first_child@xml_node@pugi@@QBE?AV12@XZ) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPublic.obj FFF
Error 30 error LNK2001: unresolved external symbol "public: struct pugi::xml_parse_result __thiscall pugi::xml_document::load_file(char const *,unsigned int,enum pugi::xml_encoding)" (?load_file@xml_document@pugi@@QAE?AUxml_parse_result@2@PBDIW4xml_encoding@2@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPublic.obj FFF
Error 1 error LNK2019: unresolved external symbol "public: __thiscall pugi::xml_attribute::operator void (__cdecl*)(class pugi::xml_attribute * * *)(void)const " (??Bxml_attribute@pugi@@QBEP6AXPAPAPAV01@@ZXZ) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseImageLayer(class pugi::xml_node const &)" (?m_ParseImageLayer@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 27 error LNK2019: unresolved external symbol "public: __thiscall pugi::xml_document::~xml_document(void)" (??1xml_document@pugi@@QAE@XZ) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseTileSets(class pugi::xml_node const &)" (?m_ParseTileSets@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 25 error LNK2019: unresolved external symbol "public: __thiscall pugi::xml_document::xml_document(void)" (??0xml_document@pugi@@QAE@XZ) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseTileSets(class pugi::xml_node const &)" (?m_ParseTileSets@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 9 error LNK2019: unresolved external symbol "public: __thiscall pugi::xml_node::operator void (__cdecl*)(class pugi::xml_node * * *)(void)const " (??Bxml_node@pugi@@QBEP6AXPAPAPAV01@@ZXZ) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseImageLayer(class pugi::xml_node const &)" (?m_ParseImageLayer@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 8 error LNK2019: unresolved external symbol "public: __thiscall pugi::xml_node::xml_node(void)" (??0xml_node@pugi@@QAE@XZ) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseImageLayer(class pugi::xml_node const &)" (?m_ParseImageLayer@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 21 error LNK2019: unresolved external symbol "public: __thiscall pugi::xml_parse_result::operator bool(void)const " (??Bxml_parse_result@pugi@@QBE_NXZ) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseTileSets(class pugi::xml_node const &)" (?m_ParseTileSets@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 7 error LNK2019: unresolved external symbol "public: bool __thiscall pugi::xml_attribute::as_bool(bool)const " (?as_bool@xml_attribute@pugi@@QBE_N_N@Z) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseLayer(class pugi::xml_node const &)" (?m_ParseLayer@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 2 error LNK2019: unresolved external symbol "public: bool __thiscall pugi::xml_attribute::operator!(void)const " (??7xml_attribute@pugi@@QBE_NXZ) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseImageLayer(class pugi::xml_node const &)" (?m_ParseImageLayer@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 11 error LNK2019: unresolved external symbol "public: bool __thiscall pugi::xml_node::operator!(void)const " (??7xml_node@pugi@@QBE_NXZ) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseImageLayer(class pugi::xml_node const &)" (?m_ParseImageLayer@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 3 error LNK2019: unresolved external symbol "public: char const * __thiscall pugi::xml_attribute::as_string(char const *)const " (?as_string@xml_attribute@pugi@@QBEPBDPBD@Z) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseImageLayer(class pugi::xml_node const &)" (?m_ParseImageLayer@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 34 error LNK2019: unresolved external symbol "public: char const * __thiscall pugi::xml_node::name(void)const " (?name@xml_node@pugi@@QBEPBDXZ) referenced in function "public: bool const __thiscall tmx::MapLoader::Load(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?Load@MapLoader@tmx@@QAE?B_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPublic.obj FFF
Error 23 error LNK2019: unresolved external symbol "public: char const * __thiscall pugi::xml_parse_result::description(void)const " (?description@xml_parse_result@pugi@@QBEPBDXZ) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseTileSets(class pugi::xml_node const &)" (?m_ParseTileSets@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 20 error LNK2019: unresolved external symbol "public: char const * __thiscall pugi::xml_text::as_string(char const *)const " (?as_string@xml_text@pugi@@QBEPBDPBD@Z) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseLayer(class pugi::xml_node const &)" (?m_ParseLayer@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 18 error LNK2019: unresolved external symbol "public: class pugi::xml_attribute __thiscall pugi::xml_node::attribute(char const *)const " (?attribute@xml_node@pugi@@QBE?AVxml_attribute@2@PBD@Z) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseImageLayer(class pugi::xml_node const &)" (?m_ParseImageLayer@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 16 error LNK2019: unresolved external symbol "public: class pugi::xml_node __thiscall pugi::xml_node::child(char const *)const " (?child@xml_node@pugi@@QBE?AV12@PBD@Z) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseImageLayer(class pugi::xml_node const &)" (?m_ParseImageLayer@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 13 error LNK2019: unresolved external symbol "public: class pugi::xml_node __thiscall pugi::xml_node::first_child(void)const " (?first_child@xml_node@pugi@@QBE?AV12@XZ) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseObjectgroup(class pugi::xml_node const &)" (?m_ParseObjectgroup@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 19 error LNK2019: unresolved external symbol "public: class pugi::xml_node __thiscall pugi::xml_node::next_sibling(char const *)const " (?next_sibling@xml_node@pugi@@QBE?AV12@PBD@Z) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseLayer(class pugi::xml_node const &)" (?m_ParseLayer@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 35 error LNK2019: unresolved external symbol "public: class pugi::xml_node __thiscall pugi::xml_node::next_sibling(void)const " (?next_sibling@xml_node@pugi@@QBE?AV12@XZ) referenced in function "public: bool const __thiscall tmx::MapLoader::Load(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?Load@MapLoader@tmx@@QAE?B_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPublic.obj FFF
Error 15 error LNK2019: unresolved external symbol "public: class pugi::xml_text __thiscall pugi::xml_node::text(void)const " (?text@xml_node@pugi@@QBE?AVxml_text@2@XZ) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseLayer(class pugi::xml_node const &)" (?m_ParseLayer@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 6 error LNK2019: unresolved external symbol "public: float __thiscall pugi::xml_attribute::as_float(float)const " (?as_float@xml_attribute@pugi@@QBEMM@Z) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseImageLayer(class pugi::xml_node const &)" (?m_ParseImageLayer@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 4 error LNK2019: unresolved external symbol "public: int __thiscall pugi::xml_attribute::as_int(int)const " (?as_int@xml_attribute@pugi@@QBEHH@Z) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseLayer(class pugi::xml_node const &)" (?m_ParseLayer@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 29 error LNK2019: unresolved external symbol "public: struct pugi::xml_parse_result __thiscall pugi::xml_document::load_file(char const *,unsigned int,enum pugi::xml_encoding)" (?load_file@xml_document@pugi@@QAE?AUxml_parse_result@2@PBDIW4xml_encoding@2@@Z) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ParseTileSets(class pugi::xml_node const &)" (?m_ParseTileSets@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 5 error LNK2019: unresolved external symbol "public: unsigned int __thiscall pugi::xml_attribute::as_uint(unsigned int)const " (?as_uint@xml_attribute@pugi@@QBEII@Z) referenced in function "private: bool const __thiscall tmx::MapLoader::m_ProcessTiles(class pugi::xml_node const &)" (?m_ProcessTiles@MapLoader@tmx@@AAE?B_NABVxml_node@pugi@@@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 31 error LNK2019: unresolved external symbol _inflate referenced in function "private: bool const __thiscall tmx::MapLoader::m_Decompress(char const *,class std::vector<unsigned char,class std::allocator<unsigned char> > &,int,int)" (?m_Decompress@MapLoader@tmx@@AAE?B_NPBDAAV?$vector@EV?$allocator@E@std@@@std@@HH@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 32 error LNK2019: unresolved external symbol _inflateEnd referenced in function "private: bool const __thiscall tmx::MapLoader::m_Decompress(char const *,class std::vector<unsigned char,class std::allocator<unsigned char> > &,int,int)" (?m_Decompress@MapLoader@tmx@@AAE?B_NPBDAAV?$vector@EV?$allocator@E@std@@@std@@HH@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 33 error LNK2019: unresolved external symbol _inflateInit2_ referenced in function "private: bool const __thiscall tmx::MapLoader::m_Decompress(char const *,class std::vector<unsigned char,class std::allocator<unsigned char> > &,int,int)" (?m_Decompress@MapLoader@tmx@@AAE?B_NPBDAAV?$vector@EV?$allocator@E@std@@@std@@HH@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Sorry, I know that's a lot.
-
Its so easy, just read the messages and you see "LNK" and "unresolved external symbols" and many function names. That means you did not LiNK a number of external symbols, namely functions and from the names they belong to "pugi" and "zlib".
Now just add those libraries in the project settings and/or adjust the library search path so they can be found and linked... ;)
-
FWIW the VS2012 project settings for the demo project (included in the archive) look like this:
(http://djfallen.com/images/project_settings.png)
assuming you are linking statically
-
Okay, I think it's a zlib problem. Here are my configs:
(http://i.imgur.com/4wZiuto.png)
Then in c/c++ General -> additional include directories:
C:\SFML-2.1\include;C:\Users\ozneh_000\Documents\TmxMapLoader\include
Linker -> general - > Additional library dependencies
C:\SFML-2.1\lib
Linker -> input -> Additional dependencies
zlibstat.lib;sfml-graphics-d.lib;sfml-window-d.lib;sfml-audio-d.lib;sfml-system-d.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
And the errors i'm getting now are about the m_Decompress function in the MapLoader class:
Error 2 error LNK2019: unresolved external symbol _inflate referenced in function "private: bool const __thiscall tmx::MapLoader::m_Decompress(char const *,class std::vector<unsigned char,class std::allocator<unsigned char> > &,int,int)" (?m_Decompress@MapLoader@tmx@@AAE?B_NPBDAAV?$vector@EV?$allocator@E@std@@@std@@HH@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 3 error LNK2019: unresolved external symbol _inflateEnd referenced in function "private: bool const __thiscall tmx::MapLoader::m_Decompress(char const *,class std::vector<unsigned char,class std::allocator<unsigned char> > &,int,int)" (?m_Decompress@MapLoader@tmx@@AAE?B_NPBDAAV?$vector@EV?$allocator@E@std@@@std@@HH@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Error 4 error LNK2019: unresolved external symbol _inflateInit2_ referenced in function "private: bool const __thiscall tmx::MapLoader::m_Decompress(char const *,class std::vector<unsigned char,class std::allocator<unsigned char> > &,int,int)" (?m_Decompress@MapLoader@tmx@@AAE?B_NPBDAAV?$vector@EV?$allocator@E@std@@@std@@HH@Z) C:\Users\ozneh_000\Documents\Visual Studio 2012\Projects\FFF\FFF\MapLoaderPrivate.obj FFF
Thanks for all the help guys
-
You need to download and compile zlib, and copy the resulting zlib/zlibstat.lib file to your lib directory. Google will point you in the right direction :-)
-
This is reaaally bothering me that this isn't working. Is it possible for me to message you somewhere like skype where it is instant messaging? I really appreciate your help.
-
Just go to zlib.net (http://zlib.net), scroll down a bit and get the package with the DLL. :P
-
Just go to zlib.net (http://zlib.net), scroll down a bit and get the package with the DLL. :P
My god. You fixed it! Thank you so much. I can't believe it was that simple
-
Alright one last thing, is there anyway to return a tile number? I plan on doing collision like
if (player.intersects(dirtTile)) { //collision here }
Or how would you implement collision with your engine?
Thanks
-
You can't access an individual tile as there is no discreet tile data as such, each layer is a group of vertices in an array representing multiple tiles (see the SFML vertex array tutorial (http://sfml-dev.org/tutorials/2.1/graphics-vertex-array.php) for how this works). The map loader takes the approach of using Objects, defined in Tiled, which represent areas which you might query for collision. The objects are available either via the GetLayers() function where each layer has a vector of MapObjects which belong to that layer, or you can retrieve an optimised vector of pointers to MapObjects via the QuadTree. The MapObject class itself then has functions like Intersects(MapObject) or Contains(point) which can be used for rudimentary collision detection. You can, of course, add more functions to the MapObject class to help with custom collision testing. There's an example of using the QuadTree here (http://trederia.blogspot.co.uk/2013/06/optimising-collision-testing.html).
-
First of all, thank you creating such a useful tool. It is much appreciated :).
Alright, now, I've been trying to figure out a way to handle collision with your code, but I'm coming up short. If I create more than 2 layers on a Tiled map, the layers don't look right when they load. So, I made 1 .tmx with 2 layers (which is all visable tiles), and then a second .tmx with a single layer with invisible tiles (for collision). I've been trying every method I could find to load the tiles from the Collision.tmx and not allow the animatedSprite to pass through them, but nothing is working. Here is my code at the moment:
#include "stdafx.h"
#include "zlib.h"
#include "MapLoader.h"
#include "AnimatedSprite.h"
#include "Animation.h"
#include "zconf.h"
#include <luabind/luabind.hpp>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <string>
#include <iostream>
int main()
{
sf::Vector2i screenDimensions(720, 420);
sf::RenderWindow window(sf::VideoMode(screenDimensions.x, screenDimensions.y), "Pokemon Clone");
// load texture
sf::Texture texture;
texture.loadFromFile("Player.png");
//create map loader and load map
tmx::MapLoader ml("Maps/");
tmx::MapLoader mll("Maps/");
ml.Load("Pallet Town.tmx");
mll.Load("Collision.tmx");
// push frames
Animation walkingAnimationDown;
walkingAnimationDown.setSpriteSheet(texture);
walkingAnimationDown.addFrame(sf::IntRect(16, 0, 16, 20));
walkingAnimationDown.addFrame(sf::IntRect(32, 0, 16, 20));
walkingAnimationDown.addFrame(sf::IntRect(16, 0, 16, 20));
walkingAnimationDown.addFrame(sf::IntRect(0, 0, 16, 20));
Animation walkingAnimationLeft;
walkingAnimationLeft.setSpriteSheet(texture);
walkingAnimationLeft.addFrame(sf::IntRect(16, 40, 16, 20));
walkingAnimationLeft.addFrame(sf::IntRect(32, 40, 16, 20));
walkingAnimationLeft.addFrame(sf::IntRect(16, 40, 16, 20));
walkingAnimationLeft.addFrame(sf::IntRect(0, 40, 16, 20));
Animation walkingAnimationRight;
walkingAnimationRight.setSpriteSheet(texture);
walkingAnimationRight.addFrame(sf::IntRect(16, 60, 16, 20));
walkingAnimationRight.addFrame(sf::IntRect(32, 60, 16, 20));
walkingAnimationRight.addFrame(sf::IntRect(16, 60, 16, 20));
walkingAnimationRight.addFrame(sf::IntRect(0, 60, 16, 20));
Animation walkingAnimationUp;
walkingAnimationUp.setSpriteSheet(texture);
walkingAnimationUp.addFrame(sf::IntRect(16, 20, 16, 20));
walkingAnimationUp.addFrame(sf::IntRect(32, 20, 16, 20));
walkingAnimationUp.addFrame(sf::IntRect(16, 20, 16, 20));
walkingAnimationUp.addFrame(sf::IntRect(0, 20, 16, 20));
// set up AnimatesSprite
AnimatedSprite animatedSprite(sf::seconds(0.13));
animatedSprite.setAnimation(walkingAnimationDown);
animatedSprite.pause();
animatedSprite.setPosition(700, 400);
sf::Clock frameClock;
sf::Music music;
if(!music.openFromFile("Pallet Town Theme.ogg"))
std::cout << "ERROR: Can't find Pallet Town Theme.ogg" << std::endl;
music.play();
music.setLoop(true);
float speed = 0.045f;
bool bNoKeyWasPressed = true;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
window.close();
if (event.type == sf::Event::LostFocus)
{
music.pause();
}
if (event.type == sf::Event::GainedFocus)
music.play();
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
if(animatedSprite.getAnimation() != &walkingAnimationUp)
{
animatedSprite.setAnimation(walkingAnimationUp);
}
animatedSprite.play();
animatedSprite.move(0, -speed);
animatedSprite.move(0, 0);
bNoKeyWasPressed = false;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
if(animatedSprite.getAnimation() != &walkingAnimationDown)
{
animatedSprite.setAnimation(walkingAnimationDown);
}
animatedSprite.play();
animatedSprite.move(0, speed);
bNoKeyWasPressed = false;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
if(animatedSprite.getAnimation() != &walkingAnimationRight)
{
animatedSprite.setAnimation(walkingAnimationRight);
}
animatedSprite.play();
animatedSprite.move(speed, 0);
bNoKeyWasPressed = false;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
if(animatedSprite.getAnimation() != &walkingAnimationLeft)
{
animatedSprite.setAnimation(walkingAnimationLeft);
}
animatedSprite.play();
animatedSprite.move(-speed, 0);
bNoKeyWasPressed = false;
}
else if(bNoKeyWasPressed)
{
animatedSprite.pause();
}
bNoKeyWasPressed = true;
// update AnimatedSprite
animatedSprite.update(frameClock.restart());
window.clear();
window.draw(ml);
ml.Draw(window, tmx::MapLayer::Back);
window.draw(animatedSprite);
ml.Draw(window, tmx::MapLayer::Front);
mll.Draw(window, tmx::MapLayer::All);
window.display();
}
return 0;
}
-
You can set the transparency of a layer via a slider in Tiled, which will allow you to hide layers if you need to. On the other hand I handle collision detection slightly differently - my reply became rather lengthy, so I've turned it into a blog post here (http://trederia.blogspot.co.uk/2013/10/collision-detection-with-tiled-maps.html). Hope it helps :)
-
Whaaaat went wrong here?
(http://puu.sh/4WHFU.png) (http://puu.sh/4WHFU.png)
Using SFML 2.1.
Any idea what could have caused this?
It compiled fine.
-
As stated, you access std::vector element past its size.
-
As stated, you access std::vector element past its size.
So my map is too big?
I have no idea what it means.
-
erk. Can you provide me with a map / tileset that causes this?
-
erk. Can you provide me with a map / tileset that causes this?
Here we go.
-
Thanks. You didn't include the png file, but my first impression is that the loader doesn't like the path to the png file in the tsx file. As a work around try putting the png file in the same folder as the tsx and edit the tsx file so
<image source="../Projects/Minecraft.png" width="256" height="256"/>
becomes
<image source="Minecraft.png" width="256" height="256"/>
oh and the tsx / png should be in the same dir as the tmx file, which will need
<tileset firstgid="1" source="../../../../Tiled/Minecraft.tsx"/>
changing to
<tileset firstgid="1" source="Minecraft.tsx"/>
-
Thanks, the Minecraft.png was indeed in the same folder. I changed the <image source> bit but no luck, still gives me exactly the same error.
This is so weird.
edit: lemme try the tmx thing
-
Works like a charm!
A bit more laggy than I hoped but then again 16x16 sprites are quite tiny. That and I'm multitasking while playing a game anyway.
Thanks so much!
-
No problem. It's a shame it doesn't really handle file paths properly but ISTR it involved either linking to boost::filesystem and I didn't want to add an extra dependency, or writing a proper file handler myself (which I'm too lazy to do :P ) I guess it ought to handle these errors a bit better though. I'll put it on the todo list for the next version.
-
There's a new feature in Tiled which is immensely helpful called "Collection of Images" tileset. It's xml code is a little different from the xml generated for regular tilesets and if I'm not missing something (hope I am) it throws off the map loader. I'm going to look and see if I can't find a fix for it in a little.
Just thought I'd let you know if you didn't already.
Love the map loader by the way.
-
Oh, thanks! I hadn't seen this yet, I shall definitely look into it. Once I get my act together I'll move the map loader to github so it'll be easier for other people to contribute 8)
-
Oh, thanks! I hadn't seen this yet, I shall definitely look into it. Once I get my act together I'll move the map loader to github so it'll be easier for other people to contribute 8)
I was able to get it working for my needs. However I've already modded how the loader draws image objects (which are the only things I use collection of images for) so my fix is fairly narrow and probably wouldn't help much. I'll use yours as soon as you finish it, I'm sure it'll be much more complete.
Also Github would be awesome. I was honestly a little surprised you didn't make a separate thread for your loader considering its completely different from the original one posted here. Anyways, Thanks for all the work you do on it :)
-
Do you have any links/examples for Collection of Images tile sets? I can't seem to find anything about it on the Tiled site.
Also, as promised GitHub page (https://github.com/fallahn/sfml-tmxloader) :)
-
Do you have any links/examples for Collection of Images tile sets? I can't seem to find anything about it on the Tiled site.
Also, as promised GitHub page (https://github.com/fallahn/sfml-tmxloader) :)
Yeah, https://github.com/bjorn/tiled/blob/6221c0c6cfa6d8fdbcbacb7c360d0e4fb7180b45/docs/map.xsd (https://github.com/bjorn/tiled/blob/6221c0c6cfa6d8fdbcbacb7c360d0e4fb7180b45/docs/map.xsd) is a link to the schema definition for the TMX (XML) files that get outputted. If you ctrl-f for "image.tileset" those are the changes that he made.
The actual changes to the xml are pretty minimal, where previously you would have a tileset arranged like this:
<tileset firstgid="" name="" tilewidth="" tileheight="">
<image source="" width="" height=""/>
<tile id="">
<properties>
<property name"" value=""/>
</properties>
</tile>
</tileset>
you now have
<tileset firstgid="" name="" tilewidth="" tileheight="">
<!-- no image here-->
<tile id="">
<properties>
<property name"" value=""/>
</properties>
<image source="" width="" height=""/>
</tile>
</tileset>
Also he explains the new format on the page you linked in your github https://github.com/bjorn/tiled/wiki/TMX-Map-Format (https://github.com/bjorn/tiled/wiki/TMX-Map-Format)
<tileset ...>
<tile id="[n]">
<!-- an embedded image --> //Not sure what this is
<image format="png"> //
<data encoding="base64">//
...
</data>//
</image>//
</tile>
<tile id="[n]">
<!-- an individually referenced image for a single tile -->
<image source="file.png"/>
</tile>
...
</tileset>
-
Thanks :)
So this is a new format which replaces the tsx schema? Or an additional format which allows multiple images to make up a single tsx/tileset? The commit date of the xsd file is from 3 years ago and the file itself says it was last updated 6/7/2008 so I'm a little dubious as to how up to date the schema is. I've always followed this (https://github.com/bjorn/tiled/wiki/TMX-Map-Format) which states that it is version 1.0 (not 0.7.0, which the xsd file implies).
If anyone else asks for this I may add it to the existing formats (while not replacing them) but for now I'll not act on it. If anyone wants to contribute this, however, I'll be more than happy to consider it :)
-
Thanks :)
So this is a new format which replaces the tsx schema? Or an additional format which allows multiple images to make up a single tsx/tileset? The commit date of the xsd file is from 3 years ago and the file itself says it was last updated 6/7/2008 so I'm a little dubious as to how up to date the schema is. I've always followed this (https://github.com/bjorn/tiled/wiki/TMX-Map-Format) which states that it is version 1.0 (not 0.7.0, which the xsd file implies).
If anyone else asks for this I may add it to the existing formats (while not replacing them) but for now I'll not act on it. If anyone wants to contribute this, however, I'll be more than happy to consider it :)
Ooh, you're right. My bad. I hadn't actually used the schema (just the changes I saw in the .tmx files.) I edited my post to include the document type definition, it looks like he documented the changes somewhere around 0.9.0.
These changes are in addition to the previous tilesets. So a regular tileset will still appear the same way in XML.
And that's fine. Like I said I've got my code working.
-
I got something basic set up and I was wondering what I can do to improve this. I can see the lines where the tiles are placed and I'm only getting 20fps, according to fraps. Here's a video, it doesn't show up too well but you can see the lines between some of the tiles.
http://youtu.be/MdZxVknEcXY
Thanks for any help I'm really new still.
-
I got something basic set up and I was wondering what I can do to improve this. I can see the lines where the tiles are placed and I'm only getting 20fps, according to fraps.
Make sure the tiles or view are always set to integer values (no 1.13 but just 1), it should remove the line issue.
As for FPS the FRAPS measuring isn't always the best way to get the FPS value, but it's quite possibly correct, it all depends on your implementation and PC power.
-
A few reasons I can think of:
You're using an old version. The latest is on GitHub (https://github.com/fallahn/sfml-tmxloader)
You're running in debug mode as opposed to release (although the frame rate drop should still not be that low)
You're drawing the debug layer and/or quadtree debug layer which can be slow
Fraps is limiting the frame rate
I've added an example called 'Benchmark' to the repository. Try building and running it in release mode. On my office machine (i5 quad core, ATi 7750, Win 7 64) I get just over 3000fps. You can use the cursor keys to move around - I've not experienced any tearing.
(http://djfallen.com/images/tmx_bench.png)
-
I was looking at the file with the benchmark and I have some suggestions:
- You may want to display milliseconds/microseconds per frame, because fps is nonlinear and not a good measurement for performance.
- And you are measuring the time in the middle of the frame not after the swap(display), so its actually not the time of one frame but a mix of part of the time from previous frame and part of the time from 2 frames ago.
-
So I had to take a break for a while due to classes and finals and I came back without changing any code from my last issue to get an error. I think the last thing I did was take a new map with the same name since my friend said he enjoyed making maps like that. I set up a breakpoint and it seems to create the error when it loads the map.
Debug Assertion Failed!
Program: C:\Windows\system32\MSVCP110D.dll
File: c:\program files (x86)\microsoft visual studio 11.0\vc\include\vector
Line: 1140
Expression: vector subscript out of range
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
sf::RenderWindow gameWindow(sf::VideoMode(Game::baseWidth, Game::baseHeight), "Legend of Link");
tmx::MapLoader ml("map/");
ml.Load("test_terrain.tmx"); //breaks here
-
Sounds like this (http://en.sfml-dev.org/forums/index.php?topic=3023.msg93541#msg93541) error. Try moving the images / tilesets to the same directory as the map file, and updating the paths in the map file itself. I'll make a note on the tracker to fix this :)
-
Thanks. I didn't even notice my tileset were set up differently.
-
Hey, I've been running performance analysis on some of my code and drawing a 25x25 map that has 2 layers and uses 1 sprite sheet through Tiled is holding about 29% of the samples. Is this normal?
(http://i.imgur.com/ZBk1lt3.png)
-
No idea. I've never tried any kind of analysis before and, to be honest, I have no idea what 29% of the samples means. However, if you want to try analysing the samples in the repository and perhaps the vertex array samples from the SFML tutorials for comparison I'd be interested in seeing the results.
-
Hey, I've been running performance analysis on some of my code and drawing a 25x25 map that has 2 layers and uses 1 sprite sheet through Tiled is holding about 29% of the samples. Is this normal?
Can't you tell your profiler where to find SFML's source code and resolve all those "sfml-graphics-d-2.dll" into something more useful?
It's normal that draw calls take up some time, whether it's normal with your setup is impossible to tell with the given information.
Is it already a performance issue on your end, or are you doing some premature optimization testing? ;)
-
No idea. I've never tried any kind of analysis before and, to be honest, I have no idea what 29% of the samples means. However, if you want to try analysing the samples in the repository and perhaps the vertex array samples from the SFML tutorials for comparison I'd be interested in seeing the results.
I'll be looking into it. I'll post back what I find.
Hey, I've been running performance analysis on some of my code and drawing a 25x25 map that has 2 layers and uses 1 sprite sheet through Tiled is holding about 29% of the samples. Is this normal?
Can't you tell your profiler where to find SFML's source code and resolve all those "sfml-graphics-d-2.dll" into something more useful?
It's normal that draw calls take up some time, whether it's normal with your setup is impossible to tell with the given information.
Is it already a performance issue on your end, or are you doing some premature optimization testing? ;)
That would be a nifty trick, I'll figure out how to do that seeing as like you said the info past m_DrawLayer is pretty useless.
I've been testing my code on different machines and focusing heavy on optimization lately. My goal is a solid 60 fps on Intel HD 4000 integrated graphics. I've gone from 20 to 35-40 in the last 10 days so so far so good.
EDIT: So for my purposes (Considering all animated tiles and objects are handled by my engine and not the tile map) just loading a .png of the level actually doubled my frame rate. I didn't end up testing the examples from the github. I may in the future if I find a need to use Tiled Map Loader to draw my maps.
-
If I wanted to use the Tiled editor to set points where say a chest would appear, the player spawns, or enemy spawns how would I do that? Would I use the object layer like you explained in the collision post?
-
I'd probably create an object layer for each type, so one for spawns, one for chests etc. Then, when parsing the map, grab the layer by name and create entities at each object position. Something like:
foreach layer in map.layers
if layer.name == "spawn"
foreach object in layer.objects
createItem(object.position)
-
Going through the code, it is not clear that vertex arrays are taken advantage of to draw each layer in a single call. As far as I can tell, each tile is represented by a sprite and each of those is drawn individually. Instead, each tile should only hold 4 sf::Vertex; in the draw function, if the tile is visible, then append its vertices to the vertex array to be drawn.
-
Not sure you're looking at the current version (https://github.com/fallahn/sfml-tmxloader/blob/master/src/MapLoaderPrivate.cpp).
In m_AddTileToLayer()
layer.vertexArrays[m_tileInfo[gid].TileSetId].append(v0);
layer.vertexArrays[m_tileInfo[gid].TileSetId].append(v1);
layer.vertexArrays[m_tileInfo[gid].TileSetId].append(v2);
layer.vertexArrays[m_tileInfo[gid].TileSetId].append(v3);
In draw()
states.texture = &m_tilesetTextures[i];
rt.draw(layer.vertexArrays[i], states);
Individual sprites are stored for tiles during loading, but they are only ever drawn by objects which are of type Tile, and image layers which consist of a single sprite.
EDIT: On reflection object layers which use a lot of tiles could benefit from also using vertex arrays - but it may involve a considerable rewrite when taking into account transforms such as flipping / rotating objects which is a feature that should be added to Tiled (http://blog.mapeditor.org/2013/04/tiled-development-update.html) soon. This would be much easier to handle using sprites.
-
I don't know how many people use box2D in their projects (certainly no one has asked for this) but I thought I'd add this feature anyway. You can now create box2D physics bodies from tmx map objects - here's a demo vid:
http://www.youtube.com/watch?v=3EukqhrU8ms
I wrote a bit about it on my blog (http://trederia.blogspot.co.uk/2013/12/tiled-map-loader-for-sfml-and-box2d.html), and uploaded the class to the github page (https://github.com/fallahn/sfml-tmxloader).
-
Hi,
This project looks awesome. I'm trying to compile it on Linux and having some trouble. Specifically, I get the following error;
src/MapObject.cpp:220:37: error: non-const lvalue reference to type
'Vector2<[...]>' cannot bind to a temporary of type 'Vector2<[...]>'
return Helpers::Vectors::Normalize(end - start);
^~~~~~~~~~~
/home/cole/Desktop/sfml-tmxloader/include/Helpers.h:70:47: note: passing
argument to parameter 'source' here
static sf::Vector2f Normalize(sf::Vector2f& source)
^
1 error generated.
Which is associated with this function:
sf::Vector2f MapObject::CollisionNormal(const sf::Vector2f& start, const sf::Vector2f& end) const
{
Segment trajectory(start, end);
for(auto& s : m_polySegs)
{
if(trajectory.Intersects(s))
{
sf::Vector2f v = s.End - s.Start;
sf::Vector2f n(v.y, -v.x);
//invert normal if pointing in wrong direction
float tAngle = Helpers::Vectors::GetAngle(end - start);
float nAngle = Helpers::Vectors::GetAngle(n);
if(nAngle - tAngle > 90.f) n =- n;
return Helpers::Vectors::Normalize(n);
}
}
return Helpers::Vectors::Normalize(end - start);
}
I have limited experience with C++, and I don't know what this code is supposed to do, but I was able to make the code compile by changing the second return line to:
return sf::Vector2f(0,0);
The examples seem to work with this code (although it's probably doing something horrendous somewhere; I don't know).
Is this problem just on my end? Am I doing something incorrectly? Thanks.
-
Hi, a lot of the collision stuff is not thouroughly tested - I don't even have a linux machine right now - so this may well be a bug. Try constructing a new vector from end-start and return that via normalize and let me know if it works. I'll make a note of it on the tracker.
-
How would I get an affect of walking in grass similar to Pokemon?
(http://oi56.tinypic.com/majiv7.jpg)
The character's legs disappear in the grass but their upper half is still visible. Is this possible with tiled and your map loader?
-
For that you have to have the sprite separated in two halfs (upper and lower body). Just check if the sprite is drawn onto a tile where semi-high things are (grass, snow, etc.) and only draw the upper body.
Not sure if this is possible with this map loader, but it is not that difficult in general.
-
That's what I was discussing with a friend and we came to the conclusion it would have to be a sprite split in half.
Thanks.
-
@fallahn
Hello I'm new here , started programming with C++/SFML. I want to try out your loader with the benchmark example. (VC2013) What have I do to compile the Benchmark example. (always get linker Errors)
The SFML intergration in VC2013 works.
Thanks
cyberpala
-
What linker errors do you get? The map loader needs to be linked against zlib as well as sfml
-
Hello,
Sorry to bother, I'm interested in the project and I'd like to learn how to use it however I can't even get it built!
It's probably something wrong on my side but here is the error cmake is giving me:
CMake Error at CMakeLists.txt:32 (install):
install Library TARGETS given no DESTINATION!
CMake Error at cmake/Modules/FindSFML.cmake:307 (message):
Could NOT find SFML (missing: SFML_SYSTEM_LIBRARY SFML_WINDOW_LIBRARY
SFML_GRAPHICS_LIBRARY)
Call Stack (most recent call first):
CMakeLists.txt:40 (find_package)
-
CMake Error at cmake/Modules/FindSFML.cmake:307 (message):
Could NOT find SFML (missing: SFML_SYSTEM_LIBRARY SFML_WINDOW_LIBRARY
SFML_GRAPHICS_LIBRARY)
Call Stack (most recent call first):
CMakeLists.txt:40 (find_package)
It doesn't find SFML. You need to set SFML_ROOT in CMake to the root dir of SFML.
-
Hey,
There seems to be a bug in
TileQuad::Ptr MapLoader::m_AddTileToLayer(MapLayer& layer, sf::Uint16 x, sf::Uint16 y, sf::Uint32 gid, const sf::Vector2f& offset)
Where you do
//applying half pixel trick avoids artifacting when scrolling
v0.texCoords = m_tileInfo[gid].Coords[0] + sf::Vector2f(0.5f, 0.5f);
v1.texCoords = m_tileInfo[gid].Coords[1] + sf::Vector2f(-0.5f, 0.5f);
v2.texCoords = m_tileInfo[gid].Coords[2] + sf::Vector2f(-0.5f, -0.5f);
v3.texCoords = m_tileInfo[gid].Coords[3] + sf::Vector2f(0.5f, -0.5f);
If I run it as is, all my tiles have a half-pixel weirdness to them, but if I remove the extra half pixels, it works perfectly. I tried with tilesets that have no margin/padding and some that have a margin/padding, it happens with both. I'm using SFML-master (today's snapshot) and MinGW 4.8.1.
Before / After
(http://i.imgur.com/tkTberM.png) (http://i.imgur.com/od7Tgbo.png)
-
What happens when you scroll your view? The half pixel fix only really applies when a view is scaled or scrolled. How do the examples look when you compile them? They work fine on every machine I've tested, but I haven't performed an exhaustive set of tests. If the examples also exhibit this behaviour for you then it may be a graphics driver issue
-
I tried Benchmark.cpp and the issue is still present. However, if I remove the half pixels and maximize the window, scrolling will sometimes vertical gaps, is that what you meant?
I'll look at it more when I get back from work. I'm running Win8 64 bits with a Radeon HD5850, latest drivers.
-
Yes, the gaps when scrolling is what I mean. It's a well documented artifact using vertex arrays (there are several posts on the forum about it). I don't have access to a Win8 machine, but I do have my suspicions about the latest AMD driver. When I updated from 13.9 to 13.12 on 2 machines I found that 1 in 3 times (more or less) I couldn't even create an SFML window without it hanging on a white screen. Updating to the latest beta drivers fixed this. AMD are obviously working on updating their OpenGL implementation too, as updating the drivers broke a few of my shaders which, as it turned out, was due to my shader code not being as strictly adherent to GLSL as they should be (so in this case the AMD update is a good thing). I'm not sure what to suggest as a fix unfortunately.
-
Unfortunately, the beta drivers didn't help.
I just tried it on my netbook running archlinux and an Intel GMA 3150 and I have the same issue. I built SFML from the sfml-git package available in AUR and built sfml-tmxloader & BenchMark using the CMakeList.txt included in the git repo.
But when I remove the half pixels and rebuild, it works.
Here's the ouput from glxinfo on my netbook:
OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) IGD x86/MMX/SSE2
OpenGL version string: 2.1 Mesa 10.1.0
OpenGL shading language version string: 1.20
Could it be something introduced in SFML-2.1? (I tried using the official 2.1 build as well, same issue)
Worst case scenario, I'll just remove them until I find a better fix, as my current game is zoomed in and doesn't show any artifacts when scrolling.
-
Just so you know, the sfml-git package is about a month out of date, but looking at the list of commits, there shouldn't be any differences.
-
hmm, this is a real head scratcher. I just tried a fresh build of sfml on mint 16, and built the tmx benchmark via cmake/make. It works fine. I'll make a note of this on the issue tracker, and try to find some other machines to test on.
-
In benchmark, try setting your view to 80x60 pixels and see what you get.
I added this to line 61:
view.setSize(80, 60);
You cans see the difference in the two images I've attached. The offset is really subtle, I don't really see it if I don't zoom the view.
-
Ah, yes I see it now. Presumably a floating point rounding error. Not sure what can be done about that. :-\
-
Hello,
Sorry to bother, I'm interested in the project and I'd like to learn how to use it however I can't even get it built!
It's probably something wrong on my side but here is the error cmake is giving me:
CMake Error at CMakeLists.txt:32 (install):
install Library TARGETS given no DESTINATION!
CMake Error at cmake/Modules/FindSFML.cmake:307 (message):
Could NOT find SFML (missing: SFML_SYSTEM_LIBRARY SFML_WINDOW_LIBRARY
SFML_GRAPHICS_LIBRARY)
Call Stack (most recent call first):
CMakeLists.txt:40 (find_package)
Hey guys, still no luck.
I've built zlib and box2d and I still am getting this error:
CMake Error at CMakeLists.txt:32 (install):
install Library TARGETS given no DESTINATION!
Line 32 reads : install(TARGETS pugi ${PROJECT_NAME} LIBRARY DESTINATION lib)
-
CMake can't find SFML - which is quite common on windows (because... windows). Alternatively you can just add the cpp files to your project, and as long as you link to zlib (and optionally box2d) everything will work fine.
-
Did you even read the error message? The issue is with installing pugi and has nothing to do with finding SFML.
Might be a misshaped CMake file. Would have to test it myself to say for sure. If you just want to build it, then you could remove that install line and copy pugi to the destination yourself. ;)
-
CMake Error at CMakeLists.txt:32 (install):
install Library TARGETS given no DESTINATION!
CMake Error at cmake/Modules/FindSFML.cmake:307 (message):
Could NOT find SFML (missing: SFML_SYSTEM_LIBRARY SFML_WINDOW_LIBRARY
SFML_GRAPHICS_LIBRARY)
?
-
CMake Error at CMakeLists.txt:32 (install):
install Library TARGETS given no DESTINATION!
Line 32 reads : install(TARGETS pugi ${PROJECT_NAME} LIBRARY DESTINATION lib)
? ;)
-
Is a compiler that supports C++11 really necessary?
I'm using VC2010 and would hate to have to move to one of the more recent and somewhat unintuitive versions. :-\
-
You can look at the source to see whether there are C++11 functions in use.
Personally the only reason I can kind of understand for sticking to VS 2010, is if they have bought it or are forced to do so by a company. Other than that there are no reasons to stay with something that is two major version behind. ;)
-
Ok, so I got this working after a bit of trouble setting up zlib.
Thx for this awesome tool!
Much easier to use than my own convoluted map making system.
Is there a way to only draw what is currently within the view to improve performance on big maps?
I loaded a 1024 x 1024 tile map where each tile is 64 x 64 pixels, and I get around 11 FPS.
I know if I'm having FPS issues as a result of map size then I should just break the map into smaller maps that get loaded individually as the player enters that area, but I would like to be able to implement this feature for if I need to in the future.
-
Currently the map loader creates a vertex array for each tileset used on a layer, so one tileset on one very large layer will create one very large vertex array. You could possibly break this down by using multiple tilesets, or use multiple layers - for example 4 separate layers to create 4 quadrants of the map. The map loader will then only draw any vertex array which intersects the view - so the worst case scenario is when the view is at the centre of the map and all 4 vertex arrays are drawn at once. Best case only one smaller vertex array is drawn, which ought to apply to the majority of the map. This is semi-scalable up to the point a single layer fits entirely in your view - but you could go ahead and split it again into 16 quadrants, making the vertex arrays much smaller, at the cost of a more convoluted map file in Tiled
EDIT:
actually when I wrote that it wasn't true that the map loader performed culling of vertex arrays which weren't in view. I've updated the source on github so now it does.
-
Hello guys! This sounds like a brilliant tool. I've been trying to get it working for a bunch of hours now. Could I please have some help?
Here is my errors:
Error 2 error LNK2001: unresolved external symbol "public: __thiscall tmx::MapLoader::MapLoader(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (??0MapLoader@tmx@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) C:\Users\Conor\Desktop\Visual Studio 2012\Projects\ConsoleApplication9\ConsoleApplication9\Source.obj ConsoleApplication9
Error 1 error LNK2001: unresolved external symbol "private: virtual void __thiscall tmx::QuadTreeNode::draw(class sf::RenderTarget &,class sf::RenderStates)const " (?draw@QuadTreeNode@tmx@@EBEXAAVRenderTarget@sf@@VRenderStates@4@@Z) C:\Users\Conor\Desktop\Visual Studio 2012\Projects\ConsoleApplication9\ConsoleApplication9\Source.obj ConsoleApplication9
Error 3 error LNK1120: 2 unresolved externals C:\Users\Conor\Desktop\Visual Studio 2012\Projects\ConsoleApplication9\Release\ConsoleApplication9.exe ConsoleApplication9
Here is the code:
#include <stdio.h>
#include <string>
#include <zlib.h>
#include <tmx/MapLoader.h>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
int main(){
tmx::MapLoader("maps");
}
I have proven SFML works and everything just before that one bad line of code, but when I try tmx::MapLoader(anystring) it produces those errors. I personally think it's a problem with zlib being linked but I can't for the life of me figure it out after hours of trying.
I'm on windows 7 with VS 2012
SFML 2.1
zlib 1.2.8
Thanks for your time. :)
-
Have you added the CPP files (except tmx2box2d.CPP) in the tmx source folder to your project?
-
OMG thank you so much. You've seriously made my day. A quick reply, exactly what I needed, I just didn't realize things were done that way I thought it was all about like, including .h or .hpp files and then they find the .cpp files for me or something.
Thanks very much!
Conor
-
Can the order in which the layers are drawn be changed?
I want to have my player sprite be able to appear to be fully/partially behind objects if an object is in front of them, i.e. further down on the screen than the player.
Like this:
(https://cdn.tutsplus.com/gamedev/authors/legacy/Nick%20Bruner/2012/12/12/finalimage.png)
I was thinking something along the lines of using the quad-tree system used for collision to find anything that is close enough to be considered for reordering, then draw anything that is further up on the Y than where the player's sprite is first, then draw anything below the player on top.
Is this feasible?
-
Or you can render tiles top to bottom, so when the tree is rendering, it will already occlude the player behind it. When the player is below the tree, it would appear on top of the tree, because the tree would be drawn before.. I think this _might_ be a solution to that problem :p
-
Uhhh... That is pretty much what I am proposing.
The thing is that the whole map gets drawn, then the player.
I need to be able to slot my player in between the different layers to achieve the effect of the bottom being in front of the player.
-
There's no specific z-ordering as such (although there was a partial implementation of being able to insert sprites onto specific layers - I don't remember where I got to with that) but you can draw a specific layer with
MapLoader::Draw(sf::RenderTarget& rt, sf::Uint16 index, bool debug = false)
so with a bit of finagling you could come up with some logic which decides which layer should be drawn and when
-
...
actually when I wrote that it wasn't true that the map loader performed culling of vertex arrays which weren't in view. I've updated the source on github so now it does.
Does it do it automatically?
I decided to test it out on a 512 x 512 tile map @ 64 x 64px tile size, where the map is just 4 layers, each one representing each quarter of the map.
(http://oi60.tinypic.com/sxc2g3.jpg)
I load the map and run the program in release, and get around 10-12 FPS no matter where the view currently is. It is the same if the view is right in a corner of the map, or on top of where all the layers meet.
Am I doing something very wrong?
(Yes I've updated to the most recent github version of the maploader.)
-
It *should* do it automatically...
but to be perfectly honest I've not thoroughly tested it (thanks to our good friend Real Life)
The idea is this: when the map loader parses layers of tiles it creates a vertex array for every tileset per layer. Each tile is made up of 4 vertices which are appended to the vertex array. Every time a tile quad is appended to the vertex array (which belongs to the LayerSet class) the vertex array updates its AABB (again, belonging to the LayerSet class). When each layerset is drawn its AABB is tested against the view port to test if it is visible, and cull it if it is not.
If you want to test this (I'm sorry but I really don't have the time myself) then the lines to note are:
here (https://github.com/fallahn/sfml-tmxloader/blob/master/src/MapLayer.cpp#L75), here (https://github.com/fallahn/sfml-tmxloader/blob/master/src/MapLayer.cpp#L112) and here (https://github.com/fallahn/sfml-tmxloader/blob/master/src/MapLoaderPrivate.cpp#L930).
-
This project looks really cool, but I'm having some difficulties building the example programs (in this case, Benchmark.cpp). I've looked at all the posts in this thread and I think I'm having an issue with the zlib library and Visual Studio 2012 ( I'm a VS newbie ). I have a feeling I'm making a common mistake and hopefully somebody might be able to catch it 8).
So, I have a VS project set up for TMX and SFML, it looks like the screenshot in my attachments. I think I have the TMX files linked correctly with Visual Studio. I know how to get SFML working, so I can check that off. I downloaded the zlib library from zlib.net ( the one with the DLL ) because I saw somebody post that earlier in the thread. It's called " zlib128-dll " and has a .dll file within called " zlib1.dll ". I put the zlib1.dll file in the debug folder in my project like I do with SFML .dll's for dynamic linking.
In Project Properties->Configuration->C/C++->General I have this:
C:\Program Files (x86)\SFML-2.1\include;C:\sfml-tmxloader-master\sfml-tmxloader-master\include;C:\zlib128-dll\include;
Then in Project Properties->Configuration->Linker->General
C:\Program Files (x86)\SFML-2.1\lib;C:\zlib128-dll\lib;
Lastly, in Project Properties->Configuration->Linked->Input->Additional Dependencies
sfml-system-d.lib;sfml-graphics-d.lib;sfml-main-d.lib;sfml-window-d.lib;
I trimmed the last line a bit because the rest of the library files are probably irrelevant for this ( like kernel32.lib ). Any suggestions?
-
I don't see a reference to the zlib .lib on the last line? Also you need to add the pugixml CPP file to your project.
-
Oh, I knew it was something small. Thanks. This looks really neat.
Is there a preferred way to make the Tiled images? Do you just make them with a paint program like GIMP or MS Paint?
-
Hi Everyone! I'm new here and I'm trying to code a mini game. I'm having a bit of a problem I haven't been able to resolve. Could anyone help me please?
My main problem is that I can not acces (Get information about) my tiles. I can have everything about my objects but not about my tiles. How is that? How can I fix it? What am I doing wrong? Could you guys help me please?
P.S: Attach image with code and prints.
-
Unfortunately the map loader doesn't store information about each individual tile, you'll have to add the functionality yourself
-
Hello again. I've been working with your great Map Loader. I've drawn some collision boxes in TileD and I'm trying to get the rectangle or its x and y values. How do I achieve this? What is QuadTrees? Thanks in advance. :D
-
Have a look at these
https://github.com/fallahn/sfml-tmxloader/wiki
-
So... trying to do this will be usless, wont it?
if(layer->name == "Capa de Patrones 1"){ //tile layer
for(auto tile = layer->tiles.begin(); tile != layer->tiles.end(); ++tile)
{
//collision = object.sprite->getGlobalBounds()->Intersects();
if(collision){
//something
}
}
}
}
/* */
And what about if I wanted to do destroy an object when collision is detected?:
for(auto layer = ml2.GetLayers().begin(); layer != ml2.GetLayers().end(); ++layer)
{
if(layer->name == "Destructible")
{
for(auto object = layer->objects.begin(); object != layer->objects.end(); ++object)
{
collision = object->GetAABB().intersects(pj->getSprite().getGlobalBounds());
if(collision){
//wanna destroy object here, how could I do it?
}
}
}
}
-
Rather than make the map objects themselves game entities, you could use them as spawn points. For example:
for(const auto& o : layer.objects)
m_items.push_back(std::make_unique<Collectable>(o.GetPosition()));
then for collision testing and destruction you don't even need to query the map:
for(auto& i : m_items)
{
if(i.contains(player.bounds))
i.setCollected(true);
}
m_items.erase(std::remove_if(m_items.begin(),
m_items.end(),
[](const Item::Ptr& p)->bool
{
return (p->Collected());
}), m_items.end());
-
Fallahn, you've really helped me. Thanks I appreciate it! I have collision working from just making levels in TileD now too. :)
-
Rather than make the map objects themselves game entities, you could use them as spawn points. For example:
for(const auto& o : layer.objects)
m_items.push_back(std::make_unique<Collectable>(o.GetPosition()));
then for collision testing and destruction you don't even need to query the map:
for(auto& i : m_items)
{
if(i.contains(player.bounds))
i.setCollected(true);
}
m_items.erase(std::remove_if(m_items.begin(),
m_items.end(),
[](const Item::Ptr& p)->bool
{
return (p->Collected());
}), m_items.end());
how would I declare "m_items"? tmx::MapObject array? std::Vector<tmx::MapObject>?
thx in advance :)
-
This is just pseudo code really. What I'm suggesting is that you make your own class which represents collectable items (although the same can be done for things like enemies)
class Collectable
{
public:
typedef std::unique_ptr<Collectable> Ptr;
Collectable(sf::vector2f spawnPosition);
void SetCollected(bool b){m_collected = b;}
bool Collected() const {return m_collected;}
private:
m_collected = false;
};
then in your game class (or whichever loads the map) have a container (m_items) of Collectable::Ptr which can be populated when loading the map. Then when you update your game you test the container for collisions (not the map itself), and remove items once they are collected.
-
Sounds a great idea! but there's something I'm missing. If I do it that way, when it comes to the point in which I have to draw the map (in the main iteration), yeah, I do erase the object from the vector but, not from the map?
-
once the map is loaded and collectables / npcs / whatever are created the map objects become moot, so you just ignore them. All you need worry about is drawing the map (and any sprites you may have, of course).
-
Still having problems to add, remove objects from layers. Tried the easiest way I could. I succesfully add the object to layer but seems to be having problems when drawing (seems it does not 'update' or refresh the layer objects at the time of drawing)
-
Hi I'm trying to get the tiled map loader up and running, I have all the libraries and includes done as well as the .cpp files added to the solution. I'm using VS 2012. The program runs just fine but it breaks when I run this command in the code down below. It says "A buffer overrun has occurred in "Time-Voyager.exe" which has corrupted the programs internal states. Press break to debug the program or continue to terminate.". The last call stack says this: "msvcr110.dll!_crt_debugger_hook(int _Reserved) Line 60 C" I'm not sure what to do I've tried everything.
#include <stdio.h>
#include <iostream>
#include <zlib.h>
#include <tmx/MapLoader.h>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <math.h>
using namespace sf;
int main(){
tmx::MapLoader myMap("maps\\");
}
-
@loopback:
You're making copies of the layers, instead of referencing them (they should actually be non-copyable, I'll have to fix that). If you make references to the layers and modify them then you should only need to call window.draw(myMap)
@KevinK:
There's not much there to go on; a wild stab in the dark I'd suggest changing the path, either replace \\ with / or leave it off altogether - the map loader should automatically add it if it's missing.
-
and How can I make those references to layers instead of making copies?
-
The same way as you make any other reference. (http://www.parashift.com/c++-faq-lite/overview-refs.html)
-
Well I messed around with it for a number of hours today, I was able to get my program to compile in debug only... what made debug work was changing from sf::String to std::string and adding the full path to my files, for whatever reason. But when I try to run my program in release it still crashes from a buffer overrun :/ I'm not sure what to do to get release mode working. I tried googling my problem to try and find similar issues and they were all not very useful. I had a lead to possibly the encoding that was causing the buffer overrun but I don't know anything about encoding.
const std::string pathToPlayer = "C:\\Users\\Kevin\\Documents\\Visual Studio 11\\Projects\\Time-Voyager2\\player.png";
const std::string myMapString = "C:\\Users\\Kevin\\Documents\\Visual Studio 11\\Projects\\Time-Voyager2\\maps";
const std::string filename = "test.tmx";
const std::string caption = "TileD Maps";
int main(){
std::cout << myMapString.length();
tmx::MapLoader myMap(myMapString);
myMap.Load(filename);
}
-
KevinK,
It really sounds like you got something screwed up in your environment. Mismatched libs, libs for a different compiler, and many other things. I suggest you delete all SFML and Tiled files from your PC, then download SFML source from github and compile that yourself. Then download and compile the Tiled source to see if that fixes the issue.
Also use forward '/' slashes in your paths. ;)
-
Hey, first of all thanks for sharing your work with us .. =).
Unfortunately I have a problem with creation of the project files with CMake.
Like Ricky (http://en.sfml-dev.org/forums/index.php?topic=3023.msg104256#msg104256 (http://en.sfml-dev.org/forums/index.php?topic=3023.msg104256#msg104256))
the error CMake is providing is as follows:
CMake Error at CMakeLists.txt:32 (install):
install Library TARGETS given no DESTINATION!
Apart from that there arent any errors.
I would be very happy, if you could provide a solution for this problem.
I read on the same page about commenting this line out, but this shouldnt be the final solution, should it?
Greetings!
-
Simpl,
I had CMake errors with an SFML project last week and I needed to have SFML_ROOT defined in the path variables. And SFML_ROOT would link to where my SFML libraries are located on my computer ( specifically the Cmake folder in SFML ). I'm not sure if that'll help you. It looks like you need a destination to install though, did you specify a destination in the "where to build the binaries" if you're using CMake GUI?
-
I'm assuming you're trying to build on windows. There's a line (https://github.com/fallahn/sfml-tmxloader/blob/master/CMakeLists.txt#L32) which installs the pugixml lib on linux which should have an 'if(UNIX)' condition which I haven't added yet. Commenting this out should fix it for now.
-
I'm currently having issues with the TMX loader and setting object's visablity to false to have them not drawn.
if (handleEvent.type == sf::Event::EventType::KeyPressed && sf::Keyboard::isKeyPressed(sf::Keyboard::E))
for(auto layer = ml.GetLayers().begin(); layer != ml.GetLayers().end(); ++layer)
{
if(layer->name == "Interactables")
{
for(auto object = layer->objects.begin(); object != layer->objects.end(); ++object)
{
if (object->Contains(sf::Vector2f(tankSprite.getPosition().x, tankSprite.getPosition().y)))
{
if (object->GetType() == "Computer")
{
for(auto object2 = layer->objects.begin(); object2 != layer->objects.end(); ++object2)
{
if (object2->GetType() == "Laser")
if (object2->GetName() == object->GetName())
{
object2->SetVisible(false);
object2->SetProperty("State", "Off");
}
}
}
}
}
}
}
That's how I am doing it but when I look at the map the object is still being drawn. I've checked to make sure the objects I want are not being set to visable when drawn with
for(auto layer = ml.GetLayers().begin(); layer != ml.GetLayers().end(); ++layer)
{
if(layer->name == "Interactables")
{
for(auto object = layer->objects.begin(); object != layer->objects.end(); ++object)
{
if (object->Visible())
std::cout << "STILL THERE! " << object->GetType() << std::endl;
}
}
}
Sorry if this code is rather sloppy, I've been quickly writing it as a proof of concept for tmx loader. Any insight to what I am doing wrong and why the objects are still being drawn on the screen would be greatly appreciated.
Thanks,
MJBrune
-
You're right. I've had a look and the object visibility flag has no effect. This is because originally objects were drawn with sprites, but have since been updated so that all objects are now part of a vertex array - making it much harder to change the visibility of individual objects (if not impossible). An oversight on my part. I can only suggest that to attach your own sprites to objects if you want an immediate fix, until I decide how to proceed on this.
-
Just a shot in the dark but couldn't you store all the vertices in an object and when the visibility flag is set you can then calculate to draw only the visible objects? Somehow taking advantage of https://www.opengl.org/sdk/docs/man/docbook4/xhtml/glDrawRangeElements.xml this function?
-
That looks like a reasonable tactic. I had considered the possibility of rewriting much of the drawing code using OpenGL, although I have very little time to work on this right now (beyond opening a new issue (https://github.com/fallahn/sfml-tmxloader/issues/16)). Pull requests are always welcome ;)
-
Hello !
I'm new in SFML programming, but thank you very much for your tmxloader, it's very useful !
I'm trying to add an object in the map, it's quite easy (I used your example AddRemoveObjects.cpp) but I can't figure out how to give the object a texture.
The object is well created and drawn, I can see it with DrawDebugShape() but it remains an empty box with no texture.
I tried to create a LayerSet with the good texture, AddTile and then use SedQuad on my object, but this has no effect.
Can you help me ?
Thank you !
-
I've not actually tried this (it's been a while since I looked at the map loader) but I think you're on the right track. The layerset you create has to be attached to a layer to be drawn iirc, and the object needs its type set to 'tile'.
-
Hi there !
I try to use the TMX map loader with QTCreator (under Ubuntu)
When I compile I get those errors :
15:57:23: Running steps for project TestTML...
15:57:23: Configuration unchanged, skipping qmake step.
15:57:23: Starting: "/usr/bin/make"
g++ -m64 -o TestTML main.o MapLoaderPrivate.o MapLoaderPublic.o QuadTreeNode.o pugixml.o -L/home/seb/Progs/libs/SFML-2.1/lib -lsfml-graphics -lsfml-window -lsfml-system
/usr/bin/ld: MapLoaderPrivate.o: undefined reference to symbol 'inflateInit2_'
//lib/x86_64-linux-gnu/libz.so.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make: *** [TestTML] Error 1
15:57:23: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project TestTML (kit: Desktop)
When executing step 'Make'
15:57:23: Elapsed time: 00:00.
I also get a lot of warnings, but it looks like the errors have something to do with the zlib ?
If I do a "locate libz.so" in a terminal, I get this :
/lib/i386-linux-gnu/libz.so.1
/lib/i386-linux-gnu/libz.so.1.2.8
/lib/x86_64-linux-gnu/libz.so.1
/lib/x86_64-linux-gnu/libz.so.1.2.8
/usr/lib/x86_64-linux-gnu/libz.so
-
Could you help me please ? :'(
-
-lzlib?
-
Could you help me please ? :'(
It's not so friendly to push the thread only after 5 hours, especially considering that this is not a general SFML topic that the whole community can answer, but a user's project. The developer most probably has a life apart from this project, so have some patience and research on your own while you're waiting...
-
Hello,
It's ok, I found where was the problem, I added "-lz" to my .pro file...
-lzlib
Thank you, it's not -lzlib but you put me on the track.
@Nexus : Sorry
-
Well from the looks of it you're checking to see if the player has fallen into the object, and stop the falling when it has, but you never move the player back out again. Presumably it'll never move, because left/right are always false while the object contains the player. At a most basic level I use the MapObject function GetCollisionNormal() (I think it's called) and use it to reflect the player's current velocity which will move it back out of the object again. For a much better article on 2D platformers, I like this article (http://www.wildbunny.co.uk/blog/2011/12/11/how-to-make-a-2d-platform-game-part-1/), however.
-
I feel dumb stupid, but could you explain how to build your TMXLoader? On windows. With VS2013 Express.
I don't work with C++ and I have absolutely no idea about what to do to build it. Or is there a binary somewhere that I can't see?
Thanks.
-
If you don't know C++ this probably isn't going to be very easy.
Firstly you need to find or build a compatible binary for zlib.
Optionally you need to build box2D.
Afterwards you can either use the included cmake file to configure a VS2013 project which will build a binary you can link to, or you can add the source files directly to your project. Either way you will also need to link zlib (and box2D if you are using it).
-
Thought so. Way too freakingly complicated for my dumb self.
I tried but i have no idea about C-Make and all that jazz. :(
Guess this one is not for me.
-
So far I have linked the zdlib onto my project and included the .h file from the 'tmx and pigixml' folder with the .cpp files added directly into my project. The error I get however was like this
Error 1 error LNK2019: unresolved external symbol _inflate referenced in function "private: bool __thiscall tmx::MapLoader::m_Decompress(char const *,class std::vector<unsigned char,class std::allocator<unsigned char> > &,int,int)" (?m_Decompress@MapLoader@tmx@@AAE_NPBDAAV?$vector@EV?$allocator@E@std@@@std@@HH@Z) D:\VS 2013 File\my sider is crolling\my sider is crolling\MapLoaderPrivate.obj my sider is crolling
Any solution?
-
That's a linker error suggesting zlib is not correctly linked. Double check the library paths in your project settings, and make sure zlib.lib is named explicitly in the file list (in both debug and release modes)
-
First of all, thank you for this great map loader! I'm using it in my game project and it works really well. Except, I have a problem now that I couldn't solve.
If I understand correctly, the Intersects method in MapObject class is supposed to return true when the two MapObjects have overlapping area, false otherwise. At least that is how I expected to use it. However, it gives random results for me.
The code I wrote looks like this:
void Player::interact()
{
std::cerr<<"E"<<std::endl;
//Determines the new position of the interactBox (a rectangular MapObject)
sf::Vector2f pos;
pos.x = getPosition().x + direction.x*10.f -inbox_width/2;
pos.y = getPosition().y + GetAnSprite().getLocalBounds().height/2 + direction.y*10.f -inbox_height/2;
//Sets position of the box
interactBox->SetPosition(pos);
//finds the right layer and checks for objects
std::vector<tmx::MapLayer> layers = Game::getMapLoader().GetLayers();
for(auto& layer : layers)
{
if(layer.type == tmx::ObjectGroup && layer.name == "interaction")
{
for(auto& obj : layer.objects)
{
if(interactBox->Intersects(obj))
{
std::cerr<<obj.GetName()<<std::endl;
break;
}
}
break;
}
}
}
This method is called everytime I press "E".
I recorded an example of how it behaves: http://gfycat.com/PerkyIncredibleHeron (http://gfycat.com/PerkyIncredibleHeron) Here the red box is the DebugShape of interactBox, the gray boxes are the objects in the "interactions" layer of the map. The first sign I am trying to interact is named "sign1" and the gray box at the top that I can interact without even touching is named "rect1".
It seems I have done something wrong and I just can't figure out why! I have poor programming skills despite coding for many years so it would be very nice if whoever understands my problem explains it to me in a simple way. Thank you in advance!
-
This is probably a bug in the intersects() function (I've not had time to work on this for ages, and the bugs are really beginning to build up :/). An alternate approach I've applied in the past is to allocate a list of points to a player / sprite, then check each one to see if it is contained within a map object. Something like:
class Player
{
...
private:
std::array<sf::vector2f, 4u> m_points = {{-0.5f, -0.5f}, {0.5f, -0.5f}, {0.5f, 0.5f}, {-0.5f, 0.5f}};
};
...
Player::interact()
{
for(const auto& o : layer.objects())
{
for(const auto& p : m_points)
{
if(o.contains(getTransform().transformPoint(p))) collide();
}
}
}
Also, I might suggest (assuming you get this to work) using the quad tree class (http://trederia.blogspot.co.uk/2013/06/optimising-collision-testing.html), or some other partitioning method to reduce the number of objects you test for collision :)
-
To be honest I was already using four points for my characters to handle obstacles while walking but I wanted the player to be able to interact with characters in the same way. Since I couldn't check two sets of points against each other, I decided to use MapObjects instead. Now that you said there is probably a bug, I got more confident in my code and looked thoroughly at the MapObject class to find out what happens exactly.
I found the problem to be in the "SetPosition" or more precisely the "move" method of MapObject:
void MapObject::Move(const sf::Vector2f& distance)
{
//update properties by movement amount
m_centrePoint += distance;
for(auto& p : m_polypoints)
p += distance;
m_debugShape.move(distance);
m_AABB.left += distance.x;
m_AABB.top += distance.y;
//set new position
m_position += distance;
//if object is of type tile move vertex data
if(m_tileQuad) m_tileQuad->Move(distance);
}
It moves the points of the map object as well as the position vector whereas the points are supposed to be relative to the position vector of the object. This results in the actual shape being moved twice as much from where it was before. Simply commenting those two lines solved my problem. Thank you!
-
Ah! OK, thanks :) I shall add it to the bug list (which I shall sit down and tackle one day :) )
-
Hi,
How do I update the drawingbounds?
I can't access the method from the mapLoader object.
Thanks
-
iirc it's used internally and automatically called during drawing, so you don't need to call it yourself
-
Oh, how would I go on about changing what region of the map it's drawing? So when I move the player the view follows >.<
Thanks
-
use a view as you normally would
http://sfml-dev.org/tutorials/2.1/graphics-view.php
-
use a view as you normally would
http://sfml-dev.org/tutorials/2.1/graphics-view.php
Ah thank you.
I'm new to sfml, didn't realise it had an inbuilt "camera" and thought Id have to change whats drawn manually.
Thanks.
-
Hi everybody,
I recently interested in using Tiled with SFML and I am looking for a small sample of code before using it, who shows me how to display a tilemap from a Tiled file and how to handle collision with a little rectangle and the tilemap.
Can you help me please?
Thank you in advance.
-
Assuming that Tiled can output a comma-separated list, you should be able to simply use the code from this tutorial (http://sfml-dev.org/tutorials/2.1/graphics-vertex-array.php#example-tile-map) to display the map and replace the level[] array values with that list. You will probably have to change the tile map parameters too (e.g. tile size, map size).
-
Hi everybody,
I recently interested in using Tiled with SFML and I am looking for a small sample of code before using it, who shows me how to display a tilemap from a Tiled file and how to handle collision with a little rectangle and the tilemap.
Can you help me please?
Thank you in advance.
There are a set of examples (https://github.com/fallahn/sfml-tmxloader/tree/master/examples) included in the repository for a range of the map loaders features, as well as some blog posts about collision linked via the wiki. (https://github.com/fallahn/sfml-tmxloader/wiki)
-
Thank you all ;)
-
An alternative to using fallahn's excellent tmx loader (https://github.com/fallahn/sfml-tmxloader) could be to do what I've done for a few projects; save as json in Tiled (http://www.mapeditor.org) and then use PicoJSON (https://github.com/kazuho/picojson) to parse the files...
-
I've implemented the Tiled loader into my game successfully and all, and have been using it quite heavily. One problem I continue to have, however, is a strange visual artifact:
(http://i.imgur.com/vSgq7ys.png)
If you can't quite spot it, here is an image cropped out to highlight the problem (notice the internal edges of the tiles looking really strange?)
(http://i.imgur.com/MXH6wWX.png)
The kind of placeholders I am using aside, for some reason the tiles become quite distorted. Characters and such do not face this problem as I use sf::Texture::setSmooth() on them, but even adding that into the tiled loader source does not produce acceptable results (and messes with the use of LTBL's light texture).
Now I don't believe it is specifically a fault of the tiled loader, but I'm wondering if something can be done. And yes, my sf::View's are clamped to whole integers. My tiles are 32x32, and my sf::View defaults to 800x600 at a 4:3 resolution (though it adjusts for widescreen resolutions as well), if that helps.
[EDIT] Also, sorry for bumping this from page 4, if that's a concern.
-
Hello. I have encountered another problem while using the map loader and solved it, so I am posting this here in case anyone else gets the same problem or fallahn decides to update it.
The loader works with no problem when the tilesets have 1 px spacing and 1 px margin. But I had a map made with a tileset that had no margins and despite Tiled showing it without a problem, in the game, the tiles were all messed up. I looked through the code and noticed these lines in MapLoaderPrivate.cpp:
//slice into tiles
int columns = (sourceImage.getSize().x - margin) / (tileWidth + spacing);
int rows = (sourceImage.getSize().y - margin) / (tileHeight + spacing);
Here, sourceImage.getSize().x and .y are the dimensions of the tileset image. The problem with this is, there are 2 margins in both dimensions (one left + one right and one up + one down) and "tiles in a row/column" - 1 spacings (since there is no spacing before the first and after the last tile).
In my case, this resulted in 56 instead of 57 tiles in a row: (968 - 0)/(16 + 1) = 56.94 which rounds down to 56.
I think the correct calculation should be like this:
//slice into tiles
int columns = (sourceImage.getSize().x - 2*margin + spacing) / (tileWidth + spacing);
int rows = (sourceImage.getSize().y - 2*margin + spacing) / (tileHeight + spacing);
So I changed it and now it works.
-
Hi guys! I've been using sfml for a while and just discovered the tmx loader. I'm using it in a college project but i'm having a particular issue. When using a layer to perform collisions my player collides well for a while but then pass througth the solid objects. This is my collision code:
for (auto layer = layers.begin(); layer != layers.end(); ++layer)
{
if (layer->name == "Coll")
{
for (auto object = layer->objects.begin(); object != layer->objects.end(); ++object)
{
if (object->Visible())
{
if (object->GetAABB().intersects(getGlobalBounds(), area))
{
if (area.width > area.height)
{
if (area.contains({ area.left, getPosition().y }))
{
// Up side crash
setPosition({ getPosition().x, getPosition().y + area.height });
std::cout << "Up side crash" << std::endl;
}
else
{
// Down side crash
onGround = true;
inAir = 0.f;
setPosition({ getPosition().x, getPosition().y - area.height});
std::cout << "Down side crash" << std::endl;
}
}
else if (area.width < area.height)
{
if (area.contains({ getPosition().x + getGlobalBounds().width - 1.f, area.top + 1.f }))
{
//Right side crash
setPosition({ getPosition().x - area.width, getPosition().y });
std::cout << "Right side crash" << std::endl;
}
else
{
//Left side crash
setPosition({ getPosition().x + area.width, getPosition().y });
std::cout << "Left side crash" << std::endl;
}
}
}
}
}
}
The code works ok if i just collide againts a simple sprite but when i use it with the .tmx map it fails. Any help?
-
Matt, Please check the latest comment on github from me about FPS and maps...
https://github.com/fallahn/sfml-tmxloader/issues/28
Anyone else here have an ideas for code they have updated the project with to help speed up render FPS?
Thanks!
-
I think the correct calculation should be like this:
//slice into tiles
int columns = (sourceImage.getSize().x - 2*margin + spacing) / (tileWidth + spacing);
int rows = (sourceImage.getSize().y - 2*margin + spacing) / (tileHeight + spacing);
So I changed it and now it works.
Thanks for finding this! I have included it in the repo now. I've also been working on killing a few other bugs, and improving the rendering of large maps. The performance should now be many times better than it previously was.
-
Sorry for newb question, just having trouble building the xcode project. Wondering if anyone has successfully. I think the issue is the with the compiler set.
I get errors like:
// /Users/aaronmcleod/Documents/programming/c/sfml-tmxloader/include/tmx/MapLayer.h:75:45: A space is required between consecutive right angle brackets (use '> >')
mutable std::vector<std::vector<sf::Vertex>> m_patches;
All of these get "No matching function for call to make_shared:
m_children.push_back(std::make_shared<QuadTreeNode>(m_level + 1, sf::FloatRect(x + halfWidth, y, halfWidth, halfHeight)));
m_children.push_back(std::make_shared<QuadTreeNode>(m_level + 1, sf::FloatRect(x, y, halfWidth, halfHeight)));
m_children.push_back(std::make_shared<QuadTreeNode>(m_level + 1, sf::FloatRect(x, y + halfHeight, halfWidth, halfHeight)));
m_children.push_back(std::make_shared<QuadTreeNode>(m_level + 1, sf::FloatRect(x+ halfWidth, y + halfHeight, halfWidth, halfHeight)));
I went into build settings, and ensured the Language C++ is set to use C++11, and libc++ (LLVM C++ standard library with C++11 support). But the compile errors still come back.
-
std::make_shared is a C++14 Feature. Make sure your compiler supports this feature, VC12 and GCC 4.8 and higher do support it I know from experience, but don't know about LLVM.
-
std::make_shared is a C++14 Feature. Make sure your compiler supports this feature, VC12 and GCC 4.8 and higher do support it I know from experience, but don't know about LLVM.
std::make_shared is a C++11 feature, std::make_unique is a C++14 feature. ;)
-
Hm, I actually thought it's a C++14 feature because std::make_unique is also.
But you are right, it's C++11, good catch ;D
Nevertheless, the compiler must support it, and it looks like agmcleod's compiler doesn't support it (which is also more likely due to his first error with two right angle brackets ).
-
All of these get "No matching function for call to make_shared:
This doesn't mean make_shared is not found, otherwise you'd get something along the lines of "undeclared identifier".
The problem might be that the code is relying on implicit conversions. Make sure that the arguments provided to std::make_share have exactly the same types as the parameters in the constructor, and that there are no ambiguous constructor overloads. (Although I would expect a slightly different error message for that, too...)
Or maybe you have a crippled std::make_shared() implementation (before variadic templates), which supports only one argument?
-
The problem might be that the code is relying on implicit conversions. Make sure that the arguments provided to std::make_share have exactly the same types as the parameters in the constructor, and that there are no ambiguous constructor overloads. (Although I would expect a slightly different error message for that, too...)
Or maybe you have a crippled std::make_shared() implementation (before variadic templates), which supports only one argument?
I was thinking that too, I started looking at the tmxloader code base a bit last night to see if it was mix matched somehow.
Keep in mind, this is me just clone the repo, generating the Xcode template via cmake, and trying to compile it. I have done no code changes, left it completely as is.
-
1> Test.obj: error LNK2019: link to the unresolved external symbol "public: __cdecl tmx :: MapLoader :: MapLoader (class std :: basic_string <char, struct std :: char_traits <char>, class std :: allocator <char >> const &, unsigned char) "(?? 0MapLoader @ tmx@@QEAA @ AEBV? $ basic_string @ DU? $ char_traits @ D @ std@@V? $ allocator @ D @ 2@@std@@E @ Z ) in main
1> Test.obj: error LNK2019: link to the unresolved external symbol "public: bool __cdecl tmx :: MapLoader :: Load (class std :: basic_string <char, struct std :: char_traits <char>, class std :: allocator <char>> const &) "(? Load @ MapLoader @ tmx@@QEAA_NAEBV? $ basic_string @ DU? $ char_traits @ D @ std@@V? $ allocator @ D @ 2@@std@Z) in main
1> F: \ 1SFMLPROJECTS \ TestProject (v12) \ x64 \ Debug \ TestProject.exe: fatal error LNK1120: unresolved external elements: 2
My libs
sfml-graphics-d.lib;sfml-window-d.lib;sfml-system-d.lib;sfml-audio-d.lib;sfml-graphics-s.lib;sfml-window-s.lib;sfml-system-s.lib;sfml-audio-s.lib;sfml-graphics-s-d.lib;sfml-window-s-d.lib;sfml-system-s-d.lib;sfml-audio-s-d.lib;Box2D.lib;tmx-loader-d.lib;tmx-loader.lib;pugixmls.lib;pugixmld.lib;zlibd.lib;freetype.lib;jpeg.lib;glew32.lib;opengl32.lib;zlibstatic.lib;
I just try load and draw map.
-
My libs
sfml-graphics-d.lib;sfml-window-d.lib;sfml-system-d.lib;sfml-audio-d.lib;sfml-graphics-s.lib;sfml-window-s.lib;sfml-system-s.lib;sfml-audio-s.lib;sfml-graphics-s-d.lib;sfml-window-s-d.lib;sfml-system-s-d.lib;sfml-audio-s-d.lib;Box2D.lib;tmx-loader-d.lib;tmx-loader.lib;pugixmls.lib;pugixmld.lib;zlibd.lib;freetype.lib;jpeg.lib;glew32.lib;opengl32.lib;zlibstatic.lib;
Why are you linking debug, release, static-debug, and static-release libraries at the same time?
-
My libs
sfml-graphics-d.lib;sfml-window-d.lib;sfml-system-d.lib;sfml-audio-d.lib;sfml-graphics-s.lib;sfml-window-s.lib;sfml-system-s.lib;sfml-audio-s.lib;sfml-graphics-s-d.lib;sfml-window-s-d.lib;sfml-system-s-d.lib;sfml-audio-s-d.lib;Box2D.lib;tmx-loader-d.lib;tmx-loader.lib;pugixmls.lib;pugixmld.lib;zlibd.lib;freetype.lib;jpeg.lib;glew32.lib;opengl32.lib;zlibstatic.lib;
Why are you linking debug, release, static-debug, and static-release libraries at the same time?
Sorry for another account, i dont password reset message on mail (dont know why). I am so disappointed in the performance of the library that started doing stupid things. And threw off debug and release and statics connecting them. Your observation is correct, but it generally does not help me to understand the essence of this error.
-
Your observation is correct, but it generally does not help me to understand the essence of this error.
If you're linking incorrectly, you'll get incorrect linking errors.
Only link the libraries for the build type that you are using (e.g. compiler, 32/64-bit, debug/release, static/dynamic).
-
Your observation is correct, but it generally does not help me to understand the essence of this error.
If you're linking incorrectly, you'll get incorrect linking errors.
Only link the libraries for the build type that you are using (e.g. compiler, 32/64-bit, debug/release, static/dynamic).
Okay, I changed my list of libraries:
sfml-graphics-d.lib
sfml-window-d.lib
sfml-system-d.lib
sfml-audio-d.lib
Box2D.lib
tmx-loader-d.lib
pugixmld.lib
zlibd.lib
Now I have everything right with my libs. Those same mistakes XD. Not Surprising
-
Guys?
-
Your previous post doesn't infer any form of intention to getting help, as you did not state if the problem was solved or not. Thus, people (maybe just me, though) generally assume that it now works as expected.
Edit: unless by
Those same mistakes XD.
you meant that the same errors were occurring.
-
An idea is to fill the remaining space automatically. This means that you dont use tiles for the outerspace.
-
An idea is to fill the remaining space automatically. This means that you dont use tiles for the outerspace.
I try load map from example, dont work. And this is not Debug error :(
-
Sorry XD, i dont load cpp to project. Now i have another error.
error C2065: m_rootNode: undeclared identifier
-
Hi all, again, i do a lot of work, and now i dont have errors, but if i start debug, i have white window, with TestProject has stopped work. I dont know what i need do, and with example maps i have this.
-
Im fix all, profit 8)
-
Hi Guys,
I want to use the tmx loader but I keep getting errors that I do not understand.
In my humble opinion I am linking everything correctly, first zLib then SFML and then the tmx loader.
I think there is a problem with zLib, maybe anyone can help me with this:
1.
Fehler LNK2019 Verweis auf nicht aufgelöstes externes Symbol "_inflate@8" in Funktion ""private: bool __thiscall tmx::MapLoader::Decompress(char const *,class std::vector<unsigned char,class std::allocator<unsigned char> > &,int,int)" (?Decompress@MapLoader@tmx@@AAE_NPBDAAV?$vector@EV?$allocator@E@std@@@std@@HH@Z)". TMX c:\Users\Maulwurf\documents\visual studio 2015\Projects\TMX\TMX\MapLoaderPrivate.obj 1 Build
2.
Fehler LNK2019 Verweis auf nicht aufgelöstes externes Symbol "_inflateEnd@4" in Funktion ""private: bool __thiscall tmx::MapLoader::Decompress(char const *,class std::vector<unsigned char,class std::allocator<unsigned char> > &,int,int)" (?Decompress@MapLoader@tmx@@AAE_NPBDAAV?$vector@EV?$allocator@E@std@@@std@@HH@Z)". TMX c:\Users\Maulwurf\documents\visual studio 2015\Projects\TMX\TMX\MapLoaderPrivate.obj 1 Build
3.
Fehler LNK2019 Verweis auf nicht aufgelöstes externes Symbol "_inflateInit2_@16" in Funktion ""private: bool __thiscall tmx::MapLoader::Decompress(char const *,class std::vector<unsigned char,class std::allocator<unsigned char> > &,int,int)" (?Decompress@MapLoader@tmx@@AAE_NPBDAAV?$vector@EV?$allocator@E@std@@@std@@HH@Z)". TMX c:\Users\Maulwurf\documents\visual studio 2015\Projects\TMX\TMX\MapLoaderPrivate.obj 1 Build
I have tried <everything> but couldnt make those errors go away :(
-
Do you link against zlib?
-
Hi guys,
I have everything working for my game project, but for some reason; whenever I place a collision box in the TILED editor; my program only picks up one collision box and does not recognize the rest.
Here is my current code:
for (auto layer = ml.GetLayers().begin(); layer != ml.GetLayers().end(); ++layer)
{
if (layer->name == "Collision")
{
for (auto object = layer->objects.begin(); object != layer->objects.end(); ++object)
{
collision = object->Contains(sf::Vector2f(actorPlayer.getPosition()));
}
}
}
Is there something I'm missing?
Thank you in advance for your time.
-
Hi Guys,
I want to use the tmx loader but I keep getting errors that I do not understand.
In my humble opinion I am linking everything correctly, first zLib then SFML and then the tmx loader.
I have tried <everything> but couldnt make those errors go away :(
if you are using Windows / MSVC there is a peculiarity in zlib which can be fixed by defining ZLIB_WINAPI. This seems quite obscure in the zlib docs and took some digging to find this.
Hi guys,
I have everything working for my game project, but for some reason; whenever I place a collision box in the TILED editor; my program only picks up one collision box and does not recognize the rest.
Thank you in advance for your time.
Put a break point in and step through your containers to make sure they contain what you think they do. If you're using visual studio this is quite easy to do by expanding the property tree when you hit the break point