VBfx / Tile tutorial / Z-buffer

Introduction

Drawing the units just in the order they are in the array results in many display errors. To solve this problem we have to add a Z-buffer that sorts the units so they get drawn in the correct order. Since this is a 2D engine Z-sorting happens in Y direction so a unit at 10, 8 is displayed behind a unit at 10, 12.

Z-buffering

Lucky we are that we already have the units map where every unit is registered at. Now since the units map is a tile-based map we can't use if for the Z-buffer but we can use this map to get only the units that are on the screen. We add those indices to a list and then perform a Z-sort on this list so we get the indices in the correct drawing order. When done we can simply draw all units contained in this list.

The code

To keep code clear I moved the code for drawing a unit into a new function called DrawUnit, you can look-up the complete code in the sample project. The only thing that changed was the DrawUnits function, we'll discuss this in code right now. I cutted the function into logical parts:

```Public Sub DrawUnits()
Dim A as Long
Dim Done as Boolean

Dim X as Long
Dim Y as Long

Dim Index as Long

Dim UnitListCount as Long
Dim UnitList() as Long
```

UnitList will hold the indices to sort. Each index stands for a unit in this list.

```    'Calculate start index
Index = Int( ( Camera.Y / TileSize ) ) * Map.W + Int( ( Camera.X / TileSize ) )
UnitListCount = -1

'Draw the map
For Y = 0 To Camera.TilesY
For X = 0 To Camera.TilesX
'Check index
If Index > ( Map.W * Map.H ) Then: Exit For
```

Instead of exiting the function we just continue after the loops now. This is because there's still code to execute after the loops this time.

```            'Get unit index
If Map.Units( Index ) > 0 Then
'Allocate memory
UnitListCount = UnitListCount + 1
ReDim Preserve UnitList( UnitListCount )

UnitList( UnitListCount ) = Map.Units( Index )
End If
```

When there's a unit (index > 0) at the current position add that index to the UnitList.

```            'Next tile
Index = Index + 1
Next

'Get next line start
Index = Index + Map.W - Camera.TilesX - 1
Next
```

Nothing to explain here...

```    'Z-sort the list
While Not Done
Done = True

For A = 0 To UnitListCount - 1
'If unit is in front of next unit
If Unit( UnitList( A ) ).Y > Unit( UnitList( A + 1 ) ).Y Then
'Swap items
Index = UnitList( A )
UnitList( A ) = UnitList( A + 1 )
UnitList( A + 1 ) = Index

'Check again
Done = False
End If
Next
Wend
```

This is called a bubble sort because it's the easiest way of sorting. The code just goes through all list items, compares a certain value and if necessary swaps those items in the list. This is repeated until all items are in the correct order. Quite slow but fast enough for a tile engine and easy to implement.

Here we performed a bubble sort to order the units by their Y property. Note again the deepness is done in Y direction in 2D top-down games!

```    'Now draw the sorted list
For A = 0 To UnitListCount
DrawUnit UnitList( A )
Next
End Sub
```

Now that the list is sorted we can simply draw all the units.

Conclusion

We're done already, now your engine supports a nice little Z-buffer for the units (and only for the units!). Download the sample code and move your unit around others to check if it's working.