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.
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.
Else '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 Next 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!