TMXTypes.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. #include "TMXTypes.h"
  2. using namespace gameplay;
  3. // TMXMap
  4. TMXMap::TMXMap()
  5. : _width(0), _height(0),
  6. _tileWidth(0.0f), _tileHeight(0.0f),
  7. _tileSets(), _layers()
  8. {
  9. }
  10. TMXMap::~TMXMap()
  11. {
  12. for (auto it = _layers.begin(); it != _layers.end(); it++)
  13. {
  14. delete *it;
  15. }
  16. }
  17. void TMXMap::setWidth(unsigned int value)
  18. {
  19. _width = value;
  20. }
  21. void TMXMap::setHeight(unsigned int value)
  22. {
  23. _height = value;
  24. }
  25. unsigned int TMXMap::getWidth() const
  26. {
  27. return _width;
  28. }
  29. unsigned int TMXMap::getHeight() const
  30. {
  31. return _height;
  32. }
  33. void TMXMap::setTileWidth(float value)
  34. {
  35. _tileWidth = value;
  36. }
  37. void TMXMap::setTileHeight(float value)
  38. {
  39. _tileHeight = value;
  40. }
  41. float TMXMap::getTileWidth() const
  42. {
  43. return _tileWidth;
  44. }
  45. float TMXMap::getTileHeight() const
  46. {
  47. return _tileHeight;
  48. }
  49. bool TMXMap::isValidTileId(unsigned int tileId) const
  50. {
  51. if (tileId != 0)
  52. {
  53. unsigned int tileSet = findTileSet(tileId);
  54. return tileSet < _tileSets.size();
  55. }
  56. return false;
  57. }
  58. unsigned int TMXMap::findTileSet(unsigned int tileId) const
  59. {
  60. if (tileId == 0)
  61. {
  62. return (unsigned int)_tileSets.size();
  63. }
  64. for (int i = (int)_tileSets.size() - 1; i >= 0; i--)
  65. {
  66. if (_tileSets[i].getFirstGid() > tileId)
  67. {
  68. continue;
  69. }
  70. return i;
  71. }
  72. return (unsigned int)_tileSets.size();
  73. }
  74. void TMXMap::addTileSet(const TMXTileSet& tileset)
  75. {
  76. _tileSets.push_back(tileset);
  77. }
  78. void TMXMap::addLayer(const TMXBaseLayer* layer)
  79. {
  80. _layers.push_back(layer);
  81. }
  82. unsigned int TMXMap::getTileSetCount() const
  83. {
  84. return (unsigned int)_tileSets.size();
  85. }
  86. unsigned int TMXMap::getLayerCount() const
  87. {
  88. return (unsigned int)_layers.size();
  89. }
  90. TMXTileSet& TMXMap::getTileSet(unsigned int index)
  91. {
  92. return _tileSets[index];
  93. }
  94. const TMXTileSet& TMXMap::getTileSet(unsigned int index) const
  95. {
  96. return _tileSets[index];
  97. }
  98. const TMXBaseLayer* TMXMap::getLayer(unsigned int index) const
  99. {
  100. return _layers[index];
  101. }
  102. // TMXTileSet
  103. TMXTileSet::TMXTileSet()
  104. : _path(""),
  105. _imgWidth(0), _imgHeight(0), _horzTileCount(0), _vertTileCount(0),
  106. _firstGid(0), _maxTileWidth(0), _maxTileHeight(0),
  107. _offset(), _spacing(0), _margin(0)
  108. {
  109. }
  110. void TMXTileSet::setImagePath(const std::string& path)
  111. {
  112. _path = path;
  113. }
  114. const std::string& TMXTileSet::getImagePath() const
  115. {
  116. return _path;
  117. }
  118. void TMXTileSet::setFirstGid(unsigned int gid)
  119. {
  120. _firstGid = gid;
  121. }
  122. unsigned int TMXTileSet::getFirstGid() const
  123. {
  124. return _firstGid;
  125. }
  126. void TMXTileSet::setMaxTileWidth(unsigned int value, bool adjustTiles)
  127. {
  128. _maxTileWidth = value;
  129. if (adjustTiles && _maxTileWidth != 0)
  130. {
  131. setImageWidth(_imgWidth);
  132. }
  133. }
  134. unsigned int TMXTileSet::getMaxTileWidth() const
  135. {
  136. return _maxTileWidth;
  137. }
  138. void TMXTileSet::setMaxTileHeight(unsigned int value, bool adjustTiles)
  139. {
  140. _maxTileHeight = value;
  141. if (adjustTiles && _maxTileHeight != 0)
  142. {
  143. setImageWidth(_imgHeight);
  144. }
  145. }
  146. unsigned int TMXTileSet::getMaxTileHeight() const
  147. {
  148. return _maxTileHeight;
  149. }
  150. void TMXTileSet::setSpacing(unsigned int value, bool adjustTiles)
  151. {
  152. _spacing = value;
  153. if (adjustTiles)
  154. {
  155. if (_maxTileWidth != 0)
  156. {
  157. setImageWidth(_imgWidth);
  158. }
  159. if (_maxTileHeight != 0)
  160. {
  161. setImageWidth(_imgHeight);
  162. }
  163. }
  164. }
  165. unsigned int TMXTileSet::getSpacing() const
  166. {
  167. return _spacing;
  168. }
  169. void TMXTileSet::setMargin(unsigned int value, bool adjustTiles)
  170. {
  171. _margin = value;
  172. if (adjustTiles)
  173. {
  174. if (_maxTileWidth != 0)
  175. {
  176. setImageWidth(_imgWidth);
  177. }
  178. if (_maxTileHeight != 0)
  179. {
  180. setImageWidth(_imgHeight);
  181. }
  182. }
  183. }
  184. unsigned int TMXTileSet::getMargin() const
  185. {
  186. return _margin;
  187. }
  188. void TMXTileSet::setImageWidth(unsigned int value)
  189. {
  190. _imgWidth = value;
  191. _horzTileCount = (value - (_margin * 2) + (_spacing ? _spacing : 0)) / (_maxTileWidth + _spacing);
  192. }
  193. void TMXTileSet::setImageHeight(unsigned int value)
  194. {
  195. _imgHeight = value;
  196. _vertTileCount = (value - (_margin * 2) + (_spacing ? _spacing : 0)) / (_maxTileHeight + _spacing);
  197. }
  198. unsigned int TMXTileSet::getHorizontalTileCount() const
  199. {
  200. return _horzTileCount;
  201. }
  202. unsigned int TMXTileSet::getVerticalTileCount() const
  203. {
  204. return _vertTileCount;
  205. }
  206. void TMXTileSet::setOffset(const Vector2& off)
  207. {
  208. _offset = off;
  209. }
  210. const Vector2& TMXTileSet::getOffset() const
  211. {
  212. return _offset;
  213. }
  214. unsigned int TMXTileSet::calculateImageDimension(unsigned int tileCount, unsigned int tileSize, unsigned int spacing, unsigned int margin)
  215. {
  216. return tileCount * (tileSize + spacing) + (margin * 2) - spacing;
  217. }
  218. Vector2 TMXTileSet::calculateTileOrigin(const Vector2& pos, const Vector2& tileSize, unsigned int spacing, unsigned int margin)
  219. {
  220. float xpos = (tileSize.x + spacing) * pos.x;
  221. float ypos = (tileSize.y + spacing) * pos.y;
  222. return Vector2(xpos + margin, ypos + margin);
  223. }
  224. // TMXBaseLayer
  225. TMXBaseLayer::TMXBaseLayer(TMXLayerType type)
  226. : _name(""), _type(type), _opacity(1.0f), _visible(true), _properties()
  227. {
  228. }
  229. TMXBaseLayer::~TMXBaseLayer()
  230. {
  231. }
  232. TMXLayerType TMXBaseLayer::getType() const
  233. {
  234. return _type;
  235. }
  236. void TMXBaseLayer::setName(const std::string& value)
  237. {
  238. _name = value;
  239. }
  240. const std::string& TMXBaseLayer::getName() const
  241. {
  242. return _name;
  243. }
  244. void TMXBaseLayer::setOpacity(float value)
  245. {
  246. _opacity = value;
  247. }
  248. float TMXBaseLayer::getOpacity() const
  249. {
  250. return _opacity;
  251. }
  252. void TMXBaseLayer::setVisible(bool value)
  253. {
  254. _visible = value;
  255. }
  256. bool TMXBaseLayer::getVisible() const
  257. {
  258. return _visible;
  259. }
  260. TMXProperties& TMXBaseLayer::getProperties()
  261. {
  262. return _properties;
  263. }
  264. const TMXProperties& TMXBaseLayer::getProperties() const
  265. {
  266. return _properties;
  267. }
  268. // TMXLayer
  269. #define FLIPPED_HORIZONTALLY_FLAG 0x80000000
  270. #define FLIPPED_VERTICALLY_FLAG 0x40000000
  271. #define FLIPPED_DIAGONALLY_FLAG 0x20000000
  272. TMXLayer::TMXLayer()
  273. : TMXBaseLayer(TMXLayerType::NormalLayer),
  274. _width(0), _height(0),
  275. _tiles()
  276. {
  277. }
  278. TMXLayer::~TMXLayer()
  279. {
  280. }
  281. void TMXLayer::setWidth(unsigned int value)
  282. {
  283. _width = value;
  284. }
  285. unsigned int TMXLayer::getWidth() const
  286. {
  287. return _width;
  288. }
  289. void TMXLayer::setHeight(unsigned int value)
  290. {
  291. _height = value;
  292. }
  293. unsigned int TMXLayer::getHeight() const
  294. {
  295. return _height;
  296. }
  297. void TMXLayer::setupTiles()
  298. {
  299. if (_tiles.size() != (_width * _height))
  300. {
  301. _tiles.resize(_width * _height);
  302. }
  303. }
  304. void TMXLayer::setTile(unsigned int x, unsigned int y, unsigned int gid)
  305. {
  306. struct layer_tile tile = {
  307. tile.gid = gid & ~(FLIPPED_HORIZONTALLY_FLAG |
  308. FLIPPED_VERTICALLY_FLAG |
  309. FLIPPED_DIAGONALLY_FLAG),
  310. tile.horz_flip = (gid & FLIPPED_HORIZONTALLY_FLAG) != 0,
  311. tile.vert_flip = (gid & FLIPPED_VERTICALLY_FLAG) != 0,
  312. tile.diag_flip = (gid & FLIPPED_DIAGONALLY_FLAG) != 0,
  313. };
  314. _tiles[x + y * _width] = tile;
  315. }
  316. const TMXLayer::layer_tile& TMXLayer::getTileStruct(unsigned int x, unsigned int y) const
  317. {
  318. return _tiles[x + y * _width];
  319. }
  320. unsigned int TMXLayer::getTile(unsigned int x, unsigned int y) const
  321. {
  322. return getTileStruct(x, y).gid;
  323. }
  324. bool TMXLayer::isEmptyTile(unsigned int x, unsigned int y) const
  325. {
  326. return getTileStruct(x, y).gid == 0;
  327. }
  328. Vector2 TMXLayer::getTileStart(unsigned int x, unsigned int y, const TMXMap& map, unsigned int resultOnlyForTileset) const
  329. {
  330. // Get the tile
  331. unsigned int gid = getTileStruct(x, y).gid;
  332. if (gid == 0)
  333. {
  334. return Vector2(-1, -1);
  335. }
  336. // Get the tileset for the tile
  337. unsigned int tileset_id = map.findTileSet(gid);
  338. if (tileset_id == map.getTileSetCount() ||
  339. (resultOnlyForTileset != TMX_INVALID_ID && tileset_id != resultOnlyForTileset))
  340. {
  341. return Vector2(-1, -1);
  342. }
  343. const TMXTileSet& tileset = map.getTileSet(tileset_id);
  344. if (tileset.getHorizontalTileCount() == 0)
  345. {
  346. return Vector2(-1, -1);
  347. }
  348. // Calculate the tile position
  349. unsigned int horzTileCount = tileset.getHorizontalTileCount();
  350. unsigned int adjusted_gid = gid - tileset.getFirstGid();
  351. return TMXTileSet::calculateTileOrigin(Vector2(static_cast<float>(adjusted_gid % horzTileCount), static_cast<float>(adjusted_gid / horzTileCount)),
  352. Vector2(static_cast<float>(tileset.getMaxTileWidth()), static_cast<float>(tileset.getMaxTileHeight())),
  353. tileset.getSpacing(),
  354. tileset.getMargin());
  355. }
  356. bool TMXLayer::hasTiles() const
  357. {
  358. size_t tile_size = _tiles.size();
  359. for (unsigned int i = 0; i < tile_size; i++)
  360. {
  361. if (_tiles[i].gid != 0)
  362. {
  363. return true;
  364. }
  365. }
  366. return false;
  367. }
  368. std::set<unsigned int> TMXLayer::getTilesetsUsed(const TMXMap& map) const
  369. {
  370. std::set<unsigned int> tilesets;
  371. unsigned int tileset_size = map.getTileSetCount();
  372. size_t tile_size = _tiles.size();
  373. for (unsigned int i = 0; i < tile_size; i++)
  374. {
  375. unsigned int gid = _tiles[i].gid;
  376. if (gid == 0)
  377. {
  378. // Empty tile
  379. continue;
  380. }
  381. unsigned int tileset = map.findTileSet(gid);
  382. if (tileset == tileset_size)
  383. {
  384. // Could not find tileset
  385. continue;
  386. }
  387. tilesets.insert(tileset);
  388. if (tilesets.size() == tileset_size)
  389. {
  390. // Don't need to continue checking, we have every possible tileset
  391. break;
  392. }
  393. }
  394. return tilesets;
  395. }
  396. // TMXImageLayer
  397. TMXImageLayer::TMXImageLayer()
  398. : TMXBaseLayer(TMXLayerType::ImageLayer),
  399. _pos(), _path("")
  400. {
  401. }
  402. TMXImageLayer::~TMXImageLayer()
  403. {
  404. }
  405. void TMXImageLayer::setX(int value)
  406. {
  407. _pos.x = static_cast<float>(value);
  408. }
  409. int TMXImageLayer::getX() const
  410. {
  411. return static_cast<int>(_pos.x);
  412. }
  413. void TMXImageLayer::setY(int value)
  414. {
  415. _pos.y = static_cast<float>(value);
  416. }
  417. int TMXImageLayer::getY() const
  418. {
  419. return static_cast<int>(_pos.y);
  420. }
  421. const Vector2& TMXImageLayer::getPosition() const
  422. {
  423. return _pos;
  424. }
  425. void TMXImageLayer::setImagePath(const std::string& path)
  426. {
  427. _path = path;
  428. }
  429. const std::string& TMXImageLayer::getImagePath() const
  430. {
  431. return _path;
  432. }