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

/* EXTRANEOUS DETAIL OMITTED */
};
You can see the class relationships clearly in the simplified UML diagram
shown in Figure 3.1.
Updating the Vehicle Physics
Before we move on to the steering behaviors themselves, I’d just like to
walk you through the
Vehicle::Update method. It’s important that you
understand every line of code in this function because it’s the main work
-
horse of the
Vehicle class. (If you do not know Newton’s laws of force and
motion, I would strongly recommend you read the relevant part of Chapter
1 before continuing.)
bool Vehicle::Update(double time_elapsed)
{
//calculate the combined force from each steering behavior in the
//vehicle’s list
SVector2D SteeringForce = m_pSteering->Calculate();
How to Create Autonomously Moving Game Agents
| 89
The Vehicle Model
Figure 3.1. The Vehicle and SteeringBehaviors class relationships
First the steering force for this simulation step is calculated. The Calculate
method sums all a vehicle’s active steering behaviors and returns the total
steering force.
//Acceleration = Force/Mass
SVector2D acceleration = SteeringForce / m_dMass;
Using Newton’s laws of physics, the steering force is converted into an
acceleration (see equation 1.93, Chapter 1).
//update velocity
m_vVelocity += acceleration * time_elapsed;
Using the acceleration, the vehicle’s velocity can be updated (see equation
1.81, Chapter 1).
//make sure vehicle does not exceed maximum velocity
m_vVelocity.Truncate(m_dMaxSpeed);
//update the position
m_vPos += m_vVelocity * time_elapsed;
The vehicle’s position can now be updated using the new velocity (see
equation 1.77, Chapter 1).
//update the heading if the vehicle has a velocity greater than a very small
//value
if (m_vVelocity.LengthSq() > 0.00000001)
{
m_vHeading = Vec2DNormalize(m_vVelocity);
m_vSide = m_vHeading.Perp();
}
As mentioned earlier, a MovingEntity has a local coordinate system that
must be kept updated each simulation step. A vehicle’s heading should
always be aligned with its velocity so this is updated, making it equal to the
normalized velocity vector. But — and this is important — the heading is
only calculated if the vehicle’s velocity is above a very small threshold
value. This is because if the magnitude of the velocity is zero, the program
will crash with a divide by zero error, and if the magnitude is non-zero but
very small, the vehicle may (depending on the platform and operating sys
-
tem) start to move erratically a few seconds after it has stopped.
The side component of the local coordinate system is easily calculated
by calling
SVector2D::Perp.
//treat the screen as a toroid
WrapAround(m_vPos, m_pWorld->cxClient(), m_pWorld->cyClient());
}
Finally, the display area is considered to wrap around from top to bottom
and from left to right (if you were to imagine it in 3D it would be toroidal
— doughnut shaped). Therefore, a check is made to see if the updated
90 | Chapter 3
The Vehicle Model

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