├── .gitignore ├── LICENSE ├── README.md ├── changes.txt ├── format └── tmx │ ├── Data.hx │ ├── Reader.hx │ └── Tools.hx ├── haxelib.json ├── test ├── assets │ ├── .keep │ ├── buch-outdoor.png │ ├── desert.tmx │ ├── desert.tsx │ ├── hexagonal-mini.tmx │ ├── hexmini.png │ ├── isometric_grass_and_water.png │ ├── isometric_grass_and_water.tmx │ ├── orthogonal-outside.tmx │ ├── perspective_walls.png │ ├── perspective_walls.tmx │ ├── perspective_walls.tsx │ ├── sewer_automap │ │ ├── rule_001.tmx │ │ ├── rule_002.tmx │ │ ├── rule_003.tmx │ │ ├── rule_004.tmx │ │ ├── rule_005.tmx │ │ ├── rule_006.tmx │ │ ├── rule_007.tmx │ │ ├── rule_008.tmx │ │ ├── rule_009.tmx │ │ ├── rules.txt │ │ ├── rules_sewers.png │ │ └── sewers.tmx │ ├── sewer_tileset.png │ ├── sewers.tmx │ ├── sticker-knight │ │ ├── README.md │ │ ├── map │ │ │ ├── alter.png │ │ │ ├── backgroundArch.png │ │ │ ├── backgroundMountain.png │ │ │ ├── backgroundTower.png │ │ │ ├── backgroundTree.png │ │ │ ├── blobBlue.png │ │ │ ├── blobGreen.png │ │ │ ├── blue.png │ │ │ ├── bombStroked.png │ │ │ ├── castleWall.png │ │ │ ├── cloud.png │ │ │ ├── column1.png │ │ │ ├── column2.png │ │ │ ├── doorBlueStroked.png │ │ │ ├── doorGreenStroke.png │ │ │ ├── doorRedStroked.png │ │ │ ├── doorStroked.png │ │ │ ├── earthWall.png │ │ │ ├── earthWall2.png │ │ │ ├── exit.png │ │ │ ├── flare.png │ │ │ ├── gemBlueStroked.png │ │ │ ├── gemRedStroked.png │ │ │ ├── grassLarge.png │ │ │ ├── grassSmall.png │ │ │ ├── grey.png │ │ │ ├── hero.png │ │ │ ├── keyGreenStroked.png │ │ │ ├── keyRedStroked.png │ │ │ ├── keyYellowStroked.png │ │ │ ├── platform1.png │ │ │ ├── platform2.png │ │ │ ├── platform3.png │ │ │ ├── platform4.png │ │ │ ├── platformBase1.png │ │ │ ├── platformBase2.png │ │ │ ├── platformBase3.png │ │ │ ├── platformBase4.png │ │ │ ├── platformBlock1.png │ │ │ ├── platformBlock2.png │ │ │ ├── platformBlock3.png │ │ │ ├── platformBlock4.png │ │ │ ├── platformConnector1.png │ │ │ ├── platformConnector2.png │ │ │ ├── platformConnector3.png │ │ │ ├── platformConnector4.png │ │ │ ├── pushBlock1.png │ │ │ ├── pushBlock2.png │ │ │ ├── pushBlock3.png │ │ │ ├── sandbox.tmx │ │ │ ├── sandbox2.tmx │ │ │ ├── shadow.png │ │ │ ├── shieldStroked.png │ │ │ ├── sign.png │ │ │ ├── skeleton.png │ │ │ ├── swordStroked.png │ │ │ ├── torch.png │ │ │ ├── trap.png │ │ │ ├── wallDecor1.png │ │ │ ├── wallDecor2.png │ │ │ ├── wallDecor3.png │ │ │ ├── window1.png │ │ │ ├── window2.png │ │ │ └── window3.png │ │ ├── preview.png │ │ ├── sprites.png │ │ └── ui │ │ │ ├── backgroundSet.png │ │ │ ├── block.png │ │ │ ├── buttonHelp.png │ │ │ ├── buttonStart.png │ │ │ ├── cloud.png │ │ │ ├── gem.png │ │ │ ├── heart.png │ │ │ ├── helpBackground.png │ │ │ ├── shield.png │ │ │ ├── title.json │ │ │ └── title.png │ └── tmw_desert_spacing.png ├── build.hxml ├── config.json ├── format-tiled.hxproj ├── project.flow ├── project.xml ├── src │ ├── Main.hx │ └── OFLLayerRender.hx └── tile_flags │ ├── .gitignore │ ├── Main.hx │ ├── build.hxml │ ├── files │ ├── buch-outdoor.png │ └── orthogonaloutside.tmx │ └── output │ └── .gitkeep └── tiled └── TileLayerRenderer.hx /.gitignore: -------------------------------------------------------------------------------- 1 | test/bin -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # haxe-format-tiled 2 | Tiled format support without additional dependencies (like OpenFL). 3 | 4 | # Deprecation notice 5 | This library is deprecated and won't be maintained in favor of its successor - [tiledhx](https://github.com/Yanrishatum/tiledhx) 6 | 7 | ## Feature-support 8 | * Currently library supports Tiled 1.1 9 | When Tiled will get new features that you will need to utilize, please create an Issue (or better a PR ;) ). I do not watch Tiled development closely, but will provide library updates for new features. 10 | 11 | ## Usage notes 12 | * 2.0 version got quite a few changes in order to bring Tiled 1.1 support. 13 | * Apart from breaking changes there Reader works a bit differently now, and you can use same reader to parse all maps, TSX and template files from single Reader instead of need to create new one each time. 14 | * You can set `resolveTSX` and `resolveTypeTemplate` functions to Reader for it to automatically apply TSX/type templates during parsing. 15 | * Current support for object templates is very basic, and not really tested. 16 | * Since Tiled 1.0 layers can be nested with Groups, and if you need to use classic non-nested layers use `Tools.linearLayers`. (Read docs first) 17 | 18 | ## License 19 | Library source code belongs to public domain with exception of assets used in test code. 20 | * `test/assets` taken from official Tiled sample folder, see their [AUTHORS](https://github.com/bjorn/tiled/blob/master/AUTHORS#L264-L273) file for license info. 21 | * `test/tile_flags/files` tileset licensed under CC-BY 3.0 and belongs to Buch (See: [OpenGameArt.org](https://opengameart.org/content/outdoor-tiles-again)) 22 | -------------------------------------------------------------------------------- /changes.txt: -------------------------------------------------------------------------------- 1 | 2.0.0: 2 | * Support up to Tiled 1.1 3 | * Breaking changes accross the board. 4 | * Support for infinite maps 5 | * Support for property types 6 | * Support for layer groups 7 | * Partial support for object templates 8 | * Added additonal resolvers for TSX/templates. 9 | 10 | 1.1.1: 11 | * Support up to Tiled 0.11. 12 | * Properties aren't supported fully yet. 13 | * Fixed Flipping flags on CPP corrupting tile ID's. 14 | 15 | 1.0.0: 16 | * Changed versioning method. 17 | * Fixed crash on parameters parsing, since they can contain it's value inside tag inner data, and not `value` attribute. 18 | 19 | 0.1.0: 20 | * Tileset structure changed to all-optional since TSX does not contain `firstgid` and `source` and TSX-based Tileset in TMX contains only `firstgid` and `source`. 21 | * Support for TSX files (external Tilesets) 22 | * Tile animations support. 23 | * Tile objects flipping flags. 24 | * Fixed negative value bitwise operations (masking of IDs). 25 | * Fixed `Tools.getTilesetByGid` not returning last tileset. 26 | * Yet again fixed `Tools.fixObjectPlacement` since I figured out where was problem in positions. 27 | * Fixed typo in Tileset tile info resulting in objectgroup always be null even if collider present. 28 | * Added tools to get row/column/total tile count on tileset. 29 | * Added support for objects without ID (they are autoassigned same way as they do in Tiled). -------------------------------------------------------------------------------- /format/tmx/Reader.hx: -------------------------------------------------------------------------------- 1 | package format.tmx; 2 | import format.tmx.Data; 3 | import haxe.io.Bytes; 4 | import haxe.io.BytesInput; 5 | import haxe.io.BytesOutput; 6 | import haxe.io.Input; 7 | import haxe.io.StringInput; 8 | #if (haxe_ver >= 4) 9 | import haxe.xml.Access as Fast; 10 | #else 11 | import haxe.xml.Fast; 12 | #end 13 | import haxe.zip.InflateImpl; 14 | import haxe.zip.Uncompress; 15 | 16 | /** 17 | * ... 18 | * @author Yanrishatum 19 | */ 20 | class Reader 21 | { 22 | private var customUncompressors:MapBytes>; 23 | private var customEncoders:MapString->Array>; 24 | 25 | private var width:Int; 26 | private var height:Int; 27 | 28 | /** For seamless TSX resolving during initial parsing. Should return corresponding TSX. Caching should be done from outside. */ 29 | public var resolveTSX:String->TmxTileset; 30 | /** For seamless Template resolving during initial parsing. */ 31 | public var resolveTemplate:String->TmxObjectTemplate; 32 | /** For seamless Type Template resolving during initial parsing. */ 33 | public var resolveTypeTemplate:String->TmxObjectTypeTemplate; 34 | 35 | public function new() 36 | { 37 | 38 | } 39 | 40 | /** 41 | * Reads TMX file. 42 | * @return 43 | */ 44 | public function read(xml:Xml, ?localPath:String):TmxMap 45 | { 46 | var map:Fast = new Fast(xml).node.map; 47 | 48 | var properties:TmxProperties = resolveProperties(map); 49 | var tilesets:Array = new Array(); 50 | var layers:Array = new Array(); 51 | 52 | for (element in map.elements) 53 | { 54 | switch (element.name) 55 | { 56 | case "tileset": tilesets.push(resolveTileset(element, null)); 57 | case "layer": layers.push(TmxLayer.LTileLayer(resolveTileLayer(element))); 58 | case "objectgroup": layers.push(TmxLayer.LObjectGroup(resolveObjectGroup(element))); 59 | case "imagelayer": layers.push(TmxLayer.LImageLayer(resolveImageLayer(element))); 60 | case "group": layers.push(TmxLayer.LGroup(resolveGroup(element))); 61 | } 62 | } 63 | 64 | this.width = Std.parseInt(map.att.width); 65 | this.height = Std.parseInt(map.att.height); 66 | 67 | return { 68 | version: map.att.version, 69 | tiledVersion: map.has.tiledversion ? map.att.tiledversion : "", 70 | orientation: resolveOrientation(map.att.orientation), 71 | width: width, 72 | height: height, 73 | tileWidth: Std.parseInt(map.att.tilewidth), 74 | tileHeight: Std.parseInt(map.att.tileheight), 75 | backgroundColor: map.has.backgroundcolor ? resolveColor(map.att.backgroundcolor) : 0, 76 | renderOrder: map.has.renderorder ? resolveRenderOrder(map.att.renderorder) : TmxRenderOrder.RightDown, 77 | properties: properties, 78 | tilesets: tilesets, 79 | layers: layers, 80 | staggerIndex: map.has.staggerindex ? resolveStaggerIndex(map.att.staggerindex) : null, 81 | staggerAxis: map.has.staggeraxis ? resolveStaggerAxis(map.att.staggeraxis) : null, 82 | hexSideLength: map.has.hexsidelength ? Std.parseInt(map.att.hexsidelength) : 0, 83 | nextObjectId: map.has.nextobjectid ? Std.parseInt(map.att.nextobjectid) : 0, 84 | nextLayerId: map.has.nextlayerid ? Std.parseInt(map.att.nextlayerid): 0, 85 | infinite: map.has.infinite ? map.att.infinite == "1" : false, 86 | localPath: localPath 87 | }; 88 | } 89 | 90 | /** 91 | * Reads TSX file. 92 | * @param root Root Tileset into which read TSX data. 93 | * @return Resulting TmxTileset. If `root` is null - returns new TmxTileset object, otherwise `root` is returned. 94 | */ 95 | public inline function readTSX(xml:Xml, root:TmxTileset = null):TmxTileset 96 | { 97 | return resolveTileset(new Fast(xml).node.tileset, root); 98 | } 99 | 100 | /** 101 | * Reads objecttypes.xml file. 102 | * @param root Optional root TMX file to propagate those types into. It uses `Tools.propagateObjectTypes` function with default propagation rules. 103 | * @return Map with object type templates. Always pass null, if using during resolveTypeTemplate 104 | */ 105 | public function readObjectTypes(xml:Xml, root:TmxMap = null):Map 106 | { 107 | var result:Map = new Map(); 108 | var f:Fast = new Fast(xml); 109 | if (!f.hasNode.objecttypes) return result; 110 | for (type in f.node.objecttypes.nodes.objecttype) 111 | { 112 | var props:Array = new Array(); 113 | for (prop in type.nodes.property) 114 | { 115 | var ptype:TmxPropertyType = 116 | if (prop.has.type) 117 | { 118 | switch (prop.att.type) 119 | { 120 | case "string": PTString; 121 | case "int": PTInt; 122 | case "float": PTFloat; 123 | case "color": PTColor; 124 | case "file": PTFile; 125 | case "bool": PTBool; 126 | default: PTString; 127 | } 128 | } 129 | else PTString; 130 | props.push( { 131 | name: prop.att.name, 132 | type: ptype, 133 | defaultValue: prop.has.resolve("default") ? prop.att.resolve("default") : null 134 | }); 135 | } 136 | result.set(type.att.name, { 137 | name: type.att.name, 138 | color: Std.parseInt("0x" + type.att.color.substr(1)), 139 | properties: props 140 | }); 141 | } 142 | if (root != null) Tools.propagateObjectTypes(root, result); 143 | return result; 144 | } 145 | 146 | /** 147 | Reads TX file. 148 | **/ 149 | public function readTemplate(xml:Xml):TmxObjectTemplate 150 | { 151 | var f:Fast = new Fast(xml); 152 | if (!f.hasNode.template) return null; 153 | var input:Fast = f.node.template; 154 | return { 155 | tileset: input.hasNode.tileset ? resolveTileset(input.node.tileset, null) : null, 156 | object: resolveObject(input.node.object, false)// don't apply object type template yet, because map object can override it 157 | }; 158 | } 159 | 160 | private function resolveGroup(input:Fast):TmxGroup 161 | { 162 | var layers:Array = new Array(); 163 | 164 | for (element in input.elements) 165 | { 166 | switch (element.name) 167 | { 168 | case "layer": layers.push(TmxLayer.LTileLayer(resolveTileLayer(element))); 169 | case "objectgroup": layers.push(TmxLayer.LObjectGroup(resolveObjectGroup(element))); 170 | case "imagelayer": layers.push(TmxLayer.LImageLayer(resolveImageLayer(element))); 171 | case "group": layers.push(TmxLayer.LGroup(resolveGroup(element))); 172 | } 173 | } 174 | 175 | return { 176 | id: input.has.id ? Std.parseInt(input.att.id) : 0, 177 | name: input.att.name, 178 | offsetX: input.has.offsetx ? Std.parseInt(input.att.offsetx) : 0, 179 | offsetY: input.has.offsety ? Std.parseInt(input.att.offsety) : 0, 180 | opacity: input.has.opacity ? Std.parseFloat(input.att.opacity) : 1, 181 | visible: input.has.visible ? input.att.visible == "1" : true, 182 | properties: resolveProperties(input), 183 | layers: layers 184 | }; 185 | } 186 | 187 | private inline function resolveStaggerIndex(input:String):TmxStaggerIndex 188 | { 189 | switch (input) 190 | { 191 | case "even": return TmxStaggerIndex.Even; 192 | case "odd": return TmxStaggerIndex.Odd; 193 | default: return TmxStaggerIndex.Unknown(input); 194 | } 195 | } 196 | 197 | private inline function resolveStaggerAxis(input:String):TmxStaggerAxis 198 | { 199 | switch (input) 200 | { 201 | case "x": return TmxStaggerAxis.AxisX; 202 | case "y": return TmxStaggerAxis.AxisY; 203 | default: return TmxStaggerAxis.Unknown(input); 204 | } 205 | } 206 | 207 | private inline function resolveOrientation(input:String):TmxOrientation 208 | { 209 | switch (input) 210 | { 211 | case "orthogonal": return TmxOrientation.Orthogonal; 212 | case "hexagonal": return TmxOrientation.Hexagonal; 213 | case "isometric": return TmxOrientation.Isometric; 214 | case "staggered": return TmxOrientation.Staggered; 215 | default : return TmxOrientation.Unknown(input); 216 | } 217 | } 218 | 219 | private inline function resolveColor(input:String):Int 220 | { 221 | if (input.charCodeAt(0) == "#".code) return Std.parseInt("0x" + input.substr(1)); 222 | else return Std.parseInt("0x" + input); 223 | } 224 | 225 | private inline function resolveRenderOrder(input:String):TmxRenderOrder 226 | { 227 | switch (input) 228 | { 229 | case "right-down": return TmxRenderOrder.RightDown; 230 | case "right-up": return TmxRenderOrder.RightUp; 231 | case "left-down": return TmxRenderOrder.LeftDown; 232 | case "left-up": return TmxRenderOrder.LeftUp; 233 | default : return TmxRenderOrder.Unknown(input); 234 | } 235 | } 236 | 237 | private inline function resolveTileset(input:Fast, root:TmxTileset):TmxTileset 238 | { 239 | var properties:TmxProperties = resolveProperties(input); 240 | var terrains:Array = new Array(); 241 | var hasTerrains:Bool = input.hasNode.terraintypes; 242 | var tiles:Array = new Array(); 243 | var hasTiles:Bool = input.hasNode.tile; 244 | var tileOffset:TmxTileOffset = null; 245 | var hasTileOffset:Bool = input.hasNode.tileoffset; 246 | var wangSets:Array = new Array(); 247 | var hasWangSets:Bool = input.hasNode.wangsets; 248 | var grid:TmxTilesetGrid = null; 249 | var hasGrid:Bool = input.hasNode.grid; 250 | 251 | if (hasTileOffset) 252 | { 253 | var node:Fast = input.node.tileoffset; 254 | tileOffset = { x:Std.parseInt(node.att.x), y:Std.parseInt(node.att.y) }; 255 | } 256 | 257 | if (hasTerrains) 258 | { 259 | for (node in input.node.terraintypes.nodes.terrain) 260 | { 261 | terrains.push( { name:node.att.name, tile:Std.parseInt(node.att.tile), properties:resolveProperties(node) } ); 262 | } 263 | } 264 | 265 | if (hasWangSets) 266 | { 267 | for (node in input.node.wangsets.nodes.wangset) 268 | { 269 | wangSets.push(resolveWangSet(node)); 270 | } 271 | } 272 | 273 | if (hasGrid) 274 | { 275 | var gnode:Fast = input.node.grid; 276 | grid = { 277 | width: Std.parseInt(gnode.att.width), 278 | height: Std.parseInt(gnode.att.height), 279 | orientation: resolveOrientation(gnode.att.orientation) 280 | }; 281 | } 282 | 283 | if (hasTiles) 284 | { 285 | for (node in input.nodes.tile) 286 | { 287 | var animation:Array = null; 288 | if (node.hasNode.animation) 289 | { 290 | animation = new Array(); 291 | for (frameInfo in node.node.animation.nodes.frame) 292 | { 293 | animation.push( { 294 | tileId: Std.parseInt(frameInfo.att.tileid), 295 | duration: Std.parseInt(frameInfo.att.duration) 296 | }); 297 | } 298 | } 299 | tiles.push( { 300 | id: Std.parseInt(node.att.id), 301 | terrain: node.has.terrain ? node.att.terrain : null, 302 | probability: node.has.probability ? Std.parseFloat(node.att.probability) : 0, 303 | properties: resolveProperties(node), 304 | image: node.hasNode.image ? resolveImage(node.node.image) : null, 305 | objectGroup: node.hasNode.objectgroup ? resolveObjectGroup(node.node.objectgroup) : null, 306 | animation: animation, 307 | type: node.has.type ? node.att.type : null 308 | }); 309 | } 310 | } 311 | 312 | //if (root == null && input.has.source && resolveTSX != null) 313 | //{ 314 | //root = resolveTSX(input.att.source); 315 | //root.source = input.att.source; 316 | //root.firstGID = input.has.firstgid ? Std.parseInt(input.att.firstgid) : null; 317 | //return root; 318 | //} 319 | 320 | if (root != null) 321 | { 322 | root.firstGID = input.has.firstgid ? Std.parseInt(input.att.firstgid) : root.firstGID; 323 | root.source = input.has.source ? input.att.source : root.source; 324 | root.name = input.has.name ? input.att.name : root.name; 325 | root.tileWidth = input.has.tilewidth ? Std.parseInt(input.att.tilewidth) : root.tileWidth; 326 | root.tileHeight = input.has.tileheight ? Std.parseInt(input.att.tileheight) : root.tileHeight; 327 | root.spacing = input.has.spacing ? Std.parseInt(input.att.spacing) : root.spacing; 328 | root.margin = input.has.margin ? Std.parseInt(input.att.margin) : root.margin; 329 | root.properties = input.hasNode.properties ? properties : root.properties; 330 | root.image = input.hasNode.image ? resolveImage(input.node.image) : root.image; 331 | root.tileCount = input.has.tilecount ? Std.parseInt(input.att.tilecount) : 0; 332 | root.columns = input.has.columns ? Std.parseInt(input.att.columns) : 0; 333 | if (hasTerrains) root.terrainTypes = terrains; 334 | if (hasTiles) root.tiles = tiles; 335 | if (hasTileOffset) root.tileOffset = tileOffset; 336 | if (hasWangSets) root.wangSets = wangSets; 337 | if (hasGrid) root.grid = grid; 338 | return root; 339 | } 340 | 341 | var tset:TmxTileset = 342 | { 343 | firstGID: input.has.firstgid ? Std.parseInt(input.att.firstgid) : null, 344 | source: input.has.source ? input.att.source : null, 345 | name: input.has.name ? input.att.name : null, 346 | tileWidth: input.has.tilewidth ? Std.parseInt(input.att.tilewidth) : 0, 347 | tileHeight: input.has.tileheight ? Std.parseInt(input.att.tileheight) : 0, 348 | spacing: input.has.spacing ? Std.parseInt(input.att.spacing) : 0, 349 | margin: input.has.margin ? Std.parseInt(input.att.margin) : 0, 350 | properties: properties, 351 | image: input.hasNode.image ? resolveImage(input.node.image) : null, 352 | tileCount: input.has.tilecount ? Std.parseInt(input.att.tilecount) : 0, 353 | columns: input.has.columns ? Std.parseInt(input.att.columns) : 0, 354 | terrainTypes: terrains, 355 | tiles: tiles, 356 | tileOffset: tileOffset, 357 | grid: grid, 358 | wangSets: wangSets 359 | }; 360 | 361 | if (tset.source != null && resolveTSX != null) 362 | { 363 | var tsx:TmxTileset = resolveTSX(tset.source); 364 | Tools.applyTSX(tsx, tset); 365 | } 366 | 367 | return tset; 368 | } 369 | 370 | private function resolveWangSet(input:Fast):TmxWangSet 371 | { 372 | var corners:Array = new Array(); 373 | var edges:Array = new Array(); 374 | var tiles:Array = new Array(); 375 | 376 | for (node in input.nodes.wangcornercolor) 377 | { 378 | corners.push(resolveWangSetColor(node)); 379 | } 380 | 381 | for (node in input.nodes.wangedgecolor) 382 | { 383 | edges.push(resolveWangSetColor(node)); 384 | } 385 | 386 | for (node in input.nodes.wangtile) 387 | { 388 | tiles.push( { 389 | tileID: node.has.tileid ? Std.parseInt(node.att.tileid) : 0, 390 | wangID: node.has.wangid ? node.att.wangid : "0,0,0,0,0,0,0,0" 391 | }); 392 | } 393 | 394 | return { 395 | name: input.has.name ? input.att.name : null, 396 | tile: input.has.tile ? Std.parseInt(input.att.tile) : 0, 397 | corners: corners, 398 | edges: edges, 399 | tiles: tiles 400 | }; 401 | 402 | } 403 | 404 | private inline function resolveWangSetColor(input:Fast):TmxWangSetColor 405 | { 406 | return { 407 | name: input.has.name ? input.att.name : null, 408 | color: input.has.color ? resolveColor(input.att.color) : 0, 409 | tile: input.has.tile ? Std.parseInt(input.att.tile) : 0, 410 | probability: input.has.probability ? Std.parseFloat(input.att.probability) : 0 411 | }; 412 | } 413 | 414 | private function resolveImage(input:Fast):TmxImage 415 | { 416 | return 417 | { 418 | format: input.has.format ? input.att.format : "", 419 | id: input.has.id ? input.att.id : "", 420 | source: input.has.source ? input.att.source : "", 421 | transparent: input.has.transparent ? resolveColor(input.att.transparent) : null, 422 | width: input.has.width ? Std.parseInt(input.att.width) : null, 423 | height: input.has.height ? Std.parseInt(input.att.height) : null, 424 | data: input.hasNode.data ? resolveData(input.node.data, false) : null 425 | }; 426 | } 427 | 428 | private function resolveData(input:Fast, isTileData:Bool = true):TmxData 429 | { 430 | var encoding:TmxDataEncoding = TmxDataEncoding.None; 431 | if (input.has.encoding) 432 | { 433 | switch(input.att.encoding) 434 | { 435 | case "base64": encoding = TmxDataEncoding.Base64; 436 | case "csv": encoding = TmxDataEncoding.CSV; 437 | default: throw 'Unknown encoding "${input.att.encoding}"'; //encoding = TmxDataEncoding.Unknown(input.att.encoding); 438 | } 439 | } 440 | 441 | var compression:TmxDataCompression = TmxDataCompression.None; 442 | if (input.has.compression) 443 | { 444 | switch (input.att.compression) 445 | { 446 | case "gzip": compression = TmxDataCompression.GZip; 447 | case "zlib": compression = TmxDataCompression.ZLib; 448 | default: throw 'Unknown compression "${input.att.compression}"'; 449 | } 450 | } 451 | 452 | var chunks:Array = null; 453 | var tiles:Array = null; 454 | var data:Bytes = null; 455 | 456 | inline function getRawData():String 457 | { 458 | return StringTools.trim(input.innerData); 459 | } 460 | 461 | inline function emptyChunk(chunk:Fast):TmxChunk 462 | { 463 | return { 464 | x: chunk.has.x ? Std.parseInt(chunk.att.x) : 0, 465 | y: chunk.has.y ? Std.parseInt(chunk.att.y) : 0, 466 | width: chunk.has.width ? Std.parseInt(chunk.att.width) : 0, 467 | height: chunk.has.height ? Std.parseInt(chunk.att.height) : 0, 468 | tiles: new Array() 469 | }; 470 | } 471 | 472 | switch (encoding) 473 | { 474 | case TmxDataEncoding.None: 475 | if (isTileData) 476 | { 477 | if (input.hasNode.chunk) 478 | { 479 | // Infinite map data 480 | chunks = new Array(); 481 | for (node in input.nodes.chunk) 482 | { 483 | var chunk:TmxChunk = emptyChunk(node); 484 | var chunkTiles:Array = chunk.tiles; 485 | for (tile in node.nodes.tile) 486 | { 487 | chunkTiles.push( new TmxTile(Std.parseInt(tile.att.gid)) ); 488 | } 489 | chunks.push(chunk); 490 | } 491 | } 492 | else 493 | { 494 | // Regular map data 495 | tiles = new Array(); 496 | for (info in input.nodes.tile) 497 | { 498 | // This tiles can have flipped flags? No documentation about this. 499 | tiles.push( new TmxTile(Std.parseInt(info.att.gid)) ); 500 | } 501 | } 502 | } 503 | else 504 | { 505 | if (compression == TmxDataCompression.None) data = Bytes.ofString(getRawData()); 506 | else data = uncompressData(new StringInput(getRawData()), compression); 507 | } 508 | case TmxDataEncoding.CSV: 509 | if (isTileData) 510 | { 511 | // TODO: Optimize, avoid .split and work with string directly 512 | if (input.hasNode.chunk) 513 | { 514 | // Infinite map data 515 | chunks = new Array(); 516 | for (node in input.nodes.chunk) 517 | { 518 | var chunk:TmxChunk = emptyChunk(node); 519 | var chunkTiles:Array = chunk.tiles; 520 | var split:Array = StringTools.trim(node.innerData).split(","); 521 | for (str in split) chunkTiles.push( new TmxTile(Std.parseInt(str)) ); 522 | chunks.push(chunk); 523 | } 524 | } 525 | else 526 | { 527 | tiles = new Array(); 528 | var split:Array = getRawData().split(","); 529 | for (str in split) tiles.push( new TmxTile(Std.parseInt(str))); 530 | } 531 | } 532 | else throw "CSV encoding available only for tile data"; 533 | case TmxDataEncoding.Base64: 534 | var tile:Int; 535 | var flipH:Bool; 536 | 537 | if (isTileData && input.hasNode.chunk) 538 | { 539 | chunks = new Array(); 540 | for (node in input.nodes.chunk) 541 | { 542 | var chunk:TmxChunk = emptyChunk(node); 543 | var chunkTiles:Array = chunk.tiles; 544 | 545 | data = haxe.crypto.Base64.decode(StringTools.trim(node.innerData)); 546 | if (compression != TmxDataCompression.None) data = uncompressData(new BytesInput(data), compression); 547 | var tilesCount:Int = Std.int(data.length / 4); 548 | var d:BytesInput = new BytesInput(data); 549 | d.bigEndian = false; 550 | for (i in 0...tilesCount) 551 | { 552 | tile = d.readInt32(); 553 | chunkTiles.push(new TmxTile(tile)); 554 | } 555 | 556 | chunks.push(chunk); 557 | } 558 | data = null; 559 | } 560 | else 561 | { 562 | data = haxe.crypto.Base64.decode(getRawData()); 563 | if (compression != TmxDataCompression.None) data = uncompressData(new BytesInput(data), compression); 564 | 565 | if (isTileData) 566 | { 567 | tiles = new Array(); 568 | var tilesCount:Int = Std.int(data.length / 4); 569 | var offset:Int = 0; 570 | var d:BytesInput = new BytesInput(data); 571 | d.bigEndian = false; 572 | for (i in 0...tilesCount) 573 | { 574 | tile = d.readInt32(); 575 | tiles.push(new TmxTile(tile)); 576 | } 577 | data = null; 578 | } 579 | } 580 | 581 | case TmxDataEncoding.Unknown(value): 582 | throw "Unknown data encoding: " + value; 583 | } 584 | 585 | return { 586 | encoding: encoding, 587 | compression: compression, 588 | tiles: tiles, 589 | chunks: chunks, 590 | data: data 591 | }; 592 | } 593 | 594 | private function uncompressData(i:Input, compression:TmxDataCompression):Bytes 595 | { 596 | switch (compression) 597 | { 598 | case TmxDataCompression.GZip: // Supported only with `format` library. 599 | #if format 600 | 601 | var o:BytesOutput = new BytesOutput(); 602 | new format.gz.Reader(i).readData(o); 603 | return o.getBytes(); 604 | 605 | #elseif debug 606 | throw "GZip compression currently not supported. Link 'format' library to enable GZip decompression."; 607 | #else 608 | throw "GZip compression currently not supported."; 609 | #end 610 | case TmxDataCompression.ZLib: 611 | return InflateImpl.run(i); 612 | case TmxDataCompression.None: 613 | return i.readAll(); 614 | case TmxDataCompression.Unknown(value): 615 | throw "Unknown compression method: " + value; 616 | } 617 | } 618 | 619 | private function resolveTileLayer(input:Fast):TmxTileLayer 620 | { 621 | // Workaround to HaxeFoundation/haxe#6822 622 | var layer:TmxTileLayer = new TmxTileLayer( 623 | (input.hasNode.data ? resolveData(input.node.data) : null), 624 | (input.has.id ? Std.parseInt(input.att.id) : 0), 625 | (input.has.name ? input.att.name : ""), 626 | (input.has.x ? Std.parseFloat(input.att.x) : 0), 627 | (input.has.y ? Std.parseFloat(input.att.y) : 0), 628 | (input.has.offsetx ? Std.parseInt(input.att.offsetx) : 0), 629 | (input.has.offsety ? Std.parseInt(input.att.offsety) : 0), 630 | (input.has.width ? Std.parseInt(input.att.width) : width), 631 | (input.has.height ? Std.parseInt(input.att.height) : height), 632 | (input.has.opacity ? Std.parseFloat(input.att.opacity) : 1), 633 | (input.has.visible ? input.att.visible == "1" : true), 634 | (input.has.tintcolor ? parseColor(input.att.tintcolor):0xFFFFFF), 635 | resolveProperties(input) 636 | ); 637 | 638 | return layer; 639 | } 640 | 641 | private inline function resolveDraworder(input:String):TmxObjectGroupDrawOrder 642 | { 643 | switch (input) 644 | { 645 | case "index": return TmxObjectGroupDrawOrder.Index; 646 | case "topdown": return TmxObjectGroupDrawOrder.Topdown; 647 | default: return TmxObjectGroupDrawOrder.Unknown(input); 648 | } 649 | } 650 | 651 | private function resolveObjectGroup(input:Fast):TmxObjectGroup 652 | { 653 | var objects:Array = new Array(); 654 | 655 | for (obj in input.nodes.object) 656 | { 657 | objects.push(resolveObject(obj)); 658 | } 659 | 660 | // Workaround to HaxeFoundation/haxe#6822 661 | var group:TmxObjectGroup = new TmxObjectGroup( 662 | (input.has.draworder ? resolveDraworder(input.att.draworder) : TmxObjectGroupDrawOrder.Topdown), 663 | objects, 664 | (input.has.color ? Std.parseInt(input.att.color) : null), 665 | (input.has.id ? Std.parseInt(input.att.id) : 0), 666 | (input.has.name ? input.att.name : ""), 667 | (input.has.x ? Std.parseFloat(input.att.x) : 0), 668 | (input.has.y ? Std.parseFloat(input.att.y) : 0), 669 | (input.has.offsetx ? Std.parseInt(input.att.offsetx) : 0), 670 | (input.has.offsety ? Std.parseInt(input.att.offsety) : 0), 671 | (input.has.width ? Std.parseInt(input.att.width) : width), 672 | (input.has.height ? Std.parseInt(input.att.height) : height), 673 | (input.has.opacity ? Std.parseFloat(input.att.opacity) : 1), 674 | (input.has.visible ? input.att.visible == "1" : true), 675 | (input.has.tintcolor ? parseColor(input.att.tintcolor):0xFFFFFF), 676 | resolveProperties(input) 677 | ); 678 | // group.drawOrder = input.has.draworder ? resolveDraworder(input.att.draworder) : TmxObjectGroupDrawOrder.Topdown; 679 | // group.objects = objects; 680 | return group; 681 | 682 | } 683 | 684 | private function resolveObject(obj:Fast, applyObjectTypeTemplate:Bool = true):TmxObject 685 | { 686 | var flippedV:Bool = false; 687 | var flippedH:Bool = false; 688 | // Type specific data. 689 | var type:TmxObjectType = 690 | if (obj.hasNode.ellipse) 691 | { 692 | TmxObjectType.OTEllipse; 693 | } 694 | else if (obj.has.gid) 695 | { 696 | #if (neko || cpp) 697 | var f:Float = Std.parseFloat(obj.att.gid); 698 | var gid:Int = f > 0x7FFFFFFF ? -Std.int(f - 2147483648) : Std.int(f); // `parseInt` on neko can't take Uint with value > INT_MAX_VALUE as input. 699 | #else 700 | var gid:Int = Std.parseInt(obj.att.gid); 701 | #end 702 | flippedH = (gid & @:privateAccess TmxTile.FLIPPED_HORIZONTALLY_FLAG) == @:privateAccess TmxTile.FLIPPED_HORIZONTALLY_FLAG; 703 | if (flippedH && gid < 0) gid = -gid; 704 | flippedV = (gid & @:privateAccess TmxTile.FLIPPED_VERTICALLY_FLAG) == @:privateAccess TmxTile.FLIPPED_VERTICALLY_FLAG; 705 | TmxObjectType.OTTile(gid & (@:privateAccess TmxTile.FLAGS_MASK | @:privateAccess TmxTile.FLIPPED_DIAGONALLY_FLAG)); 706 | } 707 | else if (obj.hasNode.polygon) 708 | { 709 | TmxObjectType.OTPolygon(readPoints(obj.node.polygon)); 710 | } 711 | else if (obj.hasNode.polyline) 712 | { 713 | TmxObjectType.OTPolyline(readPoints(obj.node.polyline)); 714 | } 715 | else if (obj.hasNode.text) 716 | { 717 | TmxObjectType.OTText(resolveText(obj.node.text)); 718 | } 719 | else if (obj.hasNode.point) 720 | { 721 | TmxObjectType.OTPoint; 722 | } 723 | //else if (obj.hasNode.image) { } // TODO: Also had no docs and questionable 724 | else 725 | { 726 | TmxObjectType.OTRectangle; 727 | } 728 | 729 | var object:TmxObject = { 730 | id: obj.has.id ? Std.parseInt(obj.att.id) : 0, // if it's not here, you doing something wrong. 731 | name: obj.has.name ? obj.att.name : "", 732 | type: obj.has.type ? obj.att.type : "", 733 | x: obj.has.x ? Std.parseFloat(obj.att.x) : 0, 734 | y: obj.has.y ? Std.parseFloat(obj.att.y) : 0, 735 | width: obj.has.width ? Std.parseFloat(obj.att.width) : 0, 736 | height: obj.has.height ? Std.parseFloat(obj.att.height) : 0, 737 | rotation: obj.has.rotation ? Std.parseFloat(obj.att.rotation) : 0, 738 | visible: obj.has.visible ? obj.att.visible == "1" : true, 739 | properties: resolveProperties(obj), 740 | objectType: type, 741 | flippedHorizontally: flippedH, 742 | flippedVertically: flippedV, 743 | template: obj.has.template ? obj.att.template : null 744 | }; 745 | 746 | if (object.template != null && resolveTemplate != null) 747 | { 748 | var template:TmxObjectTemplate = resolveTemplate(obj.att.template); 749 | if (!obj.has.name) object.name = template.object.name; 750 | if (!obj.has.type) object.type = template.object.type; 751 | if (!obj.has.x) object.x = template.object.x; 752 | if (!obj.has.y) object.x = template.object.y; 753 | if (!obj.has.width) object.width = template.object.width; 754 | if (!obj.has.height) object.height = template.object.height; 755 | if (!obj.has.rotation) object.rotation = template.object.rotation; 756 | if (!obj.has.gid) // if gid exists, these are overriden on the map object 757 | { 758 | object.flippedHorizontally = template.object.flippedHorizontally; 759 | object.flippedVertically = template.object.flippedVertically; 760 | } 761 | template.object.properties.propagateTo(object.properties); 762 | object.objectType = switch (template.object.objectType) 763 | { 764 | case OTTile(gid): OTExternalTile(gid, template.tileset); 765 | default: template.object.objectType; 766 | } 767 | } 768 | 769 | if (applyObjectTypeTemplate && object.type != null && object.type != "" && resolveTypeTemplate != null) 770 | { 771 | var template:TmxObjectTypeTemplate = resolveTypeTemplate(object.type); 772 | Tools.applyObjectTypeTemplate(object, template); 773 | } 774 | 775 | return object; 776 | } 777 | 778 | private function readPoints(input:Fast):Array 779 | { 780 | var arr:Array = new Array(); 781 | if (input.has.points) 782 | { 783 | var points:Array = input.att.points.split(" "); 784 | for (point in points) 785 | { 786 | var idx:Int = point.indexOf(","); 787 | arr.push( { x:Std.parseFloat(point.substr(0, idx)), y:Std.parseFloat(point.substr(idx + 1)) } ); 788 | } 789 | } 790 | return arr; 791 | } 792 | 793 | private function resolveText(input:Fast):TmxText 794 | { 795 | return { 796 | fontFamily: input.has.fontfamily ? input.att.fontfamily : "sans-serif", 797 | pixelSize: input.has.pixelsize ? Std.parseInt(input.att.pixelsize) : 16, // TODO: Is float? 798 | wrap: input.has.wrap ? input.att.wrap == "1" : false, 799 | color: input.has.color ? resolveColor(input.att.color) : 0, 800 | bold: input.has.bold ? input.att.bold == "1" : false, 801 | italic: input.has.italic ? input.att.italic == "1" : false, 802 | underline: input.has.underline ? input.att.underline == "1" : false, 803 | strikeout: input.has.strikeout ? input.att.strikeout == "1" : false, 804 | kerning: input.has.kerning ? input.att.kerning == "1" : true, 805 | halign: input.has.halign ? input.att.halign : TmxHAlign.Left, 806 | valign: input.has.valign ? input.att.valign : TmxVAlign.Top, 807 | text: input.innerData 808 | } 809 | } 810 | 811 | private function resolveImageLayer(input:Fast):TmxImageLayer 812 | { 813 | var layer:TmxImageLayer = new TmxImageLayer( 814 | (input.hasNode.image ? resolveImage(input.node.image) : null), 815 | (input.has.id ? Std.parseInt(input.att.id) : 0), 816 | (input.has.name ? input.att.name : ""), 817 | (input.has.x ? Std.parseFloat(input.att.x) : 0), 818 | (input.has.y ? Std.parseFloat(input.att.y) : 0), 819 | (input.has.offsetx ? Std.parseInt(input.att.offsetx) : 0), 820 | (input.has.offsety ? Std.parseInt(input.att.offsety) : 0), 821 | (input.has.width ? Std.parseInt(input.att.width) : width), 822 | (input.has.height ? Std.parseInt(input.att.height) : height), 823 | (input.has.opacity ? Std.parseFloat(input.att.opacity) : 1), 824 | (input.has.visible ? input.att.visible == "1" : true), 825 | (input.has.tintcolor ? parseColor(input.att.tintcolor):0xFFFFFF), 826 | resolveProperties(input) 827 | ); 828 | return layer; 829 | } 830 | private function parseColor(color:String):Null 831 | { 832 | if (color.length == 7) return 0xff000000 | Std.parseInt("0x" + color.substr(1)); 833 | return Std.parseInt("0x" + color.substr(1)); 834 | } 835 | 836 | private function resolveProperties(input:Fast):TmxProperties 837 | { 838 | var props:TmxProperties = new TmxProperties(); 839 | var value:String; 840 | if (input.hasNode.properties) 841 | { 842 | for (prop in input.node.properties.nodes.property) 843 | { 844 | value = prop.has.value ? prop.att.value : prop.innerData; 845 | if (prop.has.type) 846 | { 847 | switch(prop.att.type) 848 | { 849 | case "int": 850 | props.setRaw(prop.att.name, value, PTInt); 851 | case "float": 852 | props.setRaw(prop.att.name, value, PTFloat); 853 | case "bool": 854 | props.setRaw(prop.att.name, value, PTBool); 855 | case "color": 856 | props.setRaw(prop.att.name, value, PTColor); 857 | case "file": 858 | props.setRaw(prop.att.name, value, PTFile); 859 | default: 860 | props.setRaw(prop.att.name, value, PTString); 861 | } 862 | } 863 | else 864 | { 865 | props.setRaw(prop.att.name, value, PTString); 866 | } 867 | 868 | } 869 | } 870 | return props; 871 | } 872 | 873 | } 874 | -------------------------------------------------------------------------------- /format/tmx/Tools.hx: -------------------------------------------------------------------------------- 1 | package format.tmx; 2 | import haxe.io.Path; 3 | import format.tmx.Data; 4 | 5 | /** 6 | * ... 7 | * @author Yanrishatum 8 | */ 9 | class Tools 10 | { 11 | 12 | public static function applyTSX(tsx:TmxTileset, base:TmxTileset):Void 13 | { 14 | base.properties = tsx.properties; 15 | base.name = tsx.name; 16 | base.columns = tsx.columns; 17 | base.grid = tsx.grid; 18 | base.image = tsx.image; 19 | base.margin = tsx.margin; 20 | //base.source = tsx.source; 21 | base.spacing = tsx.spacing; 22 | base.tileOffset = tsx.tileOffset; 23 | base.tileCount = tsx.tileCount; 24 | base.tileHeight = tsx.tileHeight; 25 | base.tileWidth = tsx.tileWidth; 26 | base.terrainTypes = tsx.terrainTypes; 27 | base.tiles = tsx.tiles; 28 | base.wangSets = tsx.wangSets; 29 | } 30 | 31 | public static function applyObjectTypeTemplate(obj:TmxObject, ot:TmxObjectTypeTemplate):Void 32 | { 33 | var props:TmxProperties = obj.properties; 34 | for (prop in ot.properties) 35 | { 36 | if (prop.defaultValue != null && !props.exists(prop.name)) 37 | { 38 | props.setRaw(prop.name, prop.defaultValue, prop.type); 39 | } 40 | } 41 | } 42 | 43 | /** 44 | * Resolves OTExternalTile into OTTile. 45 | * Only works if templates and tilesets were resolved and their paths are relative. 46 | * @param mapPath Optional local path to the map file used for accurate TSX path resolving when comparing tilesets. 47 | */ 48 | public static function resolveOTExternalTile(map:TmxMap, ?mapPath:String):Void 49 | { 50 | var tilesetPaths:Array = new Array(); 51 | if (mapPath == null) 52 | mapPath = map.localPath == null ? "" : Path.directory(map.localPath); 53 | else 54 | mapPath = Path.directory(mapPath); 55 | for (tset in map.tilesets) 56 | { 57 | if (tset.source != null) tilesetPaths.push(Path.join([mapPath, tset.source])); 58 | else tilesetPaths.push(""); 59 | } 60 | for (layer in map.layers) 61 | { 62 | switch (layer) 63 | { 64 | case LObjectGroup(_) | LGroup(_): 65 | resolveOTExternalTileInternal(map, layer, mapPath, tilesetPaths); 66 | case _: 67 | } 68 | } 69 | } 70 | 71 | private static function resolveOTExternalTileInternal(map:TmxMap, layer:TmxLayer, mapPath:String, paths:Array):Void 72 | { 73 | switch (layer) 74 | { 75 | case LGroup(group): 76 | for (layer in group.layers) resolveOTExternalTileInternal(map, layer, mapPath, paths); 77 | case LObjectGroup(group): 78 | for (obj in group.objects) 79 | { 80 | switch (obj.objectType) 81 | { 82 | case OTExternalTile(gid, tileset): 83 | var templateSource = Path.join([mapPath, Path.directory(obj.template), tileset.source]); 84 | for (i in 0...paths.length) 85 | { 86 | if (paths[i] == templateSource) 87 | { 88 | obj.objectType = OTTile(map.tilesets[i].firstGID + gid - tileset.firstGID); 89 | break; 90 | } 91 | } 92 | case _: 93 | } 94 | } 95 | case _: 96 | } 97 | } 98 | 99 | /** 100 | * Returns linear array of layers removing all nested groups. 101 | * IMPORTANT! This function will apply group offset/opacity/visibility values to nested layers, don't use it if you need to keep them unchanged. 102 | */ 103 | public static function linearLayers(map:TmxMap):Array 104 | { 105 | var linear:Array = new Array(); 106 | for (l in map.layers) 107 | { 108 | switch (l) 109 | { 110 | case LGroup(group): 111 | linearLayersInternal(group, linear); 112 | default: 113 | linear.push(l); 114 | } 115 | } 116 | return linear; 117 | } 118 | 119 | private static function linearLayersInternal(group:TmxGroup, output:Array):Void 120 | { 121 | for (layer in group.layers) 122 | { 123 | switch (layer) 124 | { 125 | case LGroup(g): 126 | g.offsetX += group.offsetX; 127 | g.offsetY += group.offsetY; 128 | g.visible = group.visible; 129 | g.opacity *= group.opacity; 130 | linearLayersInternal(g, output); 131 | case LObjectGroup(g): 132 | g.offsetX += group.offsetX; 133 | g.offsetY += group.offsetY; 134 | g.visible = group.visible; 135 | g.opacity *= group.opacity; 136 | output.push(layer); 137 | case LTileLayer(l): 138 | l.offsetX += group.offsetX; 139 | l.offsetY += group.offsetY; 140 | l.visible = group.visible; 141 | l.opacity *= group.opacity; 142 | output.push(layer); 143 | case LImageLayer(l): 144 | l.offsetX += group.offsetX; 145 | l.offsetY += group.offsetY; 146 | l.visible = group.visible; 147 | l.opacity *= group.opacity; 148 | output.push(layer); 149 | } 150 | } 151 | } 152 | 153 | /** 154 | Propagates properties from Object Type Template for specific object 155 | @param obj 156 | @param types 157 | **/ 158 | public static function propagateObjectTypeToObject(obj:TmxObject, types:Map):Void 159 | { 160 | if (obj.type != null) 161 | { 162 | var type:TmxObjectTypeTemplate = types.get(obj.type); 163 | if (type != null) 164 | { 165 | var props:TmxProperties = obj.properties; 166 | for (prop in type.properties) 167 | { 168 | if (!props.exists(prop.name) && prop.defaultValue != null) 169 | { 170 | props.setRaw(prop.name, prop.defaultValue, prop.type); 171 | } 172 | } 173 | } 174 | } 175 | } 176 | 177 | /** 178 | Propagates tile properties of tile object in tileset to specific object. 179 | @param obj Object to propagate tile data to. 180 | @param map 181 | @param gid Global tile ID from which to take properties. 182 | **/ 183 | public static function propagateTilePropertiesToObject(obj:TmxObject, map:TmxMap, gid:Int):Void 184 | { 185 | var tset:TmxTileset = getTilesetByGid(map, gid); 186 | if (tset != null && tset.tiles != null) 187 | { 188 | var lid:Int = gid - tset.firstGID; 189 | for (tile in tset.tiles) 190 | { 191 | if (tile.id == lid) 192 | { 193 | tile.properties.propagateTo(obj.properties); 194 | if (tile.type != null && (obj.type == null || obj.type == "")) obj.type = tile.type; 195 | } 196 | } 197 | } 198 | } 199 | 200 | public static function propagateTileProperties(map:TmxMap):Void 201 | { 202 | for (layer in map.layers) 203 | { 204 | propagateTilePropertiesLayer(map, layer); 205 | } 206 | } 207 | 208 | private static function propagateTilePropertiesLayer(map:TmxMap, layer:TmxLayer) 209 | { 210 | var tset:TmxTileset; 211 | 212 | switch (layer) 213 | { 214 | case TmxLayer.LObjectGroup(group): 215 | for (obj in group.objects) 216 | { 217 | switch (obj.objectType) 218 | { 219 | case TmxObjectType.OTTile(gid): 220 | tset = getTilesetByGid(map, gid); 221 | var lid:Int = gid - tset.firstGID; 222 | for (tile in tset.tiles) 223 | { 224 | if (tile.id == lid) 225 | { 226 | tile.properties.propagateTo(obj.properties); 227 | if (tile.type != null && (obj.type == null || obj.type == "")) obj.type = tile.type; 228 | } 229 | } 230 | default: 231 | 232 | } 233 | } 234 | case TmxLayer.LGroup(g): 235 | for (l in g.layers) propagateTilePropertiesLayer(map, l); 236 | default: 237 | 238 | } 239 | } 240 | 241 | /** 242 | Propagates properties from Object Type templates to all objects on the map. 243 | @param map Map to which properties should propagate. 244 | @param types List of Object Type Templates by names. 245 | @param propagateObjectLayers Should propagate to objects on ObjectLayers? 246 | @param propagateTileColliders Should propagate to objects in collisions of tile objects? 247 | **/ 248 | public static function propagateObjectTypes(map:TmxMap, types:Map, propagateObjectLayers:Bool = true, propagateTileColliders:Bool = true):Void 249 | { 250 | inline function propagate(obj:TmxObject) 251 | { 252 | if (obj.type != null) 253 | { 254 | var type:TmxObjectTypeTemplate = types.get(obj.type); 255 | if (type != null) 256 | for (prop in type.properties) 257 | if (!obj.properties.exists(prop.name) && prop.defaultValue != null) 258 | obj.properties.setRaw(prop.name, prop.defaultValue, prop.type); 259 | } 260 | } 261 | 262 | function propagateLayer(layer:TmxLayer):Void 263 | { 264 | switch (layer) 265 | { 266 | case TmxLayer.LObjectGroup(o): 267 | for (obj in o.objects) propagate(obj); 268 | case TmxLayer.LGroup(g): 269 | for (layer in g.layers) propagateLayer(layer); 270 | default: 271 | 272 | } 273 | } 274 | 275 | if (propagateTileColliders) 276 | for (tset in map.tilesets) 277 | if (tset.tiles != null) 278 | for (tile in tset.tiles) 279 | if (tile.objectGroup != null) 280 | for (obj in tile.objectGroup.objects) propagate(obj); 281 | 282 | if (propagateObjectLayers) 283 | { 284 | for (l in map.layers) 285 | { 286 | propagateLayer(l); 287 | } 288 | } 289 | } 290 | 291 | /** 292 | Returns Tile settings for given tile global ID. 293 | **/ 294 | public static function getTileByGid(map:TmxMap, gid:Int):TmxTilesetTile 295 | { 296 | var tset:TmxTileset = getTilesetByGid(map, gid); 297 | if (tset != null && tset.tiles != null) 298 | { 299 | var lid:Int = gid - tset.firstGID; 300 | for (tile in tset.tiles) 301 | { 302 | if (tile.id == lid) return tile; 303 | } 304 | } 305 | return null; 306 | } 307 | 308 | /** 309 | Returns tileset in which given global ID present. 310 | **/ 311 | public static function getTilesetByGid(map:TmxMap, gid:Int):TmxTileset 312 | { 313 | if (gid <= 0) return null; // None 314 | var i:Int = 0; 315 | while (i < map.tilesets.length) 316 | { 317 | if (map.tilesets[i].firstGID > gid) return map.tilesets[i - 1]; 318 | i++; 319 | } 320 | return map.tilesets[i - 1]; 321 | } 322 | 323 | /** 324 | Returns tileset index in which given global ID present. 325 | **/ 326 | public static function getTilesetIndexByGid(map:TmxMap, gid:Int):Int 327 | { 328 | if (gid <= 0) return -1; // None 329 | var i:Int = 0; 330 | while (i < map.tilesets.length) 331 | { 332 | if (map.tilesets[i].firstGID > gid) return i - 1; 333 | i++; 334 | } 335 | return i - 1; 336 | } 337 | 338 | /** 339 | * Sets `x` and `y` values to `output` relative to tile position on source image of tileset. 340 | * Note: Currently do not supports non-zero margin and spacing values. 341 | * @param tileset 342 | * @param localId 343 | * @param output 344 | */ 345 | public static function getTileUVByLidUnsafe(tileset:TmxTileset, localId:Int, output:Dynamic):Void 346 | { 347 | var tilesInLine:Int = getTilesCountInLineOnTileset(tileset);// Math.floor(tileset.image.width / tileset.tileWidth); 348 | Reflect.setProperty(output, "x", (localId % tilesInLine) * (tileset.tileWidth + tileset.spacing) + tileset.margin); 349 | Reflect.setProperty(output, "y", Math.ffloor(localId / tilesInLine) * (tileset.tileHeight + tileset.spacing) + tileset.margin); 350 | } 351 | 352 | /** 353 | * Shifts origin of objects from bottom-left edge to top-left edge. 354 | * Left out for compatibility 355 | * @param map 356 | */ 357 | public static inline function fixObjectPlacement(map:TmxMap):Void topLeftObjectOrigin(map); 358 | /** 359 | * Shifts origin of objects from bottom-left edge to top-left edge. 360 | * @param map 361 | */ 362 | public static function topLeftObjectOrigin(map:TmxMap):Void 363 | { 364 | var toRad:Float = Math.PI / 180; 365 | for (type in map.layers) 366 | { 367 | switch (type) 368 | { 369 | case TmxLayer.LObjectGroup(group): 370 | for (obj in group.objects) 371 | { 372 | var height:Null = obj.height; 373 | if (height == null || height == 0) 374 | { 375 | switch (obj.objectType) 376 | { 377 | case TmxObjectType.OTTile(gid): 378 | var tset:TmxTileset = getTilesetByGid(map, gid); 379 | if (tset != null && tset.tileHeight != null) height = tset.tileHeight; 380 | else height = map.tileHeight; 381 | default: 382 | height = map.tileHeight; 383 | } 384 | } 385 | var radians:Float = obj.rotation * toRad; 386 | obj.x += Math.sin(radians) * height; 387 | obj.y -= Math.cos(radians) * height; 388 | } 389 | default: 390 | } 391 | } 392 | } 393 | 394 | /** 395 | Returns amount of tiles in one line in given tileset. Use it for UV calculation. 396 | **/ 397 | public static function getTilesCountInLineOnTileset(tileset:TmxTileset):Int 398 | { 399 | return Math.floor((tileset.image.width - tileset.margin * 2 + tileset.spacing) / (tileset.tileWidth + tileset.spacing)); 400 | } 401 | 402 | /** 403 | Returns amount of tiles in one column in given tileset. UV calculation. 404 | **/ 405 | public static function getTilesCountInColumnOnTileset(tileset:TmxTileset):Int 406 | { 407 | return Math.floor((tileset.image.height - tileset.margin * 2 + tileset.spacing) / (tileset.tileHeight + tileset.spacing)); 408 | } 409 | 410 | /** 411 | Returns total amount of tiles in tileset. 412 | **/ 413 | public static function getTilesCountInTileset(tileset:TmxTileset):Int 414 | { 415 | return Math.floor((tileset.image.width - tileset.margin * 2 + tileset.spacing) / (tileset.tileWidth + tileset.spacing)) * 416 | Math.floor((tileset.image.height - tileset.margin * 2 + tileset.spacing) / (tileset.tileHeight + tileset.spacing)); 417 | } 418 | 419 | 420 | /** 421 | Returns visual tile position based on the map parameters and optionally on tileset sizes. 422 | @param tileset Optional tileset reference. If present, it's tile sizes will be used for position calculation. 423 | @param lid Optional local tile ID on tileset. Required for imageset tilesets. 424 | **/ 425 | public static function tilePosition(map:TmxMap, tx:Int, ty:Int, ?tileset:TmxTileset, ?lid:Int):{ x:Float, y:Float } 426 | { 427 | var th:Int; 428 | var ox:Float = 0; 429 | var oy:Float = 0; 430 | if (tileset == null) 431 | { 432 | th = map.tileHeight; 433 | } 434 | else 435 | { 436 | th = tileset.tileHeight; 437 | if (tileset.tileOffset != null) 438 | { 439 | ox = tileset.tileOffset.x; 440 | oy = tileset.tileOffset.y; 441 | } 442 | if (th == 0) th = map.tileHeight; 443 | if (lid != null) 444 | { 445 | for (t in tileset.tiles) 446 | { 447 | if (t.id == lid && t.image != null) 448 | { 449 | th = t.image.height; 450 | break; 451 | } 452 | } 453 | } 454 | } 455 | th -= map.tileHeight; 456 | 457 | switch (map.orientation) 458 | { 459 | case Orthogonal, Unknown(_): 460 | return { x: map.tileWidth * tx + ox, y: map.tileHeight * ty - th + oy }; 461 | case Isometric: 462 | var hw = map.tileWidth * .5; 463 | var hh = map.tileHeight * .5; 464 | return { x: tx * hw - ty * hw + ox, y: (ty + tx) * hh - th + oy }; 465 | case Staggered: 466 | return null; 467 | case Hexagonal: 468 | return null; 469 | } 470 | } 471 | 472 | } 473 | -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "format-tiled", 3 | "url" : "https://github.com/Yanrishatum/haxe-format-tiled", 4 | "license" : "Public", 5 | "contributors" : ["Yanrishatum", "T1mL3arn", "Antriel"], 6 | "description" : "Tiled format support without additional dependencies (like OpenFL)", 7 | "version" : "2.3.0", 8 | "releasenote" : "Template support expansion; OTPoint support" 9 | } 10 | -------------------------------------------------------------------------------- /test/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/.keep -------------------------------------------------------------------------------- /test/assets/buch-outdoor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/buch-outdoor.png -------------------------------------------------------------------------------- /test/assets/desert.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | eJztmNkKwjAQRaN9cAPrAq5Yq3Xf6v9/nSM2VIbQJjEZR+nDwQZScrwztoORECLySBcIgZ7nc2y4KfyWDLx+Jb9nViNgDEwY+KioAXUgQN4+zpoCMwPmQAtoAx2CLFbA2oDEo9+hwG8DnIDtF/2K8ks086Tw2zH0uyMv7HcRr/6/EvvhnsPrsrxwX7rwU/0ODig/eV3mh3N1ld8eraWPaX6+64s9McesfrqcHfg1MpoifxcVEWjukyw+9AtFPl/I71pER3Of6j4bv7HI54s+MChhqLlPdZ/P3qMmFuo5h5NnTOhjM5tReN2yT51n5/v7J3F0vi46fk+ne7aX0i9l6If7mpufTX3f5wsqv9TAD2fJLT9VrTn7UeZnM5tR+v0LMQOHXwFnxe2/warGFRWf8QDjOLfP 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/assets/desert.tsx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /test/assets/hexagonal-mini.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | eJyl1FEKhDAMBNBSt6jVaL3/Za2QwDAkVdiPQda2zyTonimlU1N6Ws+lkZ6l56AUXcPY2qlniv5uL5Z5BdyDvFXXMoX3Rp44axl6nqFejj3LLK6xgmf3Zg06Qs+O+qiaDOZOVgXPs7jfCme8Hkce1+fNlGdlM3myDTzc580fz1htW2Baj15/R/J72wLvcVZN5HnzGnmVPJ5hNH+0dt33j4ex91TARUs+WjNZz/fewKvJfy+/1naR+dX7OfdEnUYefyOeZZ7Vht/b5HjefxJbO1iTE7YWuEpg5hfPzi8D782x3Mg7DV4= 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test/assets/hexmini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/hexmini.png -------------------------------------------------------------------------------- /test/assets/isometric_grass_and_water.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/isometric_grass_and_water.png -------------------------------------------------------------------------------- /test/assets/isometric_grass_and_water.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | eJx1lttywjAMROVgyqVtAoFC/v9L68xoh5PFPGhIYktrrVYyS0QszZ7Nvpvd0n7y24L1Q7MhrTSreN/le821HZ7lv9qYa6sdE0cYs/kX7PXYwtfaevYp7WDrd+SnHByjYr/npP1zZ4/elcuM71rjeckdc5KNHX75fMwc9s2uzb6AsYstJzwrv5/Tz89SLIZy8v203llV8xl7yMU+462/v81OqA114/UhrzUxRqwprnh6ZGzp2PNQfPqRu/X9hnMV8F/xLg1L42erDf2oaa2RI2qPtbgbhmw2H69nMUxx/gVccXdC3AW/o/HV60vW59Lhu8arDxmfGIPFUV1qbLVQEIs4PlOeHQxqVjmzr5mLYsmf+5Qj5yM1r3Ne4p1D5VcMh3qWZibLx2fYkBhPYOv81I9wbrGd45zFU7zrndpwDjkHXXfej9zHc3EG+D3AWcCZMJif7hTnVxr6i9edtoBDz8N7kxqbY6sN9gJnsnqIOqCme7Un76579sIV8dccHvHqZefH76BP9wjzkVapM2rL+5/8cR6QS9eh8p2AT12y5oO9+7yh5hzLZypnHX29/pzB9PE7bOg8Mza5KvGu4R7mp/89zqvr7x+TnxEn 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /test/assets/orthogonal-outside.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | eJyNWE1vVVUU3Y0KQeXL4kBL7QAiEkcopQOIkjgysXagYeLIpE0HGucEtY5U6giw1Bj8AdiWxhZ+ANLS4nv+AJKW1+TVH9DklWfSR+LeeWt51j3eWxmsnPvuPR9rr7P3Pvu8hpkd7DFb8dYb24Pf89bFtOOio8/xquNreZ/jdccxx0nH53j+SN7F81nHOfz+BGs1vP0C706i/1kZ+6asMWRdrvMY+4q3bzmedTwj/FfAO/i2HVcc10s4f+t4QzidcEw6vnd8lz0HfrAu3wOO8xj3seO44AT6cY0GONPWTx1jjp8cvzjO4Fsbfan/luP3XXgrJ+4XtWnjeQX9VzBmErgsdud8lXdwCb94G5w3HE+g+R5ZcwDPDx114U3dY569wkW5UZ8J8I6+AfalPbT7MvhS03nMMV3CNzT+A5zHMt70obvezjrWwfue47HwynUhH3JivwG01E1Be0cs8eW3mOd9x2lwXHVsOx7AP8bgI/PCZ5+PmwHvHceSaK76UZO2cGyg1X2mT/eKrtOwUX2Le/RcicbB4zfHyz6239sPs3VijtB6E33XRPPr0CbXmpwaAvrEPPyBvsDvOn4IbQ+4jkHnDaxfE52POl6zFIe0n1oH12Vw37Hq2HzH8W5o6DgE9FrRn+l7uk8rVvSZi6LvDdF4GaBPU2edS32kDjub1vWrMt6Mq8gJkc/OwQbypq9T54jrKcfVkrl+Fq5ctwn9/hTOZefIgPC+7VhEW9tFb+bwyL2Rw3le5DHGeVuY6xrma0DPJtpYL+Ip/JT+TM7uT9/k649jji3MEWMO+5gF2Py4hLOel8y/A1bMKdRbeW8K99BkzlIOmMVe37GuL2u+y/PYCNbbAkfGwCo0vyX9cq0nwbcsXnP/e97xAjADzutoQ6def3+kJ2lMnCmZL/wl/C7y87bsTXDuOB5Bt//jpbgiflBlQwe6am4bE40Dw6J1PscW9inmiJhlvvzVcaAn7fnT8JyC/ZG77u/SX3Nx8CPnQNRxl6xY05XZPYN5HoBv+F+VL49kccF9on9GG757q2J84KXMD0bBrw/+EHt7yro5umqOh7IW1330FHtNvkvQdg72co8GKtajnn2ib+QJ1p7T2XMgzlDPI//mv+C8Db5NWVO/MeangB/Bt4Y9CnuXs7FVIEfWofy9d5cxPF8mRKtNaDQLvxiy5O/xvgMteQ5si7Y1PLdkf8owjvW+hIan7L85gnXJRLd/wQ+ZD+jPjOU1K9ao1JLfeWatgfdtvGcNsBtnzjcu+/+VdWMubNA6i3lNx9MWahl7qvUHa1RqS79pWjord9C/hedFjLsKaByQ72KJLax1437GmqZX+OV2Mz+FP9y0dI52wKuFd3y/CH3Zh1qz1f7x7n62X/USHm3ggqU7pdYyeZ57EedTxI3W1XXw25T1a+DFs4vn/Bz4d7BHm5bOOe4XvzdLeBBRO0YdwzszeYevjFvymYg1xiv1qFvKtx1o17QUi1EXMHYOgfsR8G9Z8hXWiZyrjvFVnFl/kfOxjDdrmeAZeeuapTOce8x6gHquAVEv6jnL51VozH6shdbAn3VnrBvxdtCS7/LdeUv/NUQNxntlG7ypK/dxHWuw/tbzlTVIrMlaKu4Zeu4egm30I+a/WbTL+KaaHoeWh8GX+sZ/I1HnDlixFr9nqY5dtFQztjK+vMurbsH7hqU7J/X+GxyXMGcNWJI9oy9csOJ/PKEr/0cJe96Dvjdl/3g/2ZZ1uH9/Wbe2GnR8AC7Rb8dSPOV2jaIfc7ae6ew7akX/nQRP+kC8j/OO98vgvA95Yj/q2v2SK7Sm5fx5rC2gT/R/YsXacRT7EeMXLMVdcNa4rYrByMd6B676j44+3QFn1U7jTLkzz6nGw/I93m9Yyot5HcdzhPkrELkrYjD8mnGZc2a9pnUO+Q5mPEO/fivG21Grtktty+8eqjM58b873tk+s25c6t0+cNdS/cAYv1Oxfhn6pR20oh+dzvoOZ/b+A6OnAUo= 204 | 205 | 206 | 207 | 208 | eJzVl9lNw0AURZ8ltgr4YquAjliaYPl8DdAChCVABRB2KkBhpwK2sKQC4FgiShQ8tseMx/aVjmRLY+fO3JnnFxGRGZiVamkBFos2EaOBQGQw6N6PFmcltcbwOx50vU+neKYztsb1OmzAZq4uo9XxbjO2wfUBHMJRjt5c6RyacAlXcF2oGzu9wCu0YCohpwcPftJqFdZ+r9uGMf1nvWjtwX7P/UiEN5vzUiZRW5Qao9QarUHRftKI2qLUGKXWaCOjZ9/zprYoNUapNdrM+Hsu5m0jaotSY5Rao62M73Ax70d4gme4yOgjSb01tH/eu/947xd8izvfS7Ds6F2+VZP8e5oVx+8rY0/D90dN385QPnuapN7DZnxvT1O2HiCNqtYD2GaXt3aot9tQh62K9CJn+DyFEziuiOd7fN7BLdyUxDN5C7kL+Yf74I8+8fkB7/AGQ+zdYU/7t21YI/IWchfyD/dBoibwO1nwmSNvIXch/3AfxCopE18ibyF3If9wH8TKNhOfMq2nTSZ5yXSeTOvZn0nU83Mw78Bb1P/tUKbzlHY9k87jD20Li3Y= 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | -------------------------------------------------------------------------------- /test/assets/perspective_walls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/perspective_walls.png -------------------------------------------------------------------------------- /test/assets/perspective_walls.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | eJztlOkKgCAQhLfb7vd/24SUBqMMNevHfDB4LczusihCCCHkTzRay4XaDP7rxf1882ZpzBqTp/Wo4c7ulRy96LUKRx3EFYF5+GpESpA9V845pT/Oxijn+luIw36k8vf1Rpk1xPepx9vczV+O3GL6n4JJ9vkSOf8/Qwb/r+vHP8ZVzFwTQshf2AA5owLB 7 | 8 | 9 | 10 | 11 | eJztzgEJAAAIA7CD/Tsb4yJbgiUA8MO0AwAAhy0rhAAE 12 | 13 | 14 | 15 | 16 | eJztzjENAAAIA7Al+PeMgz0cPK2CJgBwN98BAACqBS0QAAQ= 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/assets/perspective_walls.tsx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /test/assets/sewer_automap/rule_001.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | eJxjYMAPPHHQ+AAAJfgA3A== 17 | 18 | 19 | 20 | 21 | eJxjYMAPPKG0F5T2JqAeBAAmbADf 22 | 23 | 24 | 25 | 26 | eJxjYMAPeKG0DJRWIqAeBAAMkABM 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /test/assets/sewer_automap/rule_002.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | eJxjYCAMfLDQPnjkiTGPWLUA1AACYQ== 12 | 13 | 14 | 15 | 16 | eJxjYCAMvKG0FxLfC0neC00dIeBFgloAz9QCVQ== 17 | 18 | 19 | 20 | 21 | eJxjYCAMtND4yjjUSRFhFgwoEqkOADFsAIk= 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /test/assets/sewer_automap/rule_003.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | eJxjYCAMfLDQPnjkydVPDgAAZj8DRQ== 13 | 14 | 15 | 16 | 17 | eJxjYCAMPAmIYZPHphadpgYAAL88Abc= 18 | 19 | 20 | 21 | 22 | eJxjYCAMmLCI8SCxuQjoF0Lj8xFhJ7EAABfQADk= 23 | 24 | 25 | 26 | 27 | eJxjYCAesBKQ5yXBLGoBAAmIABM= 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /test/assets/sewer_automap/rule_004.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | eJxjYMAPfKAYnU0rOVwAAJk3BME= 12 | 13 | 14 | 15 | 16 | eJxjYMAPPKEYnU2pHLodhAAAb/8D/w== 17 | 18 | 19 | 20 | 21 | eJxjYMAPePHI8aHxeYiUIwcAABkoAEI= 22 | 23 | 24 | 25 | 26 | eJxjYMAPOND47ATU0woAAAgwABA= 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /test/assets/sewer_automap/rule_005.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | eJxjYCAP+BDgk6LHBwcbnxy19ZAKAMzFByE= 12 | 13 | 14 | 15 | 16 | eJxjYCAPeBLgD6QeYsyj1BwAd2cCSQ== 17 | 18 | 19 | 20 | 21 | eJxjYCAPiKHxRYjQw43G5yRCjzAaX5AIPfQAAE2oAGM= 22 | 23 | 24 | 25 | 26 | eJxjYBgcgAVKs5GghwdK81HZLcQAABQQACU= 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /test/assets/sewer_automap/rule_006.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | eJxjYMAPfKAYnU2JHC4AAAEbA5E= 12 | 13 | 14 | 15 | 16 | eJxjYKAMeKLRyOKeWNj4AABbzAG3 17 | 18 | 19 | 20 | 21 | eJxjYCAfeBLgkwoAKZwAkw== 22 | 23 | 24 | 25 | 26 | eJxjYKAM8KLRlAAAB9wAGw== 27 | 28 | 29 | 30 | 31 | eJxjYCAMeNFoWgEACrQAGw== 32 | 33 | 34 | 35 | 36 | eJxjYCAM5KG0AhFqKQEAGSQAQA== 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /test/assets/sewer_automap/rule_007.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | eJxjYMAPfKAYnU1Ijp5mAgDb0wTB 12 | 13 | 14 | 15 | 16 | eJxjYKAMeKPRtNaHDQAAdfQBLQ== 17 | 18 | 19 | 20 | 21 | eJxjYMAPvKEYnc2AxsbGx2cmLj4++3ABAGBjA4U= 22 | 23 | 24 | 25 | 26 | eJxjYCAMPNFodHFcfELmEeITax4A5OQCSQ== 27 | 28 | 29 | 30 | 31 | eJxjYKAMSEJpaRL1aUJpbQrtBwEAMlQAiQ== 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/assets/sewer_automap/rule_008.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | eJxjYCAMfKAYGwAAD7AAmQ== 16 | 17 | 18 | 19 | 20 | eJxjYMAEPljEcAEADVAATQ== 21 | 22 | 23 | 24 | 25 | eJxjYCAMWICYF4ccAAHoABI= 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /test/assets/sewer_automap/rule_009.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | eJxjYMAEPlCMDQAAD6AAmQ== 16 | 17 | 18 | 19 | 20 | eJxjYMAESkCshUUcBAAH2ABN 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /test/assets/sewer_automap/rules.txt: -------------------------------------------------------------------------------- 1 | # rules.txt 2 | # Copyright 2011, Stefan Beller 3 | # 4 | # This file is part of the sewers example for automapping for Tiled. 5 | # 6 | # This program is free software; you can redistribute it and/or modify it 7 | # under the terms of the GNU General Public License as published by the Free 8 | # Software Foundation; either version 2 of the License, or (at your option) 9 | # any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, but WITHOUT 12 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 | # more details. 15 | # 16 | # You should have received a copy of the GNU General Public License along with 17 | # this program. If not, see . 18 | 19 | 20 | # lines starting with # or // are comments 21 | # all other lines will be parsed and treated as filenames. 22 | 23 | # Feel free to comment out certain rules, to see if and how they are working. 24 | # So have fun experimenting with this bunch of rules :) 25 | 26 | # First apply only one tile rules to fill the regions 27 | # 28 | # We mark the place, where rules are defined, with the RuleRegion layer. 29 | # So whereever there are tiles at the ruleRegion layer, it will be used as a rule. 30 | # In the RuleSet layer we can define, which combination of tiles must occur 31 | # to trigger the specific rule. 32 | # The layers Rule_Ground, Rule_Over and Rule_Over2 define the output of the rules. 33 | # 34 | # Which tiles should I use in the regions layer? 35 | # Actually there can be any tiles, but it should be the same tiles for one rule. 36 | # So use whatever you want, maybe a colorful tile so you can see easily that these 37 | # tiles are used for defining the rule region. 38 | # 39 | # In the very first rulefile used for Automapping it might be useful to define 40 | # some map properties: 41 | # "DeleteTiles" = "true", "false" - This property determines if all tiles in the 42 | # whole region where Automapping takes place 43 | # are deleted. 44 | # That is useful, when not all layers are covered 45 | # at all places. (Check the Over and Over2 layer!) 46 | # "AutoMappingRadius" = 0,1,2... - This property determines which regions are 47 | # automatically remapped at live Automapping. 48 | # When you draw directly into the map, 49 | # not the whole map is remapped, but only a little 50 | # place around. Here you can specify how many 51 | # tiles at least should be remapped. 52 | 53 | ./rule_001.tmx 54 | 55 | 56 | 57 | 58 | # Setup the right transition tiles at the border of light blue stone tiles 59 | # 60 | # Basically it is the same as the first rule, we are just using bigger rules. 61 | # Whenever there is a light blue tile beside a grey tile, one of these rules 62 | # will apply. 63 | 64 | ./rule_002.tmx 65 | 66 | 67 | 68 | 69 | # Now put straight walls 70 | # 71 | # Note: Compare the regions and the set layer! 72 | # Not at all places where a rule is defined, there is a tile in the input_set layer. 73 | # This means that there can be any tiles except those used by the rule. 74 | # So there are no black tiles allowed, when there are no tiles in the input_set 75 | # layer. 76 | 77 | ./rule_003.tmx 78 | 79 | 80 | 81 | 82 | # Now we add inner corners for walls 83 | # 84 | # (No new features introduced) 85 | 86 | ./rule_004.tmx 87 | 88 | 89 | 90 | 91 | # Now we add the corners for walls 92 | # 93 | # (No new features introduced) 94 | 95 | ./rule_005.tmx 96 | 97 | 98 | 99 | 100 | # Correct the error we got in the two previous rulefiles (overwrite it once more) 101 | # 102 | # Here we can see the use of input_set and input_NotSet 103 | # With the input_NotSet we can define which tiles must not be used at certain places 104 | # Important sideeffect: the empty regions in ruleSet can be anything now, including 105 | # black tiles as used here! 106 | # 107 | # So when you use both input_Set and input_NotSet, you need to specify exactly what 108 | # is allowed at which places. 109 | 110 | ./rule_006.tmx 111 | 112 | 113 | 114 | 115 | # Setup the corner stones for light blue stone tiles 116 | # 117 | # Hey, there are multiple layers called input_NotSet! 118 | # Yes, when you need to specify multiple allowed or disallowed tiles per 119 | # position, you can use multiple layers of input_Set and input_NotSet 120 | 121 | ./rule_007.tmx 122 | 123 | 124 | 125 | 126 | 127 | # Setup objects now 128 | # The objects '1' will be placed. They will be placed based on the 129 | # Over layer, which was created by previous rules. 130 | # The placement of objects is done in south-east corners. 131 | 132 | ./rule_008.tmx 133 | 134 | 135 | 136 | 137 | # Setup another object. 138 | # This object is based on input from the Ground layer. 139 | # It will put objects to borderstones which are near an end of that borderline. 140 | # 141 | 142 | ./rule_009.tmx 143 | -------------------------------------------------------------------------------- /test/assets/sewer_automap/rules_sewers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sewer_automap/rules_sewers.png -------------------------------------------------------------------------------- /test/assets/sewer_automap/sewers.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | eJztlUEOwCAIBLH+/8/eDSBQ1jTNHuZiDKOGxSEigxDyCWYRtPsx6HBH74hyn2r9zT2T7uj+jPemW+sfrRai16K1ut1ebtEZ8+aFdxaU27qj5a7O1FOfRd1v86XlZc+T9RZVt3aG6FrX/0UIIVkWa5oFDA== 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test/assets/sewer_tileset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sewer_tileset.png -------------------------------------------------------------------------------- /test/assets/sewers.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | eJzjZWBg4ANiJSjmAWJeJDFlIJaBYkU0eWU0tfTWr4JFvwgQMwGxGJn2cwIxFxBzk6lfEIiFgFiYTP3omN76h1L8K6PFNTnxjxzXxMQ/svnKaHFNTPwjm6+MJ95wxR/IfDeo+SA5LQJYG0m/JhY5AJBFGTU= 10 | 11 | 12 | eJyTYWBgkEHCikDMA8S8RGIZCvVrAbEqFIPYanS2H5t+ESBmIhJj088JxFw4sDoaH5t+QSAWQsMaWMSEsOjXhIYjsRhdP6VYEoilgFiaTP0g/ysBsTKZ+mH+16aB34aj/wGGoBjD 13 | 14 | 15 | eJzjZWBg4IViPiBWQsLKQCxDAPMOcf1MSFiMDP1cSJgbqk8FiLWAWJsI/UJIWJgEe2FYCwsmxt5RPIpBGADIuxtd 16 | 17 | 18 | eJyTYWBgkGEgH8iM6h/VP6p/yOoHAG1pA4E= 19 | 20 | 21 | eJyTYWBgkBnFeLEkEEthwdJE6lcEYiUsWJkE/TxAzIuE+UjULwLETEhYjET9nEDMhYS5SdQvCMRuQCwEpYVJ0K8JxFpYsDad4n84YwCmQRvk 22 | 23 | 24 | eJyTYWBgkBnFo3gUj0gMAD9IHAE= 25 | 26 | 27 | eJyTYWBgkBnFo3gUj0gMAD9IHAE= 28 | 29 | 30 | eJyTYWBgkGEgH8iM6h/VP6p/yOoHAG1pA4E= 31 | 32 | 33 | eJyTYWBgkBnFo3gUj0gMAD9IHAE= 34 | 35 | 36 | eJyTYWBgkBnFo3gUj0gMAD9IHAE= 37 | 38 | 39 | eJyTYWBgkBnFo3gUj0gMAD9IHAE= 40 | 41 | 42 | eJyTYWBgkGEgH8iM6h/VP6p/yOoHAG1pA4E= 43 | 44 | 45 | eJyTYWBgkBlAPApGwSgYOAAAK8MDgQ== 46 | 47 | 48 | eJyTYWBgkBlAPApGwSgYOAAAK8MDgQ== 49 | 50 | 51 | eJyTYWBgkBlAPApGwSgYOAAAK8MDgQ== 52 | 53 | 54 | eJyTYWBgkGEgH8hQqH8UjIJRMHAAALUvAHE= 55 | 56 | 57 | 58 | 59 | 60 | 61 | eJxjYBgFgwmwADErELORqZ8HiHmBmI9qLhoFwxkAAHz4ADc= 62 | 63 | 64 | eJxjYEAFZgyUgaGmXx+IjaHYBIhNSdRvDsTWQOwCpW1J1D8KRsFAAgAswwMF 65 | 66 | 67 | eJxjYBgFxAAWIGZFwmwk6ucBYl4kzEdV142CUUAeAADwwABb 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /test/assets/sticker-knight/README.md: -------------------------------------------------------------------------------- 1 | Sticker Knight platformer example 2 | --------------------------------- 3 | 4 | This example is by @ponywolf and released to the public domain. You can 5 | find it at http://opengameart.org/content/sticker-knight-platformer. 6 | 7 | It's a great example of using the flexible image collection tilesets with 8 | tiles on object layers, for both the map and the UI. 9 | -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/alter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/alter.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/backgroundArch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/backgroundArch.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/backgroundMountain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/backgroundMountain.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/backgroundTower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/backgroundTower.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/backgroundTree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/backgroundTree.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/blobBlue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/blobBlue.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/blobGreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/blobGreen.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/blue.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/bombStroked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/bombStroked.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/castleWall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/castleWall.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/cloud.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/column1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/column1.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/column2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/column2.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/doorBlueStroked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/doorBlueStroked.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/doorGreenStroke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/doorGreenStroke.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/doorRedStroked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/doorRedStroked.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/doorStroked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/doorStroked.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/earthWall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/earthWall.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/earthWall2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/earthWall2.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/exit.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/flare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/flare.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/gemBlueStroked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/gemBlueStroked.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/gemRedStroked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/gemRedStroked.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/grassLarge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/grassLarge.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/grassSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/grassSmall.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/grey.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/hero.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/keyGreenStroked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/keyGreenStroked.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/keyRedStroked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/keyRedStroked.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/keyYellowStroked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/keyYellowStroked.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platform1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platform1.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platform2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platform2.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platform3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platform3.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platform4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platform4.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platformBase1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platformBase1.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platformBase2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platformBase2.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platformBase3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platformBase3.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platformBase4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platformBase4.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platformBlock1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platformBlock1.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platformBlock2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platformBlock2.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platformBlock3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platformBlock3.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platformBlock4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platformBlock4.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platformConnector1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platformConnector1.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platformConnector2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platformConnector2.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platformConnector3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platformConnector3.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/platformConnector4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/platformConnector4.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/pushBlock1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/pushBlock1.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/pushBlock2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/pushBlock2.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/pushBlock3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/pushBlock3.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/sandbox.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/sandbox2.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/shadow.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/shieldStroked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/shieldStroked.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/sign.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/sign.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/skeleton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/skeleton.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/swordStroked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/swordStroked.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/torch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/torch.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/trap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/trap.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/wallDecor1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/wallDecor1.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/wallDecor2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/wallDecor2.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/wallDecor3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/wallDecor3.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/window1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/window1.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/window2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/window2.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/map/window3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/map/window3.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/preview.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/sprites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/sprites.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/ui/backgroundSet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/ui/backgroundSet.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/ui/block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/ui/block.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/ui/buttonHelp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/ui/buttonHelp.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/ui/buttonStart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/ui/buttonStart.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/ui/cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/ui/cloud.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/ui/gem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/ui/gem.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/ui/heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/ui/heart.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/ui/helpBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/ui/helpBackground.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/ui/shield.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/ui/shield.png -------------------------------------------------------------------------------- /test/assets/sticker-knight/ui/title.json: -------------------------------------------------------------------------------- 1 | { "backgroundcolor":"#3b97d3", 2 | "height":26, 3 | "layers":[ 4 | { 5 | "draworder":"topdown", 6 | "height":26, 7 | "name":"background", 8 | "objects":[ 9 | { 10 | "gid":7, 11 | "height":262.666666666667, 12 | "id":11, 13 | "name":"", 14 | "rotation":0, 15 | "type":"", 16 | "visible":true, 17 | "width":1736, 18 | "x":-256, 19 | "y":920.666666666667 20 | }, 21 | { 22 | "gid":6, 23 | "height":832, 24 | "id":34, 25 | "name":"", 26 | "rotation":0, 27 | "type":"", 28 | "visible":true, 29 | "width":1216, 30 | "x":122, 31 | "y":810 32 | }], 33 | "opacity":1, 34 | "type":"objectgroup", 35 | "visible":true, 36 | "width":38, 37 | "x":0, 38 | "y":0 39 | }, 40 | { 41 | "draworder":"topdown", 42 | "height":26, 43 | "name":"clouds", 44 | "objects":[ 45 | { 46 | "gid":8, 47 | "height":61.3333333333333, 48 | "id":14, 49 | "name":"", 50 | "rotation":0, 51 | "type":"", 52 | "visible":true, 53 | "width":184, 54 | "x":640, 55 | "y":320 56 | }, 57 | { 58 | "gid":8, 59 | "height":61.3333333333333, 60 | "id":17, 61 | "name":"", 62 | "rotation":0, 63 | "type":"", 64 | "visible":true, 65 | "width":184, 66 | "x":336, 67 | "y":144 68 | }, 69 | { 70 | "gid":8, 71 | "height":61.3333333333333, 72 | "id":21, 73 | "name":"", 74 | "rotation":0, 75 | "type":"", 76 | "visible":true, 77 | "width":192, 78 | "x":1024, 79 | "y":145 80 | }, 81 | { 82 | "gid":2147483656, 83 | "height":61.3333333333333, 84 | "id":23, 85 | "name":"", 86 | "rotation":0, 87 | "type":"", 88 | "visible":true, 89 | "width":184, 90 | "x":44, 91 | "y":136 92 | }, 93 | { 94 | "gid":6, 95 | "height":600, 96 | "id":8, 97 | "name":"", 98 | "rotation":0, 99 | "type":"", 100 | "visible":true, 101 | "width":954, 102 | "x":-226, 103 | "y":768 104 | }, 105 | { 106 | "gid":2147483654, 107 | "height":546, 108 | "id":35, 109 | "name":"", 110 | "rotation":0, 111 | "type":"", 112 | "visible":true, 113 | "width":826, 114 | "x":710, 115 | "y":782 116 | }, 117 | { 118 | "gid":2147483656, 119 | "height":103.333333333333, 120 | "id":36, 121 | "name":"", 122 | "rotation":0, 123 | "type":"", 124 | "visible":true, 125 | "width":284, 126 | "x":926, 127 | "y":307 128 | }, 129 | { 130 | "gid":8, 131 | "height":103.333333333333, 132 | "id":37, 133 | "name":"", 134 | "rotation":0, 135 | "type":"", 136 | "visible":true, 137 | "width":284, 138 | "x":124, 139 | "y":353 140 | }], 141 | "opacity":0.490000009536743, 142 | "type":"objectgroup", 143 | "visible":true, 144 | "width":38, 145 | "x":0, 146 | "y":0 147 | }, 148 | { 149 | "draworder":"topdown", 150 | "height":38, 151 | "name":"title", 152 | "objects":[ 153 | { 154 | "gid":4, 155 | "height":386, 156 | "id":1, 157 | "name":"logo", 158 | "rotation":0, 159 | "type":"", 160 | "visible":true, 161 | "width":736, 162 | "x":256, 163 | "y":480 164 | }], 165 | "opacity":1, 166 | "type":"objectgroup", 167 | "visible":true, 168 | "width":25, 169 | "x":0, 170 | "y":0 171 | }, 172 | { 173 | "draworder":"topdown", 174 | "height":26, 175 | "name":"help", 176 | "objects":[ 177 | { 178 | "gid":3, 179 | "height":715.669407858419, 180 | "id":26, 181 | "name":"", 182 | "rotation":0, 183 | "type":"", 184 | "visible":true, 185 | "width":745.251573276788, 186 | "x":237.507948400548, 187 | "y":739.425850721188 188 | }], 189 | "opacity":1, 190 | "type":"objectgroup", 191 | "visible":false, 192 | "width":38, 193 | "x":0, 194 | "y":0 195 | }, 196 | { 197 | "draworder":"topdown", 198 | "height":38, 199 | "name":"buttons", 200 | "objects":[ 201 | { 202 | "gid":2, 203 | "height":85.3333333333333, 204 | "id":2, 205 | "name":"start", 206 | "rotation":0, 207 | "type":"", 208 | "visible":true, 209 | "width":256, 210 | "x":485, 211 | "y":655.333333333333 212 | }, 213 | { 214 | "gid":1, 215 | "height":64, 216 | "id":3, 217 | "name":"help", 218 | "rotation":0, 219 | "type":"", 220 | "visible":true, 221 | "width":192, 222 | "x":515.599635905335, 223 | "y":761.206553703963 224 | }], 225 | "opacity":1, 226 | "type":"objectgroup", 227 | "visible":true, 228 | "width":26, 229 | "x":0, 230 | "y":0 231 | }], 232 | "nextobjectid":38, 233 | "orientation":"orthogonal", 234 | "renderorder":"right-down", 235 | "tileheight":32, 236 | "tilesets":[ 237 | { 238 | "columns":0, 239 | "firstgid":1, 240 | "margin":0, 241 | "name":"ui", 242 | "spacing":0, 243 | "tilecount":7, 244 | "tileheight":832, 245 | "tiles": 246 | { 247 | "0": 248 | { 249 | "image":"buttonHelp.png" 250 | }, 251 | "1": 252 | { 253 | "image":"buttonStart.png" 254 | }, 255 | "2": 256 | { 257 | "image":"helpBackground.png" 258 | }, 259 | "3": 260 | { 261 | "image":"title.png" 262 | }, 263 | "5": 264 | { 265 | "image":"backgroundSet.png" 266 | }, 267 | "6": 268 | { 269 | "image":"block.png" 270 | }, 271 | "7": 272 | { 273 | "image":"cloud.png" 274 | } 275 | }, 276 | "tilewidth":1232 277 | }], 278 | "tilewidth":32, 279 | "version":1, 280 | "width":38 281 | } -------------------------------------------------------------------------------- /test/assets/sticker-knight/ui/title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/sticker-knight/ui/title.png -------------------------------------------------------------------------------- /test/assets/tmw_desert_spacing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/assets/tmw_desert_spacing.png -------------------------------------------------------------------------------- /test/build.hxml: -------------------------------------------------------------------------------- 1 | -cp src/ 2 | -cp ../ 3 | -main Main 4 | -js bin/ -------------------------------------------------------------------------------- /test/config.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /test/format-tiled.hxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | "$(CompilerPath)/haxelib" run lime build "$(OutputFile)" $(TargetBuild) -$(BuildConfig) -Dfdb 48 | 49 | 50 | 51 | 52 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /test/project.flow: -------------------------------------------------------------------------------- 1 | { 2 | project : { 3 | name : 'empty', 4 | version : '1.0.0', 5 | author : 'luxeengine', 6 | 7 | app : { 8 | name : 'luxe_empty', 9 | package : 'com.luxeengine.empty', 10 | main : 'Main', 11 | codepaths: ['src', '../'] 12 | }, 13 | 14 | build : { 15 | dependencies : { 16 | luxe : '*', 17 | format: '*' 18 | } 19 | }, 20 | 21 | files : { 22 | config : 'config.json', 23 | assets : 'assets/' 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | -------------------------------------------------------------------------------- /test/src/Main.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import format.tmx.Data.TmxLayer; 4 | import format.tmx.Data.TmxMap; 5 | import format.tmx.Data.TmxTileset; 6 | import format.tmx.Reader; 7 | import haxe.CallStack; 8 | import openfl.Assets; 9 | import openfl.Lib; 10 | import openfl.display.Sprite; 11 | 12 | class Main extends Sprite 13 | { 14 | private var r:Reader; 15 | 16 | public function new() 17 | { 18 | super(); 19 | try 20 | { 21 | 22 | r = new Reader(); 23 | r.resolveTSX = getTSX; 24 | tsx = new Map(); 25 | //var t:TmxMap = r.read(Xml.parse(Assets.getText("assets/desert.tmx"))); 26 | //var t:TmxMap = r.read(Xml.parse(Assets.getText("assets/hexagonal-mini.tmx"))); 27 | //var t:TmxMap = r.read(Xml.parse(Assets.getText("assets/isometric_grass_and_water.tmx"))); 28 | var t:TmxMap = r.read(Xml.parse(Assets.getText("assets/sewers.tmx"))); 29 | 30 | //scaleX = scaleY = 2; 31 | //x = 20; 32 | x = Lib.current.stage.stageWidth / 2; 33 | y = 20; 34 | for (l in t.layers) 35 | { 36 | switch (l) 37 | { 38 | case TmxLayer.LTileLayer(tl): 39 | addChild(new OFLLayerRender(t, tl)); 40 | default: 41 | 42 | } 43 | } 44 | } 45 | catch (e:Dynamic) 46 | { 47 | trace(e); 48 | trace(CallStack.toString(CallStack.exceptionStack())); 49 | } 50 | //untyped __cpp__("cout") << untyped __cpp__("sizeof")(t); 51 | } 52 | 53 | private var tsx:Map; 54 | private function getTSX(name:String):TmxTileset 55 | { 56 | var cached:TmxTileset = tsx.get(name); 57 | if (cached != null) return cached; 58 | cached = r.readTSX(Xml.parse(Assets.getText("assets/" + name))); 59 | tsx.set(name, cached); 60 | return cached; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /test/src/OFLLayerRender.hx: -------------------------------------------------------------------------------- 1 | package; 2 | import format.tmx.Data.TmxMap; 3 | import format.tmx.Data.TmxTileLayer; 4 | import format.tmx.Data.TmxTileset; 5 | import format.tmx.Data.TmxTile; 6 | import format.tmx.Tools; 7 | import haxe.io.Path; 8 | import openfl.Assets; 9 | import openfl.display.Graphics; 10 | import openfl.display.Sprite; 11 | import openfl.geom.Matrix; 12 | import openfl.geom.Point; 13 | import tiled.TileLayerRenderer; 14 | 15 | /** 16 | * ... 17 | * @author Yanrishatum 18 | */ 19 | class OFLLayerRender extends Sprite 20 | { 21 | 22 | private var render:InternalOFLRender; 23 | 24 | public function new(map:TmxMap, layer:TmxTileLayer) 25 | { 26 | super(); 27 | render = new InternalOFLRender(map, layer); 28 | render.g = graphics; 29 | render.render(); 30 | } 31 | 32 | 33 | 34 | } 35 | 36 | private class InternalOFLRender extends TileLayerRenderer 37 | { 38 | public var g:Graphics; 39 | private var m:Matrix = new Matrix(); 40 | private var uv:Point = new Point(); 41 | 42 | override function renderOrthoTile(x:Float, y:Float, tile:TmxTile, tileset:TmxTileset):Void 43 | { 44 | if (tileset.tileOffset != null) 45 | { 46 | x += tileset.tileOffset.x; 47 | y += tileset.tileOffset.y; 48 | } 49 | Tools.getTileUVByLidUnsafe(tileset, tile.gid - tileset.firstGID, uv); 50 | m.setTo(1, 0, 0, 1, x - uv.x, y - uv.y + map.tileHeight - tileset.tileHeight); 51 | g.beginBitmapFill(Assets.getBitmapData(Path.join([ "assets/" , tileset.image.source])), m, false); 52 | g.drawRect(x, y + map.tileHeight - tileset.tileHeight, tileset.tileWidth, tileset.tileHeight); 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /test/tile_flags/.gitignore: -------------------------------------------------------------------------------- 1 | cpp 2 | cs 3 | out.hl 4 | cpp.exe 5 | cs.exe 6 | out.n 7 | output/* 8 | !output/.gitkeep -------------------------------------------------------------------------------- /test/tile_flags/Main.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import sys.io.FileOutput; 4 | import format.tmx.Data; 5 | import format.tmx.Reader; 6 | import sys.io.File; 7 | import haxe.io.Bytes; 8 | 9 | class Main 10 | { 11 | private static macro function getFName():haxe.macro.Expr 12 | { 13 | var name = "output/" + haxe.macro.Context.definedValue("build_type"); 14 | return macro $v{name}; 15 | } 16 | 17 | #if verify_mode 18 | 19 | public static function main() 20 | { 21 | var files = sys.FileSystem.readDirectory("output"); 22 | var master:Bytes = sys.io.File.getBytes(getFName()); 23 | 24 | var tc = Std.int(master.length / 5); 25 | trace("Verifying against: " + getFName()); 26 | for (file in files) 27 | { 28 | if ("output/" + file == getFName()) continue; // Master 29 | var slave:Bytes = sys.io.File.getBytes("output/" + file); 30 | var o:Int = 0; 31 | for (i in 0...tc) 32 | { 33 | if (slave.getInt32(o) != master.getInt32(o) || slave.get(o + 4) != master.get(o + 4)) 34 | { 35 | trace('$file tile $i: Invalid tile GID; Flip: ${slave.get(o + 4)}'); 36 | } 37 | o += 5; 38 | } 39 | } 40 | } 41 | 42 | #else 43 | 44 | public static function main() 45 | { 46 | dump(); 47 | 48 | } 49 | 50 | #end 51 | 52 | private static function dump() 53 | { 54 | trace("Target: " + getFName()); 55 | var fio:FileOutput = File.write(getFName()); 56 | var tmx:TmxMap = new Reader().read(Xml.parse(File.getContent("files/orthogonaloutside.tmx"))); 57 | for (layer in tmx.layers) 58 | { 59 | switch (layer) 60 | { 61 | case TmxLayer.LTileLayer(tl): 62 | for (t in tl.data.tiles) 63 | { 64 | fio.writeInt32(t.gid); 65 | fio.writeByte(t.flippedHorizontally ? 1 : 0); 66 | } 67 | default: 68 | 69 | } 70 | } 71 | fio.close(); 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /test/tile_flags/build.hxml: -------------------------------------------------------------------------------- 1 | -cp ../.. 2 | -cp . 3 | -main Main 4 | 5 | --each 6 | 7 | -D build_type=hl 8 | -hl out.hl 9 | 10 | --next 11 | -D build_type=cpp 12 | -dce full 13 | -cpp cpp 14 | 15 | --next 16 | -D build_type=neko 17 | -neko out.n 18 | 19 | # --next 20 | # -D build_type=js 21 | # -js out.js 22 | 23 | --next 24 | -D build_type=cs 25 | -cs cs 26 | 27 | --next 28 | -D build_type=interp 29 | --interp 30 | 31 | --next 32 | -cmd echo Running files 33 | -cmd hl out.hl 34 | -cmd cp cpp/Main.exe cpp.exe 35 | -cmd cpp.exe 36 | -cmd cp cs/bin/Main.exe cs.exe 37 | -cmd cs.exe 38 | -cmd neko out 39 | 40 | --next 41 | -D build_type=hl 42 | -D verify_mode 43 | --interp 44 | -------------------------------------------------------------------------------- /test/tile_flags/files/buch-outdoor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/tile_flags/files/buch-outdoor.png -------------------------------------------------------------------------------- /test/tile_flags/files/orthogonaloutside.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | oAAAAKEAAACiAAAAowAAAKMAAICiAACAoQAAgKAAAIC4AAAAuQAAALoAAAC7AAAAuwAAgLoAAIC5AACAuAAAgNAAAADRAAAA0gAAANMAAADTAACA0gAAgNEAAIDQAACAAAAAAOkAAADqAAAA6wAAAOsAAIDqAACA6QAAgOsAAAA= 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /test/tile_flags/output/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yanrishatum/haxe-format-tiled/da8daaca11e0d4eaceb34f679968bcb9c4cb1c56/test/tile_flags/output/.gitkeep -------------------------------------------------------------------------------- /tiled/TileLayerRenderer.hx: -------------------------------------------------------------------------------- 1 | package tiled; 2 | import format.tmx.Data.TmxMap; 3 | import format.tmx.Data.TmxOrientation; 4 | import format.tmx.Data.TmxRenderOrder; 5 | import format.tmx.Data.TmxStaggerAxis; 6 | import format.tmx.Data.TmxStaggerIndex; 7 | import format.tmx.Data.TmxTile; 8 | import format.tmx.Data.TmxTileLayer; 9 | import format.tmx.Data.TmxTileset; 10 | import format.tmx.Tools; 11 | 12 | /** 13 | * Basic abstract rendering for tile layers. Not the fastest one, but should get you started. 14 | * @author Yanrishatum 15 | */ 16 | class TileLayerRenderer 17 | { 18 | 19 | public var renderX:Float; 20 | public var renderY:Float; 21 | 22 | private var map:TmxMap; 23 | private var layer:TmxTileLayer; 24 | 25 | public function new(map:TmxMap, layer:TmxTileLayer) 26 | { 27 | this.map = map; 28 | this.layer = layer; 29 | renderX = 0; 30 | renderY = 0; 31 | } 32 | 33 | public function render():Void 34 | { 35 | // Only orthogonal is implemented properly. Others are buggy/not implemented/incomplete 36 | switch (map.orientation) 37 | { 38 | case TmxOrientation.Orthogonal: 39 | renderOrthogonal(); 40 | case TmxOrientation.Isometric: 41 | renderIsometric(); 42 | case TmxOrientation.Staggered: 43 | 44 | case TmxOrientation.Hexagonal: 45 | renderHexagonal(); 46 | case TmxOrientation.Unknown(v): 47 | // Do nothing 48 | } 49 | } 50 | 51 | private function renderOrthogonal():Void 52 | { 53 | // TODO: Regard renderorder 54 | if (map.infinite) 55 | { 56 | if (layer.data.chunks != null) 57 | { 58 | for (chunk in layer.data.chunks) 59 | { 60 | renderOrthoTiles(renderX + layer.offsetX + chunk.x * map.tileWidth, renderY + layer.offsetY + chunk.y * map.tileHeight, chunk.tiles, chunk.width); 61 | } 62 | } 63 | } 64 | else 65 | { 66 | renderOrthoTiles(renderX + layer.offsetX, renderY + layer.offsetY, layer.data.tiles, layer.width); 67 | } 68 | } 69 | 70 | /** 71 | Override for optimized rendering 72 | **/ 73 | private function renderOrthoTiles(ox:Float, y:Float, tiles:Array, width:Int):Void 74 | { 75 | var i:Int = 0; 76 | var ix:Int = 0; 77 | var x:Float = ox; 78 | var tset:TmxTileset; 79 | var tile:TmxTile; 80 | while (i < tiles.length) 81 | { 82 | tile = tiles[i]; 83 | if (tile.gid != 0) 84 | { 85 | renderOrthoTile(x, y, tile, Tools.getTilesetByGid(map, tile.gid)); 86 | } 87 | i++; 88 | if (++ix == width) 89 | { 90 | ix = 0; 91 | x = ox; 92 | y += map.tileHeight; 93 | } 94 | else 95 | { 96 | x += map.tileWidth; 97 | } 98 | } 99 | } 100 | 101 | private function renderOrthoTile(x:Float, y:Float, tile:TmxTile, tileset:TmxTileset):Void 102 | { 103 | throw "Not implemented"; 104 | } 105 | 106 | private function renderHexagonal():Void 107 | { 108 | if (map.infinite) 109 | { 110 | renderOrthogonal(); // TODO 111 | } 112 | else 113 | { 114 | renderHexaTiles(renderX + layer.offsetX, renderY + layer.offsetX, map.staggerIndex == TmxStaggerIndex.Odd, layer.data.tiles, layer.width); 115 | } 116 | } 117 | 118 | private function renderHexaTiles(ox:Float, y:Float, isEven:Bool, tiles:Array, width:Int):Void 119 | { 120 | var baseEven:Bool = isEven; 121 | var i:Int = 0; 122 | var ix:Int = 0; 123 | var x:Float = isEven ? ox : ox + map.tileWidth / 2; 124 | 125 | var tile:TmxTile; 126 | var staggerHor:Bool = map.staggerAxis == TmxStaggerAxis.AxisX; // Not properly supported yet 127 | while (i < tiles.length) 128 | { 129 | tile = tiles[i]; 130 | renderHexaTile(x, y + (staggerHor && !isEven ? map.tileHeight / 2 : 0), tile, Tools.getTilesetByGid(map, tile.gid)); 131 | i++; 132 | if (++ix == width) 133 | { 134 | ix = 0; 135 | if (staggerHor) 136 | { 137 | isEven = baseEven; 138 | y += map.tileHeight; 139 | x = ox; 140 | } 141 | else 142 | { 143 | y += (map.tileHeight - map.hexSideLength) / 2 + map.hexSideLength; 144 | isEven = !isEven; 145 | x = isEven ? ox : ox + map.tileWidth / 2; 146 | } 147 | } 148 | else 149 | { 150 | if (staggerHor) 151 | { 152 | x += (map.tileWidth - map.hexSideLength) / 2 + map.hexSideLength; 153 | isEven = !isEven; 154 | } 155 | else 156 | { 157 | x += map.tileWidth; 158 | } 159 | } 160 | } 161 | } 162 | 163 | private function renderHexaTile(x:Float, y:Float, tile:TmxTile, tileset:TmxTileset):Void 164 | { 165 | renderOrthoTile(x, y, tile, tileset); 166 | } 167 | 168 | private function renderIsometric():Void 169 | { 170 | if (map.infinite) 171 | { 172 | renderOrthogonal(); 173 | } 174 | else 175 | { 176 | renderIsoTiles(renderX + layer.offsetX, renderY + layer.offsetX, layer.data.tiles, layer.width, layer.height); 177 | } 178 | } 179 | 180 | private function renderIsoTiles(ox:Float, y:Float, tiles:Array, width:Int, height:Int):Void 181 | { 182 | var i:Int = 0; 183 | var ix:Int = 0; 184 | var iy:Int = 0; 185 | var x:Float = ox; 186 | var tset:TmxTileset; 187 | var tile:TmxTile; 188 | var hw:Float = map.tileWidth / 2; 189 | var hh:Float = map.tileHeight / 2; 190 | 191 | while (i < tiles.length) 192 | { 193 | tile = tiles[i]; 194 | renderIsoTile(x + ((ix - iy) * width), y + (ix + iy) * height, tile, Tools.getTilesetByGid(map, tile.gid)); 195 | i++; 196 | if (++ix == width) 197 | { 198 | ix = 0; 199 | iy++; 200 | //x = ox; 201 | //y += hh; 202 | } 203 | else 204 | { 205 | //x += hw; 206 | } 207 | } 208 | } 209 | 210 | private function renderIsoTile(x:Float, y:Float, tile:TmxTile, tileset:TmxTileset):Void 211 | { 212 | renderOrthoTile(x, y, tile, tileset); 213 | } 214 | 215 | } --------------------------------------------------------------------------------