The base class `cForce::force`
returns a zero vector, but we have 'global' force classes `cForceGravity`, `cForceDrag`, and `cForceVortex`
which return non-trivial values. We use them in the Ballworld and Dambuilder games, discussed in Chapter 18: Interesting Worlds. We also have 'relative' steering force classes liked `cForceObjectSeek`, `cForceClassEvade`, and `cForceEvadeBullet`.

Figure 7.2 is a class diagram of all the forces we provide with the Pop Framework.

The idea is that each `force(cCritter*)`
method should return a force that the critter will divide by its mass and add into its acceleration. The magnitude of the force will depend on the critter's current situation in the world and on a `Real _intensity`
field that `cForce`
has.

Gravity is proportional to mass ? much as electrostatic attraction is proportional to electric charge ? and, again from Newton, we know that the gravitational force (F) between two objects is a gravitational constant (G) times the product of their masses (m1 and m2) divided by the square of the distances between them (D^{2}), to give a force like

For simple simulations, we like to use a much simpler approximation to gravitational force. It's characteristic of games to choose liveliness and speed of execution over a 100% accurate emulation. For a small object near the surface of the Earth, the distance to the Earth's center is so large that the object's motions don't effectively change this distance. In a situation like this, we can lump together the gravitational constant, the Earth's mass, the inverse square of the distance to the Earth into a new constant (g), and then an object of mass (m) will experience a gravitational force (F) of size

It's useful to have the freedom to specify the direction of a 'global' gravity like this, so we'll give our `cForceGravity`
class a `_pulldirection`
as well as its `_intensity`
constant.

cVector cForceGravity::force(cCritter *pcritter) { return _intensity * pcritter->mass() * _pulldirection; }

Remember that the `cCritter`
maintains its mass as a quantity proportional to its density times the cube of the critter's radius.

For simulating something like a solar system, we'd want to implement a more sophisticated kind of object-to-object gravity ? this is left for Exercise 7.5.

We think of drag as being a force like friction. The effect of friction is to slow something to a stop. Normally friction increases with an object's speed, and acts in a direction opposite to the object's motion. Friction is also proportional to an object's area: think of a sliding puck or of an airship moving through the atmosphere pushed by the wind. More area means more drag.

To make our drag force more general, we allow for the possibility that it is a drag relative to some moving fluid. Either we think of objects sliding on a moving surface such as a conveyer belt, or we think of floating objects under the influence of air or water currents. We use a `_``windvector`
field to specify the speed and direction of the medium's motion. The effect of drag in a moving medium is to match the object's velocity to the velocity of the medium. If the `_``windvector`
is the zero vector, then our generalized drag force is the same as friction. The idea is to continually return a force that will act to accelerate the critter in such a way as to minimize the difference between the critter's velocity and the `_windvector`.

cVector cForceDrag::force(cCritter *pcritter) { Real area = pcritter->radius()*pcritter->radius(); return cVector(area * _intensity * (_windvector ? pcritter->velocity())); }

One caveat regarding `cForceDrag`. If you set the `_intensity`
to a large value, there is a danger of overshooting the `_``windvector`
and oscillating back and forth. In terms of a simple frictional drag force with zero `_``windvector`, if you define an overly large `_``intensity`
constant, then your simulated physics will cause a moving object to jerk backwards due to its counteracting friction force, and then, once it's going backwards, the drag will make the object jerk forwards again, and so on. Generally it's a good idea to keep the intensity of a `cForceDrag`
between 0.0 and 1.0. (Do remember, however, that, in general, if you find some anomalous tweak of your values that enhances your game, go ahead and use the values even if they're not physically realistic.)

It might be fun to have some whirlpools, so we allow for a child of `cForceDrag`
in which the `windvector` varies from point to point. We call our new force `cForceVortex`, and we set it up as shown in Figure 7.3. We specify a center of the vortex and, thinking of the eye of a hurricane, we call it `_eyeposition`. And we give a `_spiralangle` to determine which way the vortex is moving things: inward, outwards, or in a circular fashion.

The idea is that the drag force at a critter position is computed as follows: (a) take the vector that runs from the `_eyeposition`
to the critter position; (b) imagine placing this vector with its tail at the critter position: and (c) rotate this vector couterclockwise by `_spiralangle`
degrees. The further a critter gets from the eye position, the more powerful is the vortex force. Remember that in C++ angles are measured in radians, so we normally think of the angle as some multiple of `PI`. (By the way, we #`define`
`PI` in `realnumber.h`.) So if you want a circular motion, you set `_spiralangle` equal to `PI/2.0`. The `cForceVortex force`
method gets implemented like this.

cVector cForceVortex::force(cCritter *pcritter) { _windvector = (pcritter->position() ? _eyeposition); _windvector.turn(_spiralangle); return cForceDrag::force(pcritter); }

The next forces we look at are what might be called 'relative' forces as opposed to 'global' forces. Relative forces involve a critter's reaction to some other critter. We provide for two kinds of relative forces. In the `cForceObject`, we react to some one specific other critter that we're watching. The baseclass `cForceObject`
holds a `cCritter *_pnode` reference field to a certain critter and its `force(pcritter)` method considers the `pcritter` situation relative to `_pnode`.

There are a variety of `cForceObject`
forces like this that we might implement. Spring forces and relative gravitational forces come to mind. The Pop Framework provides a `cForceObjectSpringRod`, which is a force for attracting a critter to another critter by a 'spring' while using a 'rod' to keep them from getting too close. You can make amazing wobbly assemblages of things by hooking critters together with these. The `cForceObjectSpringRod:force(cCritter *pcritter)`
does the following.

If

`pcritter`is closer than the desired`_rodlength`from the`_pnode`, we move`pcritter`out to`_rodlength`away from`_pnode`and return a zero forceOtherwise return a force proportional to the distance between

`pcritter`and`_pnode`.

The Worms game, described in Chapter 14: 2D Shooting Games, demonstrates a use of the `cForceObjectSpringRod`. Full code for all the forces can be found in `force.cpp`.

Another kind of relative `cForceObject`
force is the `cForceObjectSeek`, which helps the `pcritter` pursue a `_pnode` critter. The simplest notion would be to have `cForceObjectSeek::force(pcritter)`
simply return a force along the vector direction from pcritter to the _pnode of the `cForceObject`.

The Pop Framework uses an improved seeking force suggested by Craig Reynolds (op. cit., p. 154). Reynolds makes the point that rather than applying a force in the desired direction of motion, it's more effective to apply a force in the direction of the difference between the critter's desired motion and its current motion, as shown in Figure 7.4. We will also have the seek force set the critter's speed to its maximum.

There is a more general kind of relative force we can consider. This is a force in which a critter reacts to any and all members of a specified class of critters that we watch. We create a base class `cForceClass`
for this and give it a `CRuntimeClass *_pnodeclass`
member. As is discussed in Chapter 22: Topics in C++, a `CRuntimeClass`
object keeps track of a class type, basically by storing a string with the name of the type along with some additional information.

One issue in interacting with objects of a certain class type K is whether we also want to interact with objects of class KChild, where KChild is a child class of K. We give the `cForceClass`
a `BOOL _includechildclasses` field to let the programmer decide.

In the Pop Framework we provide a `cForceClassEvade`
force for evading all objects of a given class, and we derive as child of this a `cForceEvadeBullet`
to evade all `cCritterBullet`
objects. Here's a summary of how `cForceEvadeBullet`
acts.

If there are no bullets to evade, return a zero force.

Otherwise find the closest bullet.

If the closest bullet is moving away from you, return a zero force.

Set your evade direction to point away from the bullet.

If this evade direction lies in the same direction the bullet is moving, you're in a 'rabbit running down a railroad track away from a locomotive' situation, which is no good. Rotate your evade direction by 90 degrees.

Now, your desired evade velocity is your maximum speed times the evade direction.

Return an evade force which is the vector difference between the evade velocity and your current velocity.