Friday, October 24, 2008

XNA Series - Modular AI - Waypoints

So in our last AI lesson we talked about 3 methods, TurnTowards, MoveForward and Seek. Where TurnTowards turned our rotation towards a point by an maximum amount, Move Forward moved us at a certain distance based on our rotation and Seek combined the 2 to let us move our GameAgent towards a goal.

In this post we will create a path made from Waypoints that we want our object to follow. We will start by adding a Waypoint class to our project. It will contain a position vector, and a bool indicating if we have visited it yet.

public class Waypoint
{
public Vector2 position;
public bool visted = false;

public Waypoint(Vector2 v){
position = v;
}
}


and then declaring a List collection of Waypoint objects in our game class

List<Waypoint> path;


and then initialize it in our constructor

path = new List<Waypoint>();


we can also add Waypoints to our path either here or in LoadContent like this

path.Add(new Waypoint(new Vector2(10,10)));
path.Add(new Waypoint(new Vector2(400,10)));
path.Add(new Waypoint(new Vector2(20,100)));
path.Add(new Waypoint(new Vector2(120,300)));

in Update we can do this to allow for adding new Waypoints during gametime.

MouseState ms = Mouse.GetState();
if (ms.LeftButton == ButtonState.Pressed)
{
path.Add(new Waypoint(new Vector2(ms.X, ms.Y)));
}


Now we need to create a new method in our GameAgent class called FollowPath. It will take a List<Waypoint> object, a speed and a turn speed as parameters.

public void FollowPath(List<Waypoint> p, float speed, float turnSpeed)
{


Now for each waypoint, we will check if we are within an certain distance and if so we will mark that Waypoint as visited

foreach (Waypoint w in p)
{
if (Vector2.Distance(position, w.position) < 20){
visted = true;


then if the current Waypoint is not visited, we will seek it and return


if (w.visted == false)
{
Seek(w.position, speed, turnSpeed);
return;
}
}
return;
}

So now in our Update method we can assign this action to our Agent

a.FollowPath(path,2.5f,0.1f);

and another action to another

b.Seek(a.position,2f, 0.02f);

So we have a following a path and b Seeking a. With the ability to add new points by clicking. Please be aware though that the mouse is not shown on the screen during gametime, so you have to guess where your mouse is (silly you may think, but I'll post on showing the mouse soon) So this example works out pretty well, You can tinker with the speed and turnSpeeds to see how they effect the movement.

So until next time...


The Project Files for this post
Post a Comment