How do I Isometric Z Ordering?

Get help using Construct 2

Post » Wed Apr 29, 2015 1:29 pm

So I'm having a bit of a problem with Z Ordering when it comes to an Isometric game I'm working on. For the most part it is working, but I have issues when interacting with certain shape objects. Such as objects that are long and on a diagonal or objects that aren't shaped like a box. Right now I'm using a ZOrdering based on the Y of the player and the buildings. Does anyone know of a better way to do this, I figured If I knew Trigonometry maybe there would be a solution, but I don't. I'm looking online for other solutions and if I find one I'll post here.

The Player is the red cube you can move him with the arrow keys.

.CAPX ... Order.capx

I have some plugins in my Construct, but I'm not using them in the .capx, so hopefully it should open.
Posts: 201
Reputation: 4,471

Post » Wed Apr 29, 2015 1:54 pm

Hey @VictoryX, :)

Filmation math
This is one of the best explanations I've found for a general approach to Z ordering objects for isometric rendering.

Isometric depth sorting ... h-sorting/
This dev blog article walks through implementing and optimizing isometric Z ordering for a game targeted at mobile devices.
It actually links to the first article, but this one spends more time talking about the actual code, pitfalls, and making it efficient.

My isometric demo capx
(see my 1st and 3rd post for details. 3rd post has capx.)
Finally, here's a reply post I made a little bit ago, for some one asking about jumping in isometric games.
I built a simple isometric demo capx, which you can download there.
Granted I'm using a simpler Z ordering system than is described in the above articles.

Example image:
Posts: 323
Reputation: 6,021

Post » Wed Apr 29, 2015 2:33 pm

Thanks for the post. As far as the first link goes the math is over my head. If someone understands it and could break it down for me that would be awesome. As for the second and third links they seem to be working with cube objects exclusively. My current setup works with cube objects, what I'm having trouble with is oddly shaped objects.
Posts: 201
Reputation: 4,471

Post » Tue May 05, 2015 5:21 pm

Hey again @VictoryX, :)

Since it sounds like you're working with objects that are more complex than perfect 1x1x1 cubes, I think what you're looking for is the approach described in the Filmation math article.

The math can look a bit daunting, but fortunately it's actually not too bad if you break it into parts.

There are really only 2 main mathy things going on in the article, "Positioning objects on screen" and "Z ordering objects".

Firstly consider that an Isometric world represents a 3D space, with its own X, Y, and Z coords.
However, your computer screen, (your Construct2 "layout"), is a 2D surface with only X and Y.

(From here on, the 2D X and Y axes will be referred to as Xp and Yp, to match the article)

In the article, this image shows the 3D coord space, labeled X, Y, Z (three central arrows),
and the 2D coord space, labeled Xp, Yp (two arrows at left and bottom. And notice that Yp points up NOT down).
I'll explain what the "(x0,y0)" is later.

First super important thing to notice is that the 3D coord axes and 2D coord axes have some similar looking labels,
X vs Xp, and Y vs Yp,
but they are NOT the same thing.
For instance, the isometric 3D Y axis points towards the bottom left of the screen, but the 2D Yp axis points upwards towards the top of the screen.

With that in mind here come the mathy parts...

Positioning objects on screen
Firstly we'll need to decide where the origin of our 3D space (0, 0, 0) will appear, on the 2D screen.
In the image above, the 3D space origin (0, 0, 0) is in the middle of the image, and it is labeled "(x0, y0)".

But why is the 3D origin point labeled with 2D coords in that image?
Well, it's a point in 3D space, but it's also a point on the screen.
So it would be technically correct to label the point with both 3D and 2D coords, such as (0, 0, 0) & (x0, y0).

It might not be obvious at first, but the 2D coords (x0, y0), are actually variable names, NOT x times zero or something.
(x0, y0) means ( The Xp coord of the 3D origin , The Yp coord of the 3D origin ).

So, if we had a 2D display area that was 600 pixels wide by 400 pixels tall, and we decided to position the 3D origin dead center in that 2D display area, then the 3D space origin (0, 0, 0), would appear at the 2D coords (300, 200).
So in this example, in the above image, the "(x0, y0)" label, x0 would equal 300, and y0 would equal 200.

So suppose we put an object, a cat, in our isometric world.
Our isometric world is a 3D space, so in order to properly place this cat, in 3D space, we need to specify an (X, Y, Z) coord for it.
Lets make things easy, and put this cat at (0, 0, 0). This places it at the origin of our 3D universe.
Which is how you keep cats happy.
So we know where the cat is in the 3D universe, but we don't yet know where it should show up on our 2D screen.
We don't yet know what the cat's 2D display position is, its (Xp, Yp) coord?

Okay, so we actually do know where the cat should appear on the screen, in this very special case, because we placed the cat at the 3D origin, and we set the 3D origin to appear at the 2D screen coords (300,200). But we don't yet know how to *CALCULATE*, from the 3D world coords, where the cat should appear in 2D screen coords.

This is where the first of the mathy parts comes in:

The article gives us the following formula for converting 3D world coords to 2D screen coords.
(x,y,z) ( x0 + √3 x/2 − √3 y/2 , y0x/2 − y/2 + z )

And before it does anything else, the article says, screw that formula, it's too hard, and doesn't fit pixel art very well, so use this simpler formula instead.

(x,y,z)( x0 + xy , y0 x/2 − y/2 + z )

The catch is, the simpler formula will squash things vertically (on the 3D Z axis) just a little bit. But that's okay, because now all the diagonal floor tiles will have their seems running along the 3D X and Y axes, making them 2-to-1 pixel diagonal lines, which is much easier to draw in pixel art than 30 degree lines.

Lets try this simple formula on our cat and see if the result makes sense.

Recall that x0 and y0 are the 2D screen coords we placed our 3D origin at. In our case,
x0 = 300
y0 = 200
and our cat is at,
(0, 0, 0)

(x,y,z)( x0 + xy , y0 x/2 − y/2 + z )

(x,y,z)( 300 + xy , 200x/2 − y/2 + z )

(0,0,0)( 300 + 00 , 2000/2 − 0/2 + 0 )

(0,0,0)( 300 , 200 )

So our cat should be displayed at 2D screen coords (300, 200), which makes sense, because that's where we placed the 3D origin, and we placed that cat at the 3D origin.

Now what if we place a meatloaf at 3D coords (0,0,1), directly above the cat in the 3D space Z axis?

(x,y,z)( x0 + xy , y0x/2 − y/2 + z )

(x,y,z)( 300 + xy , 200 − x/2 − y/2 + z )

(0,0,1)( 300 + 00 , 2000/2 − 0/2 + 1 )

(0,0,1)( 300 , 20000 + 1 )

(0,0,1)( 300 , 201 )

So the meatloaf is displayed a little higher on the screen than the cat.
(Remember that in this article screen Yp points up NOT down. This is not mandatory for isometric graphics or anything, you can tweak the math to make screen Yp point down if you need it to, which you probably will, since Construct2's screen Y axis points down.)

Z ordering objects
The second of the two mathy parts.

In the article, this part begins in the paragraph right after the simplified expression:

"But there is one detail left: if an object A appears behind B, we must draw A before we render B."

And this is true.
So if object A and B are rectangular solids, and aren't necessarily cubes we need to know where they are and how big they are in 3D space.
For each of these two objects we can describe their position and size with two points.

How can we describe a 3D cuboid with two points?
Well, consider when you are selecting a bunch of files on your desktop, and you click and drag a rectangular selection box.
The start point you clicked and the end point you dragged to are two points that describe the size and position of that selection rectangle.

Similarly, you can describe 3D rectangular solids by specifying 2 points, like a start and end point for a 3D selection box.
For instance, imagine drawing a rectangular selection box flat on a desk, but then dragging the end point up off the desk, to raise a rectangular prism up out of the desk surface, like a sky scraper.

In the article, object A is described by two points expressed as (xA,yA,zA) and (x'A,y'A,z'A).
Notice the single quote marks in the second point, these single quotes are usually read as "prime", so that x'A would be read as "x prime A". Basically it's just a way of distinguishing starting x from ending x', that's all.

Anyway, object B, as you might guess, is expressed as (xB,yB,zB), (x'B,y'B,z'B).

Finally, the article tells us that the start point must be the far vertex on the cuboid, and the end point is the near point on the cuboid.
Though the article puts it in mathematical terms as seen below.

xA < x'A,
yA < y'A,
zA < z'A.

All that's left is the actual calculation to determine if two objects overlap, and then if they do, which is on top.
At this stage the process basically is just some greater-than, less-than style math, so the hard part (conceptually following what all the coordinates represent) is pretty much already out of the way.

I hope that helps out.
Sorry for the monstrous post. :)
Posts: 323
Reputation: 6,021

Post » Tue May 05, 2015 5:31 pm

@fisholith if by 'monstrous' you mean 'awesome', then thanks!
Posts: 1,154
Reputation: 15,003

Post » Tue May 05, 2015 5:57 pm

@fisholith thanks for that explanation its very helpful
Posts: 174
Reputation: 10,212

Post » Tue Sep 15, 2015 5:44 pm

I'm a bit late to the party but your example and explanations are really cool and exactly what I was looking for, Fisholit, thanks.

I don't know if you're still around but I've tried to add some more blocks with a different heightZ to your demo.
The jump part works ok but I can't figure out how to z-order that stuff correctly.

Here is the capx:

Your hack Image
doesn't do the trick anymore for the higher blocks obviously.

I hope you or anyone can read this and help me to fix this out.

Posts: 31
Reputation: 1,409

Post » Wed Sep 16, 2015 7:18 pm

That hack is what's refereed to as absolute isometric sorting, which as noted works if most of the blocks are on the same level and if they're mostly the same size.

For the general case you'd need relative isometric sorting, which is done with a topological sort.
I just posted a behavior that does that, or if you're interested in the logic behind it done with events, look at the iso_test2.capx in that topic.
Posts: 5,235
Reputation: 67,756

Return to How do I....?

Who is online

Users browsing this forum: el3um4s and 10 guests