O'Reilly logo

Programming Game AI by Example by Mat Buckland

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Ü
NOTE Because of the number of demos I‘ve created for this chapter, the
SteeringBehaviors class is enormous and contains much more code than
would ever get used in a single project. Very rarely will you use more than a
handful of behaviors for each game you design. Therefore, whenever I use
steering behaviors in later chapters, I will use a cut-down version of the
SteeringBehaviors class, custom made for the task at hand. I suggest you do
the same. (Another approach is to define a separate class for each behavior and
add them to a
std::container as you need them.)
Inside the Vehicle::Update method you will see this line:
SVector2D SteeringForce = m_pSteering->Calculate();
This call determines the resultant force from all the active behaviors. This
is not simply a sum of all the steering forces though. Don’t forget that the
vehicle is constrained by a maximum steering force, so this sum must be
truncated in some way to make sure its magnitude never exceeds the limit.
There are a number of ways you can do this. It’s impossible to say if one
method is better than another because it depends on what behaviors you
need to work with and what CPU resources you have to spare. They all
have their pros and cons. I strongly recommend you experiment for
yourself.
Weighted Truncated Sum
The simplest approach is to multiply each steering behavior with a weight,
sum them all together, and then truncate the result to the maximum allow-
able steering force. Like this:
SVector2D Calculate()
{
SVector2D SteeringForce;
SteeringForce += Wander() * dWanderAmount;
SteeringForce += ObstacleAvoidance() * dObstacleAvoidanceAmount;
SteeringForce += Separation() * dSeparationAmount;
return SteeringForce.Truncate(MAX_STEERING_FORCE);
}
This can work fine, but the trade-off is that it comes with a few problems.
The first problem is that because every active behavior is calculated every
time step, this is a very costly method to process. Additionally, the behav
-
ior weights can be very difficult to tweak. (Did I say difficult? Sorry, I
mean very difficult! J ) The biggest problem, however, happens with con
-
flicting forces — a common scenario is where a vehicle is backed up
against a wall by several other vehicles. In this example, the separating
forces from the neighboring vehicles can be greater than the repulsive force
from the wall and the vehicle can end up being pushed through the wall
boundary. This is almost certainly not going to be favorable. Sure you can
make the weights for the wall avoidance huge, but then your vehicle may
behave strangely next time it finds itself alone and next to a wall. Like I
120 | Chapter 3
Combining Steering Behaviors

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required