//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
출처: https://eliasdaler.wordpress.com/2013/11/20/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:
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
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.
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.)
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:
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.
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:
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. :)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
'프로그래밍 관련 > 3D,2D DRAW 관련' 카테고리의 다른 글
DirectX, OpenGL 텍스처 필터링 ( Texture Filtering ) 관련 (0) | 2020.09.10 |
---|---|
[3D프로그래밍] 클리핑 관련 (0) | 2018.06.25 |
OpenGL Shader를 이용해 YUV 420 포맷 색상을 RGB로 변경하기 (0) | 2017.08.18 |
OpenGL Stencil Buffer의 사용법 (0) | 2017.08.18 |
OpenGL glPolygonMode()와 glCullFace() (0) | 2017.08.18 |
댓글 영역