I've spent many days googling this and still have issues with my game engine I'd like to ask about, which I haven't seen addressed before. I think the problem is that my game is an unusual combination of a completely 2D graphical approach using XNA's SpriteBatch, and a completely 3D engine (the amazing BEPU physics engine) with rotation mostly disabled.

In essence, my question is similar to this one (the part about "faux 3D"), but the difference is that in my game, the player as well as every other creature is represented by 3D objects, and they can all jump, pick up other objects, and throw them around.

What this means is that sorting by one value, such as a Z position (how far north/south a character is on the screen) won't work, because as soon as a smaller creature jumps on top of a larger creature, or a box, and walks backwards, the moment its z value is less than that other creature, it will appear to be behind the object it is actually standing on.

I actually originally solved this problem by splitting every object in the game into physics boxes which MUST have a Y height equal to their Z depth. I then based the depth sorting value on the object's y position (how high it is off the ground) PLUS its z position (how far north or south it is on the screen).

The problem with this approach is that it requires all moving objects in the game to be split graphically into chunks which match up with a physical box which has its y dimension equal to its z dimension. Which is stupid.

So, I got inspired last night to rewrite with a fresh approach. My new method is a little more complex, but I think a little more sane: every object which needs to be sorted by depth in the game exposes the interface IDepthDrawable and is added to a list owned by the DepthDrawer object. IDepthDrawable contains:

public interface IDepthDrawable
    Rectangle Bounds { get; } //possibly change this to a class if struct copying of the xna Rectangle type becomes an issue
    DepthDrawShape DepthShape { get; }
    void Draw(SpriteBatch spriteBatch);

The Bounds Rectangle of each IDepthDrawable object represents the 2D Axis-Aligned Bounding Box it will take up when drawn to the screen. Anything that doesn't intersect the screen will be culled at this stage and the remaining on-screen IDepthDrawables will be Bounds tested for intersections with each other. This is where I get a little less sure of what I'm doing. Each group of collisions will be added to a list or other collection, and each list will sort itself based on its DepthShape property, which will have access to the object-to-be-drawn's physics information. For starting out, lets assume everything in the game is an axis aligned 3D Box shape. Boxes are pretty easy to sort. Something like:

if (depthShape1.Back > depthShape2.Front) //if depthShape1 is in front of depthShape2.
    //depthShape1 goes on top. 
else if (depthShape1.Bottom > depthShape2.Top) //if depthShape1 is above depthShape2.
    //depthShape1 goes on top. 

//if neither of these are true, depthShape2 must be in front or above.

So, by sorting draw order by several different factors from the physics engine, I believe I can get a really correct draw order. My question is, is this a good way of going about this, or is there some tried and true, tested way which is completely different and has somehow completely eluded me on the internets?

  • \$\begingroup\$ You are making are this far too complex. And you need to break things up - big time. Take a big step back, look again at the design drawing board, and decide what your game needs, i.e. What major impact will it have in-game, if any? Drop the rest, and keep it simple, or you will burn yourself out on trivialities. You've the benefit of writing a 2D game, so leverage that; complex logic is rarely worth it. I suggest, to save you and us time, that you put a separate section into the top of your question to describe what you are trying to achieve. We will then help you find the best solution. \$\endgroup\$
    – Engineer
    Commented Nov 3, 2012 at 12:06
  • 1
    \$\begingroup\$ (Try to make your question concise.) \$\endgroup\$
    – Engineer
    Commented Nov 3, 2012 at 12:10
  • 1
    \$\begingroup\$ The ability to draw objects in the correct order is something my game needs, and not something I can solve by shifting the design (as far as I can see). Creatures can jump, obstacles can be varying heights... Bombs can be thrown, and all this is modeled with a 3D physics engine -- unless I want to change/remove fundamental things like this I don't think I can simplify my depth sorting problem. But point taken - I will try to rephrase the question to spend less time explaining what I've done in the past and the big picture, and focus more on my current questions. Thanks for the advice Nick! \$\endgroup\$
    – Alic44
    Commented Nov 3, 2012 at 20:21
  • \$\begingroup\$ Sure, I appreciate your position... it's just hard to see. I also mentioned all this because I had to pull out a section (final paragraph) on collision detection, which doesn't belong in a question about rendering. Apologies if the advice came across at all harsh. \$\endgroup\$
    – Engineer
    Commented Nov 3, 2012 at 20:52
  • \$\begingroup\$ No worries dude :) Thanks for your time, I should be saying. I think the last paragraph may have been about dealing with "collisions" between the Bounding Rectangles, and what to do when groups of graphics collide with one neighbor but not with each other -- in other words, it was a very specific implementation question stuck into this big, rambling, more general question. I think I've figured out an implementation to what I tried to describe above though, so later today I may just post my own solution. Is it considered ok to answer your own questions here? \$\endgroup\$
    – Alic44
    Commented Nov 3, 2012 at 21:20


You must log in to answer this question.

Browse other questions tagged .