This entry is part of 9 in the series Steering Behaviors

Next up in the steering behaviors series is flow field following. Once again, we will be using the Vector2D.as and Vehicle.as classes for this. If you don’t have them, you should get them because you will need them. This post is based on Craig Reynold’s article Steering Behaviors For Autonomous Characters.

Flow Field

Flow Field, click to watch.

Using a flow field (also called a force field or a vector field) can be very useful. A level designer (or level editor, if you make one) can easily create a flow field by drawing arrows onto the screen. The vehicle will then be affected as it moves by this field.

Think of each arrow as a vector. If you do that, using a flow field becomes super easy. All you have to do is take the current force and apply it to the vehicles velocity. Just like that, the vehicle is following the force field.

There is one problem. How do you find the current force? How do you determine which of those vectors is the one you need to apply to the vehicle?

The solution I chose may not be the best way, but its fast and it works. What I’ve chosen to do is make a 2D array (a grid) to store the flow field. Each vector on the field will be 50px by 50px. The vector can be longer than 50px, but it will only affect a vehicle in the 50×50 square.

This makes determining where the vehicle is simple, just a simple:

Math.floor(vehicle.x/50);

Math.floor(vehicle.y/50);

Will give us the vehicles coordinates on the force field.

Creating a field is easy:


for(i = 0; i < 15; i++){
field[i] = [];
for(var j:int = 0; j < 15; j++){
field[i][j] = new Vector2D(15,15);//this is what you'll change to get a different field
//it can be random, based on position, whatever.
//You can even use an editor to change it, use to demo to see an example
}
}

All that does is creates a simple 2D array(field) that stores all the forces for the field. field[x][y] represents the force at that location. You can change the 15,15 to whatever to create different fields. You can even make an editor like it did(see demo) to edit the field.

Using the field is quite simple:


public function flowField(field:Array):void {
var fieldX:int = Math.floor(position.x/50);//find the vehicles location in the field
var fieldY:int = Math.floor(position.y/50);
if(fieldX < 0 || fieldY < 0 || fieldX > field.length || fieldY > field[0].length){
//this is the important part. If the vehicle is not in the field, we do nothing
//if the x or y is less than 0, it isn't on the field
//if the x or y is greater than the length of the array(size of the field), you are not in the field
return;
}
var force:Vector2D = field[fieldX][fieldY].cloneVector();//clone the vector so we don't change it
velocity.add(force.divide(mass).truncate(_maxForce));//apply the vector based on mass and within the max force.
}

The key part there is finding where on the field the vehicle is. If your field doesn’t start at 0,0, you’ll have to add offsets to the x and y values so your vehicle is on the right place on the field.

if(fieldX < 0 || fieldY < 0 || fieldX > field.length || fieldY > field[0].length){

This statement may be a bit confusing for some of you. Since the field is a 2D array, field.length is the how width the field it. field[0].length is how tall the field is. Remember, this 2D array is field[x][y]. The first array is the x values, the second is the y.

Using brackets, it looks like this:

[[1,2,3,4,5],
[1,2,3,4,5],
[1,2,3,4,5],
[1,2,3,4,5]]

Looks just like a grid, that’s all a 2D array is. There plenty of topics on this. If you’re still confused, a simple google search will help you understand multidimensional arrays.

Click here to play with the demo.

Series Navigation