1 //
2 // Copyright (c) 2008-2017 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 
23 #include "../Precompiled.h"
24 
25 #include "../Resource/XMLElement.h"
26 #include "../Resource/JSONFile.h"
27 #include "../Urho2D/TileMapDefs2D.h"
28 
29 #include "../DebugNew.h"
30 
31 namespace Urho3D
32 {
33 extern URHO3D_API const float PIXEL_SIZE;
34 
GetMapWidth() const35 float TileMapInfo2D::GetMapWidth() const
36 {
37     return width_ * tileWidth_;
38 }
39 
GetMapHeight() const40 float TileMapInfo2D::GetMapHeight() const
41 {
42     if (orientation_ == O_STAGGERED)
43         return (height_ + 1) * 0.5f * tileHeight_;
44     else if (orientation_ == O_HEXAGONAL)
45         return (height_) * 0.5f * (tileHeight_ + tileHeight_ * 0.5f);
46     else
47         return height_ * tileHeight_;
48 }
49 
ConvertPosition(const Vector2 & position) const50 Vector2 TileMapInfo2D::ConvertPosition(const Vector2& position) const
51 {
52     switch (orientation_)
53     {
54     case O_ISOMETRIC:
55         {
56             Vector2 index = position * PIXEL_SIZE / tileHeight_;
57             return Vector2((width_ + index.x_ - index.y_) * tileWidth_ * 0.5f,
58                 (height_ * 2.0f - index.x_ - index.y_) * tileHeight_ * 0.5f);
59         }
60 
61     case O_STAGGERED:
62         return Vector2(position.x_ * PIXEL_SIZE, GetMapHeight() - position.y_ * PIXEL_SIZE);
63 
64     case O_HEXAGONAL:
65     case O_ORTHOGONAL:
66     default:
67         return Vector2(position.x_ * PIXEL_SIZE, GetMapHeight() - position.y_ * PIXEL_SIZE);
68     }
69 
70     return Vector2::ZERO;
71 }
72 
TileIndexToPosition(int x,int y) const73 Vector2 TileMapInfo2D::TileIndexToPosition(int x, int y) const
74 {
75     switch (orientation_)
76     {
77     case O_ISOMETRIC:
78         return Vector2((width_ + x - y - 1) * tileWidth_ * 0.5f, (height_ * 2 - x - y - 2) * tileHeight_ * 0.5f);
79 
80     case O_STAGGERED:
81         if (y % 2 == 0)
82             return Vector2(x * tileWidth_, (height_ - 1 - y) * 0.5f * tileHeight_);
83         else
84             return Vector2((x + 0.5f) * tileWidth_, (height_ - 1 - y) * 0.5f * tileHeight_);
85 
86     case O_HEXAGONAL:
87         if (y % 2 == 0)
88             return Vector2(x * tileWidth_, (height_ - 1 - y) * 0.75f * tileHeight_);
89         else
90             return Vector2((x + 0.5f) * tileWidth_, (height_ - 1 - y)  * 0.75f * tileHeight_);
91 
92     case O_ORTHOGONAL:
93     default:
94         return Vector2(x * tileWidth_, (height_ - 1 - y) * tileHeight_);
95     }
96 
97     return Vector2::ZERO;
98 }
99 
PositionToTileIndex(int & x,int & y,const Vector2 & position) const100 bool TileMapInfo2D::PositionToTileIndex(int& x, int& y, const Vector2& position) const
101 {
102     switch (orientation_)
103     {
104     case O_ISOMETRIC:
105     {
106         float ox = position.x_ / tileWidth_ - height_ * 0.5f;
107         float oy = position.y_ / tileHeight_;
108 
109         x = (int)(width_ - oy + ox);
110         y = (int)(height_ - oy - ox);
111     }
112         break;
113 
114     case O_STAGGERED:
115         y = (int)(height_ - 1 - position.y_ * 2.0f / tileHeight_);
116         if (y % 2 == 0)
117             x = (int)(position.x_ / tileWidth_);
118         else
119             x = (int)(position.x_ / tileWidth_ - 0.5f);
120 
121         break;
122 
123     case O_HEXAGONAL:
124         y = (int)(height_ - 1 - position.y_ / 0.75f / tileHeight_);
125         if (y % 2 == 0)
126             x = (int)(position.x_ / tileWidth_);
127         else
128             x = (int)(position.x_ / tileWidth_ - 0.75f);
129         break;
130 
131     case O_ORTHOGONAL:
132     default:
133         x = (int)(position.x_ / tileWidth_);
134         y = height_ - 1 - int(position.y_ / tileHeight_);
135         break;
136 
137     }
138 
139     return x >= 0 && x < width_ && y >= 0 && y < height_;
140 }
141 
PropertySet2D()142 PropertySet2D::PropertySet2D()
143 {
144 }
145 
~PropertySet2D()146 PropertySet2D::~PropertySet2D()
147 {
148 }
149 
Load(const XMLElement & element)150 void PropertySet2D::Load(const XMLElement& element)
151 {
152     assert(element.GetName() == "properties");
153     for (XMLElement propertyElem = element.GetChild("property"); propertyElem; propertyElem = propertyElem.GetNext("property"))
154         nameToValueMapping_[propertyElem.GetAttribute("name")] = propertyElem.GetAttribute("value");
155 }
156 
HasProperty(const String & name) const157 bool PropertySet2D::HasProperty(const String& name) const
158 {
159     return nameToValueMapping_.Find(name) != nameToValueMapping_.End();
160 }
161 
GetProperty(const String & name) const162 const String& PropertySet2D::GetProperty(const String& name) const
163 {
164     HashMap<String, String>::ConstIterator i = nameToValueMapping_.Find(name);
165     if (i == nameToValueMapping_.End())
166         return String::EMPTY;
167 
168     return i->second_;
169 }
170 
Tile2D()171 Tile2D::Tile2D() :
172     gid_(0)
173 {
174 }
175 
GetSprite() const176 Sprite2D* Tile2D::GetSprite() const
177 {
178     return sprite_;
179 }
180 
HasProperty(const String & name) const181 bool Tile2D::HasProperty(const String& name) const
182 {
183     if (!propertySet_)
184         return false;
185     return propertySet_->HasProperty(name);
186 }
187 
GetProperty(const String & name) const188 const String& Tile2D::GetProperty(const String& name) const
189 {
190     if (!propertySet_)
191         return String::EMPTY;
192 
193     return propertySet_->GetProperty(name);
194 }
195 
TileMapObject2D()196 TileMapObject2D::TileMapObject2D()
197 {
198 }
199 
GetNumPoints() const200 unsigned TileMapObject2D::GetNumPoints() const
201 {
202     return points_.Size();
203 }
204 
GetPoint(unsigned index) const205 const Vector2& TileMapObject2D::GetPoint(unsigned index) const
206 {
207     if (index >= points_.Size())
208         return Vector2::ZERO;
209 
210     return points_[index];
211 }
212 
GetTileSprite() const213 Sprite2D* TileMapObject2D::GetTileSprite() const
214 {
215     return sprite_;
216 }
217 
HasProperty(const String & name) const218 bool TileMapObject2D::HasProperty(const String& name) const
219 {
220     if (!propertySet_)
221         return false;
222     return propertySet_->HasProperty(name);
223 }
224 
GetProperty(const String & name) const225 const String& TileMapObject2D::GetProperty(const String& name) const
226 {
227     if (!propertySet_)
228         return String::EMPTY;
229     return propertySet_->GetProperty(name);
230 }
231 
232 }
233