TmxFile2D.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. //
  2. // Copyright (c) 2008-2014 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include "Precompiled.h"
  23. #include "Animation2D.h"
  24. #include "Context.h"
  25. #include "FileSystem.h"
  26. #include "Log.h"
  27. #include "ResourceCache.h"
  28. #include "Sprite2D.h"
  29. #include "Texture2D.h"
  30. #include "TmxFile2D.h"
  31. #include "XMLFile.h"
  32. #include "DebugNew.h"
  33. namespace Urho3D
  34. {
  35. TmxFile2D::TmxFile2D(Context* context) :
  36. Resource(context),
  37. width_(0),
  38. height_(0),
  39. tileWidth_(0),
  40. tileHeight_(0)
  41. {
  42. }
  43. TmxFile2D::~TmxFile2D()
  44. {
  45. }
  46. void TmxFile2D::RegisterObject(Context* context)
  47. {
  48. context->RegisterFactory<TmxFile2D>();
  49. }
  50. bool TmxFile2D::BeginLoad(Deserializer& source)
  51. {
  52. loadXMLFile_ = new XMLFile(context_);
  53. if (!loadXMLFile_->Load(source))
  54. {
  55. LOGERROR("Load XML failed " + source.GetName());
  56. loadXMLFile_.Reset();
  57. return false;
  58. }
  59. XMLElement rootElem = loadXMLFile_->GetRoot("map");
  60. if (!rootElem)
  61. {
  62. LOGERROR("Invalid tmx file " + source.GetName());
  63. loadXMLFile_.Reset();
  64. return false;
  65. }
  66. // If we're async loading, request the texture now. Finish during EndLoad().
  67. if (GetAsyncLoadState() == ASYNC_LOADING)
  68. {
  69. for (XMLElement tileSetElem = rootElem.GetChild("tileset"); tileSetElem; tileSetElem = tileSetElem.GetNext("tileset"))
  70. {
  71. String loadTextureName = GetParentPath(GetName()) + tileSetElem.GetChild("image").GetAttribute("source");
  72. GetSubsystem<ResourceCache>()->BackgroundLoadResource<Texture2D>(loadTextureName, true, this);
  73. }
  74. }
  75. return true;
  76. }
  77. bool TmxFile2D::EndLoad()
  78. {
  79. // Actually load the folders and animations now
  80. if (!loadXMLFile_)
  81. return false;
  82. XMLElement rootElem = loadXMLFile_->GetRoot("map");
  83. String version = rootElem.GetAttribute("version");
  84. if (version != "1.0")
  85. {
  86. LOGERROR("Invalid version");
  87. return false;
  88. }
  89. String orientation = rootElem.GetAttribute("orientation");
  90. if (orientation != "orthogonal")
  91. {
  92. LOGERROR("Unsupported orientation now");
  93. return false;
  94. }
  95. width_ = rootElem.GetInt("width");
  96. height_ = rootElem.GetInt("height");
  97. tileWidth_ = rootElem.GetInt("tilewidth");
  98. tileHeight_ = rootElem.GetInt("tileheight");
  99. // Load tile set
  100. for (XMLElement tileSetElem = rootElem.GetChild("tileset"); tileSetElem; tileSetElem = tileSetElem.GetNext("tileset"))
  101. {
  102. if (!LoadTileSet(tileSetElem))
  103. {
  104. loadXMLFile_.Reset();
  105. return false;
  106. }
  107. }
  108. // Load layer
  109. for (XMLElement layerElem = rootElem.GetChild("layer"); layerElem; layerElem = layerElem.GetNext("layer"))
  110. {
  111. if (!LoadLayer(layerElem))
  112. {
  113. loadXMLFile_.Reset();
  114. return false;
  115. }
  116. }
  117. loadXMLFile_.Reset();
  118. return true;
  119. }
  120. const TmxLayer2D* TmxFile2D::GetLayer(unsigned index) const
  121. {
  122. if (index >= layers_.Size())
  123. return 0;
  124. return &layers_[index];
  125. }
  126. Sprite2D* TmxFile2D::GetTileSprite(int gid) const
  127. {
  128. HashMap<int, SharedPtr<Sprite2D> >::ConstIterator i = tileSprites_.Find(gid);
  129. if (i == tileSprites_.End())
  130. return 0;
  131. return i->second_;
  132. }
  133. bool TmxFile2D::LoadTileSet(const XMLElement& element)
  134. {
  135. XMLElement imageElem = element.GetChild("image");
  136. String loadTextureName = GetParentPath(GetName()) + imageElem.GetAttribute("source");
  137. ResourceCache* cache = GetSubsystem<ResourceCache>();
  138. SharedPtr<Texture2D> texture(cache->GetResource<Texture2D>(loadTextureName));
  139. if (!texture)
  140. {
  141. LOGERROR("Could not load texture " + loadTextureName);
  142. loadXMLFile_.Reset();
  143. return false;
  144. }
  145. textures_.Push(texture);
  146. int gid = element.GetInt("firstgid");
  147. int tileWidth = element.GetInt("tilewidth");
  148. int tileHeight = element.GetInt("tileheight");
  149. int spacing = element.GetInt("spacing");
  150. int margin = element.GetInt("margin");
  151. int imageWidth = imageElem.GetInt("width");
  152. int imageHeight = imageElem.GetInt("height");
  153. for (int y = margin; y < imageHeight - margin; y += tileHeight + spacing)
  154. {
  155. for (int x = margin; x < imageWidth - margin; x += tileWidth + spacing)
  156. {
  157. SharedPtr<Sprite2D> sprite(new Sprite2D(context_));
  158. sprite->SetTexture(texture);
  159. sprite->SetRectangle(IntRect(x, y, x + tileWidth, y + tileHeight));
  160. sprite->SetHotSpot(Vector2(0.0f, 0.0f));
  161. tileSprites_[gid++] = sprite;
  162. }
  163. }
  164. return true;
  165. }
  166. bool TmxFile2D::LoadLayer(const XMLElement& element)
  167. {
  168. layers_.Push(TmxLayer2D());
  169. TmxLayer2D& layer = layers_.Back();
  170. layer.tmxFile_ = this;
  171. layer.name_ = element.GetAttribute("name");
  172. layer.width_ = element.GetInt("width");
  173. layer.height_ = element.GetInt("height");
  174. XMLElement dataElem = element.GetChild("data");
  175. if (!dataElem)
  176. {
  177. LOGERROR("Could not find data in layer");
  178. return false;
  179. }
  180. if (dataElem.HasAttribute("encoding") && dataElem.GetAttribute("encoding") != "xml")
  181. {
  182. LOGERROR("Encoding not support now");
  183. return false;
  184. }
  185. layer.tiles_.Reserve(layer.width_ * layer.height_);
  186. for (XMLElement tileElem = dataElem.GetChild("tile"); tileElem; tileElem = tileElem.GetNext("tile"))
  187. {
  188. layer.tiles_.Push(tileElem.GetInt("gid"));
  189. }
  190. return true;
  191. }
  192. }