Jump to content

Isometric plugin performance tips?


laurie
 Share

Recommended Posts

I have a simple prototype that, so far, just has a tilemap using lewster's isometric plugin and a "hero" character with animations (admittedly a lot of animations...). I loaded it up on an iPad Air and was taken aback to see only 2 to 4 frames per second :-/ On a hunch, I reduced the map size from 100x100 to 10x10 and boom, 60 fps.

 

The tilemap is built just like the pointer interaction example (http://rotates.org/phaser/iso/examples/interaction.htm). Commenting out the pointer interaction code didn't help frame rate at all.

 

Is this expected performance? Are there things I can do to improve it? For example, can layers that should always depth-sort behind anything else be rendered once on start and cached? Can I do better (performance wise) than one IsoSprite per tile? Are there Sprite/IsoSprite features I can disable to help performance (for example, turning off pointer tracking or other on-by-default event checks?

 

A 100x100 tile world may prove larger than I need when I get to the level design stage, but probably not by an order of magnitude...

 

Thanks,

 

Laurie

Link to comment
Share on other sites

With a 100x100 map you're rendering 1000 sprites, which will be taxing with or without the Isometric plug-in, especially if you're not using a texture atlas. Things would probably improve markedly if you were using a texture atlas - though I'm not sure if you're doing so already or not. That example doesn't depth sort, so I'm assuming you're not depth sorting either, but yes, the optimal way to do this kind of thing is to have separate groups to act as 'layers' for objects which do not need to be depth sorted against one another. In your example you'd probably want a single group for your floor tiles, then another group on top with your character and any objects the character can walk behind or in front of (walls, other characters etc) and then depth sort that group only.

 

As for the rendering of the world itself - this is where the plug-in currently falls short, as it doesn't have a fast method of handling large scenes a la Phaser's Tilemap system. What's needed is a way to render just the on-screen portion of an arbitrarily sized tile-based scene using just as many IsoSprites as are necessary to fill up a single screen, then when the camera moves, the IsoSprites on screen are moved, killed and recycled as necessary. See this for a visual demonstration of the technique: http://www.tonypa.pri.ee/tbw/tut19.html 

 

I've not yet decided whether I'm willing to go this far and add an isometric tilemap renderer, as it's a lot of work and extraneous to the needs of the game I'm working on (which is where the plug-in originated) but I'm happy for anyone else to have a go :)

Link to comment
Share on other sites

No texture atlas, just a single tile image as in the example, and no depth sorting yet either. I took out the code to track pointer position and highlight the tile under the pointer, too, which gave a small increase in fps -- and more importantly, makes the set of floor tiles static (i.e. no rendering changes at run-time). In theory I should be able to render that layer into an image at startup, and just render the static image instead of the set of IsoSprites; I was hoping I might be able to add the iso sprites to a group, set a flag on the group, and have Phaser handle that optimization for me ;-) 

 

Using a pool of sprites to render just the visible portion of the map certainly makes sense, especially for large maps. Optimizing the size of the borders outside of the visible region to accommodate smooth scrolling (i.e. no glitching as sprites are shifted in at the edges) should be straight forward; the border size would probably need to be larger for drag-scrolling maps, smaller for game where the viewport moves more slowly. 

 

In the absence of other built-in optimizations, a renderer like that is probably what I'll try next. I'll be sure to make it general-purpose enough for reuse and make it available if I get something working well.

 

Thanks for the insights,

 

Laurie

Link to comment
Share on other sites

Phaser (or rather pixi, its underlying rendering engine) does have a feature such as you describe, group.cacheAsBitmap = true will flatten any display object hierarchy into a single texture (it uses a RenderTexture internally) however it's not entirely perfect and I've often noticed problems when using it such as it not allowing you to turn off smoothing and glitchy inaccurate flattening, but it's worth a try. It will however probably eat up a ton of memory on a 100x100 isometric scene, so be wary of that!

Link to comment
Share on other sites

Ah-ha, I thought I'd seen mention of such a feature somewhere! ;-) Good point about memory use (though that depends on tile size of course). I guess I'll have to test to see if the memory use cost outweighs the performance cost without caching. Probably the optimal thing to do would be set up the iso sprite group, extract the resulting RenderTexture, then replace the whole group with an image backed by that texture. But for larger maps, I suspect your other suggestion of dynamically moving around just enough iso sprites to fill the viewport is going to work out better.

 

L.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...