VBfx / Tile tutorial / Step 5

Re-constructing the path

The following function goes back from the goal to the start following the Parent link of each node:

Private Sub CheckBack( iNode as cNode )
    'Add waypoint
    With Unit( TargetUnit )
        'Create waypoint
        .WayPointCount = .WayPointCount + 1
        ReDim Preserve .WayPoint( .WayPointCount )
        'Setup waypoint
        .WayPoint( .WayPointCount ).X = iNode.X
        .WayPoint( .WayPointCount ).Y = iNode.Y
    End With
    If Not iNode.Parent Is Nothing Then
        'Check next parent
        CheckBack iNode.Parent
    End If
End Sub

First the current node is added to the unit as a waypoint. The second step is to check if there's any Parent node. If so we continue re-constructing the path from there, if not we're done here.

Now that's it for the path finding module, the rest is left to the units.

UpdateUnits again

All we have to do now is implementing a function that moves the units towards their next waypoint. Since we already have a frequently-called function (UpdateUnits) we can extend this one. We're getting a little deeper into maths but please try to understand what the code does.

Public Sub UpdateUnits()
    Dim A as Long
    Dim Angle as Single
    Dim TempDestination as tCoord2D
    'Frequently update
    For A = 1 To UnitCount
        With Unit( A )
            If .WayPointCount > -1 Then
                'Get waypoint position
                TempDestination.X = .WayPoint( .WayPointCount ).X * TileSize
                TempDestination.Y = .WayPoint( .WayPointCount ).Y * TileSize

The function first gets the next waypoint's position converting it into pixel-based coordinates.

                'Check distance
                If Distance( .X, .Y, TempDestination.X, TempDestination.Y ) < ( TileSize / 2 ) Then
                    'Step to next waypoint
                    .WayPointCount = .WayPointCount - 1

If the distance is small enough we reached this waypoint and can go on to the next one. I used ( TileSize / 2 ) here to make sure the unit is on the specified tile, the smaller this value is the nearer will the unit move towards the center of each tile.

                    'Get angle to next waypoint
                    Angle = GetAngle( CSng( .X ), CSng( .Y ), CSng( TempDestination.X ), CSng( TempDestination.Y ) )

First we get the angle between the waypoint and the unit. Knowing the angle allows us to keep the moving speed constant even when moving diagonal.

                    'Get 4-based direction
                    If Angle >= ( Pi / 4 ) * 5 And Angle < ( Pi / 4 ) * 7 Then: .Direction = 0
                    If Angle >= ( Pi / 4 ) * 7 Or Angle < ( Pi / 4 ) * 1 Then: .Direction = 1
                    If Angle >= ( Pi / 4 ) * 1 And Angle < ( Pi / 4 ) * 3 Then: .Direction = 2
                    If Angle >= ( Pi / 4 ) * 3 And Angle < ( Pi / 4 ) * 5 Then: .Direction = 3

This is a pure visual effect setting the direction so the unit looks into the correct direction when moving. Note that angles are in rad where 90 degrees would be (Pi / 2), thus the weird Pi-divisions.

                    'Move in this direction
                    MoveUnit A, .X + ( Cos( Angle ) * .Speed ), .Y + ( Sin( Angle ) * .Speed )

Finally we move the unit towards the waypoint. The Cos() function returns the X-component, the Sin() function the Y-component of the angle. Note that I added a Speed property to the unit Type here, in the example all units move the same speed however.

                End If
            End If
            'Animate if moved
            .Animated = .Moved
            .Moved = False

This check stays the same of course.

        End With
End Sub


Breath-through now, you're done with the tutorial. In the first part you learned about the theory and how the famous A* algorithm works. The second part showed you how to make a fully-working path finding that even checks the map for unit collisions and tile friction. The final step was using the waypoints given by the path finding so the unit moves there smoothly.

In the sample code I added a short function to make the waypoints visible. I didn't explain this in the tutorial since that's for debug reasons only. You can simply turn it off by removing the code. And now download that sample and check it out!