Category Archives: Graphics

Another method for z-sorting

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 pc, and mover is the collision line. pc is pinned to mover.

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.

 

Advertisements

MTile/GTile edge definition syntax

Though this syntax was developed many months ago, I had forgotten to document this.

Overview

This edge definition refers to the edges that exists in any GTile tile/sprite. This obviously means that edge definition is a Tiled property of the GTile, which is then passed on in C2 to generate MTile edges at runtime.

Note that a GTile refers to a graphics tile which is a bigger-sized tile. An MTile refers to a movement tile which is smaller and forms the grid of possible tiles to move to. Every GTile is subdivided into equal square MTiles.

Edge definition

Below is an image representing one GTile, and the MTile IDs within it:

For every GTile, there can exist any number of edges. Using this image as an example:

That sprite is mapped out as:

Here, we introduce the edge syntax used to define those edges.

<mtile_id>:<gridmove_direction>[,<mtile_id>:<gridmove_direction>...]

Where mtile_id is the id of the MTile that needs an edge definition (because it is neighbouring a GTile edge), and gridmove_direction is the direction where the edge lies on that MTile specified in the GridMove format.

In the sprite above, the edge definition is:

1:0,5:0,8:3,9:3,10:3,11:3

That is, the MTile ID 1 and 5 have a edges at Direction 0 (east), IDs 8, 9, 10, and 11 have edge at Direction 3 (north). Note that it’s possible to have defined other MTiles, such as:

6:1,7:1

…to replace 10:3, 11:3. It doesn’t matter, as long as the same edge is not specified twice.

Tiled

Note that the edge definition is inputted in Tiled in its tilesheet editor. Currently, there are two Tile properties associated with edge: edge and edge4. edge was the original use, which subdivided each GTile into 2×2 MTiles. edge4 subdivided it further (4×4) giving it a maximum of 16 MTiles per GTile (this depicted in the image above).

In the C2 project, only one type is used and can be interchanged or modified depending on final design choices.

How to get height level of tile in iso view

 

pasted-image-at-2016_11_13-09_06-pm
How to get height level of tile in iso view.

The purpose of this graphic is to determine the unit height of an agreed isometric tile. This unit height is important to when modelling 3d objects which feature floor levels. The next height level should always correspond to the tile above.

  • Need the Hypothenus to get the diamond’s upper and lower tips.
  • Knowing the camera angle and the Hypothenus, what is the Opposite.
  • tan θ = O/A (in which case ‘A’ is the Hypothenus)
  • O= tan θ * A (multiply the tangent of the angle by the Hypothenus)
  • In the example above, O = 50.4367359
  • If O and A is known, what is the angle?
  • θ = atand(O/A) (arctan in degrees)

Solve for the camera angle needed to match a 2x2m tile’s height with the grid if the height is 100cm and 200cm.

  • 200^2 + 200^2 = 80000
  • A = sqrt(80000) = 282.8427
  • θ = ( O / 282.8427)
  • if O=100
    • 100/282.8427 = 0.35355
    • atand(0.35355) = 19.471
  • if O=200
    • 200/282.8427 = 0.7071
    • atand(0.7071) = 35.2643
  • if O=250
    • 250/282.8427 = 0.8838
    • atand(0.8838) = 41.4729