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

//should be
double multiplier = 1.0 + (m_dDBoxLength - LocalPosOfClosestObstacle.x) /
m_dDBoxLength;
//calculate the lateral force
SteeringForce.y = (ClosestIntersectingObstacle->BRadius()-
LocalPosOfClosestObstacle.y) * multiplier;
//apply a braking force proportional to the obstacle’s distance from
//the vehicle.
const double BrakingWeight = 0.2;
SteeringForce.x = (ClosestIntersectingObstacle->BRadius() -
LocalPosOfClosestObstacle.x) *
BrakingWeight;
}
//finally, convert the steering vector from local to world space
return VectorToWorldSpace(SteeringForce,
m_pVehicle->Heading(),
m_pVehicle->Side());
}
z
3D TIP When implementing obstacle avoidance in three dimensions, use
spheres to approximate the obstacles and a cylinder in place of the detection
box. The math to check against a sphere is not that much different than that to
check against a circle. Once the obstacles have been converted into local space,
steps A and B are the same as you have already seen, and step C just involves
checking against another axis.
Wall Avoidance
A wall is a line segment (in 3D, a polygon) with a normal pointing in the
direction it is facing. Wall avoidance steers to avoid potential collisions
with a wall. It does this by projecting three “feelers” out in front of the
vehicle and testing to see if any of them intersect with any walls in the
game world. See Figure 3.10. (The little “stub” halfway along the wall
indicates the direction of the wall normal.) This is similar to how cats and
rodents use their whiskers to navigate their environment in the dark.
104 | Chapter 3
The Steering Behaviors
Figure 3.10. Wall avoidance
When the closest intersecting wall has been found (if there is one of
course), a steering force is calculated. This is deduced by calculating how
far the feeler tip has penetrated through the wall and then by creating a
force of that magnitude in the direction of the wall normal.
Vector2D SteeringBehaviors::WallAvoidance(const std::vector<Wall2D>& walls)
{
//the feelers are contained in a std::vector, m_Feelers
CreateFeelers();
double DistToThisIP = 0.0;
double DistToClosestIP = MaxDouble;
//this will hold an index into the vector of walls
int ClosestWall = -1;
Vector2D SteeringForce,
point, //used for storing temporary info
ClosestPoint; //holds the closest intersection point
//examine each feeler in turn
for (int flr=0; flr<m_Feelers.size(); ++flr)
{
//run through each wall checking for any intersection points
for (int w=0; w<walls.size(); ++w)
{
if (LineIntersection2D(m_pVehicle->Pos(),
m_Feelers[flr],
walls[w].From(),
walls[w].To(),
DistToThisIP,
point))
{
//is this the closest found so far? If so keep a record
if (DistToThisIP < DistToClosestIP)
{
DistToClosestIP = DistToThisIP;
ClosestWall = w;
ClosestPoint = point;
}
}
}//next wall
//if an intersection point has been detected, calculate a force
//that will direct the agent away
if (ClosestWall >=0)
{
//calculate by what distance the projected position of the agent
//will overshoot the wall
Vector2D OverShoot = m_Feelers[flr] - ClosestPoint;
//create a force in the direction of the wall normal, with a
How to Create Autonomously Moving Game Agents
| 105
The 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