13.2 The cCritterArmed

13.2 The cCritterArmed

The cCritterArmed has the ability to shoot bullets; this is what its shoot method does.

To begin with, let's explain how the cCritterArmed::shoot gets called. The call is the responsibility of the cCritterArmed::update method, which checks if (a) the critter's _armed flag is on, meaning that it is allowed to shoot at all, and (b) the critter's _bshooting flag is on, meaning that it is supposed to shoot right now. When we use a cCritterArmed as a player, the _bshooting flag is something we normally turn on and off by pressing the space bar or the left mouse button. When we have a self-running 'robotic' cCritterArmedRobot child of the cCritterArmed class as a rival in our game, the _bshooting flag will often be continually on, with the _waitshoot time interval preventing the cCritterArmedRobot from shooting perpetually.

Here's a slightly simplified version of our cCritterArmed::update code.

 void cCritterArmed::update(CPopView *pactiveview)  {  //(1) Call base class update to apply force.      cCritter::update(pactiveview);  //(2) Align gun with move direction if necessary.      if (_aimtoattitudelock)          setAimVector(attitudeTangent()); /* Keep the gun pointed in              the right direction. */  /* (3) Shoot if requested, and if enough time has elapsed since last  shot. */      if (_armed && _bshooting && (_age  _ageshoot > _waitshoot))      {          shoot();          _ageshoot = _age;      }  } 

To make the aim direction of the gun visible, we override and extend cCritterArmed::draw to draw a little line segment under cCritterArmed's sprite to represent the direction of the gun.

Now let's say something about what the cCritterArmed::shoot method does. We want to allow for different cCritterArmed child classes to use different kinds of bullets, so there is a CRuntimeClass *_pbulletclass variable to specify the kinds of bullets used. This means that we don't need to override the shoot method. Instead we just change the _pbulletclass . The CRuntimeClass *_pbulletclass variable is set by default in the constructor to RUNTIME_CLASS(cCritterBullet) . You can find out more about the CRuntimeClass type in Chapter 22: Topics in C++. Basically it holds a string with a name of the class as well as an integer giving the size in bytes of the class instance objects.

The way _bulletclass gets used hinges on an interesting OOP feature, which allows us to create an instance of a class object from the name of the class. That is, there is a general CRuntimeClass::CreateObject method which will return an object of the type specified by the caller CRuntimeClass object.

The cCritterArmed::shoot() does the following.

  • If the shooter has more than _maxbullets active, delete the oldest one.

  • Create a pbullet with pbulletclass->CreateObject() .

  • Call pbullet->initialize(this) , with a pointer to the shooter as an argument.

The reason we need both the second and the third step is that the CRuntimeClass::CreateObject() doesn't take an argument; in effect it always calls a no-argument constructor. So we need the extra initialize call to feed in information from the shooter.

Software Engineering and Computer Games
Software Engineering and Computer Games
Year: 2002
Pages: 272

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net