Isometric Tilemap + Loads of Sprites - Anyone with experience that could give some advice?

Hello!

We’re building a game for multiple platforms using cocos2dx and marmalade. The game is using isometric tilemap (2-3 layers) and a rather large amount of entities that has to be moving through the layers. (up to a few hundred objects on the screen at the same time excl the tilemap).

I would like to know if anyone has done this previously here and can offer some advice on how to handle the z-sorting?

This is the idea I am going to attempt:

  • Render Background - Z-order (no depth buffer)
  • Enable Depth Buffer
  • Render ContentLayer with Z-sorting (depth buffer enabled).
  • Disable Depth Buffer
  • Render HUD

Does this seem to make sense?

I guess there’s no rights and wrongs here, but I figured maybe someone has done something similar and could share some advice :slight_smile:

Best
Anton

I use vertex z, draw order, depth test, alpha test shader, and 2d projection to achieve isometric rendering.

The following is required in app delegate:

pDirector~~>setDepthTest;
pDirector~~>setProjection(kCCDirectorProjection2D);

Your sprite batches will need the following shader:

batch->setShaderProgram(CCShaderCache::sharedShaderCache()>programForKey);

Now simply use sprite>setVertexZ(z) to change the order in which objects are drawn.

When using multiple batches it is best to have the actual draw order set to be similar to the vertex z order.
For example: background batch first, scene batch second, and hud batch third.
The reason for this is because small slightly visible transparent outlines can occur if the actual draw order doesn’t match the vertex z order. Hope this makes sense. =)

Explaining (sorry for my bad English translation)

“Rendering” of sprites / tiles isometrically is a little more complicated than the process explained. The “explained” serves as a working basis and for scenarios where “no sprite” is above / below another (the sprites are just front or back at the same level). In this case the algorithm is clear: follow the drawing order +(Z-X).

But what happens when I have floating elements to a level/height Y?

a-) If the sprites are placed on top of other sprites exactly without overlapping/intersecting with any of them (on the Y axis), the order can be used paint +(Z-X)-Y.

b-) If the sprite “intersects/overlaps” more then 1 sprite simultaneously (in X, Y and/or Z) WE HAVE A PROBLEM: In what order will draw them?. Then we need a complex sorting algorithm to determinate the order. Not to mention when we have “a lot of” floating sprites to be “integrated”.

I, after a long analysis (and much suffering), was able to implement an algorithm. I would never have imagine complexity (honestly I thought it will be easier) of this “affair” and I went

finding as I started developing my first game in cocos2d-x 2.5D. An algorithm of this type requires, in the first instance, a "comparison “everything with everything” but is possible to make a lot of optimizations for reducing calculation process so much.

An example (demo) of the algorithm result can be seen here:


Refering to large amount of objects I suggest you classify every object as:
1)- “below-able/back-able”, and
2)- “the other ones”.
You only need:

  • processing algorithm for 1) and drawing this ones
  • draw 2) ones

You’re on the right track. We had to hack around the TMXTiledMap quite a bit, though hopefully the latest code is now solid.

We have a game with similar requirements. 3 layers, 10-100 entities that can move through layers. I did look into rendering the same as your idea and only use depth buffer for the tilemap and entities and HUD, but in the end we just decided to specify the Z coordinate for every Node. We have been able to keep 60 fps on most hardware.

NOTE: you might need to add a small offset to prevent Z-fighting:
entity->setPositionZ( tileMap->getVertexZ( Vec2(2,2) ) + 0.1f);

I’d love to go back and try separating the layers without depth buffer, though that would probably be for a next project. So would love to know or hear if you figure out the cocos2d and shader code to achieve your idea.

A side-topic question for you, if you don’t mind. What are you using Marmalade for specifically? Does it further help with cross-platform? Does it provide the extras outside core rendering like social, IAP, analytics, networking, etc? Just always been curious why I’d go use Marmalade. Is it for their build system or workflow? I’ve downloaded and read sample code and tutorials a handful of times, still don’t fully get it, unless you use it instead of cocos2d-x.