Advertisement
Guest User

Tiled Map Loader sfml 2

a guest
Sep 9th, 2012
2,051
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.93 KB | None | 0 0
  1. /*********************************************************************
  2. Quinn Schwab
  3. 16/08/2010
  4.  
  5. SFML Tiled Map Loader
  6.  
  7. The zlib license has been used to make this software fully compatible
  8. with SFML. See http://www.sfml-dev.org/license.php
  9.  
  10. This software is provided 'as-is', without any express or
  11. implied warranty. In no event will the authors be held
  12. liable for any damages arising from the use of this software.
  13.  
  14. Permission is granted to anyone to use this software for any purpose,
  15. including commercial applications, and to alter it and redistribute
  16. it freely, subject to the following restrictions:
  17.  
  18. 1. The origin of this software must not be misrepresented;
  19. you must not claim that you wrote the original software.
  20. If you use this software in a product, an acknowledgment
  21. in the product documentation would be appreciated but
  22. is not required.
  23.  
  24. 2. Altered source versions must be plainly marked as such,
  25. and must not be misrepresented as being the original software.
  26.  
  27. 3. This notice may not be removed or altered from any
  28. source distribution.
  29. *********************************************************************/
  30.  
  31. #include "level.h"
  32.  
  33. #include <iostream>
  34. #include "tinyxml/tinyxml.h"
  35. #include <fstream>
  36.  
  37. int Object::GetPropertyInt(std::string name)
  38. {
  39. int i;
  40. i = atoi(properties[name].c_str());
  41.  
  42. return i;
  43. }
  44.  
  45. float Object::GetPropertyFloat(std::string name)
  46. {
  47. float f;
  48. f = strtod(properties[name].c_str(), NULL);
  49.  
  50. return f;
  51. }
  52.  
  53. std::string Object::GetPropertyString(std::string name)
  54. {
  55. return properties[name];
  56. }
  57.  
  58. Level::Level()
  59. {
  60. //ctor
  61. }
  62.  
  63. Level::~Level()
  64. {
  65. //dtor
  66. }
  67. using namespace std;
  68. bool Level::LoadFromFile(std::string filename)
  69. {
  70. TiXmlDocument levelFile(filename.c_str());
  71.  
  72. if (!levelFile.LoadFile())
  73. {
  74. std::cout << "Loading level \"" << filename << "\" failed." << std::endl;
  75. return false;
  76. }
  77.  
  78. //Map element. This is the root element for the whole file.
  79. TiXmlElement *map;
  80. map = levelFile.FirstChildElement("map");
  81.  
  82. //Set up misc map properties.
  83. width = atoi(map->Attribute("width"));
  84. height = atoi(map->Attribute("height"));
  85. tileWidth = atoi(map->Attribute("tilewidth"));
  86. tileHeight = atoi(map->Attribute("tileheight"));
  87.  
  88. //Tileset stuff
  89. TiXmlElement *tilesetElement;
  90. tilesetElement = map->FirstChildElement("tileset");
  91. firstTileID = atoi(tilesetElement->Attribute("firstgid"));
  92. spacing = atoi(tilesetElement->Attribute("spacing"));
  93. margin = atoi(tilesetElement->Attribute("margin"));
  94.  
  95. //Tileset image
  96. TiXmlElement *image;
  97. image = tilesetElement->FirstChildElement("image");
  98. std::string imagepath = image->Attribute("source");
  99.  
  100. if (!tilesetImage.loadFromFile(imagepath))//Load the tileset image
  101. {
  102. std::cout << "Failed to load tile sheet." << std::endl;
  103. return false;
  104. }
  105.  
  106. tilesetImage.createMaskFromColor(sf::Color(255, 0, 255));
  107.  
  108. tilesetTexture.loadFromImage(tilesetImage);
  109. tilesetTexture.setSmooth(false);
  110.  
  111. //Columns and rows (of tileset image)
  112. int columns = tilesetTexture.getSize().x / tileWidth;
  113. int rows = tilesetTexture.getSize().y / tileHeight;
  114.  
  115. std::vector <sf::Rect<int> > subRects;//container of subrects (to divide the tilesheet image up)
  116.  
  117. //tiles/subrects are counted from 0, left to right, top to bottom
  118. for (int y = 0; y < rows; y++)
  119. {
  120. for (int x = 0; x < columns; x++)
  121. {
  122. sf::Rect <int> rect;
  123. rect.top = y * tileHeight;
  124. rect.height = y * tileHeight + tileHeight;
  125. rect.left = x * tileWidth;
  126. rect.width = x * tileWidth + tileWidth;
  127. subRects.push_back(rect);
  128. }
  129. }
  130.  
  131. //Layers
  132. TiXmlElement *layerElement;
  133. layerElement = map->FirstChildElement("layer");
  134. while (layerElement)
  135. {
  136. Layer layer;
  137. if (layerElement->Attribute("opacity") != NULL)//check if opacity attribute exists
  138. {
  139. float opacity = strtod(layerElement->Attribute("opacity"), NULL);//convert the (string) opacity element to float
  140. layer.opacity = 255 * opacity;
  141. }
  142. else
  143. {
  144. layer.opacity = 255;//if the attribute doesnt exist, default to full opacity
  145. }
  146.  
  147. //Tiles
  148. TiXmlElement *layerDataElement;
  149. layerDataElement = layerElement->FirstChildElement("data");
  150.  
  151. if (layerDataElement == NULL)
  152. {
  153. std::cout << "Bad map. No layer information found." << std::endl;
  154. }
  155.  
  156. TiXmlElement *tileElement;
  157. tileElement = layerDataElement->FirstChildElement("tile");
  158.  
  159. if (tileElement == NULL)
  160. {
  161. std::cout << "Bad map. No tile information found." << std::endl;
  162. return false;
  163. }
  164.  
  165. int x = 0;
  166. int y = 0;
  167.  
  168. while (tileElement)
  169. {
  170. int tileGID = atoi(tileElement->Attribute("gid"));
  171. int subRectToUse = tileGID - firstTileID;//Work out the subrect ID to 'chop up' the tilesheet image.
  172. if (subRectToUse >= 0)//we only need to (and only can) create a sprite/tile if there is one to display
  173. {
  174. sf::Sprite sprite;//sprite for the tile
  175. sprite.setTexture(tilesetTexture);
  176. sprite.setTextureRect(subRects[subRectToUse]);
  177. sprite.setPosition(x * tileWidth, y * tileHeight);
  178.  
  179. sprite.setColor(sf::Color(255, 255, 255, layer.opacity));//Set opacity of the tile.
  180.  
  181. //add tile to layer
  182. layer.tiles.push_back(sprite);
  183. }
  184.  
  185. tileElement = tileElement->NextSiblingElement("tile");
  186.  
  187. //increment x, y
  188. x++;
  189. if (x >= width)//if x has "hit" the end (right) of the map, reset it to the start (left)
  190. {
  191. x = 0;
  192. y++;
  193. if (y >= height)
  194. {
  195. y = 0;
  196. }
  197. }
  198. }
  199.  
  200. layers.push_back(layer);
  201.  
  202. layerElement = layerElement->NextSiblingElement("layer");
  203. }
  204.  
  205. //Objects
  206. TiXmlElement *objectGroupElement;
  207. if (map->FirstChildElement("objectgroup") != NULL)//Check that there is atleast one object layer
  208. {
  209. objectGroupElement = map->FirstChildElement("objectgroup");
  210. while (objectGroupElement)//loop through object layers
  211. {
  212. TiXmlElement *objectElement;
  213. objectElement = objectGroupElement->FirstChildElement("object");
  214. while (objectElement)//loop through objects
  215. {
  216. std::string objectType;
  217. if (objectElement->Attribute("type") != NULL)
  218. {
  219. objectType = objectElement->Attribute("type");
  220. }
  221. std::string objectName;
  222. if (objectElement->Attribute("name") != NULL)
  223. {
  224. objectName = objectElement->Attribute("name");
  225. }
  226. int x = atoi(objectElement->Attribute("x"));
  227. int y = atoi(objectElement->Attribute("y"));
  228. int width = atoi(objectElement->Attribute("width"));
  229. int height = atoi(objectElement->Attribute("height"));
  230.  
  231. Object object;
  232. object.name = objectName;
  233. object.type = objectType;
  234.  
  235. sf::Rect <int> objectRect;
  236. objectRect.top = y;
  237. objectRect.left = x;
  238. objectRect.height = y + height;
  239. objectRect.width = x + width;
  240.  
  241. if (objectType == "solid")
  242. {
  243. solidObjects.push_back(objectRect);
  244. }
  245.  
  246. object.rect = objectRect;
  247.  
  248. TiXmlElement *properties;
  249. properties = objectElement->FirstChildElement("properties");
  250. if (properties != NULL)
  251. {
  252. TiXmlElement *prop;
  253. prop = properties->FirstChildElement("property");
  254. if (prop != NULL)
  255. {
  256. while(prop)
  257. {
  258. std::string propertyName = prop->Attribute("name");
  259. std::string propertyValue = prop->Attribute("value");
  260.  
  261. object.properties[propertyName] = propertyValue;
  262.  
  263. prop = prop->NextSiblingElement("property");
  264. }
  265. }
  266. }
  267.  
  268. objects.push_back(object);
  269.  
  270. objectElement = objectElement->NextSiblingElement("object");
  271. }
  272. objectGroupElement = objectGroupElement->NextSiblingElement("objectgroup");
  273. }
  274. }
  275. else
  276. {
  277. std::cout << "No object layers found..." << std::endl;
  278. }
  279.  
  280. return true;
  281. }
  282.  
  283. Object Level::GetObject(std::string name)
  284. {
  285. for (int i = 0; i < objects.size(); i++)
  286. {
  287. if (objects[i].name == name)
  288. {
  289. return objects[i];
  290. }
  291. }
  292. }
  293.  
  294. void Level::SetDrawingBounds(sf::Rect<float> bounds)
  295. {
  296. drawingBounds = bounds;
  297.  
  298. //Adjust the rect so that tiles are drawn just off screen, so you don't see them disappearing.
  299. drawingBounds.top -= tileHeight;
  300. drawingBounds.left -= tileWidth;
  301. drawingBounds.width += tileWidth;
  302. drawingBounds.height += tileHeight;
  303. }
  304.  
  305. void Level::Draw(sf::RenderWindow &window)
  306. {
  307. for (int layer = 0; layer < layers.size(); layer++)
  308. {
  309. for (int tile = 0; tile < layers[layer].tiles.size(); tile++)
  310. {
  311. if (drawingBounds.contains(layers[layer].tiles[tile].getPosition().x, layers[layer].tiles[tile].getPosition().y))
  312. {
  313. window.draw(layers[layer].tiles[tile]);
  314. }
  315. }
  316. }
  317. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement