Guest User

Untitled

a guest
May 5th, 2016
16
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #ifndef LEVEL_H
  2. #define LEVEL_H
  3.  
  4. #include <string>
  5. #include <vector>
  6. #include <map>
  7. #include <SFML/Graphics.hpp>
  8. #include <iostream>
  9. #include "TinyXML/tinyxml.h"
  10.  
  11. struct Object
  12. {
  13. int GetPropertyInt(std::string name);//номер свойства объекта в нашем списке
  14. float GetPropertyFloat(std::string name);
  15. std::string GetPropertyString(std::string name);
  16.  
  17. std::string name;//объявили переменную name типа string
  18. std::string type;//а здесь переменную type типа string
  19. sf::Rect<float> rect;//тип Rect с нецелыми значениями
  20. std::map<std::string, std::string> properties;//создаём ассоциатиный массив. ключ - строковый тип, значение - строковый
  21.  
  22. sf::Sprite sprite;//объявили спрайт
  23. };
  24.  
  25. struct Layer//слои
  26. {
  27. int opacity;//непрозрачность слоя
  28. std::vector<sf::Sprite> tiles;//закидываем в вектор тайлы
  29. };
  30.  
  31. class Level//главный класс - уровень
  32. {
  33. public:
  34. bool LoadFromFile(std::string filename);//возвращает false если не получилось загрузить
  35. Object GetObject(std::string name);
  36. std::vector<Object> GetObjects(std::string name);//выдаем объект в наш уровень
  37. std::vector<Object> GetAllObjects();//выдаем все объекты в наш уровень
  38. void Draw(sf::RenderWindow &window);//рисуем в окно
  39. sf::Vector2i GetTileSize();//получаем размер тайла
  40.  
  41. private:
  42. int width, height, tileWidth, tileHeight;//в tmx файле width height в начале,затем размер тайла
  43. int firstTileID;//получаем айди первого тайла
  44. sf::Rect<float> drawingBounds;//размер части карты которую рисуем
  45. sf::Texture tilesetImage;//текстура карты
  46. std::vector<Object> objects;//массив типа Объекты, который мы создали
  47. std::vector<Layer> layers;
  48. };
  49.  
  50. ///////////////////////////////////////
  51.  
  52.  
  53. int Object::GetPropertyInt(std::string name)//возвращаем номер свойства в нашем списке
  54. {
  55. return atoi(properties[name].c_str());
  56. }
  57.  
  58. float Object::GetPropertyFloat(std::string name)
  59. {
  60. return strtod(properties[name].c_str(), NULL);
  61. }
  62.  
  63. std::string Object::GetPropertyString(std::string name)//получить имя в виде строки.вроде понятно
  64. {
  65. return properties[name];
  66. }
  67.  
  68. bool Level::LoadFromFile(std::string filename)//двоеточия-обращение к методам класса вне класса
  69. {
  70. TiXmlDocument levelFile(filename.c_str());//загружаем файл в TiXmlDocument
  71.  
  72. // загружаем XML-карту
  73. if (!levelFile.LoadFile())//если не удалось загрузить карту
  74. {
  75. std::cout << "Loading level \"" << filename << "\" failed." << std::endl;//выдаем ошибку
  76. return false;
  77. }
  78.  
  79. // работаем с контейнером map
  80. TiXmlElement *map;
  81. map = levelFile.FirstChildElement("map");
  82.  
  83. // пример карты: <map version="1.0" orientation="orthogonal"
  84. // width="10" height="10" tilewidth="34" tileheight="34">
  85. width = atoi(map->Attribute("width"));//извлекаем из нашей карты ее свойства
  86. height = atoi(map->Attribute("height"));//те свойства, которые задавали при работе в
  87. tileWidth = atoi(map->Attribute("tilewidth"));//тайлмап редакторе
  88. tileHeight = atoi(map->Attribute("tileheight"));
  89.  
  90. // Берем описание тайлсета и идентификатор первого тайла
  91. TiXmlElement *tilesetElement;
  92. tilesetElement = map->FirstChildElement("tileset");
  93. firstTileID = atoi(tilesetElement->Attribute("firstgid"));
  94.  
  95. // source - путь до картинки в контейнере image
  96. TiXmlElement *image;
  97. image = tilesetElement->FirstChildElement("image");
  98. std::string imagepath = image->Attribute("source");
  99.  
  100. // пытаемся загрузить тайлсет
  101. sf::Image img;
  102.  
  103. if (!img.loadFromFile(imagepath))
  104. {
  105. std::cout << "Failed to load tile sheet." << std::endl;//если не удалось загрузить тайлсет-выводим ошибку в консоль
  106. return false;
  107. }
  108.  
  109.  
  110. img.createMaskFromColor(sf::Color(255, 255, 255));//для маски цвета.сейчас нет маски
  111. tilesetImage.loadFromImage(img);
  112. tilesetImage.setSmooth(false);//сглаживание
  113.  
  114. // получаем количество столбцов и строк тайлсета
  115. int columns = tilesetImage.getSize().x / tileWidth;
  116. int rows = tilesetImage.getSize().y / tileHeight;
  117.  
  118. // вектор из прямоугольников изображений (TextureRect)
  119. std::vector<sf::Rect<int>> subRects;
  120.  
  121. for (int y = 0; y < rows; y++)
  122. for (int x = 0; x < columns; x++)
  123. {
  124. sf::Rect<int> rect;
  125.  
  126. rect.top = y * tileHeight;
  127. rect.height = tileHeight;
  128. rect.left = x * tileWidth;
  129. rect.width = tileWidth;
  130.  
  131. subRects.push_back(rect);
  132. }
  133.  
  134. // работа со слоями
  135. TiXmlElement *layerElement;
  136. layerElement = map->FirstChildElement("layer");
  137. while (layerElement)
  138. {
  139. Layer layer;
  140.  
  141. // если присутствует opacity, то задаем прозрачность слоя, иначе он полностью непрозрачен
  142. if (layerElement->Attribute("opacity") != NULL)
  143. {
  144. float opacity = strtod(layerElement->Attribute("opacity"), NULL);
  145. layer.opacity = 255 * opacity;
  146. }
  147. else
  148. {
  149. layer.opacity = 255;
  150. }
  151.  
  152. //  контейнер <data>
  153. TiXmlElement *layerDataElement;
  154. layerDataElement = layerElement->FirstChildElement("data");
  155.  
  156. if (layerDataElement == NULL)
  157. {
  158. std::cout << "Bad map. No layer information found." << std::endl;
  159. }
  160.  
  161. //  контейнер <tile> - описание тайлов каждого слоя
  162. TiXmlElement *tileElement;
  163. tileElement = layerDataElement->FirstChildElement("tile");
  164.  
  165. if (tileElement == NULL)
  166. {
  167. std::cout << "Bad map. No tile information found." << std::endl;
  168. return false;
  169. }
  170.  
  171. int x = 0;
  172. int y = 0;
  173.  
  174. while (tileElement)
  175. {
  176. int tileGID = atoi(tileElement->Attribute("gid"));
  177. int subRectToUse = tileGID - firstTileID;
  178.  
  179. // Устанавливаем TextureRect каждого тайла
  180. if (subRectToUse >= 0)
  181. {
  182. sf::Sprite sprite;
  183. sprite.setTexture(tilesetImage);
  184. sprite.setTextureRect(subRects[subRectToUse]);
  185. sprite.setPosition(x * tileWidth, y * tileHeight);
  186. sprite.setColor(sf::Color(255, 255, 255, layer.opacity));
  187.  
  188. layer.tiles.push_back(sprite);//закидываем в слой спрайты тайлов
  189. }
  190.  
  191. tileElement = tileElement->NextSiblingElement("tile");
  192.  
  193. x++;
  194. if (x >= width)
  195. {
  196. x = 0;
  197. y++;
  198. if (y >= height)
  199. y = 0;
  200. }
  201. }
  202.  
  203. layers.push_back(layer);
  204.  
  205. layerElement = layerElement->NextSiblingElement("layer");
  206. }
  207.  
  208. // работа с объектами
  209. TiXmlElement *objectGroupElement;
  210.  
  211. // если есть слои объектов
  212. if (map->FirstChildElement("objectgroup") != NULL)
  213. {
  214. objectGroupElement = map->FirstChildElement("objectgroup");
  215. while (objectGroupElement)
  216. {
  217. //  контейнер <object>
  218. TiXmlElement *objectElement;
  219. objectElement = objectGroupElement->FirstChildElement("object");
  220.  
  221. while (objectElement)
  222. {
  223. // получаем все данные - тип, имя, позиция, и тд
  224. std::string objectType;
  225. if (objectElement->Attribute("type") != NULL)
  226. {
  227. objectType = objectElement->Attribute("type");
  228. }
  229. std::string objectName;
  230. if (objectElement->Attribute("name") != NULL)
  231. {
  232. objectName = objectElement->Attribute("name");
  233. }
  234. int x = atoi(objectElement->Attribute("x"));
  235. int y = atoi(objectElement->Attribute("y"));
  236.  
  237. int width, height;
  238.  
  239. sf::Sprite sprite;
  240. sprite.setTexture(tilesetImage);
  241. sprite.setTextureRect(sf::Rect<int>(0, 0, 0, 0));
  242. sprite.setPosition(x, y);
  243.  
  244. if (objectElement->Attribute("width") != NULL)
  245. {
  246. width = atoi(objectElement->Attribute("width"));
  247. height = atoi(objectElement->Attribute("height"));
  248. }
  249. else
  250. {
  251. width = subRects[atoi(objectElement->Attribute("gid")) - firstTileID].width;
  252. height = subRects[atoi(objectElement->Attribute("gid")) - firstTileID].height;
  253. sprite.setTextureRect(subRects[atoi(objectElement->Attribute("gid")) - firstTileID]);
  254. }
  255.  
  256. // экземпляр объекта
  257. Object object;
  258. object.name = objectName;
  259. object.type = objectType;
  260. object.sprite = sprite;
  261.  
  262. sf::Rect <float> objectRect;
  263. objectRect.top = y;
  264. objectRect.left = x;
  265. objectRect.height = height;
  266. objectRect.width = width;
  267. object.rect = objectRect;
  268.  
  269. // "переменные" объекта
  270. TiXmlElement *properties;
  271. properties = objectElement->FirstChildElement("properties");
  272. if (properties != NULL)
  273. {
  274. TiXmlElement *prop;
  275. prop = properties->FirstChildElement("property");
  276. if (prop != NULL)
  277. {
  278. while (prop)
  279. {
  280. std::string propertyName = prop->Attribute("name");
  281. std::string propertyValue = prop->Attribute("value");
  282.  
  283. object.properties[propertyName] = propertyValue;
  284.  
  285. prop = prop->NextSiblingElement("property");
  286. }
  287. }
  288. }
  289.  
  290.  
  291. objects.push_back(object);
  292.  
  293. objectElement = objectElement->NextSiblingElement("object");
  294. }
  295. objectGroupElement = objectGroupElement->NextSiblingElement("objectgroup");
  296. }
  297. }
  298. else
  299. {
  300. std::cout << "No object layers found..." << std::endl;
  301. }
  302.  
  303. return true;
  304. }
  305.  
  306. Object Level::GetObject(std::string name)
  307. {
  308. // только первый объект с заданным именем
  309. for (int i = 0; i < objects.size(); i++)
  310. if (objects[i].name == name)
  311. return objects[i];
  312. }
  313.  
  314. std::vector<Object> Level::GetObjects(std::string name)
  315. {
  316. // все объекты с заданным именем
  317. std::vector<Object> vec;
  318. for (int i = 0; i < objects.size(); i++)
  319. if (objects[i].name == name)
  320. vec.push_back(objects[i]);
  321.  
  322. return vec;
  323. }
  324.  
  325.  
  326. std::vector<Object> Level::GetAllObjects()
  327. {
  328. return objects;
  329. };
  330.  
  331.  
  332. sf::Vector2i Level::GetTileSize()
  333. {
  334. return sf::Vector2i(tileWidth, tileHeight);
  335. }
  336.  
  337. void Level::Draw(sf::RenderWindow &window)
  338. {
  339. // рисуем все тайлы (объекты не рисуем!)
  340. for (int layer = 0; layer < layers.size(); layer++)
  341. for (int tile = 0; tile < layers[layer].tiles.size(); tile++)
  342. window.draw(layers[layer].tiles[tile]);
  343. }
  344.  
  345. #endif
RAW Paste Data