Selaa lähdekoodia

Add tile map support in Urho2D, current not all of features are supported in Urho2D, but I think we can add it later. Fore more information about tile map, please refer http://www.mapeditor.org/.

aster 11 vuotta sitten
vanhempi
sitoutus
ef32eee6ee

+ 2 - 0
Bin/Data/Scripts/Editor/AttributeEditor.as

@@ -886,6 +886,7 @@ void InitResourcePicker()
     Array<String> materialFilters = {"*.xml", "*.material"};
     Array<String> anmSetFilters = {"*.scml"};
     Array<String> pexFilters = {"*.pex"};
+    Array<String> tmxFilters = {"*.tmx"};
     resourcePickers.Push(ResourcePicker("Animation", "*.ani", ACTION_PICK | ACTION_TEST));
     resourcePickers.Push(ResourcePicker("Font", fontFilters));
     resourcePickers.Push(ResourcePicker("Image", imageFilters));
@@ -903,6 +904,7 @@ void InitResourcePicker()
     resourcePickers.Push(ResourcePicker("Sprite2D", textureFilters, ACTION_PICK | ACTION_OPEN));
     resourcePickers.Push(ResourcePicker("AnimationSet2D", anmSetFilters, ACTION_PICK | ACTION_OPEN));
     resourcePickers.Push(ResourcePicker("ParticleEffect2D", pexFilters, ACTION_PICK | ACTION_OPEN));
+    resourcePickers.Push(ResourcePicker("TmxFile2D", tmxFilters, ACTION_PICK | ACTION_OPEN));
 }
 
 ResourcePicker@ GetResourcePicker(StringHash resourceType)

BIN
Bin/Data/Urho2D/Desert.png


+ 1214 - 0
Bin/Data/Urho2D/Desert.tmx

@@ -0,0 +1,1214 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<map version="1.0" orientation="orthogonal" width="30" height="20" tilewidth="32" tileheight="32">
+ <tileset firstgid="1" name="Desert" tilewidth="32" tileheight="32" spacing="1" margin="1">
+  <image source="Desert.png" width="265" height="199"/>
+ </tileset>
+ <layer name="Background" width="30" height="20">
+  <data>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="1"/>
+   <tile gid="2"/>
+   <tile gid="3"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="1"/>
+   <tile gid="2"/>
+   <tile gid="3"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="9"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="11"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="17"/>
+   <tile gid="10"/>
+   <tile gid="19"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="17"/>
+   <tile gid="10"/>
+   <tile gid="19"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="25"/>
+   <tile gid="26"/>
+   <tile gid="27"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="25"/>
+   <tile gid="26"/>
+   <tile gid="27"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="33"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="35"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="41"/>
+   <tile gid="34"/>
+   <tile gid="43"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="41"/>
+   <tile gid="34"/>
+   <tile gid="43"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="34"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="36"/>
+   <tile gid="37"/>
+   <tile gid="30"/>
+   <tile gid="36"/>
+   <tile gid="37"/>
+   <tile gid="30"/>
+   <tile gid="36"/>
+   <tile gid="37"/>
+   <tile gid="30"/>
+   <tile gid="36"/>
+   <tile gid="37"/>
+   <tile gid="30"/>
+   <tile gid="36"/>
+   <tile gid="37"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="34"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="34"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="44"/>
+   <tile gid="45"/>
+   <tile gid="30"/>
+   <tile gid="44"/>
+   <tile gid="45"/>
+   <tile gid="30"/>
+   <tile gid="44"/>
+   <tile gid="45"/>
+   <tile gid="30"/>
+   <tile gid="44"/>
+   <tile gid="45"/>
+   <tile gid="30"/>
+   <tile gid="44"/>
+   <tile gid="45"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="34"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="34"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="34"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="34"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="34"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="34"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="36"/>
+   <tile gid="37"/>
+   <tile gid="30"/>
+   <tile gid="36"/>
+   <tile gid="37"/>
+   <tile gid="30"/>
+   <tile gid="36"/>
+   <tile gid="37"/>
+   <tile gid="30"/>
+   <tile gid="36"/>
+   <tile gid="37"/>
+   <tile gid="30"/>
+   <tile gid="36"/>
+   <tile gid="37"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="34"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="34"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="44"/>
+   <tile gid="45"/>
+   <tile gid="30"/>
+   <tile gid="44"/>
+   <tile gid="45"/>
+   <tile gid="30"/>
+   <tile gid="44"/>
+   <tile gid="45"/>
+   <tile gid="30"/>
+   <tile gid="44"/>
+   <tile gid="45"/>
+   <tile gid="30"/>
+   <tile gid="44"/>
+   <tile gid="45"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="34"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="25"/>
+   <tile gid="34"/>
+   <tile gid="27"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="25"/>
+   <tile gid="34"/>
+   <tile gid="27"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="33"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="34"/>
+   <tile gid="35"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="41"/>
+   <tile gid="42"/>
+   <tile gid="43"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="41"/>
+   <tile gid="42"/>
+   <tile gid="43"/>
+   <tile gid="30"/>
+   <tile gid="10"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="1"/>
+   <tile gid="10"/>
+   <tile gid="3"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="1"/>
+   <tile gid="10"/>
+   <tile gid="3"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="9"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="10"/>
+   <tile gid="11"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="17"/>
+   <tile gid="18"/>
+   <tile gid="19"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="17"/>
+   <tile gid="18"/>
+   <tile gid="19"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+   <tile gid="30"/>
+  </data>
+ </layer>
+ <layer name="Foreground" width="30" height="20">
+  <data>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="31"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="46"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="0"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+   <tile gid="38"/>
+  </data>
+ </layer>
+</map>

+ 3 - 0
Bin/Data/Urho2D/Desert.xml

@@ -0,0 +1,3 @@
+<texture>
+    <filter mode="nearest" />
+</texture>

+ 1 - 1
Source/Engine/Urho2D/AnimatedSprite2D.cpp

@@ -250,7 +250,7 @@ void AnimatedSprite2D::SetAnimationSetAttr(ResourceRef value)
     SetAnimationSet(cache->GetResource<AnimationSet2D>(value.name_));
 }
 
-Urho3D::ResourceRef AnimatedSprite2D::GetAnimationSetAttr() const
+ResourceRef AnimatedSprite2D::GetAnimationSetAttr() const
 {
     return GetResourceRef(animationSet_, AnimationSet2D::GetTypeStatic());
 }

+ 1 - 1
Source/Engine/Urho2D/ParticleEmitter2D.cpp

@@ -167,7 +167,7 @@ void ParticleEmitter2D::SetParticleEffectAttr(ResourceRef value)
     SetEffect(cache->GetResource<ParticleEffect2D>(value.name_));
 }
 
-Urho3D::ResourceRef ParticleEmitter2D::GetParticleEffectAttr() const
+ResourceRef ParticleEmitter2D::GetParticleEffectAttr() const
 {
     return GetResourceRef(effect_, ParticleEffect2D::GetTypeStatic());
 }

+ 149 - 0
Source/Engine/Urho2D/TileMap2D.cpp

@@ -0,0 +1,149 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "Precompiled.h"
+#include "Context.h"
+#include "Node.h"
+#include "ResourceCache.h"
+#include "TileMap2D.h"
+#include "TileMapLayer2D.h"
+#include "TmxFile2D.h"
+
+#include "DebugNew.h"
+
+namespace Urho3D
+{
+
+extern const float PIXEL_SIZE;
+extern const char* URHO2D_CATEGORY;
+
+TileMap2D::TileMap2D(Context* context) :
+    Component(context)
+{
+}
+
+TileMap2D::~TileMap2D()
+{
+}
+
+void TileMap2D::RegisterObject(Context* context)
+{
+    context->RegisterFactory<TileMap2D>(URHO2D_CATEGORY);
+
+    ACCESSOR_ATTRIBUTE(TileMap2D, VAR_RESOURCEREF, "Tmx File", GetTmxFileAttr, SetTmxFileAttr, ResourceRef, ResourceRef(TmxFile2D::GetTypeStatic()), AM_DEFAULT);
+}
+
+void TileMap2D::SetTmxFile(TmxFile2D* tmxFile)
+{
+    if (tmxFile == tmxFile_)
+        return;
+
+    if (tmxFile_)
+    {
+        for (unsigned i = 0; i < layers_.Size(); ++i)
+            layers_[i]->GetNode()->Remove();
+        layers_.Clear();
+    }
+
+    tmxFile_ = tmxFile;
+    
+    if (!tmxFile_)
+        return;
+
+    unsigned numLayers = tmxFile_->GetNumLayers();
+    for (unsigned i = 0; i < numLayers; ++i)
+    {
+        const TmxLayer2D* tmxLayer = tmxFile_->GetLayer(i);
+        SharedPtr<Node> layerNode(GetNode()->CreateChild(tmxLayer->name_, LOCAL));
+        layerNode->SetTemporary(true);
+
+        SharedPtr<TileMapLayer2D> tileMapLayer(layerNode->CreateComponent<TileMapLayer2D>());
+        tileMapLayer->SetTmxLayer(tmxLayer, i);
+
+        layers_.Push(tileMapLayer);
+    }
+}
+
+TmxFile2D* TileMap2D::GetTmxFile() const
+{
+    return tmxFile_;
+}
+
+int TileMap2D::GetWidth() const
+{
+    return tmxFile_ ? tmxFile_->GetWidth() : 0;
+}
+
+int TileMap2D::GetHeight() const
+{
+    return tmxFile_ ? tmxFile_->GetHeight() : 0;
+
+}
+
+int TileMap2D::GetTileWidth() const
+{
+    return tmxFile_ ? tmxFile_->GetTileWidth() : 0;
+
+}
+
+int TileMap2D::GetTileHeight() const
+{
+    return tmxFile_ ? tmxFile_->GetTileHeight() : 0;
+
+}
+Vector2 TileMap2D::GetSize() const
+{
+    if (!tmxFile_)
+        return Vector2::ZERO;
+
+    return Vector2(tmxFile_->GetWidth() * tmxFile_->GetTileWidth() * PIXEL_SIZE,
+        tmxFile_->GetHeight() * tmxFile_->GetTileHeight() * PIXEL_SIZE);
+}
+
+Vector2 TileMap2D::GetTileSize() const
+{
+    if (!tmxFile_)
+        return Vector2::ZERO;
+
+    return Vector2(tmxFile_->GetTileWidth() * PIXEL_SIZE, tmxFile_->GetTileHeight() * PIXEL_SIZE);
+}
+
+TileMapLayer2D* TileMap2D::GetLayer(unsigned index) const
+{
+    if (index >= layers_.Size())
+        return 0;
+
+    return layers_[index];
+}
+
+void TileMap2D::SetTmxFileAttr(ResourceRef value)
+{
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    SetTmxFile(cache->GetResource<TmxFile2D>(value.name_));
+}
+
+ResourceRef TileMap2D::GetTmxFileAttr() const
+{
+    return GetResourceRef(tmxFile_, TmxFile2D::GetTypeStatic());
+}
+
+}

+ 80 - 0
Source/Engine/Urho2D/TileMap2D.h

@@ -0,0 +1,80 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include "Component.h"
+
+namespace Urho3D
+{
+
+class TileMapLayer2D;
+class TmxFile2D;
+
+/// Tile map component.
+class URHO3D_API TileMap2D : public Component
+{
+    OBJECT(TileMap2D);
+
+public:
+    /// Construct.
+    TileMap2D(Context* context);
+    /// Destruct.
+    ~TileMap2D();
+    /// Register object factory.
+    static void RegisterObject(Context* context);
+
+    /// Set tmx file.
+    void SetTmxFile(TmxFile2D* tmxFile);
+
+    /// Return tmx file.
+    TmxFile2D* GetTmxFile() const;
+    /// Return width.
+    int GetWidth() const;
+    /// Return height.
+    int GetHeight() const;
+    /// Return size.
+    Vector2 GetSize() const;
+    /// Return tile width in pixel.
+    int GetTileWidth() const;
+    /// Return tile height in pixel.
+    int GetTileHeight() const;
+    /// Return tile size.
+    Vector2 GetTileSize() const;
+    /// Return number of layers.
+    unsigned GetNumLayers() const { return layers_.Size(); }
+    /// Return tile map layer at index.
+    TileMapLayer2D* GetLayer(unsigned index) const;
+    
+    /// Set tile map file attribute.
+    void SetTmxFileAttr(ResourceRef value);
+    /// Return tile map file attribute.
+    ResourceRef GetTmxFileAttr() const;
+
+private:
+    /// Tmx file.
+    SharedPtr<TmxFile2D> tmxFile_;
+    /// Tile map layers.
+    Vector<SharedPtr<TileMapLayer2D> > layers_;
+};
+
+}

+ 144 - 0
Source/Engine/Urho2D/TileMapLayer2D.cpp

@@ -0,0 +1,144 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "Precompiled.h"
+#include "Context.h"
+#include "ResourceCache.h"
+#include "TileMapLayer2D.h"
+#include "TmxFile2D.h"
+#include "TileMapLayer2D.h"
+#include "Node.h"
+#include "StaticSprite2D.h"
+
+#include "DebugNew.h"
+
+namespace Urho3D
+{
+
+
+extern const float PIXEL_SIZE;
+
+TileMapLayer2D::TileMapLayer2D(Context* context) :
+    Component(context),
+    tmxLayer_(0),
+    drawOrder_(0)
+{
+}
+
+TileMapLayer2D::~TileMapLayer2D()
+{
+}
+
+void TileMapLayer2D::RegisterObject(Context* context)
+{
+    context->RegisterFactory<TileMapLayer2D>();
+}
+
+void TileMapLayer2D::SetTmxLayer(const TmxLayer2D* tmxLayer, int drawOrder)
+{
+    if (tmxLayer == tmxLayer_)
+        return;
+
+    if (tmxLayer_)
+    {
+        for (unsigned i = 0; i < tileNodes_.Size(); ++i)
+        {
+            if (tileNodes_[i])
+                tileNodes_[i]->Remove();
+        }
+
+        tileNodes_.Clear();
+    }
+
+    tmxLayer_ = tmxLayer;
+    drawOrder_ = drawOrder;
+
+    if (!tmxLayer_)
+        return;
+
+    int width = tmxLayer_->width_;
+    int height = tmxLayer->height_;
+    tileNodes_.Resize(width * height);
+
+    TmxFile2D* tmxFile = tmxLayer_->tmxFile_;
+    float tileWidth = tmxFile->GetTileWidth() * PIXEL_SIZE;
+    float tileHeight = tmxFile->GetTileHeight() * PIXEL_SIZE;
+
+    for (int x = 0; x < width; ++x)
+    {
+        for (int y = 0; y < height; ++y)
+        {
+            int gid = tmxLayer->tiles_[y * width + x];
+            if (gid <= 0)
+                continue;
+            
+            Sprite2D* sprite = tmxFile->GetTileSprite(gid);
+            if (!sprite)
+                continue;
+            
+            SharedPtr<Node> tileNode(GetNode()->CreateChild("Tile"));
+            tileNode->SetTemporary(true);
+
+            tileNode->SetPosition(Vector3(x * tileWidth, (height - y - 1) * tileHeight, 0.0f));
+            StaticSprite2D* staticSprite = tileNode->CreateComponent<StaticSprite2D>();
+            staticSprite->SetSprite(sprite);
+            staticSprite->SetLayer(drawOrder_);
+            staticSprite->SetOrderInLayer(y * width + x);
+
+            tileNodes_[y * width + x] = tileNode;
+        }
+    }
+}
+
+void TileMapLayer2D::SetDrawOrder(int drawOrder)
+{
+    if (drawOrder == drawOrder_)
+        return;
+
+    drawOrder_ = drawOrder;
+
+    for (unsigned i = 0; i < tileNodes_.Size(); ++i)
+        tileNodes_[i]->GetComponent<StaticSprite2D>()->SetLayer(drawOrder_);
+}
+
+int TileMapLayer2D::GetWidth() const
+{
+    return tmxLayer_ ? tmxLayer_->width_ : 0;
+}
+
+int TileMapLayer2D::GetHeight() const
+{
+    return tmxLayer_ ? tmxLayer_->height_ : 0;
+}
+
+Node* TileMapLayer2D::GetTileNode(int x, int y) const
+{
+    if (!tmxLayer_)
+        return 0;
+
+    if (x < 0 || x >= tmxLayer_->width_ || y < 0 || y >= tmxLayer_->height_)
+        return 0;
+
+    return tileNodes_[y * tmxLayer_->height_ + x];
+}
+
+}

+ 71 - 0
Source/Engine/Urho2D/TileMapLayer2D.h

@@ -0,0 +1,71 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include "Component.h"
+
+namespace Urho3D
+{
+
+struct TmxLayer2D;
+class Node;
+
+/// Tile map component.
+class URHO3D_API TileMapLayer2D : public Component
+{
+    OBJECT(TileMapLayer2D);
+
+public:
+    /// Construct.
+    TileMapLayer2D(Context* context);
+    /// Destruct.
+    ~TileMapLayer2D();
+    /// Register object factory.
+    static void RegisterObject(Context* context);
+
+    /// Set tmx layer.
+    void SetTmxLayer(const TmxLayer2D* tmxLayer, int drawOrder);
+    /// Set draw order
+    void SetDrawOrder(int drawOrder);
+
+    /// Return tmx layer.
+    const TmxLayer2D* GetTmxLayer() const { return tmxLayer_; }
+    /// Return draw order.
+    int GetDrawOrder() const { return drawOrder_; }
+    /// Return width.
+    int GetWidth() const;
+    /// Return height.
+    int GetHeight() const;
+    /// Return tile node.
+    Node* GetTileNode(int x, int y) const;
+
+private:
+    /// Tmx layer.
+    const TmxLayer2D* tmxLayer_;
+    /// Draw order.
+    int drawOrder_;
+    /// Tile nodes.
+    Vector<SharedPtr<Node> > tileNodes_;
+};
+
+}

+ 229 - 0
Source/Engine/Urho2D/TmxFile2D.cpp

@@ -0,0 +1,229 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "Precompiled.h"
+#include "Animation2D.h"
+#include "Context.h"
+#include "FileSystem.h"
+#include "Log.h"
+#include "ResourceCache.h"
+#include "Sprite2D.h"
+#include "Texture2D.h"
+#include "TmxFile2D.h"
+#include "XMLFile.h"
+
+#include "DebugNew.h"
+
+namespace Urho3D
+{
+
+TmxFile2D::TmxFile2D(Context* context) :
+    Resource(context),
+    width_(0),
+    height_(0),
+    tileWidth_(0),
+    tileHeight_(0)
+{
+}
+
+TmxFile2D::~TmxFile2D()
+{
+}
+
+void TmxFile2D::RegisterObject(Context* context)
+{
+    context->RegisterFactory<TmxFile2D>();
+}
+
+bool TmxFile2D::BeginLoad(Deserializer& source)
+{
+    loadXMLFile_ = new XMLFile(context_);
+    if (!loadXMLFile_->Load(source))
+    {
+        LOGERROR("Load XML failed " + source.GetName());
+        loadXMLFile_.Reset();
+        return false;
+    }
+
+    XMLElement rootElem = loadXMLFile_->GetRoot("map");
+    if (!rootElem)
+    {
+        LOGERROR("Invalid tmx file " + source.GetName());
+        loadXMLFile_.Reset();
+        return false;
+    }
+
+    // If we're async loading, request the texture now. Finish during EndLoad().
+    if (GetAsyncLoadState() == ASYNC_LOADING)
+    {
+        for (XMLElement tileSetElem = rootElem.GetChild("tileset"); tileSetElem; tileSetElem = tileSetElem.GetNext("tileset"))
+        {
+            String loadTextureName = GetParentPath(GetName()) + tileSetElem.GetChild("image").GetAttribute("source");
+            GetSubsystem<ResourceCache>()->BackgroundLoadResource<Texture2D>(loadTextureName, true, this);
+        }
+    }
+
+    return true;
+}
+
+bool TmxFile2D::EndLoad()
+{
+    // Actually load the folders and animations now
+    if (!loadXMLFile_)
+        return false;
+
+    XMLElement rootElem = loadXMLFile_->GetRoot("map");
+
+    String version = rootElem.GetAttribute("version");
+    if (version != "1.0")
+    {
+        LOGERROR("Invalid version");
+        return false;
+    }
+
+    String orientation = rootElem.GetAttribute("orientation");
+    if (orientation != "orthogonal")
+    {
+        LOGERROR("Unsupported orientation now");
+        return false;
+    }
+
+    width_ = rootElem.GetInt("width");
+    height_ = rootElem.GetInt("height");
+    tileWidth_ = rootElem.GetInt("tilewidth");
+    tileHeight_ = rootElem.GetInt("tileheight");
+
+    // Load tile set
+    for (XMLElement tileSetElem = rootElem.GetChild("tileset"); tileSetElem; tileSetElem = tileSetElem.GetNext("tileset"))
+    {
+        if (!LoadTileSet(tileSetElem))
+        {
+            loadXMLFile_.Reset();
+            return false;
+        }
+    }
+
+    // Load layer
+    for (XMLElement layerElem = rootElem.GetChild("layer"); layerElem; layerElem = layerElem.GetNext("layer"))
+    {
+        if (!LoadLayer(layerElem))
+        {
+            loadXMLFile_.Reset();
+            return false;
+        }
+    }
+
+    loadXMLFile_.Reset();
+    return true;
+}
+
+const TmxLayer2D* TmxFile2D::GetLayer(unsigned index) const
+{
+    if (index >= layers_.Size())
+        return 0;
+
+    return &layers_[index];
+}
+
+Sprite2D* TmxFile2D::GetTileSprite(int gid) const
+{
+    HashMap<int, SharedPtr<Sprite2D> >::ConstIterator i = tileSprites_.Find(gid);
+    if (i == tileSprites_.End())
+        return 0;
+
+    return i->second_;
+}
+
+bool TmxFile2D::LoadTileSet(const XMLElement& element)
+{
+    XMLElement imageElem = element.GetChild("image");
+    String loadTextureName = GetParentPath(GetName()) + imageElem.GetAttribute("source");
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    SharedPtr<Texture2D> texture(cache->GetResource<Texture2D>(loadTextureName));
+    if (!texture)
+    {
+        LOGERROR("Could not load texture " + loadTextureName);
+        loadXMLFile_.Reset();
+        return false;
+    }
+
+    textures_.Push(texture);
+
+    int gid = element.GetInt("firstgid");
+    int tileWidth = element.GetInt("tilewidth");
+    int tileHeight = element.GetInt("tileheight");
+    int spacing = element.GetInt("spacing");
+    int margin = element.GetInt("margin");
+    int imageWidth = imageElem.GetInt("width");
+    int imageHeight = imageElem.GetInt("height");
+
+    for (int y = margin; y < imageHeight - margin; y += tileHeight + spacing)
+    {
+        for (int x = margin; x < imageWidth - margin; x += tileWidth + spacing)
+        {
+            SharedPtr<Sprite2D> sprite(new Sprite2D(context_));
+            sprite->SetTexture(texture);
+            sprite->SetRectangle(IntRect(x, y, x + tileWidth, y + tileHeight));
+            sprite->SetHotSpot(Vector2(0.0f, 0.0f));
+
+            tileSprites_[gid++] = sprite;
+        }
+    }
+
+    return true;
+}
+
+bool TmxFile2D::LoadLayer(const XMLElement& element)
+{
+    layers_.Push(TmxLayer2D());
+    TmxLayer2D& layer = layers_.Back();
+    layer.tmxFile_ = this;
+
+    layer.name_ = element.GetAttribute("name");
+
+    layer.width_ = element.GetInt("width");
+    layer.height_ = element.GetInt("height");
+
+    XMLElement dataElem = element.GetChild("data");
+    if (!dataElem)
+    {
+        LOGERROR("Could not find data in layer");
+        return false;
+    }
+
+    if (dataElem.HasAttribute("encoding") && dataElem.GetAttribute("encoding") != "xml")
+    {
+        LOGERROR("Encoding not support now");
+        return false;
+    }
+
+    layer.tiles_.Reserve(layer.width_ * layer.height_);
+
+    for (XMLElement tileElem = dataElem.GetChild("tile"); tileElem; tileElem = tileElem.GetNext("tile"))
+    {
+        layer.tiles_.Push(tileElem.GetInt("gid"));
+    }
+
+    return true;
+}
+
+}

+ 109 - 0
Source/Engine/Urho2D/TmxFile2D.h

@@ -0,0 +1,109 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include "Resource.h"
+
+namespace Urho3D
+{
+
+class Sprite2D;
+class Texture2D;
+class TmxFile2D;
+class XMLElement;
+class XMLFile;
+
+/// Tile map layer.
+struct TmxLayer2D
+{
+    /// Tmx file.
+    WeakPtr<TmxFile2D> tmxFile_;
+    /// Name.
+    String name_;
+    /// Width.
+    int width_;
+    /// Height.
+    int height_;
+    /// Tiles.
+    PODVector<int> tiles_;
+};
+
+/// Tile map file.
+class URHO3D_API TmxFile2D : public Resource
+{
+    OBJECT(TmxFile2D);
+
+public:
+    /// Construct.
+    TmxFile2D(Context* context);
+    /// Destruct.
+    virtual ~TmxFile2D();
+    /// Register object factory. 
+    static void RegisterObject(Context* context);
+
+    /// Load resource from stream. May be called from a worker thread. Return true if successful.
+    virtual bool BeginLoad(Deserializer& source);
+    /// Finish resource loading. Always called from the main thread. Return true if successful.
+    virtual bool EndLoad();
+
+    /// Return width.
+    int GetWidth() const { return width_; }
+    /// Return height.
+    int GetHeight() const { return height_; }
+    /// Return tile width.
+    int GetTileWidth() const { return tileWidth_; }
+    /// Return tile height.
+    int GetTileHeight() const { return tileHeight_; }
+    /// Return number of layers.
+    unsigned GetNumLayers() const { return layers_.Size(); }
+    /// Return layer at index.
+    const TmxLayer2D* GetLayer(unsigned index) const;
+    /// Return tile sprite by gid.
+    Sprite2D* GetTileSprite(int gid) const;
+
+private:
+    /// Load tile set.
+    bool LoadTileSet(const XMLElement& element);
+    /// Load layer.
+    bool LoadLayer(const XMLElement& element);
+    
+    /// XML file used during loading.
+    SharedPtr<XMLFile> loadXMLFile_;
+    /// Width.
+    int width_;
+    /// Height.
+    int height_;
+    /// Tile width.
+    int tileWidth_;
+    /// Tile height.
+    int tileHeight_;
+    /// Textures.
+    Vector<SharedPtr<Texture2D> > textures_;
+    /// Gid to tile sprite mapping.
+    HashMap<int, SharedPtr<Sprite2D> > tileSprites_;
+    /// Layers.
+    Vector<TmxLayer2D> layers_;
+};
+
+}
+

+ 7 - 0
Source/Engine/Urho2D/Urho2D.cpp

@@ -52,6 +52,9 @@
 #include "Sprite2D.h"
 #include "SpriteSheet2D.h"
 #include "StaticSprite2D.h"
+#include "TileMap2D.h"
+#include "TileMapLayer2D.h"
+#include "TmxFile2D.h"
 
 #include "DebugNew.h"
 
@@ -78,6 +81,10 @@ void RegisterUrho2DLibrary(Context* context)
     ParticleEffect2D::RegisterObject(context);
     ParticleEmitter2D::RegisterObject(context);
 
+    TmxFile2D::RegisterObject(context);
+    TileMap2D::RegisterObject(context);
+    TileMapLayer2D::RegisterObject(context);
+
     PhysicsWorld2D::RegisterObject(context);
     RigidBody2D::RegisterObject(context);
 

+ 33 - 0
Source/Samples/36_Urho2DTileMap/CMakeLists.txt

@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2008-2014 the Urho3D project.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+# Define target name
+set (TARGET_NAME 36_Urho2DTileMap)
+
+# Define source files
+define_source_files (EXTRA_H_FILES ${COMMON_SAMPLE_H_FILES})
+
+# Setup target with resource copying
+setup_main_executable ()
+
+# Setup test cases
+add_test (NAME ${TARGET_NAME} COMMAND ${TARGET_NAME} -timeout ${URHO3D_TEST_TIME_OUT})

+ 190 - 0
Source/Samples/36_Urho2DTileMap/Urho2DTileMap.cpp

@@ -0,0 +1,190 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "Camera.h"
+#include "CoreEvents.h"
+#include "Engine.h"
+#include "Font.h"
+#include "Graphics.h"
+#include "Input.h"
+#include "Octree.h"
+#include "Renderer.h"
+#include "ResourceCache.h"
+#include "Scene.h"
+#include "Text.h"
+#include "Urho2DTileMap.h"
+#include "Zone.h"
+#include "TmxFile2D.h"
+#include "TileMap2D.h"
+#include "Drawable2D.h"
+
+#include "DebugNew.h"
+
+// Number of static sprites to draw
+static const StringHash VAR_MOVESPEED("MoveSpeed");
+static const StringHash VAR_ROTATESPEED("RotateSpeed");
+
+DEFINE_APPLICATION_MAIN(Urho2DTileMap)
+
+Urho2DTileMap::Urho2DTileMap(Context* context) :
+    Sample(context)
+{
+}
+
+void Urho2DTileMap::Start()
+{
+    // Execute base class startup
+    Sample::Start();
+
+    // Create the scene content
+    CreateScene();
+
+    // Create the UI content
+    CreateInstructions();
+
+    // Setup the viewport for displaying the scene
+    SetupViewport();
+
+    // Hook up to the frame update events
+    SubscribeToEvents();
+}
+
+void Urho2DTileMap::CreateScene()
+{
+    scene_ = new Scene(context_);
+    scene_->CreateComponent<Octree>();
+
+    // Create camera node
+    cameraNode_ = scene_->CreateChild("Camera");
+    // Set camera's position
+    cameraNode_->SetPosition(Vector3(0.0f, 0.0f, -10.0f));
+
+    Camera* camera = cameraNode_->CreateComponent<Camera>();
+    camera->SetOrthographic(true);
+
+    Graphics* graphics = GetSubsystem<Graphics>();
+    camera->SetOrthoSize((float)graphics->GetHeight() * PIXEL_SIZE);
+
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    // Get sprite
+    Sprite2D* sprite = cache->GetResource<Sprite2D>("Urho2D/Aster.png");
+    if (!sprite)
+        return;
+
+    float halfWidth = graphics->GetWidth() * 0.5f * PIXEL_SIZE;
+    float halfHeight = graphics->GetHeight() * 0.5f * PIXEL_SIZE;
+
+    // Get tmx file
+    TmxFile2D* tmxFile = cache->GetResource<TmxFile2D>("Urho2D/Desert.tmx");
+    if (!tmxFile)
+        return;
+
+    SharedPtr<Node> tileMapNode(scene_->CreateChild("TileMap"));
+    tileMapNode->SetPosition(Vector3(0.0f, 0.0f, -1.0f));
+
+    TileMap2D* tileMap = tileMapNode->CreateComponent<TileMap2D>();
+    // Set animation
+    tileMap->SetTmxFile(tmxFile);
+
+    Vector2 halfSize = tileMap->GetSize() * 0.5f;
+    // Set camera's position
+    cameraNode_->SetPosition(Vector3(halfSize.x_, halfSize.y_, -10.0f));
+}
+
+void Urho2DTileMap::CreateInstructions()
+{
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    UI* ui = GetSubsystem<UI>();
+
+    // Construct new Text object, set string to display and font to use
+    Text* instructionText = ui->GetRoot()->CreateChild<Text>();
+    instructionText->SetText("Use WASD keys to move, use PageUp PageDown keys to zoom.");
+    instructionText->SetFont(cache->GetResource<Font>("Fonts/Anonymous Pro.ttf"), 15);
+
+    // Position the text relative to the screen center
+    instructionText->SetHorizontalAlignment(HA_CENTER);
+    instructionText->SetVerticalAlignment(VA_CENTER);
+    instructionText->SetPosition(0, ui->GetRoot()->GetHeight() / 4);
+}
+
+void Urho2DTileMap::SetupViewport()
+{
+    Renderer* renderer = GetSubsystem<Renderer>();
+
+    // Set up a viewport to the Renderer subsystem so that the 3D scene can be seen
+    SharedPtr<Viewport> viewport(new Viewport(context_, scene_, cameraNode_->GetComponent<Camera>()));
+    renderer->SetViewport(0, viewport);
+}
+
+void Urho2DTileMap::MoveCamera(float timeStep)
+{
+    // Do not move if the UI has a focused element (the console)
+    if (GetSubsystem<UI>()->GetFocusElement())
+        return;
+
+    Input* input = GetSubsystem<Input>();
+
+    // Movement speed as world units per second
+    const float MOVE_SPEED = 4.0f;
+
+    // Read WASD keys and move the camera scene node to the corresponding direction if they are pressed
+    if (input->GetKeyDown('W'))
+        cameraNode_->Translate(Vector3::UP * MOVE_SPEED * timeStep);
+    if (input->GetKeyDown('S'))
+        cameraNode_->Translate(Vector3::DOWN * MOVE_SPEED * timeStep);
+    if (input->GetKeyDown('A'))
+        cameraNode_->Translate(Vector3::LEFT * MOVE_SPEED * timeStep);
+    if (input->GetKeyDown('D'))
+        cameraNode_->Translate(Vector3::RIGHT * MOVE_SPEED * timeStep);
+
+    if (input->GetKeyDown(KEY_PAGEUP))
+    {
+        Camera* camera = cameraNode_->GetComponent<Camera>();
+        camera->SetZoom(camera->GetZoom() * 1.01f);
+    }
+
+    if (input->GetKeyDown(KEY_PAGEDOWN))
+    {
+        Camera* camera = cameraNode_->GetComponent<Camera>();
+        camera->SetZoom(camera->GetZoom() * 0.99f);
+    }
+}
+
+void Urho2DTileMap::SubscribeToEvents()
+{
+    // Subscribe HandleUpdate() function for processing update events
+    SubscribeToEvent(E_UPDATE, HANDLER(Urho2DTileMap, HandleUpdate));
+
+    // Unsubscribe the SceneUpdate event from base class to prevent camera pitch and yaw in 2D sample
+    UnsubscribeFromEvent(E_SCENEUPDATE);
+}
+
+void Urho2DTileMap::HandleUpdate(StringHash eventType, VariantMap& eventData)
+{
+    using namespace Update;
+
+    // Take the frame time step, which is stored as a float
+    float timeStep = eventData[P_TIMESTEP].GetFloat();
+
+    // Move the camera, scale movement with time step
+    MoveCamera(timeStep);
+}

+ 85 - 0
Source/Samples/36_Urho2DTileMap/Urho2DTileMap.h

@@ -0,0 +1,85 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include "Sample.h"
+
+namespace Urho3D
+{
+    class Node;
+    class Scene;
+}
+
+/// Urho2D tile map example.
+/// This sample demonstrates:
+///     - Creating a 2D scene with tile map
+///     - Displaying the scene using the Renderer subsystem
+///     - Handling keyboard to move and zoom 2D camera
+class Urho2DTileMap : public Sample
+{
+    OBJECT(Urho2DTileMap);
+
+public:
+    /// Construct.
+    Urho2DTileMap(Context* context);
+
+    /// Setup after engine initialization and before running the main loop.
+    virtual void Start();
+
+protected:
+    /// Return XML patch instructions for screen joystick layout for a specific sample app, if any.
+    virtual String GetScreenJoystickPatchString() const { return
+        "<patch>"
+        "    <remove sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]/attribute[@name='Is Visible']\" />"
+        "    <replace sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]/element[./attribute[@name='Name' and @value='Label']]/attribute[@name='Text']/@value\">Zoom In</replace>"
+        "    <add sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]\">"
+        "        <element type=\"Text\">"
+        "            <attribute name=\"Name\" value=\"KeyBinding\" />"
+        "            <attribute name=\"Text\" value=\"PAGEUP\" />"
+        "        </element>"
+        "    </add>"
+        "    <remove sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]/attribute[@name='Is Visible']\" />"
+        "    <replace sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]/element[./attribute[@name='Name' and @value='Label']]/attribute[@name='Text']/@value\">Zoom Out</replace>"
+        "    <add sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]\">"
+        "        <element type=\"Text\">"
+        "            <attribute name=\"Name\" value=\"KeyBinding\" />"
+        "            <attribute name=\"Text\" value=\"PAGEDOWN\" />"
+        "        </element>"
+        "    </add>"
+        "</patch>";
+    }
+
+private:
+    /// Construct the scene content.
+    void CreateScene();
+    /// Construct an instruction text to the UI.
+    void CreateInstructions();
+    /// Set up a viewport for displaying the scene.
+    void SetupViewport();
+    /// Read input and moves the camera.
+    void MoveCamera(float timeStep);
+    /// Subscribe to application-wide logic update events.
+    void SubscribeToEvents();
+    /// Handle the logic update event.
+    void HandleUpdate(StringHash eventType, VariantMap& eventData);
+};

+ 2 - 1
Source/Samples/CMakeLists.txt

@@ -72,4 +72,5 @@ add_subdirectory (31_MaterialAnimation)
 add_subdirectory (32_Urho2DConstraints)
 add_subdirectory (33_Urho2DSpriterAnimation)
 add_subdirectory (34_DynamicGeometry)
-add_subdirectory (35_SignedDistanceFieldText)
+add_subdirectory (35_SignedDistanceFieldText)
+add_subdirectory (36_Urho2DTileMap)