VBfx / Tile tutorial / Step 3

Moving units

We have to do 2 things when moving units around. First is setting the new position while checking the map boundaries and later a collision check will follow. Second thing is to register the unit at the collision map we talked about. Also we have to watch out for newly created objects that have index -1 because they aren't on the map yet.


I made a function that moves a specified unit and does everything mentioned above, let's have a look at it:

Public Sub MoveUnit( Index as Long, NewX as Long, NewY as Long )
    Dim TempX as Long
    Dim TempY as Long

    'Check boundaries
    If NewX < 0 Then: NewX = 0
    If NewY < 0 Then: NewY = 0
    If NewX > ( ( Map.W - 1 ) * TileSize ) Then: NewX = ( ( Map.W - 1 ) * TileSize )
    If NewY > ( ( Map.H - 1 ) * TileSize ) Then: NewY = ( ( Map.H - 1 ) * TileSize )
    With Unit( Index )
        'Unregister from map
        If .MapIndex > -1 Then: Map.Units( .MapIndex ) = 0
        'Apply new position
        .X = NewX
        .Y = NewY
        'Get map index
        .MapIndex = ( (.Y / TileSize) * Map.W ) + (.X / TileSize)
        'Register there
        Map.Units( .MapIndex ) = Index
    End With
End Sub

So what happens here? In the first line we check if the index is bigger than -1. If so the unit is already on the map and we have to unregister it first. Since index contains the map index we can just set that item to -1.

The code then checks the new coordinates if they are inside the map. If not they're clipped to the map boundaries. When all checks are done the new coordinates are applied to the unit.

The second part of the function calculates the map index by the well-known formula (Y * W) + X. Note that the coordinates are in pixels so we have to divide them by the tile size first. The result is stored directly in the MapIndex property. Finally in the last line the map at this position is set to te current object's index.


Whenever you call the MoveUnit function the unit is unregistered from the collision map (Map.Units), moved and finally re-registered at the new position. Since there's no math and no loops this isn't eating much performance. The function is optimized a little by storing the current map index in each unit so we know where it's registered at.

Before we go on working with the units map we'll make a quick DrawUnits function to show what we got. Just keep on reading!