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

}
}
if (On(obstacle_avoidance) && RandFloat() > prObstacleAvoidance)
{
m_vSteeringForce += ObstacleAvoidance(m_pVehicle->World()->Obstacles()) *
m_dWeightObstacleAvoidance / prObstacleAvoidance;
if (!m_vSteeringForce.IsZero())
{
m_vSteeringForce.Truncate(m_pVehicle->MaxForce());
return m_vSteeringForce;
}
}
if (On(separation) && RandFloat() > prSeparation)
{
m_vSteeringForce += Separation(m_pVehicle->World()->Agents()) *
m_dWeightSeparation / prSeparation;
if (!m_vSteeringForce.IsZero())
{
m_vSteeringForce.Truncate(m_pVehicle->MaxForce());
return m_vSteeringForce;
}
}
/* ETC ETC */
This method requires far less CPU time than the others, but at the cost of
accuracy. Additionally, you will have to tweak the probabilities a fair bit
before you get the behavior just as you want it. Nevertheless, if you are low
on resources and it’s not imperative your agent’s movements are precise,
this method is certainly worth experimenting with. You can see the effect
of each of the three summing methods I’ve described by running the demo
Big Shoal/Big Shoal.exe. This demonstration shows a shoal of 300 small
vehicles (think fish) being wary of a single larger wandering vehicle (think
shark). You can switch between the various summing methods to observe
how they affect the frame rate and accuracy of the behaviors. You can also
add walls or obstacles to the environment to see how the agents handle
those using the different summing methods.
Ensuring Zero Overlap
Often when combining behaviors, the vehicles will occasionally overlap
one another. The separation steering force alone is not enough to prevent
this from happening. Most of the time this is okay — a little overlap will
go unnoticed by the player — but sometimes it’s necessary to ensure that
whatever happens, vehicles cannot pass through one anothers bounding
124 | Chapter 3
Ensuring Zero Overlap
radii. This can be prevented with the use of a non-penetration constraint.
This is a function that tests for overlap. If there is any, the vehicles are
moved apart in a direction away from the point of contact (and without
regard to their mass, velocity, or any other physical constraints). See Figure
3.17.
The constraint is implemented as a function template and can be used for
any objects derived from a
BaseGameEntity. You can find the code in the
EntityFunctionTemplates.h header and it looks like this:
template <class T, class conT>
void EnforceNonPenetrationConstraint(const T& entity,
const conT& ContainerOfEntities)
{
//iterate through all entities checking for any overlap of bounding radii
for (typename conT::const_iterator curEntity =ContainerOfEntities.begin();
curEntity != ContainerOfEntities.end();
++curEntity)
{
//make sure we don't check against the individual
if (*curEntity == entity) continue;
//calculate the distance between the positions of the entities
Vector2D ToEntity = entity->Pos() - (*curEntity)->Pos();
double DistFromEachOther = ToEntity.Length();
//if this distance is smaller than the sum of their radii then this
//entity must be moved away in the direction parallel to the
//ToEntity vector
double AmountOfOverLap = (*curEntity)->BRadius() + entity->BRadius() -
DistFromEachOther;
if (AmountOfOverLap >= 0)
{
//move the entity a distance away equivalent to the amount of overlap.
entity->SetPos(entity->Pos() + (ToEntity/DistFromEachOther) *
AmountOfOverLap);
}
}//next entity
}
How to Create Autonomously Moving Game Agents
| 125
Ensuring Zero Overlap
Figure 3.17. The non-penetration constraint in action

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