Z-order in top-down 2d games

This tutorial is language agnostic. It doesn’t contain implementation, because it may differ a lot between different languages or frameworks. Ideas themselves are what’s the most important, I think.

Basics

So, what is z-order?
Z-order is an ordering of overlapping 2d objects. Look at the picture:
1

Rectangle B is drawn after rectangle A. The result is rectB is drawn “above” rectA. RectB is said to have higher z-order than rectA. Really simple.

Z-order in games

2

Screenshot from Legend of Zelda: A Link to the Past(Nintendo, SNES)

You can tell that Link is behind that tree. But this is actually an illusion of depth achieved by using clever z-ordering. The tree is drawn after Link, so it has higher z-order.

3
And now Link is drawn after the tree. He has higher z-order and it looks like he’s standing closer to the camera. And here’s how you can achieve the same effect.

First approach: layers

This is actually how A Link to the Past does it(I don’t know about moving objects, but it surely uses layers for static objects. You can see it yourself if you swing your sword at different positions near houses, walls etc.)

4

Layer approach

One sprite can be divided in two parts(as shown in the picture) which have different constant z-order. You draw all objects with z = 0, then with z = 1, etc.
This method works good and it’s easy to implement, but after a while it becomes hard to maintain, because every time you add a new sprite you have to divide it by parts and calculate areas which must be drawn before of after player and other objects.

And this can get quite complicated with lots of objects. And what about moving objects? If some enemy is circling around you, how can you find out who must have higher z-order?

Second approach: dynamic z-order

This is where it gets smarter. First, let’s look at collision bounding boxes:

5

Look at the Link’s bounding box. Its lowest Y coordinate is higher than tree’s and that’s why Link is drawn after the tree. And look at another situation. Now lowest Y coordinate of tree is higher, so you draw it after Link.

6

So, that’s what you do:

Sort all objects(or sprites) visible on the screen and sort this list by (boundingBox.top + boundingBox.height) value from lowest to highest and then draw objects in this order.

If some object doesn’t have boundingBox, you can think like its boundingBox.top + boundingBox.width equals 0. 

Complex objects

Drawing something like arcs is trickier. It requires you to use two bounding boxes for each column. And how do you deal with the part which is above player?
You need to use z axis for this. “Z” has nothing to do with z-order in the context. It tells you how far from the ground is boundingBox of an object(z = 0 is ground level). Here’s how the arc can be separated:

7

The algorithm is the same, but now you can sort by lowest Y coordinate for each Z and then combine them in one list sorted by Z. You’ll get something like this:

objects = {

link, (z = 0, lowY = 64)

column_a, (z = 0, lowY = 100)

column_b, (z = 0, lowY = 100)

topPart (z = 1, lowY = 80)

}

So arc will consist from three parts and each will be drawn in needed order.

Separating by z axis is actually very useful, because, for example, objects with higher z value don’t have to be checked when you check collision with objects but that’s another thing to talk about. ;)

Final words

And that’s all I have to say about z-order. I hope it’s not very confusing. :)

Your feedback is welcome at eliasdaler@yandex.ru

9 thoughts on “Z-order in top-down 2d games

  1. So, if i got it right, the z-axis is a sort of gitan layer right ? It’s a sort of array of plan (ground, aboveGround etc …) ? Thanks for your tutorial, it was interesting ! :)

  2. Hello, thanks for the tutorial c: But I was wondering… isn’t sorting too slow/consuming? I mean, if I have a 200×200 tilemap with several objects each tile, it would propably lag a little bit, wouldn’t it? Do you know any other method that is more eficient than sorting a whole list of sprites?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s