Tiled Map Engine

Thank you very much, I ran it and it looks great, I’ll try to fiddle with it when I have time. [import]uid: 215209 topic_id: 35538 reply_id: 144752[/import]

Ok, I’ve finally finished v0.1 of Quartz Tile Renderer. And below is it rendering the city map - it’s not culling anything, it’s just building the entire map.

 

It’s going so fast because there’s only one tileset. With only one tileset, image groups are available. It’ll still work with multi-tileset maps, only it won’t be so fast.

 

If you can get Quartz to be able to do auto-culling (with the .draw and .erase functions), that would be the best solution. There could be an “autoCull” parameter that sets whether it culls the map automatically or not. I’m still working on that.

 

https://www.dropbox.com/s/9fo5r79z466pj31/QTR%20Example%202.zip

 

C

@no2games:
I’ve just finished v0.0 of Quartz Tile Renderer - it just renders maps, no physics, values, or anything else. However, it does use an extremely fast method of culling. It’s based on a post months (years?) ago about culling; it changes the image on tiles instead of moving them one by one. That way you only render the amount of tiles needed. The culling isn’t customizable, it just culls to the screen size. However, custom culling shouldn’t be too hard to add.

The thing that I really want to add is rendering only the tiles that exist. As is, for each layer, Quartz is rendering visible width*visible height tiles per layer - if you only have one real tile on a layer, it still renders every one possible. So a map with 32x32 px tiles on a 1024x768 sized device, even if only one tile is displayed, will render 33x25 tiles (one more in both dimensions) or 825 tiles. That’s a lot of tiles, and with a lot of layers, it can get slowed down. Here’s an example, along with the Quartz renderer.

I like the name idea, too. Ceramic can be the name of the entire library, and each component can be one of the names you mentioned. I’m calling this rendering library “Quartz” because it’s pretty, but not worth much :slight_smile:

@cjc83486:
Are you going to be a tester, or a co-creator? Either one is fine. I’m just curious.
Caleb [import]uid: 147322 topic_id: 35538 reply_id: 144818[/import]

Caleb- Most likely test, though here and there I may add additional features in which I’ll definately post incase you guys want to add them. As far as actual development I dont think with school, work, and my current project that ill have time to make a huge contribution, just small additions. Haha you guys definately make it hard to say no though with how well it is turning out. I love the way you are optimizing the maps with culling and visible display area. I was thinking the same thing about the latter :).

No2games- Have you been making sure that all the points are in a clockwise rotation? If the problem keeps persisting maybe the easiest thing to do is just make polygons and triangles out of multiple line objects. Im away from my computer currently (typing on phone) so i dont know how tiled is outputing a polygon’s points. However, if it lists it in the order a person places the points in tiled, then you can play connect the dots with line objects. This will overcone corona’s restriction on non-convex polygons and a limit to 8 sides. :slight_smile: This will make a polygon with no inside however… But may be useful still for what we are doing.
[import]uid: 215209 topic_id: 35538 reply_id: 144866[/import]

@Caleb,

Good first effort on Quartz, I can see the concept, but I think you should load 2x or 4x the number of tiles vs. the screen size. I was only seeing 20fps in the windows simulator and 10 to 15fps on my old iPad while scrolling, and I think it’s all in that map.move() function.

I think if you loaded enough tiles to cover a full scroll in all directions (so 4 * w,h) and let the person move the map display object normally, then on release call map.update() you wouldn’t even notice the update() function happen.

That should be easily 60fps with a minor hiccup on release that you could then optimize the crap out of.

Just my $.02 :slight_smile: [import]uid: 51498 topic_id: 35538 reply_id: 144881[/import]

@Curt

I didn’t know that the points needed to be clockwise… That would make sense. I found this code on stack overflow to order points in that way…

function appSortPointsClockwise(points)  
 local centerPoint = appGetCenterPointOfPoints(points)  
 app.pointsCenterPoint = centerPoint  
 table.sort(points, appGetIsLess)  
 return points  
end  
  
function appGetIsLess(a, b)  
 local center = app.pointsCenterPoint  
  
 if a.x \>= 0 and b.x \< 0 then return true  
 elseif a.x == 0 and b.x == 0 then return a.y \> b.y  
 end  
  
 local det = (a.x - center.x) \* (b.y - center.y) - (b.x - center.x) \* (a.y - center.y)  
 if det \< 0 then return true  
 elseif det \> 0 then return false  
 end  
  
 local d1 = (a.x - center.x) \* (a.x - center.x) + (a.y - center.y) \* (a.y - center.y)  
 local d2 = (b.x - center.x) \* (b.x - center.x) + (b.y - center.y) \* (b.y - center.y)  
 return d1 \> d2  
end  
  
function appGetCenterPointOfPoints(points)  
 local pointsSum = {x = 0, y = 0}  
 for i = 1, #points do pointsSum.x = pointsSum.x + points[i].x; pointsSum.y = pointsSum.y + points[i].y end  
 return {x = pointsSum.x / #points, y = pointsSum.y / #points}  
end  

I will try and add that in this week… [import]uid: 51498 topic_id: 35538 reply_id: 144882[/import]

Oh, and BTW (I know this is 3 posts right in a row) I’m in love with the names, and I like the idea of breaking out the different renders to keep the overall project from getting too complicated. Here’s how I see it working…

require ("ceramic") -- object physics and rendering to display object  
require ("quartz") -- rendering/culling engine for large maps  
require ("marble") -- some cool other feature, maybe random map generation  
etc  
etc  

all of these libraries would require the tiled.lua core that could share the loading/savinging/ect. [import]uid: 51498 topic_id: 35538 reply_id: 144884[/import]

Awesome, glad that was the case, I can’t wait to use it, though unfortunately I have 3 midterm tests this week, a quiz, and a lab, so I’m a bit full. So question, does CoronaTiled currently only load in object layers or does it load in tiles as well at the moment? I know you guys plan to eventually make it into two separate parts, but just asking for the current version.

Thanks a ton guys, your work is amazing, once the word gets out I’m sure a ton of people will be using it. [import]uid: 215209 topic_id: 35538 reply_id: 145019[/import]

@no2games:
Should have said potentially extremely fast :slight_smile:

From working a bit more on it, I think I’ll keep that for now. I’m attempting a new method of culling, just to see which is the easiest/cleanest/fastest. Now I’m going to try removing and adding tiles offscreen and onscreen. So I’ll see which is fastest.

C [import]uid: 147322 topic_id: 35538 reply_id: 145060[/import]

FYI: I pushed some bug fixes out this morning…

@ Caleb

Potential performance vs. actual performance :slight_smile: That gets me every time.

@cjc83486

Yes, the code in the link above does all this…

  • JSON/LUA exported map files
  • Multiple Tile Layers
  • Multiple Tilesets
  • Margins and spacing
  • Uses Corona Image Maps and Image Map groups if you limit yourself to a single tileset image
  • Object types (regular, polygon, line)
  • Image Objects
  • Physics and display object properties
  • Image Layers

It’s pretty much good to go to build a full game. In fact, I was going build a quick clone of a Labyrinth-style game using Ceramic/Tiled as an example. I figure it would be about 150 lines of code tops. [import]uid: 51498 topic_id: 35538 reply_id: 145068[/import]

Hey Caleb, 

 

I’m finally getting to the culling part of my game and (as you have seen) is quite a challenge.  So I took a quick look at your quartz Tile renderer.  

 

Currently, what I’m using for my game is CoronaTiled by no2games for objects and tiles, and Perspective (it put a grin on my face when I saw) by you.  

(I was using my own camera function with scrollviews before, but the scrollviews kept consuming my touch events, so I decided to switch to Perspective which is pretty solid and works the same or better of what I made, but wasn’t having touch event problems.)

 

Anyway, I looked through it and I couldn’t get it to load a map right away, I found that it was only the tileset file having a directory not from my computer.  I just removed the extension and made it “open_tileset.old.png” as shown:

 "author":"Silveira Neto" }, "tileheight":32, "tilesets":[ { "firstgid":1, "image":"open\_tileset.old.png", 

&nbsp;



After that I noticed it had a whole bunch of gaps between the tile (especially when scrolling). &nbsp;I'm not sure if this is just me or my computer or what. &nbsp;I saw that your fps is 60 on the Corona Simulator but about 15 on IOS iphone simulator. &nbsp;Is this just me? &nbsp;I never know it's me or the code.. &nbsp;Here is a screen shot:



![ScreenShot2013-03-17at11448PM.png](http://i1110.photobucket.com/albums/h455/cjc83486/ScreenShot2013-03-17at11448PM.png)



&nbsp;



For my game I use a config file that seems to fix the sizing and gaps in the tiles (for Iphone, iphone 4, and Iphone 5 at least..) &nbsp;I can quick send/post it if you are having these spaces as well. If you aren't, do you have any idea why I'm getting these gaps using the same code you are?



&nbsp;



Anyways, when I use my config file it looks great and renders about the same (60 on corona, 15 on iOS). &nbsp;I know that with culling by not loading the entire map it should work way faster. &nbsp;Also with my config file, it makes the tiles larger, so thus I assume with culling it would work slightly faster because it has less tiles to load per width and height of screen.



&nbsp;



Oh, one last thing Caleb, I was wondering how we were going to integrate both Quartz and Ceramic (CoronaTiled)? &nbsp;Are you guys going to eventually merge the code, or will the user have to somehow combine the two? Also, for culling, I was wondering since you created Perspective, if that would be the best way to go about culling. &nbsp;Since it already has a camera function built in, you could make it so anything out of the screen on the scrolling layers were removed/purged. &nbsp;I don't know if that makes it easier or adds complexity though.



&nbsp;



Thanks!



&nbsp;



-Curt

no2games:

Hey I’ve been looking over your code and trying to incorporate it into my game, however, it seems that if you try to use more than one tile set it doesn’t work? I don’t know if you meant to make it that way or if it is a bug?

-Curt [import]uid: 215209 topic_id: 35538 reply_id: 145485[/import]

It should load as many tilesets as you put in, so it’s probably a bug. (However, using a single tile sheet makes for faster map rendering…)

Can you make a map that breaks and post it out on a dropbox link?

[import]uid: 51498 topic_id: 35538 reply_id: 145553[/import]

I’ve worked on Quartz a bit more, and, instead of automatic culling, it now has a more customizable memory saving method. I’m not quite finished with it, so I’ll probably post it up tomorrow. Here’s a teaser, though:
[lua]
function quartz.render(mapFile, x1, y1, x2, y2)
[/lua]

C [import]uid: 147322 topic_id: 35538 reply_id: 145554[/import]

@Curt,

I added a second tile layer to the demo.tmx file and it seems to be working fine, but I don’t know if i fixed some other bug that made it work, so I pushed a 0.3 release out to GitHub.

So re-grab the files and see if that works. If it doesn’t send me your map and I will debug it. One other thing, I try to strip all directory info from a tilemap, so the .json file and the .png file both need to be in the root directory for now. Also, the tilemap image files can’t have any other slashes, hyphens or periods in them.

@Caleb,

Sounds good. So are you using the Map Loading function that I’m using, or are you doing your own? I was thinking about breaking out the Map Data+Physics+Properties into a separate call so you passed the structure to the renderer. That way for small maps you could call Ceramic as the renderer and for large maps Quartz.

I still need to spend a few hours renaming everything to Ceramic and making a screencast.

By the way, I found a good and complicated TiledMap with 8 layers and plenty of tiles here…

https://github.com/silveira/openpixels/tree/master/examples/tiled

This renders at about 25FPS on my iPhone 5, so it would be a good benchmark for you renderer. [import]uid: 51498 topic_id: 35538 reply_id: 145557[/import]

Firstly, gaps between tiles. I’ve found that it doesn’t happen if the device vs. screen size is the same. So a 320x480 config.lua file won’t have gaps on an iPhone simulator - but it will on an iPad simulator. And a 1024x768 config.lua won’t have gaps on an iPad simulator, but it will on an iPhone simulator. I don’t know what’s causing this.

 

Secondly, FPS. Culling will come. That’s all I can say. But, I had no idea it would go so slowly on the iOS simulator… I expect it’ll be about the same on device. Oh well. I wonder why it went so fast in the simulator…

 

Thirdly, Quartz and Ceramic will, in the end, be in the same library - probably named something straightforward like “CoronaTiled”. You’ll render maps and object layers with CoronaTiled, which will, in turn, use Ceramic and/or Quartz to build the map. I’m not exactly sure how that’ll work at the moment, but we’re not at that point yet.

 

I’m thinking that I’ll use my own camera function for Quartz. Using Perspective will, in my opinion, simply expand the library into a bigger one - I think it’ll be easier just to make a simpler, independent, tile camera.

 

Anyway, you’re a big help with debugging and feedback :slight_smile:

 

C

It seems putting the .png files in the root directory was the solution. I had them in a subfolder before. Can they not be in a subfolder when you publish it with apple, or is it just something you currently have on the back burners?

Thanks a lot for the help though.

**Edit**

I got the object layer to work, however I found a bug when using .lua files and not .json, it seems the ellipse renders as a box and not an ellipse? Weird, I didn’t look into it too much and just exported my file as a .json instead. [import]uid: 215209 topic_id: 35538 reply_id: 145624[/import]

@No2Games:
Quartz doesn’t do automatic culling - yet. Right now it loads “chunks” of the map, which can be added to or removed from the entire thing. Here’s how you use Quartz:

[lua]
local thisMap=quartz.render(“thisMap.json”, 1, 1, 32, 24) --> Only render a “chunk” specified, if no dimensions it renders the whole thing
thisMap.draw(32, 24, 33, 25) --> Add to the drawn “chunk”
thisMap.erase(32, 24, 33, 25) --> Remove from the “chunk”
[/lua]

I believe culling shouldn’t be too hard… some sort of a function that adds to one side and erases another when it’s moved. The problem is, I’ve not figured it out. I’ll keep at it, though :slight_smile:

[EDIT]: I’ve already found a bug in the “draw” and “erase” functions… So it’s not quite finished, it would appear :frowning:
[EDIT 2]: I’m just going to take it down, for now. I’ve found quite a lot of bugs - just after I made it public. So I’ll work on it a bit more.

C [import]uid: 147322 topic_id: 35538 reply_id: 145636[/import]

Ok, I’ve finally finished v0.1 of Quartz Tile Renderer. And below is it rendering the city map - it’s not culling anything, it’s just building the entire map.

 

It’s going so fast because there’s only one tileset. With only one tileset, image groups are available. It’ll still work with multi-tileset maps, only it won’t be so fast.

 

If you can get Quartz to be able to do auto-culling (with the .draw and .erase functions), that would be the best solution. There could be an “autoCull” parameter that sets whether it culls the map automatically or not. I’m still working on that.

 

https://www.dropbox.com/s/9fo5r79z466pj31/QTR%20Example%202.zip

 

C

@Caleb-

The camera function doesn’t really matter to me, but I really like how you did the layers in Perspective. It is a pretty solid camera library!  But I trust you’d make about the same quality either way, so I was just trying to save you some time. :slight_smile:

Culling-  It’s kind of crazy but I’m actually at that point where I’m looking at performance of my game engine.  So far for testing I’ve taken my characters and objects out to see if they are causing a lot of lag, but it seems its more or less the map engine (on my computer it is fine, but if I try to screen record my Corona Simulator or put my game on iOS Simulator, the performance suffers significantly).  This makes sense, because I’m rendering an 11 layer 96x80 tile sized map with 2 pretty big tile sets.  Do I actually need that big of a map/level?  No, but I feel with culling we should hopefully be able to run this at least at 30FPS on the phone.  With culling, map size shouldn’t really make a difference, the performance really would only be affected by the number of layers and tilesets used, correct?  I’m not sure how your guys’ map engines deal with empty tile spaces currently (with multiple layers that don’t use every tile this might be something to look into).

Anyway, I really like your Draw and Erase functions!  Actually, if that was in Corona Tiled right now, I think a lot of my lag would vanish.

@no2games-

I was thinking about culling, and I was wondering how we are going to be handling objects(and physics objects) that are off the screen?  It is basically under the same realm of culling a tile map, are we going to add them when they are close to the display or are you going to leave that up to the user?