Following Another Character
Although following another
character might seem complicated at first, don’t worry
too much. Remember that keeping it simple is the solution. Following a character
is as easy as walking a route. Because a character already knows its own
coordinates
and the coordinates of the character it is following, you can use previously
seen
functions to move the character toward another one.
The only difference at this
point is that you might want a character to get within a
specific distance from the followed character, as illustrated in Figure 16.5.
Knowing each character’s
coordinates (the character being followed and the character
doing the following), you can construct a single function that determines
which direction the “following” character should move:
void
CalculateFollowMovement(
float CharXPos, float CharZPos, // Coordinate of character
float WalkSpeed, // Walking speed of char.
float FollowXPos, float FollowZPos, // Coords of followed char.
float FollowDistance, // Distance to follow at
float *MoveX, float *MoveZ) // Variables for movement
{
// Fix for faster distance checking
FollowDistance *= FollowDistance;
// Get distance between characters
float XDiff = (float)fabs(FollowXPos - CharXPos);
float ZDiff = (float)fabs(FollowZPos - CharZPos);
float Length = XDiff*XDiff + ZDiff*ZDiff;
// If distance between characters is less than allowed,
// then just stand still.
if(Length < FollowDistance) {
*MoveX = *MoveZ = 0.0f;
return;
}
// Calculate rate to move based on character walking speed
Length = sqrt(Length);
*MoveX = (CharXPos - FollowXPos) / Length * WalkSpeed;
*MoveZ = (CharZPos - FollowZPos) / Length * WalkSpeed;
}
Whenever you want to update a
character that is following another one, you merely
pass along the required data and move the character using the returned movement
variables.
Evading
Another Character
Evading means to move a
character away from another one. If the character to be
avoided is closer than the minimum set distance, the evading character moves in
the opposite direction through the use of the CalculateEvadeMovement function:
void
CalculateEvadeMovement(
float CharXPos, float CharZPos, // Coordinate of character
float WalkSpeed, // Walking speed of char.
float FollowXPos, float FollowZPos, // Coords of evaded char.
float EvadeDistance, // Distance to evade
float *MoveX, float *MoveZ) // Variables for movement
{
// Fix for faster distance checking
FollowDistance *= FollowDistance;
// Get distance between characters
float XDiff = (float)fabs(FollowXPos - CharXPos);
float ZDiff = (float)fabs(FollowZPos - CharZPos);
float Length = XDiff*XDiff + ZDiff*ZDiff;
// If distance between characters is more than allowed,
// then just stand still.
if(Length > EvadeDistance) {
*MoveX = *MoveZ = 0.0f;
return;
}
// Calculate rate to move based on character walking speed
Length = sqrt(Length);
*MoveX = -((CharXPos - FollowXPos) / Length * WalkSpeed);
*MoveZ = -((CharZPos - FollowZPos) / Length * WalkSpeed);
}