Richard Ellingworth / Mbed 2 deprecated RobotRic

Dependencies:   25LCxxx_SPI CommonTypes Gameduino mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GameObject.cpp Source File

GameObject.cpp

00001 /*
00002  * SOURCE FILE : GameObject.cpp
00003  *
00004  * The abstract base class for all graphical game objects.
00005  *
00006  */
00007 
00008 #include "GameObject.h"
00009 #include "GameObjectLocator.h"
00010 #include "ArenaConst.h"
00011 #include "GDExtra.h"
00012 #include "EnemyFactory.h"
00013 
00014 /**********************************/
00015 /* INITIALISE AN ARRAY OF OBJECTS */
00016 /**********************************/
00017 // Really only intended for the initialisation of enemy objects and humans.
00018 // Each object in the array is allocated a consecutive sprite number and is positioned
00019 // randomly in the arena. The objects movement is restricted to within the arena.
00020 // Pass pointer to array of pointers to GameObjects in objects.
00021 // Pass number of pointers in the array in objectCount.
00022 // Pass pointer to a sprite number in spriteNumber. This number is incremented by this method.
00023 void GameObject::InitialiseAll( GameObject **objects, UInt8 objectCount, UInt8 *spriteNumber ) {
00024     GameObject *object;
00025     for( UInt8 i = 0; i < objectCount; ++i ) {
00026         object = objects[ i ];
00027         if( object != (GameObject*)NULL ) {
00028             // Use next sprite number.
00029             object->SpriteNumber = *spriteNumber;
00030             // Position object randomly.
00031             GameObjectLocator::Locate( object );
00032             // Restrict movement to arena.
00033             object->MovementRestricted = true;
00034             object->Bounds = &ArenaRectangle;
00035         }
00036         // Next sprite number.
00037         (*spriteNumber)++;
00038     }
00039 }
00040 
00041 /****************************/
00042 /* MOVE AN ARRAY OF OBJECTS */
00043 /****************************/
00044 // Pass pointer to array of pointers to GameObjects in objects.
00045 // Pass number of pointers in the array in objectCount.
00046 // Returns true if any non-null objects were found in the array.
00047 bool GameObject::MoveAll( GameObject **objects, UInt8 objectCount ) {
00048   if( objects != (GameObject**)NULL ) {
00049       GameObject *object;
00050       bool foundNonNull = false;
00051       for( UInt8 i = 0; i < objectCount; ++i ) {
00052         object = objects[ i ];
00053         if( object != (GameObject*)NULL ) {
00054           foundNonNull = true;
00055           object->Move();
00056         }
00057       }
00058       return foundNonNull;
00059    }
00060    else {
00061       // A null pointer was passed. Do nothing.
00062       return false;
00063    }
00064 }
00065 
00066 /****************************/
00067 /* DRAW AN ARRAY OF OBJECTS */
00068 /****************************/
00069 // Pass pointer to Gameduino to draw on in gd.
00070 // Pass pointer to array of pointers to GameObjects in objects.
00071 // Pass number of pointers in the array in objectCount.
00072 void GameObject::DrawAll( Gameduino *gd, GameObject **objects, UInt8 objectCount ) {
00073   GameObject *object;
00074   for( UInt8 i = 0; i < objectCount; ++i ) {
00075     object = objects[ i ];
00076     if( object != (GameObject*)NULL ) {
00077       // Check if object is visible.
00078       // If not then it wants killing off and a NULL
00079       // should be written to the array of pointers
00080       // and the sprite should be hidden.
00081       // If it is an enemy then it must be deleted using EnemyFactory.
00082       if( ! object->Visible ) {
00083         if( object->GetType() == EnemyObjectType ) {
00084             EnemyFactory::Instance.DeleteEnemy( (EnemyObject*)object );
00085         }
00086         objects[ i ] = (GameObject*)NULL;
00087         GDExtra::HideSprite( gd, object->SpriteNumber );
00088       }
00089       else {
00090         object->Draw( gd );
00091       }
00092     }
00093   }
00094 }
00095 
00096 /************************************************/
00097 /* FIND AN UNUSED OBJECT IN AN ARRAY OF OBJECTS */
00098 /************************************************/
00099 // Pass pointer to array of pointers to GameObjects in objects.
00100 // Pass number of pointers in the array in objectCount.
00101 // Pass pointer to variable that will hold index of object found in index.
00102 // Returns true if an unused object was found, false if not.
00103 // An unused object is indicated by a null pointer in the array.
00104 bool GameObject::FindUnusedObject( GameObject **objects, UInt8 objectCount, UInt8 *index ) {
00105   for( UInt8 i = 0; i < objectCount; ++i ) {
00106     if( objects[ i ] == (GameObject*)NULL ) {
00107       // Found a null pointer. Store index in index pointer
00108       // and return true.
00109       *index = i;
00110       return true;
00111     }
00112   }
00113   // Did not find a null pointer.
00114   return false;
00115 }
00116 
00117 /****************************************************/
00118 /* FIND COLLISIONS WITH ALL THE OBJECTS IN AN ARRAY */
00119 /****************************************************/
00120 // Pass pointer to Gameduino in gd parameter.
00121 // Pass pointer to array of pointers to GameObjects in objects.
00122 // Pass number of pointers in the array in objectCount.
00123 // Pass pointer to a function that takes two UInt8 parameters in func.
00124 // The first parameter is the index of the object in the objects array that hit something.
00125 // The second parameter is the sprite number of the sprite which it hit.
00126 void GameObject::FindCollisions( Gameduino *gd, GameObject **objects, UInt8 objectCount, void (*func)( UInt8, UInt8 ) ) {
00127   GameObject *object;
00128   UInt8 hitSpriteNumber;
00129   // Repeat for each non-null object in the array.
00130   for( UInt8 i = 0; i < objectCount; ++i ) {
00131     object = objects[ i ];
00132     if( object != (GameObject*)NULL ) {
00133       // Get sprite number that has collided with the sprite number of the object.
00134       hitSpriteNumber = gd->rd( Gameduino::COLLISION + object->SpriteNumber );
00135       // If result is 0xFF then no collision was found.
00136       if( hitSpriteNumber != 0xFF ) {
00137         // Collision, so call function to deal with it.
00138         func( i, hitSpriteNumber );
00139       }
00140     }
00141   }
00142 }
00143 
00144 /*************************************************************************/
00145 /* FIND AN OBJECT WITH A PARTICULAR SPRITE NUMBER IN AN ARRAY OF OBJECTS */
00146 /*************************************************************************/
00147 // Pass pointer to array of pointers to GameObjects in objects.
00148 // Pass number of pointers in the array in objectCount.
00149 // Pass sprite number to look for in spriteNumber.
00150 // Index of object with given sprite number written to variable pointed to by index.
00151 // Returns true if sprite number was found, false if not.
00152 bool GameObject::FindSpriteNumber( GameObject **objects, UInt8 objectCount, UInt8 spriteNumber, UInt8 *index ) {
00153   GameObject *object;
00154   for( UInt8 i = 0; i < objectCount; ++i ) {
00155     object = objects[ i ];
00156     if( ( object != (GameObject*)NULL ) && ( object->SpriteNumber == spriteNumber ) ) {
00157       *index = i;
00158       return true;
00159     }
00160   }
00161   // Did not find sprite number.
00162   return false;
00163 }
00164 
00165 /**********************************************/
00166 /* FIND NEAREST OBJECT IN AN ARRAY OF OBJECTS */
00167 /**********************************************/
00168 // Pass pointer to array of pointers to GameObjects in objects.
00169 // Pass number of pointers in the array in objectCount.
00170 // Pass x and y coordinates of point you want to check.
00171 // Pass pointer to validation function in ValidFunc.
00172 // This is used to establish if a particular object is to be considered
00173 // when finding nearest object. It should return true if object should be considered
00174 // or false to ignore it. Pass NULL if all objects are considered valid.
00175 // Pass pointer to variable that will hold index of object found in index.
00176 // Returns true if nearest object was found, false if not (maybe no objects in array).
00177 bool GameObject::FindNearestObject(
00178     GameObject **objects, UInt8 objectCount,
00179     Int16 x, Int16 y,
00180     bool (*ValidFunc)( GameObject *object ),
00181     UInt8 *index
00182 ) {
00183   GameObject *object;
00184     bool found = false;
00185     Int16 minDistance = 0x7FFF, distance;
00186   for( UInt8 i = 0; i < objectCount; ++i ) {
00187     object = objects[ i ];
00188     if(
00189             ( object != (GameObject*)NULL ) &&
00190             ( ( ValidFunc == NULL ) || ValidFunc( object ) )
00191         ) {
00192             // This calculation doesn't really calculate the distance between points.
00193             // Should really be calculating square root of the sum of the squares of the
00194             // difference between coordinates. Could leave out the square root.
00195             // However, this is a lot quicker, has less danger of overflow and is a
00196             // fairly good approximation for the purposes of a game.
00197             distance = abs( x - object->Xco ) + abs( y - object->Yco );
00198             if( distance < minDistance ) {
00199                 found = true;
00200                 minDistance = distance;
00201                 *index = i;
00202             }
00203     }
00204   }
00205   return found;
00206 }
00207 
00208 /***************************************************************************/
00209 /* REMOVE ALL OBJECTS IN AN ARRAY THAT ARE NOT RETAINED ON A LEVEL RESTART */
00210 /***************************************************************************/
00211 // Pass pointer to array of pointers to GameObjects in objects.
00212 // Pass number of pointers in the array in objectCount.
00213 // All objects pointed to in the array that have their RetainOnLevelRestart property set
00214 // to false are removed by writing NULL into the array.
00215 void GameObject::RemoveUnretainedObjects( GameObject **objects, UInt8 objectCount ) {
00216   GameObject *object;
00217   for( UInt8 i = 0; i < objectCount; ++i ) {
00218     object = objects[ i ];
00219     if( ( object != (GameObject*)NULL ) && ! object->RetainOnLevelRestart ) {
00220             objects[ i ] = (GameObject*)NULL;
00221     }
00222   }
00223 }
00224 
00225 /*******************************/
00226 /* MOVE TOWARDS ANOTHER OBJECT */
00227 /*******************************/
00228 // Pass object to move towards in object.
00229 // Pass speed at which to move in speed.
00230 void GameObject::MoveTowards( GameObject *object, Int16 speed ) {
00231   if( Xco <= object->Xco - speed ) {
00232     Xco += speed;
00233   }
00234   else if( Xco >= object->Xco + speed ) {
00235     Xco -= speed;
00236   }
00237   if( Yco <= object->Yco - speed ) {
00238     Yco += speed;
00239   }
00240   else if( Yco >= object->Yco + speed ) {
00241     Yco -= speed;
00242   }
00243 }