## Advanced Tiled Loader - No longer maintained

Party member
Posts: 399
Joined: Mon Jan 10, 2011 8:25 am
Location: Oklahoma

### Advanced Tiled Loader - No longer maintained

I am no longer maintaining this library. See my response on page 25:
I feel like I should address this myself. I probably won't be updating ATL in it's current state. ATL was my first major coding project and even though I dedicated many, many hours to it and learned a lot it I've never been happy with the results. Basically the scope is just way too large and I am way too inexperienced of a programmer. Instead of focusing just on the loading aspect of the library I tried to create an all-in-one solution that includes the rendering, saving, and real-time modification of maps and ended up with a huge inflexible mess. If I do come back to ATL I will likely salvage it into a different project with a much more focused goal.

I also apologize to anyone who feels like they wasted their time with ATL and it did not meet their expectations, or to anyone who genuinely finds it useful and is now finding out I don't plan to maintain it any longer. I honestly gave it my best shot but I've come to realize that is was really never a good library in the first place, which is a pretty hard pill to swallow.

Of course if someone does wish to maintain the library it is on github for anyone to extend, but in its present form I would personally discourage its use as it is now fairly out of date along with all of its previous limitations.
------------------------------------------------------------------------

Advanced Tiled Loader (ATL) loads and renders Tiled maps inside of the Löve game framework.

Supported features include:
• Multiple Layers
• All object types (regular, polygon, and tile)
• Properties
• Transparent colors
• Margins and spacing
• External tilesets
• zlib/gzip decompression
• Isometric maps
• Flipped and rotated tiles
Quick example:

Code: Select all

-- Gets the loader

-- Path to the tmx files. The file structure must be similar to how they are saved in Tiled

-- Loads the map file and returns it

-- Draws the map
map:draw()

-- Limits the drawing range of the map. Important for performance
map:setDrawRange(0,0,love.graphics.getWidth(), love.graphics.getHeight())

-- Automatically sets the drawing range to the size of the screen.
map:autoDrawRange(tx, ty, scale, padding)

-- Accessing individual layers
map.layers["layer name"]

-- A shortcut for accessing specific layers
map("layer name")

-- Finding a specific tile
map.layers["layer name"]:get(5,5)

-- A shortcut for finding a specific tile
map("layer name")(5,5)

-- Iterating over all tiles in a layer
for x, y, tile in map("layer name"):iterate() do
print( string.format("Tile at (%d,%d) has an id of %d", x, y, tile.id) )
end

-- Iterating over all objects in a layer
for i, obj in pairs( map("object layer").objects ) do
print( "Hi, my name is " .. obj.name )
end

-- Find all objects of a specific type in all layers
for _, layer in pairs(map.layers) do
if layer.class == "ObjectLayer" then
for _, obj in pairs(player.objects) do
if obj.type == "enemy" then print(obj.name) end
end
end
end

-- draw the tile with the id 4 at (100,100)
map.tiles[4]:draw(100,100)

-- Access the tile's properties set by Tiled
map.tiles[4].properties

-- Turns off drawing of non-tiled objects.
map.drawObjects = false

For learning resources and the most up-to-date version please use github and the wiki.

Please post if you have any questions or feedback.

Code: Select all

CHANGES:

0.12.1 (10/31/12)
- TileLayer:drawAfterTile() has been reworked into TileLayer:newAfterTileFunction()
- Arguments for the Map functions that create and add map components directly to the
map have changed. (Map:newTileLayer(), Map:newObjectLayer(), etc)

0.12.0 (10/17/12)
- Maps can now be saved with Loader.save()
- Introduced ATL properties
0.11.0 (09/04/12)
- Renamed Map.drawList to Map.layerOrder.
- Renamed Map.drawPosition to Map.layerPosition.
- Combined Map.tileLayers and Map.objectLayers into one table - Map.layers.
- The functionality of tileData is now combined with TileLayer.
- Changed Map.__call to return layers by their name.
- Created Map.callback() to forward love callbacks to layers.
- Created Map.swapLayers()
- Created Map.newCustomLayers() which is a new interface for creating custom layers.
- Classes now remember their class name.
- Removed object movement functions to deter the use of objects other than reading data from.
- Removed the fixPO2 option for the loader.
- Generally cleaned up the code and made it easier to read.
- Properties are now automatically converted into proper types (numbers, boolean, string) when loaded.
- Readme file changed. There is now a new VERSION.txt file for version information.

0.10.2 (04/26/12)
- Relative paths now fully work. Before, ATL did not like to travel backwards in
a directory from a map file to reach a tileset.

0.10.1 (04/20/12)
- Added quit compatibility for love 0.8.0 in the example files
- AdvTiledLoader can now be correctly required from any subfolder
- Fixed a bug with map.drawObjects not working
- Undefined object colors will now appear grey instead of black
- Added Loader.drawObjects and Loader.useSpriteBatch values. These values will be
applied to any new map that is loaded.
- Fixed a bug where the map would be drawn incorrectly if the map's width and height
were different

0.10.0 (04/11/12)
- 2d arrays are replaced with a much easier to use grid class.
- Tiles are now directly inserted into TileLayer.tileData. You no longer have to
look them up via their ID in Map.tiles.
- Tile indexes are now the same as their coordinants as shown inside the Tiled.
- Added support for Tiled version 0.8.0. This includes tile rotation, polygon
objects, polyline objects, tilemap offset, and tilemap propterties.
- Moved the object drawing code from object layers to the objects themselves.
- Added functions tileCopy(), tilePaste(), tileRotate(), tileFlipX(), tileFlipY()
to TileLayers.

0.9.0 (8/22/11)
- Advanced Tile Loader now has a wiki page and a github repository!
- Cleaned up the code quite a bit.
- Classes are now broken up into individual files rather than grouping similar
ones into one file.
- Many identifiers have been changed to be less confusing and more consistent. Now
camelCase is used to separate words instead of underscores. Internal
functions and data are now prefixed with an underscore.
- Sprite batch mode can now be set through the map or through individual tile
layers. Tile layer settings take precedence.
- A bug with layer transparency has been fixed.
- Tile:draw() now accepts parameters for scaling, rotation, and offset.
- TileLayer:drawAfterTile() now works with multiple functions
- Forcing a redraw is now automatic when you switch sprite batch modes.
- Added support for flipped tiles that were introduced in Tiled version 0.7.1

0.8.2 (5/9/11):
- Tileset images are now cached between maps.
- Added an option to automatically pad images for PO2. To do this set
- Changed Map.tl and Map.ol back to their old names. Map.tl and Map.ol remain as
aliases.
- Tile layers can now render using sprite batches by setting TileLayer.use_batch
to true.
- Added an init.lua file.
- Removed hardcoded require() paths. Added in global TILED_LOADER_PATH to point
to the library path.
- Renamed the TileSet functions getWidth() and getHeight() to tilesWide() and
tilesHigh().

0.8.1 (3/10/11):
- Renamed Map.tilelayers and Map.objectlayers to Map.tl and Map.ol respectively.
- Added function Tile.drawAfterTile()
- You may now define a draw() function for objects which overrides the default
drawing routine

0.8.0 (2/28/11):
- Initial release

Last edited by Kadoba on Thu Dec 26, 2013 9:30 pm, edited 25 times in total.

crow
Party member
Posts: 186
Joined: Thu Feb 24, 2011 11:47 pm
Location: UK
Contact:

That is really nice but could we see a demo with maybe a spirte/player on the map/tiled
Sir Kittenface
Möko IDE Codename (Erös) Returns Soon

I am dyslexic so if any of my replys confusing please just ask me to reword it as this will make things a lot easier for all parties lol.

kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Contact:

This is quite awesome!. One minor thing: I expected the mouse wheel to work the opposite way.
When I write def I mean function.

Party member
Posts: 399
Joined: Mon Jan 10, 2011 8:25 am
Location: Oklahoma

crow wrote:That is really nice but could we see a demo with maybe a spirte/player on the map/tiled
Ok. This shouldn't been too hard on orthogonal maps but on isometric maps it can be kind of tricky at the moment.
kikito wrote:This is quite awesome!. One minor thing: I expected the mouse wheel to work the opposite way.
Whoops. I'll fix that when I upload the next update.

Party member
Posts: 399
Joined: Mon Jan 10, 2011 8:25 am
Location: Oklahoma

### Update! Advanced Tiled Loader 0.8.1 is go!

Update! First of all I realize that in practice typing out map.tilelayers and map.objectlayers is just too long. So I have shortened "map.tilelayers" and "map.objectlayers" to "map.tl" and "map.ol" respectively. I'm usually against shortening variable names in such a way but they are accessed very often so I don't think it will be too confusing.

I've added some functions to make it easier to draw things when you need them to be drawn. Previously the only time you could draw things inside of the map was in-between layers but now you should be able to draw them in-between any tile or object that you want.

Now there are three ways to draw stuff inside the map:

To draw in-between layers add the function that you want called in the map's draw_list table. This table holds the map's object and tile layers in the order drawn. Let's say that you have a drawing function that you want to be called before layer 3. Then you simply insert it in the map's draw list like so:

Code: Select all

table.insert( map.draw_list, 3, drawing_function )

If you wanted to call the same function before a tile layer named "ground" but you're not for sure what number it is then you can check it using "map:drawPosition(value)".

Code: Select all

local pos = map:drawPosition( map.tl["ground"] )
table.insert( map.draw_list, pos, draw_function )

The second way to draw something is immediately after a tile has been drawn. This is necessary when you have tilemaps that have view obstructing tiles on the same layer which are often in isometric maps. To do this, use the function called "drawAfterTile(h,w,funct)" on the tile layer like so:

Code: Select all

map.tl["ground"]:drawAfterTile(3, 5, draw_function)

Now after tile (3,5) is drawn this will call draw_function(x,y) where x and y are the lower left position of the tile.

A couple of gotchas with this. First of all, tiles are indexed vertically and then horizontally which means tile (3,5) is the fifth tile on the third row. This is a little counter-intuitive but it's the way tiles are drawn and stored in tmx files. Second of all, if a tile isn't drawn then the function passed with drawAfterTile() is not called. So if you're drawing a large object then it's a good idea to pad the map's draw_range a bit. The last gotcha is that if you are trying to draw something wider than the map's tilewidth then the next tile is probably going to clip it.

The third way to draw something in the map is to define an object's draw() function. This will overload the normal object drawing routine. However you will need to make sure the object is within the map's draw_range in order to be drawn. To do this always move the object with object:move(), object:moveTo(), or object:resize() or call object:updateDrawInfo() after changing x, y, width, or height values OR you can manually manipulate the left, right, top, and bottom values inside the object's draw_info. If you want the object to be drawn no matter what you can use this code:

Code: Select all

object.draw_info.left = -math.huge
object.draw_info.top = -math.huge
object.draw_info.right = math.huge
object.draw_info.bottom = math.huge
Although if you're going to have large maps with a lot of objects I don't recommend this for performance reasons.

I've also changed the first two maps in my example .love to include a little guy you can move around with the "WASD" keys. The first example is orthogonal and uses a map object with an overloaded draw() function and the second map is isometric and uses the drawAfterTile() function. The image is from an old abandoned project of mine.

If anyone has any questions or feedback then please reply!

kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Contact:

### Re: Update! Advanced Tiled Loader 0.8.1 is go!

Kadoba wrote:Update! First of all I realize that in practice typing out map.tilelayers and map.objectlayers is just too long. So I have shortened "map.tilelayers" and "map.objectlayers" to "map.tl" and "map.ol" respectively. I'm usually against shortening variable names in such a way but they are accessed very often so I don't think it will be too confusing.
I recommend you to give a look at the second talk in cleancoders. It costs \$12, but it's fun to watch and explains a very nice rule to choose names appropiatedly. If I were you, I'd have used map.objectLayers and map.tileLayers, and then used local variables on places where they were used a lot:

Code: Select all

local tl = map.tilelayers
... now work with tl

Appart from that, nice to see continuous work on this one. I might end up creating a fork for my tile tutorial
When I write def I mean function.

Party member
Posts: 399
Joined: Mon Jan 10, 2011 8:25 am
Location: Oklahoma

kikito wrote: stuff
Sounds good. Yeah admittedly I've been really bad about choosing names for this project. I have a really good convention for other languages but it doesn't really carry over to Lua very well.

Also it would be really awesome if you used this in your tutorial.

Ortzinator
Prole
Posts: 5
Joined: Wed Mar 16, 2011 5:27 am

Thanks a lot for this! I'm using it in a project. By far the best Tiled loader I've come across.

Here's the code to get draw range to work with the hump camera (since its origin is in the center).

Code: Select all

camWorldWidth = love.graphics.getWidth() / cam.zoom
camWorldHeight = love.graphics.getHeight() / cam.zoom
camWorldX = cam.pos.x - (camWorldWidth / 2)
camWorldY = cam.pos.y - (camWorldHeight / 2)
map:setDrawRange(camWorldX, camWorldY, camWorldWidth, camWorldHeight)

artfulgamer
Prole
Posts: 1
Joined: Mon Apr 04, 2011 3:05 am

Just wanted to thank you for this code/demo. I've been working with it over the past week, slowly learning LUA/LOVE2D and your code structure to build a small isometric game.

Great seeing code so well documented!