Basic Loader for Tiled Maps in Corona (JSON formated)

I spend the past two days rolling my own code to load JSON saved maps from Tiled 0.9.0 http://www.mapeditor.org/

http://developer.coronalabs.com/code/corona-tiled

It does orthogonal, multiple layers, multiple spritesets, but not much else… If anyone is interested in expanding this and creating an open source loader for Tiled Maps, I’d be down with that. It’s on Github for just that purpose…

https://github.com/superqix/CoronaTiled

What’s left to be done…

TMX files
Offsets
Object types (regular, polygon, line)
Properties
Physics
Transparent colors
External tilesets
zlib/gzip compression
Isometric maps
Flipped and rotated tiles
Saving loaded maps [import]uid: 51498 topic_id: 35500 reply_id: 335500[/import]

Nice!

Have you checked out this?

Caleb [import]uid: 147322 topic_id: 35500 reply_id: 141189[/import]

@Caleb

I wish i would have saw that before working on my map loader. Oh well… I chose not to use the .lua output from Tiled, because I thought it would be easier to load multiple maps via JSON files rather than require-ing everything in the upfront.

BTW, I like the way you’ve handled the physics and layers properties. Very smart…

Also, since I wrote mine, I found an opensource Tiled loader for LOVE2D–a desktop based Lua game engine…

https://github.com/Kadoba/Advanced-Tiled-Loader

He has all the BASE64 and compression stuff for TMX maps and a drawing system that only displays visible tiles.

Would you want to collaborate on pulling these 3 projects together? [import]uid: 51498 topic_id: 35500 reply_id: 141200[/import]

I believe that Lime (well, the old, no longer purchaseable) version also had support for encoded Tiled output. I’ll have to root through the source files but I believe there was an OSS interpreter lua file involved (obviously not about to share owned code, but I should refresh myself on the OSS part)

no2games : Very interesting! Some questions, though:

  1. Does your code solution support culling (that is, if I feed in a large map, how many tiles are drawn roughly?)

I’m sure you saw the million-tile engine thread; I pretty much can’t use a tile engine unless it supports some strong method of culling or limited-tile use due to the crippling performance issues of loading all tiles into memory.

  1. If you only support a single tileset, what’s your basic imageGroup structure? In my (limited) tile engine coding experience it seemed fine to use multiple imageGroups so long as they were all connected by a standard display.newGroup(). [import]uid: 41884 topic_id: 35500 reply_id: 141201[/import]

@Richard9

If you want to use imageGroups to hold the tiles then you are stuck to using one tileset–that’s just how Corona works. The code will load as many tilesets as you want, but they will get stored in a “regular” group internally.

I like the way the Advanced Tiled Loader approaches it with LOVE… You set the bounds of where the map is drawn.

-- 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)  

I’m digging into that to see what the approach is.

The other thing I was thinking of was “chunking” the map. So you would request a range of tiles…

myChunk=map:getChunk(50,50,100,100)  

That would give you a display object with just 100x100 tiles starting at tile 50,50. Then you could load other “chunks” as you approached the bounds. I’d just make sure the chunks were only about 2x the display size so the would load fast.
[import]uid: 51498 topic_id: 35500 reply_id: 141202[/import]

@no2games

  1. What I meant was that you could use an imageGroup per layer. Yes, only one imageSheet can be used per imageGroup, but I believe it would be valid code to allow for each tile layer to use its own sheet and thus own imageGroup, underneath the overall displayGroup. Or is that how you implemented?

  2. The ATL solution sounds a bit like dyson’s - just load enough tiles to load onscreen and then use an enterFrame loop to update their frames based on how the camera travels. Because you’re just changing frames and not loading new tiles, CPU use doesn’t spike.

(There was a thread about this; I rolled my own tile engine using this method and it seems to work great; the only complication is that you need a table to manage where you are as the tiles hardly move.)

  1. My only concern with Love (and this is just speaking as an interested party that hasn’t tried it yet) is that they seem to have a very alien way of accessing the frame (AFAIK they have a a whole library for setting up the draw cycle, which is a lot different than Corona). Not sure how different the code is from what we would use…

[import]uid: 41884 topic_id: 35500 reply_id: 141208[/import]

@no2games:

I’d gladly collaborate on it!

I think we should do it on a thread, like this one, so that it’s completely opensource and people can see it, edit it, etc. I’ll be checking into the ATL and seeing how it works, differences between Love and Corona, whatever.

So it’d load .json maps or .tmx maps? (or both?)

Or it could even just read .lua maps - it could use my new library, S2T, to be able to convert strings to tables - not as much parsing needed.

Caleb [import]uid: 147322 topic_id: 35500 reply_id: 141210[/import]

Very cool. I agree communicating through a thread is perfect for this. We can use the GitHub I already set up to host the code repository. Do you have a github account?

I’ve been looking into the ATL code this morning. It looks like porting the code to draw the map might be a little ambitious, but the code for loading TMX maps into a table seems to be pretty straight forward. That should be an easy port. (Although I don’t know if it’s worth supporting ZIP compression for the map data since everything gets ZIPped anyway.)

Also, he’s got some good info in his comments around isometric maps. I wrote an isoGame engine forever ago, but it wasn’t quite setup like Tiled is.

How do you want to proceed? Just pick a feature and get started? [import]uid: 51498 topic_id: 35500 reply_id: 141213[/import]

1 other point guys; I see Jay is considering moving Lime to OSS. Definitely some stuff to pick at there if he does so… [import]uid: 41884 topic_id: 35500 reply_id: 141214[/import]

On the JSON vs. TMX vs. Lua front, it doesn’t really matter to me–other than the fact that I hate parsing XML (which is what TMX is based on…) However, the Tiled guys have stated that only way to make sure you are getting all the data is to look at the TMX file. Some exports don’t include everything… [import]uid: 51498 topic_id: 35500 reply_id: 141215[/import]

If Lime goes OSS, that would certainly be easier than starting all over :slight_smile:

I certainly understand wanting to sell something that you’ve spent lots of time on, but I think Corona needs two Community OSS projects–a cross-platform code editor with AutoComplete, Code hints, etc. and a Level/World builder. I think having 4 or 5 different closed sourced versions of both of these makes it hard to spin up new projects.

I think Tiled is a good choice for the latter, but I don’t think we will ever get proper Editor/IDE (especially on the Windows side of the fence.)

My $0.02. [import]uid: 51498 topic_id: 35500 reply_id: 141216[/import]

I think we should start with basic loading of maps.

So with that, either Gridmap or your loader could be started with.

.json maps seem like a good idea - if there’s already a handy json.decode function, why create a new one? :slight_smile:

I do have a GitHub account, but… I’ve never done anything with it, as I can’t figure out how to use it. You can’t, by any chance, use Dropbox?

I’ve also opened up a new thread for this:

http://developer.coronalabs.com/forum/2013/02/01/tiled-map-engine

Caleb [import]uid: 147322 topic_id: 35500 reply_id: 141248[/import]

Let’s move off to your new thread… [import]uid: 51498 topic_id: 35500 reply_id: 141251[/import]

Nice!

Have you checked out this?

Caleb [import]uid: 147322 topic_id: 35500 reply_id: 141189[/import]

@Caleb

I wish i would have saw that before working on my map loader. Oh well… I chose not to use the .lua output from Tiled, because I thought it would be easier to load multiple maps via JSON files rather than require-ing everything in the upfront.

BTW, I like the way you’ve handled the physics and layers properties. Very smart…

Also, since I wrote mine, I found an opensource Tiled loader for LOVE2D–a desktop based Lua game engine…

https://github.com/Kadoba/Advanced-Tiled-Loader

He has all the BASE64 and compression stuff for TMX maps and a drawing system that only displays visible tiles.

Would you want to collaborate on pulling these 3 projects together? [import]uid: 51498 topic_id: 35500 reply_id: 141200[/import]

I believe that Lime (well, the old, no longer purchaseable) version also had support for encoded Tiled output. I’ll have to root through the source files but I believe there was an OSS interpreter lua file involved (obviously not about to share owned code, but I should refresh myself on the OSS part)

no2games : Very interesting! Some questions, though:

  1. Does your code solution support culling (that is, if I feed in a large map, how many tiles are drawn roughly?)

I’m sure you saw the million-tile engine thread; I pretty much can’t use a tile engine unless it supports some strong method of culling or limited-tile use due to the crippling performance issues of loading all tiles into memory.

  1. If you only support a single tileset, what’s your basic imageGroup structure? In my (limited) tile engine coding experience it seemed fine to use multiple imageGroups so long as they were all connected by a standard display.newGroup(). [import]uid: 41884 topic_id: 35500 reply_id: 141201[/import]

@Richard9

If you want to use imageGroups to hold the tiles then you are stuck to using one tileset–that’s just how Corona works. The code will load as many tilesets as you want, but they will get stored in a “regular” group internally.

I like the way the Advanced Tiled Loader approaches it with LOVE… You set the bounds of where the map is drawn.

-- 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)  

I’m digging into that to see what the approach is.

The other thing I was thinking of was “chunking” the map. So you would request a range of tiles…

myChunk=map:getChunk(50,50,100,100)  

That would give you a display object with just 100x100 tiles starting at tile 50,50. Then you could load other “chunks” as you approached the bounds. I’d just make sure the chunks were only about 2x the display size so the would load fast.
[import]uid: 51498 topic_id: 35500 reply_id: 141202[/import]

@no2games

  1. What I meant was that you could use an imageGroup per layer. Yes, only one imageSheet can be used per imageGroup, but I believe it would be valid code to allow for each tile layer to use its own sheet and thus own imageGroup, underneath the overall displayGroup. Or is that how you implemented?

  2. The ATL solution sounds a bit like dyson’s - just load enough tiles to load onscreen and then use an enterFrame loop to update their frames based on how the camera travels. Because you’re just changing frames and not loading new tiles, CPU use doesn’t spike.

(There was a thread about this; I rolled my own tile engine using this method and it seems to work great; the only complication is that you need a table to manage where you are as the tiles hardly move.)

  1. My only concern with Love (and this is just speaking as an interested party that hasn’t tried it yet) is that they seem to have a very alien way of accessing the frame (AFAIK they have a a whole library for setting up the draw cycle, which is a lot different than Corona). Not sure how different the code is from what we would use…

[import]uid: 41884 topic_id: 35500 reply_id: 141208[/import]

@no2games:

I’d gladly collaborate on it!

I think we should do it on a thread, like this one, so that it’s completely opensource and people can see it, edit it, etc. I’ll be checking into the ATL and seeing how it works, differences between Love and Corona, whatever.

So it’d load .json maps or .tmx maps? (or both?)

Or it could even just read .lua maps - it could use my new library, S2T, to be able to convert strings to tables - not as much parsing needed.

Caleb [import]uid: 147322 topic_id: 35500 reply_id: 141210[/import]

Very cool. I agree communicating through a thread is perfect for this. We can use the GitHub I already set up to host the code repository. Do you have a github account?

I’ve been looking into the ATL code this morning. It looks like porting the code to draw the map might be a little ambitious, but the code for loading TMX maps into a table seems to be pretty straight forward. That should be an easy port. (Although I don’t know if it’s worth supporting ZIP compression for the map data since everything gets ZIPped anyway.)

Also, he’s got some good info in his comments around isometric maps. I wrote an isoGame engine forever ago, but it wasn’t quite setup like Tiled is.

How do you want to proceed? Just pick a feature and get started? [import]uid: 51498 topic_id: 35500 reply_id: 141213[/import]