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
//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
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
//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

Get Programming Game AI by Example now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.