Z-sorting has been, in my experiments, been based on the Y value of a given Sprite object. It’s the sorting mechanisms have been specifically explored rather than the logic that they were arranged.
In this post I want to describe an alternate method to sort using collisions.
This method was developed to solve the issue of complex graphical elements. By ‘complex’, this refers to images that are possibly concave, or elongated. In previous z-sorting implementations, the Sprites being sorted needed to remain within a given Tile area in order for the Y position to be specifically determined for that graphic element to be properly sorted. So what I aimed to do is to overcome/get rid of the limitation that forced discrete graphical elements to remain within one Tile.
Consider the image below.
Note the elongated ‘wall’ and the L-shaped wall, both of which implicitly extend beyond one Tile area. The goal here is this: given these irregularly-sized/shaped elements, find a way to determine whether the character Sprite should be sorted behind/above the ‘walls’.
First I considered finding intersections of 2d vectors in which to construct a depth stack, but then thought it was too computationally cumbersome as an initial approach. Furthermore, this required multiple definitions of 2d vectors if, for example, the shape of the ‘wall’ was L-shaped. Note that the bottom edges were the 2d vectors that were being checked against the character’s position and vector which was, in turn, based on the isometric tile ratio, which determined the vector direction to check with. Again, very cumbersome.
So I came upon an idea of using collisions for a check. The logic is simple. If the character’s base position touches (collides into) a wall, it will be set to be behind the wall. This is the starting point and main principle of the method.
The image below describes it in C2’s event sheet.
The main Sprite being sorted is
mover is the collision line.
pc is pinned to
The offsets shown in the image above are somewhat arbitrary. What’s important is the principle of the collisions, which are explained below.
The first issue is that the base of the character (a.k.a ‘mover’) must actually be a volume or area, not a single point because the Sprite needs to check for a hit on the full base width of the Sprite.
The red line is the ‘mover’, and is tailor fitted to the width extent of the Sprite that is being sorted. In fact it should encompass the widest width of the Sprite animation. The ‘mover’ is collision-aware, of course.
Second, we have to consider the Y position of the mover in relation to the Sprite being sorted. Ideally, the position should be the bottom vertex of the virtual Tile diamond. When the ‘mover’ is too high, the collision will occur ahead of time and will seem too premature. This offset doesn’t need to be precise as it is based on the specifics of the graphics, and the parameters of the game’s aesthetics.
Third, the ‘wall’ Sprites must have accurate collision polygons; as accurate as you need them to have.
Fourth, since we are dealing with 2d layers, we need to design our ‘sortable’ graphical elements so that they can split up so that can be sorted at all.
So if we were designing a four-sided room, you can encompass it with 2 elements. The first element is the bottom L-shaped wall, and the second element is the upper L-shaped wall. In this way, it possible for the character to appear either in front, or behind, either of these two elements.