8.5 The full cCritter prototype

8.5 The full cCritter prototype

Here's a full listing of the cCritter prototype from a recent critter.h header file. For the most current listing, you can examine the file itself inside Visual Studio.

 //////////////////////////////////////////////////////////////////////  // Critter.h: interface for the cCritter class.  //  //////////////////////////////////////////////////////////////////////  #ifndef CRITTER_H  #define CRITTER_H  #include "randomizer.h"  #include "realbox.h"  #include "realpixelconverter.h"  #include "vectortransformation.h"  #include <mmsystem.h> //For PlaySound flags  class cGraphics;  #define USEBOUNCINESS /* Compile switch used in critter.cpp,  critterwall.cpp, realbox.cpp. */      /* We don't need to include the headers for the following classes      as we only mention them as pointers. In general, we only include a      header in a header if we absolutely have to. Here we can get by      with forward class declarations that simply say such and such a      class exists. Of course we will need to include the headers in      the critter.cpp which is where we actually use the properties of      these classes. */  class cBiota; //For the *_pownerbiota member.  class cSprite; //For the *_psprite member.  class cListener; //For *_plistener member.  class cForce; //For _forcearray member.  class cDistanceAndDirection;      // Return type of the distanceAndDirection function.  class CPopView; //Used as an argument to sniff.  class cGame; //For the return type of the pgame() method.  class cGraphics; //For the draw method.  class cCritter : public CObject  {  DECLARE_SERIAL(cCritter); /* An MFC macro used to enable      CRuntimeClass reflection of class type, dynamic creation,      and serialization. */  public:  // Statics ========================================  //Constant Statics ================================      //The MF_ statics are mutation flags used in the mutate methods.      static const int MF_NUDGE;      static const int MF_POSITION;      static const int MF_VELOCITY;      static const int MF_ALL; //MF_POSITION  MF_VELOCITY      /* Wrapflag values specify possible behaviors when critter hits          edge of world. */      static const int BOUNCE;      static const int WRAP;      static const int CLAMP;      /* special high density used for player or other immovable critter. */      static const Real INFINITEDENSITY;  //Variable Statics ================================      //These might (rarely) be reset by a cGame constructor.  //Motion Statics ================================      static Real MINSPEED; //Used in randomizing critter _speed.      static Real MAXSPEED; /* Used in randomizing, and to clamp _speed          in move(dt). */      static Real MINTWITCHTHRESHOLDSPEED;          //Default for _mintwitchthresholdspeed      static Real NEAREDGEPERCENT; // Default arg for moveToMoveboxEdge.      static BOOL STARTWRAPFLAG;      static Real DENSITY; //Default density.  //State Statics ===============================      static Real MUTATIONSTRENGTH; //Default argument to mutate method.      static Real MINRADIUS; //Used in randomizing      static Real MAXRADIUS;      static Real BULLETRADIUS; /* Gets set to cGame::BULLETRADIUS in          cGame constructor. */      static Real PLAYERRADIUS;      static Real LISTENERACCELERATION;          //Default for _listeneracceleration      static int STARTHEALTH; //Default is 1.      static Real SAFEWAIT; /* Time in seconds of invulnerability, use          at start up and after damage, gives critters breathing room so          they don't get damaged twice in a row, like by the same bullet          volley. */      static Real FIXEDLIFETIME; /* Default lifetime for critters with          _usefixedlifetime TRUE. */  protected:  //=================================================  //State Fields. ===================================  //=================================================      Real _age; /* Measure in seconds of time simulated, start at 0.0          when constructed. */      BOOL _usefixedlifetime;          //If TRUE, then die when _age > _fixedlifetime.      Real _fixedlifetime;          //Max lifetime in seconds, applies only if _usefixedlifetime.      int _health; /* Lose by being hit and taking damage(). Usually die          when _health is 0. */      BOOL _shieldflag; //Immunity to damage() calls.      UINT _personality; /* Random bits to sometimes use for making          critters have different behaviors, as when using evasion          forces. */      Real _mutationstrength; /* Number between 0.0 and 1.0 controlling          how different a spawned copy will be. */      cCritter *_ptarget;/* In case you are following or dragging or          watching or aimed at someone else, use this field to track          them. _ptarget is one of the only fields that is NOT          serialized. We use the _targetindex with the _pownerbiota to          copy or serialize _ptarget. */  //================================================  //Game Fields ===================================  //================================================      cBiota *_pownerbiota; /* Used in makeServiceRequest and in other          places. It allows the critter to be aware of all the other          critters. Gets set by the cCritter(cGame *pownergame)          constructor. _pownerbiota is NOT serialized. */      int _score; //Usually gain by eating or shooting others.      int _value; //Value to another critter shooting or eating this one.      int _newlevelscorestep;          //Step size between score levels that are rewarded.      int _newlevelreward; //Health reward for new score level.  //================================================  //Motion Fields. ==================================  //================================================  //Position Fields =================================      cVector _position;      cRealBox _movebox; //Keep critter inside _movebox.      cRealBox _dragbox; /* Usually same as _movebox, but in          cGamePickNPop, it's bigger, so can drag a critter outside of          its _movebox. */      int _wrapflag; //BOUNCE, WRAP, or CLAMP when you bump a wall.      int _outcode; /* Flag info about which wall, if any, the last          move bumped. */  //Velocity Fields ================================      BOOL _fixedflag; //Refuse to move.      cVector _velocity;      Real _speed;      cVector _tangent; /* We always keep _velocity = _speed * _tangent.          It's useful to have _tangent around even when _speed goes to 0          and _velocity is zero, this way we know what direction to          start back up in. */      cVector _normal; /* We maintain a _normal and _binormal vector to          fully express themotion of the critter through 3D space. */      cVector _binormal; //Always cVector::ZAXIS in 2D worlds.      Real _maxspeed; //Clamp _speed below this in move().      Real _maxspeedstandard;/* In case _maxspeed might be temporarily          increased, for instance if the critter is allowed to move          extra fast while fleeing or chasing another. */  //Acceleration Mass, and Force Fields ==============================      cVector _acceleration; /* _acceleration gets reset during every          cycle, using the _forcearray and possibly the _plistener to          change it. */      Real _mass; /* Use fixMass() helper to maintain _mass = _density *          radius()^3. */      Real _density; /* Default is 1. We often assign the cCritterPlayer          a very large _density so that it can whack others around. */      CTypedPtrArray<CObArray, cForce*> _forcearray;          //We serialize this array  //Listener Fields. ================================      cListener *_plistener; //Never NULL. We serialize the plistener.      Real _listeneracceleration; /* This is the acceleration used by          listeners such as cListenerCar and cListenerSpaceship that          "drive" the critter around. Like the critter's engine          strength. */  //Collision Fields ================================      Real _collidepriority;      /* These are default cCritter _collidepriority values, in          increasing size for increasingly high priority, where in a          pair of critters, the higher priority critter is the caller of          the collide method, and the lower priority critter is the          argument to the collide call. */      Real _absorberflag; /* Don't change your own velocity after a          collision. This siphons energy out of the system, cooling          down the motions by absorbing it. */      Real _bounciness; /* ranges from 0.0 to 1.0. Determines how          elastically you bounce off of walls    or off of other          critters.  1.0 is perfect bounce, 0.9 is pretty reasonable,          0.0 don't bounce at all. */      Real _mintwitchthresholdspeed; /* If we have          _attitudetomotionlock, and we have some critters barely          bouncing on a "floor" it looks bad if they keep twitching          their orientation up and down. Don't change the _attitude          to match the motion if the speed is less than          _mintwitchtriggerspeed. */  //==============================================  //Attitude and Display Fields ============================  //==============================================      cSprite *_psprite; //Never NULL. We serialize the _psprite.      BOOL _attitudetomotionlock; /* Shall I lock together the display          sprite and the motion? By default the player has          _attitudetomotionlock FALSE and all other critters have it          TRUE. */      cMatrix _attitude; /* The attitude expresses the way that the          critter is situated for rendering. When _attitudetomotionlock          is TRUE, _attitude has the columns _tangent, _normal,          _binormal, _position. If _attitudetomotionlock is FALSE,          _attitude can be instead controlled by _spin or by the          _plistener actions. */      cSpin _spin; /* A cSpin holds the spinangle in radians per          second and the spinaxis which is the axis to spin around          (z by default). Presently used only when _attitudetomotionlock          is OFF. */      Real _defaultprismdz; /* We copy this into the psprite's _prismdz          field in setSprite. If we are in 3D and if the sprite is, for          instance, a polygon that makes use of the _prismdz field, then          _prismdz will determine the z-thickness of the sprite. */  //=============================================  //Bookkeeping Fields ===============================  //=============================================  //Serialized Bookkeeping Fields ===============================      Real _lasthit_age; /* Age at last hit (or age at birth), use to          time invulnerability. */      BOOL _oldrecentlydamaged; /* Used in update() in connection with          sprite display lists. */      cVector _oldposition;          //This is used by the cCritterWall::collide method.      cVector _oldtangent;          //This is used by the cCritter::fixNormalAndBinormal method.      cVector _wrapposition1, _wrapposition2, _wrapposition3;          //Use for showing wrap in 2D      int _targetindex; /* _targetindex is a dummy used to copy and          serialize the _ptarget pointer reference. */  //Nonserialized Bookkeeping Fields ============================      int _metrickey; /* Index into the _pownerbiota cBiota's _metric,          can be used to look up metric values. _metrickey is NOT          serialized. Uspd if #define USEMETRIC*/  public:  //==================================================  //Constructor and destructor and helpers ==========================  //=================================================      cCritter(cGame *pownergame = NULL); /* Initializes fields, adds          to pownergame if not null. With the NULL default for the          pownergame argument, this constructor doubles as a no-argument          constructor. */      virtual void copy(cCritter *pcritter); /* Helper function for copy          constructor, and for clone method. */      cCritter(cCritter *pcritter); //copy constructor      cCritter* clone(); /* Returns a pointer to a cCritter of the same          child class type, with the same info in it. */      virtual ~cCritter(); /* deletes pointer members and calls          cBiota::removeReferencesTo(this). The destructor is virtual          so that child critter destructors can do extra cleanup before          the baseclass destructor. */      void removeReferencesTo(cCritter *pdeadcritter); /* Don't let          pdeadcritter be the _ptarget or the pnode() of any          cForceObject in the _forcearray. */  //=============================================  //Mutators ================================  //=============================================  //State Field Mutators ==============================      void setValue(int value){_value = value;}          /* The velocity, direction, and speed mutators always keep              _velocity = _speed * _tangent. */      void setShield(BOOL shield){_shieldflag = shield;}      void setUseFixedLifetime(BOOL yesno){_usefixedlifetime = yesno;}      void setFixedLifetime(Real lifetime){_fixedlifetime = lifetime;}      void setMutationStrength(Real mutationstrength){_mutationstrength          = mutationstrength;}      virtual void setTarget(cCritter *pcritter){_ptarget = pcritter;}          /* Comes in handy sometimes, though more often I'll use a          cForceObject. */      void setMetricKey(int i){_metrickey = i;}      virtual void reset(); //can override to do special things.      virtual void setAge(Real age){_age = age; _lasthit_age = _age           cCritter::SAFEWAIT;} //overridden by cCritterArmedRobot.  //Game Field Mutators ===================================      void setOwner(cBiota* pownerbiota){_pownerbiota = pownerbiota;}          //Used in Add and CBiota::Serialize      virtual void addScore(int scorechange);      void setHealth(int health){_health = health;          if(_health<0)_health=0;} /* We can add health points at          certain score levels. */      void setNewlevelreward(int healthgain){_newlevelreward =          healthgain;}      void setNewlevelscorestep(int pointspread){_newlevelscorestep =          pointspread;}  //===============================================  //Motion Field Mutators ==============================  //===============================================  //Position Field Mutators =============================      int setMoveBox(const cRealBox &box);      void setDragBox(const cRealBox &box){_dragbox = box;}      virtual void setWrapflag(int wrapflag);          //We have a kludge override for cCritterWall      virtual int moveTo(const cVector &newposition, BOOL          treatascontinuousmotion = FALSE); /* Do the move,          and then clamp against _movebox, return outcode of          clamp. */      virtual int moveToZ(Real z){return moveTo(cVector(_position.x(),          _position.y(), z));} /* I use moveToZ in          cGamePickNPop::seedCritters. */      virtual int moveToProportional(const cVector &newposition,          Real proportion, BOOL treatascontinuousmotion = FALSE);          /* Proportion between 0.0 and 1.0 is how much of the way          you want to move towards newposition. */      virtual int dragTo(const cVector &newposition, Real dt);          /* Move and clamp against _dragbox, return outcode. In          addition, use dt to set critter velocity to match the drag          velocity. I make it virtual so cCritterWall can override to          NOT change the velocity. */      void moveToMoveboxEdge(Real percent = cCritter::NEAREDGEPERCENT);          /* Useful in some games, to start a critter near the _movebox              edge. */  //Velocity Field Mutators ============================      void setFixedflag(BOOL flag){_fixedflag = flag;}      void setVelocity(const cVector &velocity);      void addVelocity(const cVector velocitychange)          {setVelocity(_velocity + velocitychange);}      void setTangent(const cVector &direction);      void rotate(const cSpin &spin); /* cSpin is a way to express          general 3D angles. */      void yaw(Real turnangle); //Rotate around _binormal.      void roll(Real turnangle); //Rotate around _tangent      void pitch(Real turnangle); //Rotate around _normal      void orthonormalize(); /* Make sure _tangent, _normal, _binormal          are orthogonal units. */      void setSpeed(Real speed);      void setMaxspeed(Real maxspeed)          {_maxspeed = _maxspeedstandard = maxspeed;}      void setTempMaxspeed(Real maxspeed){_maxspeed = maxspeed;}      void restoreMaxspeed(){_maxspeed = _maxspeedstandard;}  //Acceleration, Mass and Force Field Mutators ======================      void setAcceleration(const cVector &acceleration)          {_acceleration = acceleration;}      void addAcceleration(const cVector &acceleration)          {_acceleration += acceleration;}      void setDensity(Real density){_density = density; fixMass();}      void fixMass(); //Keep _mass = _density * _radius()^3.      void addForce(cForce *pforce);      void clearForcearray();      void copyForcearray(cCritter *pcritter); /* This helper method          will empty the existing force array and copy all of the forces          in the pcritter force array. */      virtual void copyPhysicsForces(cCritter *pcritter); /* A more          modest kind of force copying. Here we don't wipeout the          existing forces in the caller, and we only copy the "physics"          forces like cForceGravity and cForceDrag from pcritter. Use          the BOOL cForce::isGlobalPhysicsForce() to tell us which ones.          We need this method so that bullets can copy the physics of          their shooters but not their behavioral forces. */  //Listener Field Mutators ==================================      void setListener(cListener *plistener);      void setListenerAcceleration(Real la){_listeneracceleration = la;}  //Collision Field Mutators ===================================      void setMinTwitchThresholdSpeed(Real twitchspeed)          {_mintwitchthresholdspeed = twitchspeed;}      void setBounciness(Real bounciness)          {CLAMP(bounciness, 0.0, 1.0); _bounciness = bounciness;}      void setAbsorberflag(BOOL flag)          {_absorberflag = flag;          _absorberflag?_bounciness=0.0:_bounciness=1.0;}      void setCollidePriority(Real collidepriority);          //Rebuild the pgame()->_pcollider just in case.  //===================================================  //Attitude and Display Field Mutators ===============================  //===================================================      void setSprite(cSprite *psprite);      void setSpin(cVector3 spinvector){_spin = cSpin(spinvector);}      void setAttitudeToMotionLock(int lockmode)          {_attitudetomotionlock = lockmode;}      void setSpin(Real spinangle, cVector3 spinaxis = cVector::ZAXIS)          {_spin = cSpin(spinangle, spinaxis);}      void rotateAttitude(Real angle);          //{_attitude *= cMatrix::rotation(angle);}      void rotateAttitude(cSpin &spin);          //{_attitude *= cMatrix::rotation(spin);}      void setAttitude(const cMatrix &attitude); /* This changes the          orientation aspect of _attitude, but NOT the _position          aspect, that is, it leaves the last column alone. */      void resetAttitude(); /* Assume the identity orientation. */      void setAttitudeTangent(const cVector &tangent); /* points          _attitude in tangent direction. If _attitudetomotionlock is          TRUE, we move _tangent to match. */      void copyMotionMatrixToAttitudeMatrix();      void copyAttitudeMatrixToMotionMatrix();      BOOL lookAt(const cVector &targetpos); /* Aim attitudeTangent          at targetpos, and try and perverse attitudeNormal while          you're at it. Return FALSE if the targetpos is right on          top of you, preventing you from looking at it, else return          TRUE. */      BOOL lookAtProportional(const cVector &targetpos, Real          proportion); /* Proportion is between 0.0 and          1.0 specifying how far towards targetpos you turn          to look. */      int setRadius(Real radius);      void setPrismDz(Real prismdz); /* Sets _defaultprismdz and the          current _psprite->_prismdz. */  //===========================================  //Randomizing mutators ===========================  //===========================================      void randomizePosition(const cRealBox &startbox);      void randomizePosition(){randomizePosition(_movebox);}      void randomizeRadius(Real minradius, Real maxradius)          {setRadius(cRandomizer::pinstance()->randomReal(minradius,              maxradius));}      void randomizeVelocity(Real speed);      void randomizeVelocity(Real minspeed, Real maxspeed);      void randomizeVelocity(){randomizeVelocity(MINSPEED, _maxspeed);}      void randomizeSpin(Real minspeed, Real maxspeed);      virtual void mutate(int mutationflags, Real mutationstrength);          /* Mutate flagged position, velocity and sprite properties by          an amount specified in mutationstrength. */      void mutate(int mutationflags)          {mutate(mutationflags, _mutationstrength);} /* Uses the member          _mutationstrength, which defaults to 0.6. */      void randomize(int mutationflags){mutate(mutationflags, 1.0);}          //1.0 is maximum.  //==============================================  //Accessors =================================  //==============================================  //State Field Accessors ==============================      Real mutationStrength()const{return _mutationstrength;}      int value()const{return _value;}      unsigned long personality()const{return _personality;}      BOOL shield()const{return _shieldflag;}      BOOL usefixedlifetime(){return _usefixedlifetime;}      Real fixedlifetime(){return _fixedlifetime;}      Real age()const{return _age;}      BOOL recentlyDamaged(){return (_age  _lasthit_age) < SAFEWAIT;}  //Game Field Accessors =================================      cBiota* pownerbiota()const;      virtual cGame* pgame()const; /*Normally this will just return          _pownerbiota->pgame(), but in the case of a cCritterViewer          associated with a CPopView we use a different path to the          cGame.*/      cCritter* ptarget()const{return _ptarget;}      cCritter* pplayer(); /* return pgame()->pplayer(), in other words          the player of the game that this critter belongs to. */      int score()const{return _score;}      int health()const{return _health;}  //===============================================  //Motion Field Accessors ==============================  //===============================================  //Position Field Accessors ==============================      cVector position() const {return _position;}      cVector oldposition() const {return _oldposition;}      cPlane plane()const{return cPlane(_position, _binormal);}      int wrapflag()const {return _wrapflag;}      cRealBox moveBox()const{return _movebox;}      cRealBox dragBox()const{return _dragbox;}      cRealBox realBox(); //Smallest box holding the sprite.      virtual BOOL draggable(){return TRUE;} /* Used to see if a critter          is willing to be dragged in cGame::onLButtonDown. If you ever          want a non-draggable critter child class, override draggable          to return FALSE. */      BOOL in3DWorld(); //Tells you if the owner game has a z-Thickness.  //Velocity Field Accessors ==================================      BOOL fixedflag()const{return _fixedflag;}      cVector velocity() const {return _velocity;}      cVector tangent() const {return _tangent;}      cVector normal() const{return _normal;}      cVector binormal() const{return _binormal;}      Real speed()const {return _speed;}      Real maxspeed()const {return _maxspeed;}      Real maxspeedstandard()const {return _maxspeedstandard;}  //Acceleration, Force and Mass Field Accessors =======================      cVector acceleration() const {return _acceleration;}      Real density()const{return _density;}      CTypedPtrArray<CObArray, cForce*>* pforcearray()          {return &_forcearray;}  //Listener Field Accessors ================================      cListener* plistener()const{return _plistener;}      Real listeneracceleration()const{return _listeneracceleration;}  //Collision Field Accessors =================================      Real minTwitchThresholdSpeed(){return _mintwitchthresholdspeed;}      Real bounciness(){return _bounciness;}      BOOL absorberflag()const{return _absorberflag;}      Real mass()const{return _mass;}      Real collidePriority(){return _collidepriority;}  //===============================================  //Attitude and Display Field Accessors ===========================  //===============================================      cSprite* psprite() const{return _psprite;}      Real radius() const;      cSpin spin()const{return _spin;}      cMatrix attitude(){return _attitude;}      cVector attitudeTangent()const {return _attitude.column(0);}      cVector attitudeNormal()const {return _attitude.column(1);}      cVector attitudeBinormal()const{return _attitude.column(2);}      BOOL attitudetomotionlock() const{return _attitudetomotionlock;}      Real defaultprismdz()const{return _defaultprismdz;}  //================================================  //Bookkeeping Field Accessors ==================================  //================================================      int metrickey()const{return _metrickey;}  //================================================  // Serialize methods ==============================  //================================================      virtual void Serialize(CArchive &ar);  //================================================  // Helper methods ==================================  //===============================================  //Service Request Methods ==========================================      /* The point of these is that if a critter is do something that          affects the set of critters as a whole, we want it to let the          cBiota* _pownerbiota do it, so that all critter changes are          coordinated. So critter just passes this request to its          _pownerbiota, and later _pownerbiota calls          cBiota::processServiceRequests. */      void makeServiceRequest(CString request);      void add_me(cBiota *pownerbiota, BOOL immediateadd = FALSE);          /* Make a request to the pownerbiota to add yourself to its          array, normally this doesn't happen until pownerbiota makes a          periodic call to processServiceRequests, but you can force it          to be immediate with immediateadd. */      void delete_me(){_health = 0; makeServiceRequest("delete_me");}      void spawn(){makeServiceRequest("spawn");}      void zap(){makeServiceRequest("zap");}      void replicate(){makeServiceRequest("replicate");}          //copy yourself to all the others.  //Helper Methods for Move Methods ====================================      virtual int clamp();          //Clamp against _movebox. cCritterWall treats differently.      virtual int clamp(const cRealBox &border); //Clamp against border      virtual void addvelocityandcheckedges(Real dt); /* do _position +=          dt*_velocity, and clamp, wrap, or bounce the new position off          the _movebox. Set _outcode to tell which edges. Called by          move(). Need the dt to figure out a velocity bounce. */      void synchSpeedAndDirectionToVelocity(); /* Enforces          _speed*_tangent = _velocity and avoids having _speed less than          SMALL_REAL */      void fixNormalAndBinormal(); /* This is easy in 2D, subtler in 3D.          Call this from inside move on every update. It also          orthonormolizes _tangent, _normal, and _binormal. */  //Helper method for pointer references. ==============================      virtual void fixPointerRefs(); /* This helper is for fixing things          like _ptarget after serialization, is also needed when we          delete a critter.*/  //================================================  //Distance, touch, sniff, collide methods ============================  //================================================      /* The first three methods' code depends whether USEMETRIC is          #defined in metric.h */      virtual cVector directionTo(cCritter *pcritter);          //Use cMetricCritter or compute direct      Real distanceTo(cCritter *pcritter);          //Uses cBiota's cMetricCritter or computes direct      Real distanceTo(const cLine &testline)          {return testline.distanceTo(_position);}//Direct      cDistanceAndDirection distanceAndDirectionTo(cCritter *pcritter);          //ditto      Real distanceTo(const cVector &vpoint); //Brute force.      virtual BOOL touch(const cVector &vpoint);//Brute force.      virtual BOOL touch(const cLine &sightline); /* In 3D, clicking the          screen really picks a line of sight rather than a particular          point in space. */      virtual BOOL touch(cCritter *pcritter); /* TRUE if pcritter is          different from this and the distance between the centers is          less than the sum of the radii. Uses cBiota's cMetricCritter          or just does the brute force distance checks. */      virtual BOOL contains(cCritter *pcritter); /* TRUE if the disk of          pcritter is inside the disk of the caller. */      virtual COLORREF sniff(const cVector &snifflocation, CPopView          *pactiveview); /* Can be used in update to check the current          screen's pixel color at locations you're interested in. */      virtual int collidesWith(cCritter *pcritterother); /* Returns          cCollider::DONTCOLLIDE, ::COLLIDEASCALLER, or ::COLLIDEASARG          to specify which of the pair, if either, gets to call for a          collision. Default just checks _fixedflag and          _collidepriority. */      virtual BOOL collide(cCritter *pcritter); /* Does a physically          natural collision and possibly overrides to make the critters          react in some other way such as damage. */  //==========================================  //Game methods ============================  //==========================================      virtual void die(){delete_me();} /* Can be overridden to add          dying behavior. But should eventually produce a call to          delete_me. */      virtual void cCritter::dieOfOldAge(){delete_me();} /* dieOfOldAge          is called in the update method if(_usefixedlifetime &&          _age > _fixedlifetime). We distinguish between die() and          dieOfOldAge() so die() can make a different sound for          instance. */      virtual int damage(int hitstrength); /* Deducts hitstrength from          _health, calls die if this is below zero, returns _value as a          reward to the damager. */  //========================================  //Force and Listen methods ==============================  //========================================      virtual void feellistener(Real dt); /* Call _plistener->listen,          maybe more. */      virtual void feelforce(); /* Do _acceleration =          (sum of _forcearray[i]->force(this))/mass(). feelforce is          virtual because you might possibly want to select which forces          you feel, depending on the situation, like whether you're          currently pursuing or fleeing. */  //=================================================  //Drawing methods ====================================  //=================================================      void updateAttitude(Real dt, BOOL forceattitudeupdate = FALSE);          /* This keeps graphical attitude matrix of the critter in          synch with its motionmatrix. To prevent a too-busy look, we          normally don't do the update if the _speed is less than          _mintwitchthresholdspeed. But if we are controlling the          critter with arrow key calls to, e.g. the yaw, pitch and roll          methods, we do want to force the update of the appearance, and          then you set the forceattitudeupdate argument to TRUE. */      virtual void draw(cGraphics *pgraphics, int drawflags=0);          /* Calls _psprite->draw. Has to be virtual because some child          critters draw stuff (like guns) on top of sprite. */      virtual void drawHighlight(cGraphics *pgraphics, Real          highlightratio); /* Draw a highlighted XOR circle around the          sprite with a size = highlightratio * radius(). */  //============================================  //Sound methods =============================  //============================================      static void playSound(CString wavfileresourcename, int soundflags          = SND_RESOURCE  SND_ASYNC);          /* By default interrupts any current sounds to play this              sound. wavfileresourcename has to be the resource name of              a *.wav file that you added as a resource to your build. */      static void stopSound(); //Turns off any currently playing sounds.  //===========================================  //Simulation methods ==============================  //===========================================      virtual void animate(Real dt); /* Calls _psprite->animate(dt,          this). Can override to setAimVector. */      virtual void update(CPopView *pactiveview, Real dt); /* Call force          to set the _acceleration to zero or to the quantity determined          by _pforce. The pactiveview argument can be used to sniff          pixel colors. */      int move(Real dt); /* You really should NOT change the delicately          constructed move method, which is why its not virtual. */  };  #endif //CRITTER_H 

cCritter initialization

To complete this detailed code section, here's how the cCritter fields get initialized by the default constructor. Remember that when we define children of the critter class, like, say, cCritterArmed , when the cCritterArmed constructor is called the base class cCritter constructor gets called first. In other words, the cCritter constructor is code that all of our critters will execute at start up. Child classes may override some of these initialization values; they may also initialize additional variables that the child class may have.

We go ahead and list the full code of a recent version of the cCritter constructor here just to give you an idea of all the member fields actually used. A C++ usage worth noting here is that when we write a C++ constructor, it's common to set the values of fields by using initializer lines of the form _variable(value), rather than having a line of the form _variable = value; inside the curly brackets of the constructor. It makes the code easier to overview, and it's useful to see the allocation calls using new isolated inside the constructor's curly brackets, so that then it's easier to remember what you have to undo in the destructor. (If you happen to have any data fields that were declared as const you are in fact required to use initializer lines to set their values.)

Also note that if the pownergame argument isn't supplied, it will get the default NULL value, and the code involving it will be skipped over in the constructor.

 cCritter::cCritter(cGame *pownergame):      _pownerbiota(NULL),      _age(0.0),      _lasthit_age(- cCritter::SAFEWAIT), /* We do this so          that critters don't start out thinking they were          just hit. cCritter::SAFEWAIT is currently 0.3          seconds. */      _oldrecentlydamaged(FALSE), //Can use to notice when you need to          change sprite.      _health(cCritter::STARTHEALTH), //Default 1.      _usefixedlifetime(FALSE),      _fixedlifetime(cCritter::FIXEDLIFETIME),      _shieldflag(FALSE),      _outcode(0),      _score(0),      _newlevelscorestep(0),      _newlevelreward(0),      _value(1),      _personality(cRandomizer::pinstance()->random()),          //Use our static randomizing method.      _movebox(cRealBox(4.0,3.0, 0.0)),          //Dummy defaults to be reset with setMoveBox      _dragbox(cRealBox(_movebox)),          //Dummy defaults to be reset with setDrag      _wrapflag(cCritter::STARTWRAPFLAG), //cCritter::BOUNCE      _defaultprismdz(cSprite::CRITTERPRISMDZ),      _density(cCritter::DENSITY),          //This standard value is currently 1.0.      _mass(1.0), //Dummy default is reset by fixMass.      _collidepriority(cCollider::CP_CRITTER),      _absorberflag(FALSE),      _fixedflag(FALSE),      _position(cVector::ZEROVECTOR),      _oldposition(cVector::ZEROVECTOR),      _wrapposition1(cVector::ZEROVECTOR),      _wrapposition2(cVector::ZEROVECTOR),      _wrapposition3(cVector::ZEROVECTOR),      _velocity(cVector::ZEROVECTOR),      _speed(0.0), //Must match _velocity.magnitude().      _tangent(cVector(1.0, 0.0)),          //We always want some unit vector _tangent.      _oldtangent(cVector(1.0, 0.0)),      _normal(cVector(0.0, 1.0)),      _binormal(cVector(0.0, 0.0, 1.0)),      _attitudetomotionlock(TRUE),      _acceleration(cVector::ZEROVECTOR),      _listeneracceleration(cCritter::LISTENERACCELERATION),      _spin(), /* _spin is initialized to 0 spinangle around ZAXIS by          default constructor */      _maxspeed(cCritter::MAXSPEED), //Default 3.0      _maxspeedstandard(cCritter::MAXSPEED),      _mintwitchthresholdspeed(cCritter::MINTWITCHTHRESHOLDSPEED),      _bounciness(1.0),      _mutationstrength(cCritter::MUTATIONSTRENGTH),          //Default 0.6 (out of 1.0 max)      _ptarget(NULL),      _metrickey(0)  {      _psprite = new cSprite(); /* Let's always have a valid sprite.          The default cSprite looks like a circle, by the way. */      _plistener = new cListener(); /* For uniformity, always have a          valid listener as well. The default listener does nothing.          Don't call setListener(new cListener()) here as this call may          have side-effects I don't want yet. */      _attitude.setLastColumn(_position);          /* The default _attitude constructor has set the matrix          to the identity matrix, and it's more accurate to the          make the fourth column match the position. */      if (pownergame)          pownergame->add(this, TRUE); /* This call will set _movebox              and _dragbox to match pownergame->_border, and will set              _wrapflag to match pownergame->wrapflag). The TRUE flag              means to insert the critter into the game cBiota array              right away. */  } 

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