Version of Robotron arcade game using LPC1768, a Gameduino shield, a serial EEPROM (for high scores), two microswitch joysticks and two buttons plus a box to put it in. 20 levels of mayhem.

Dependencies:   25LCxxx_SPI CommonTypes Gameduino mbed

Committer:
RichardE
Date:
Mon Jun 17 15:10:43 2013 +0000
Revision:
18:70190f956a24
Parent:
10:bfa1c307c99d
Improved response to button 1 when entering high scores (HighScoreEntry.cpp).

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RichardE 4:673eb9735d44 1 /*
RichardE 4:673eb9735d44 2 * SOURCE FILE : GameObject.cpp
RichardE 4:673eb9735d44 3 *
RichardE 4:673eb9735d44 4 * The abstract base class for all graphical game objects.
RichardE 4:673eb9735d44 5 *
RichardE 4:673eb9735d44 6 */
RichardE 4:673eb9735d44 7
RichardE 4:673eb9735d44 8 #include "GameObject.h"
RichardE 4:673eb9735d44 9 #include "GameObjectLocator.h"
RichardE 6:8bbdb70bc11c 10 #include "ArenaConst.h"
RichardE 4:673eb9735d44 11 #include "GDExtra.h"
RichardE 10:bfa1c307c99d 12 #include "EnemyFactory.h"
RichardE 4:673eb9735d44 13
RichardE 4:673eb9735d44 14 /**********************************/
RichardE 4:673eb9735d44 15 /* INITIALISE AN ARRAY OF OBJECTS */
RichardE 4:673eb9735d44 16 /**********************************/
RichardE 4:673eb9735d44 17 // Really only intended for the initialisation of enemy objects and humans.
RichardE 4:673eb9735d44 18 // Each object in the array is allocated a consecutive sprite number and is positioned
RichardE 4:673eb9735d44 19 // randomly in the arena. The objects movement is restricted to within the arena.
RichardE 4:673eb9735d44 20 // Pass pointer to array of pointers to GameObjects in objects.
RichardE 4:673eb9735d44 21 // Pass number of pointers in the array in objectCount.
RichardE 4:673eb9735d44 22 // Pass pointer to a sprite number in spriteNumber. This number is incremented by this method.
RichardE 4:673eb9735d44 23 void GameObject::InitialiseAll( GameObject **objects, UInt8 objectCount, UInt8 *spriteNumber ) {
RichardE 6:8bbdb70bc11c 24 GameObject *object;
RichardE 6:8bbdb70bc11c 25 for( UInt8 i = 0; i < objectCount; ++i ) {
RichardE 6:8bbdb70bc11c 26 object = objects[ i ];
RichardE 6:8bbdb70bc11c 27 if( object != (GameObject*)NULL ) {
RichardE 6:8bbdb70bc11c 28 // Use next sprite number.
RichardE 6:8bbdb70bc11c 29 object->SpriteNumber = *spriteNumber;
RichardE 6:8bbdb70bc11c 30 // Position object randomly.
RichardE 6:8bbdb70bc11c 31 GameObjectLocator::Locate( object );
RichardE 6:8bbdb70bc11c 32 // Restrict movement to arena.
RichardE 6:8bbdb70bc11c 33 object->MovementRestricted = true;
RichardE 6:8bbdb70bc11c 34 object->Bounds = &ArenaRectangle;
RichardE 6:8bbdb70bc11c 35 }
RichardE 4:673eb9735d44 36 // Next sprite number.
RichardE 4:673eb9735d44 37 (*spriteNumber)++;
RichardE 6:8bbdb70bc11c 38 }
RichardE 4:673eb9735d44 39 }
RichardE 4:673eb9735d44 40
RichardE 4:673eb9735d44 41 /****************************/
RichardE 4:673eb9735d44 42 /* MOVE AN ARRAY OF OBJECTS */
RichardE 4:673eb9735d44 43 /****************************/
RichardE 4:673eb9735d44 44 // Pass pointer to array of pointers to GameObjects in objects.
RichardE 4:673eb9735d44 45 // Pass number of pointers in the array in objectCount.
RichardE 4:673eb9735d44 46 // Returns true if any non-null objects were found in the array.
RichardE 4:673eb9735d44 47 bool GameObject::MoveAll( GameObject **objects, UInt8 objectCount ) {
RichardE 5:0b0651ac7832 48 if( objects != (GameObject**)NULL ) {
RichardE 5:0b0651ac7832 49 GameObject *object;
RichardE 5:0b0651ac7832 50 bool foundNonNull = false;
RichardE 5:0b0651ac7832 51 for( UInt8 i = 0; i < objectCount; ++i ) {
RichardE 5:0b0651ac7832 52 object = objects[ i ];
RichardE 5:0b0651ac7832 53 if( object != (GameObject*)NULL ) {
RichardE 5:0b0651ac7832 54 foundNonNull = true;
RichardE 5:0b0651ac7832 55 object->Move();
RichardE 5:0b0651ac7832 56 }
RichardE 5:0b0651ac7832 57 }
RichardE 5:0b0651ac7832 58 return foundNonNull;
RichardE 5:0b0651ac7832 59 }
RichardE 5:0b0651ac7832 60 else {
RichardE 5:0b0651ac7832 61 // A null pointer was passed. Do nothing.
RichardE 5:0b0651ac7832 62 return false;
RichardE 5:0b0651ac7832 63 }
RichardE 4:673eb9735d44 64 }
RichardE 4:673eb9735d44 65
RichardE 4:673eb9735d44 66 /****************************/
RichardE 4:673eb9735d44 67 /* DRAW AN ARRAY OF OBJECTS */
RichardE 4:673eb9735d44 68 /****************************/
RichardE 6:8bbdb70bc11c 69 // Pass pointer to Gameduino to draw on in gd.
RichardE 4:673eb9735d44 70 // Pass pointer to array of pointers to GameObjects in objects.
RichardE 4:673eb9735d44 71 // Pass number of pointers in the array in objectCount.
RichardE 6:8bbdb70bc11c 72 void GameObject::DrawAll( Gameduino *gd, GameObject **objects, UInt8 objectCount ) {
RichardE 4:673eb9735d44 73 GameObject *object;
RichardE 4:673eb9735d44 74 for( UInt8 i = 0; i < objectCount; ++i ) {
RichardE 4:673eb9735d44 75 object = objects[ i ];
RichardE 4:673eb9735d44 76 if( object != (GameObject*)NULL ) {
RichardE 4:673eb9735d44 77 // Check if object is visible.
RichardE 4:673eb9735d44 78 // If not then it wants killing off and a NULL
RichardE 4:673eb9735d44 79 // should be written to the array of pointers
RichardE 4:673eb9735d44 80 // and the sprite should be hidden.
RichardE 10:bfa1c307c99d 81 // If it is an enemy then it must be deleted using EnemyFactory.
RichardE 4:673eb9735d44 82 if( ! object->Visible ) {
RichardE 10:bfa1c307c99d 83 if( object->GetType() == EnemyObjectType ) {
RichardE 10:bfa1c307c99d 84 EnemyFactory::Instance.DeleteEnemy( (EnemyObject*)object );
RichardE 10:bfa1c307c99d 85 }
RichardE 4:673eb9735d44 86 objects[ i ] = (GameObject*)NULL;
RichardE 6:8bbdb70bc11c 87 GDExtra::HideSprite( gd, object->SpriteNumber );
RichardE 4:673eb9735d44 88 }
RichardE 4:673eb9735d44 89 else {
RichardE 6:8bbdb70bc11c 90 object->Draw( gd );
RichardE 4:673eb9735d44 91 }
RichardE 4:673eb9735d44 92 }
RichardE 4:673eb9735d44 93 }
RichardE 4:673eb9735d44 94 }
RichardE 4:673eb9735d44 95
RichardE 4:673eb9735d44 96 /************************************************/
RichardE 4:673eb9735d44 97 /* FIND AN UNUSED OBJECT IN AN ARRAY OF OBJECTS */
RichardE 4:673eb9735d44 98 /************************************************/
RichardE 4:673eb9735d44 99 // Pass pointer to array of pointers to GameObjects in objects.
RichardE 4:673eb9735d44 100 // Pass number of pointers in the array in objectCount.
RichardE 4:673eb9735d44 101 // Pass pointer to variable that will hold index of object found in index.
RichardE 4:673eb9735d44 102 // Returns true if an unused object was found, false if not.
RichardE 4:673eb9735d44 103 // An unused object is indicated by a null pointer in the array.
RichardE 4:673eb9735d44 104 bool GameObject::FindUnusedObject( GameObject **objects, UInt8 objectCount, UInt8 *index ) {
RichardE 4:673eb9735d44 105 for( UInt8 i = 0; i < objectCount; ++i ) {
RichardE 4:673eb9735d44 106 if( objects[ i ] == (GameObject*)NULL ) {
RichardE 4:673eb9735d44 107 // Found a null pointer. Store index in index pointer
RichardE 4:673eb9735d44 108 // and return true.
RichardE 4:673eb9735d44 109 *index = i;
RichardE 4:673eb9735d44 110 return true;
RichardE 4:673eb9735d44 111 }
RichardE 4:673eb9735d44 112 }
RichardE 4:673eb9735d44 113 // Did not find a null pointer.
RichardE 4:673eb9735d44 114 return false;
RichardE 4:673eb9735d44 115 }
RichardE 4:673eb9735d44 116
RichardE 4:673eb9735d44 117 /****************************************************/
RichardE 4:673eb9735d44 118 /* FIND COLLISIONS WITH ALL THE OBJECTS IN AN ARRAY */
RichardE 4:673eb9735d44 119 /****************************************************/
RichardE 6:8bbdb70bc11c 120 // Pass pointer to Gameduino in gd parameter.
RichardE 4:673eb9735d44 121 // Pass pointer to array of pointers to GameObjects in objects.
RichardE 4:673eb9735d44 122 // Pass number of pointers in the array in objectCount.
RichardE 4:673eb9735d44 123 // Pass pointer to a function that takes two UInt8 parameters in func.
RichardE 4:673eb9735d44 124 // The first parameter is the index of the object in the objects array that hit something.
RichardE 4:673eb9735d44 125 // The second parameter is the sprite number of the sprite which it hit.
RichardE 6:8bbdb70bc11c 126 void GameObject::FindCollisions( Gameduino *gd, GameObject **objects, UInt8 objectCount, void (*func)( UInt8, UInt8 ) ) {
RichardE 4:673eb9735d44 127 GameObject *object;
RichardE 4:673eb9735d44 128 UInt8 hitSpriteNumber;
RichardE 4:673eb9735d44 129 // Repeat for each non-null object in the array.
RichardE 4:673eb9735d44 130 for( UInt8 i = 0; i < objectCount; ++i ) {
RichardE 4:673eb9735d44 131 object = objects[ i ];
RichardE 4:673eb9735d44 132 if( object != (GameObject*)NULL ) {
RichardE 4:673eb9735d44 133 // Get sprite number that has collided with the sprite number of the object.
RichardE 6:8bbdb70bc11c 134 hitSpriteNumber = gd->rd( Gameduino::COLLISION + object->SpriteNumber );
RichardE 4:673eb9735d44 135 // If result is 0xFF then no collision was found.
RichardE 4:673eb9735d44 136 if( hitSpriteNumber != 0xFF ) {
RichardE 4:673eb9735d44 137 // Collision, so call function to deal with it.
RichardE 4:673eb9735d44 138 func( i, hitSpriteNumber );
RichardE 4:673eb9735d44 139 }
RichardE 4:673eb9735d44 140 }
RichardE 4:673eb9735d44 141 }
RichardE 4:673eb9735d44 142 }
RichardE 4:673eb9735d44 143
RichardE 4:673eb9735d44 144 /*************************************************************************/
RichardE 4:673eb9735d44 145 /* FIND AN OBJECT WITH A PARTICULAR SPRITE NUMBER IN AN ARRAY OF OBJECTS */
RichardE 4:673eb9735d44 146 /*************************************************************************/
RichardE 4:673eb9735d44 147 // Pass pointer to array of pointers to GameObjects in objects.
RichardE 4:673eb9735d44 148 // Pass number of pointers in the array in objectCount.
RichardE 4:673eb9735d44 149 // Pass sprite number to look for in spriteNumber.
RichardE 4:673eb9735d44 150 // Index of object with given sprite number written to variable pointed to by index.
RichardE 4:673eb9735d44 151 // Returns true if sprite number was found, false if not.
RichardE 4:673eb9735d44 152 bool GameObject::FindSpriteNumber( GameObject **objects, UInt8 objectCount, UInt8 spriteNumber, UInt8 *index ) {
RichardE 4:673eb9735d44 153 GameObject *object;
RichardE 4:673eb9735d44 154 for( UInt8 i = 0; i < objectCount; ++i ) {
RichardE 4:673eb9735d44 155 object = objects[ i ];
RichardE 4:673eb9735d44 156 if( ( object != (GameObject*)NULL ) && ( object->SpriteNumber == spriteNumber ) ) {
RichardE 4:673eb9735d44 157 *index = i;
RichardE 4:673eb9735d44 158 return true;
RichardE 4:673eb9735d44 159 }
RichardE 4:673eb9735d44 160 }
RichardE 4:673eb9735d44 161 // Did not find sprite number.
RichardE 4:673eb9735d44 162 return false;
RichardE 4:673eb9735d44 163 }
RichardE 4:673eb9735d44 164
RichardE 4:673eb9735d44 165 /**********************************************/
RichardE 4:673eb9735d44 166 /* FIND NEAREST OBJECT IN AN ARRAY OF OBJECTS */
RichardE 4:673eb9735d44 167 /**********************************************/
RichardE 4:673eb9735d44 168 // Pass pointer to array of pointers to GameObjects in objects.
RichardE 4:673eb9735d44 169 // Pass number of pointers in the array in objectCount.
RichardE 4:673eb9735d44 170 // Pass x and y coordinates of point you want to check.
RichardE 4:673eb9735d44 171 // Pass pointer to validation function in ValidFunc.
RichardE 4:673eb9735d44 172 // This is used to establish if a particular object is to be considered
RichardE 4:673eb9735d44 173 // when finding nearest object. It should return true if object should be considered
RichardE 4:673eb9735d44 174 // or false to ignore it. Pass NULL if all objects are considered valid.
RichardE 4:673eb9735d44 175 // Pass pointer to variable that will hold index of object found in index.
RichardE 4:673eb9735d44 176 // Returns true if nearest object was found, false if not (maybe no objects in array).
RichardE 4:673eb9735d44 177 bool GameObject::FindNearestObject(
RichardE 4:673eb9735d44 178 GameObject **objects, UInt8 objectCount,
RichardE 4:673eb9735d44 179 Int16 x, Int16 y,
RichardE 4:673eb9735d44 180 bool (*ValidFunc)( GameObject *object ),
RichardE 4:673eb9735d44 181 UInt8 *index
RichardE 4:673eb9735d44 182 ) {
RichardE 4:673eb9735d44 183 GameObject *object;
RichardE 4:673eb9735d44 184 bool found = false;
RichardE 4:673eb9735d44 185 Int16 minDistance = 0x7FFF, distance;
RichardE 4:673eb9735d44 186 for( UInt8 i = 0; i < objectCount; ++i ) {
RichardE 4:673eb9735d44 187 object = objects[ i ];
RichardE 4:673eb9735d44 188 if(
RichardE 4:673eb9735d44 189 ( object != (GameObject*)NULL ) &&
RichardE 4:673eb9735d44 190 ( ( ValidFunc == NULL ) || ValidFunc( object ) )
RichardE 4:673eb9735d44 191 ) {
RichardE 4:673eb9735d44 192 // This calculation doesn't really calculate the distance between points.
RichardE 4:673eb9735d44 193 // Should really be calculating square root of the sum of the squares of the
RichardE 4:673eb9735d44 194 // difference between coordinates. Could leave out the square root.
RichardE 4:673eb9735d44 195 // However, this is a lot quicker, has less danger of overflow and is a
RichardE 4:673eb9735d44 196 // fairly good approximation for the purposes of a game.
RichardE 4:673eb9735d44 197 distance = abs( x - object->Xco ) + abs( y - object->Yco );
RichardE 4:673eb9735d44 198 if( distance < minDistance ) {
RichardE 4:673eb9735d44 199 found = true;
RichardE 4:673eb9735d44 200 minDistance = distance;
RichardE 4:673eb9735d44 201 *index = i;
RichardE 4:673eb9735d44 202 }
RichardE 4:673eb9735d44 203 }
RichardE 4:673eb9735d44 204 }
RichardE 4:673eb9735d44 205 return found;
RichardE 4:673eb9735d44 206 }
RichardE 4:673eb9735d44 207
RichardE 4:673eb9735d44 208 /***************************************************************************/
RichardE 4:673eb9735d44 209 /* REMOVE ALL OBJECTS IN AN ARRAY THAT ARE NOT RETAINED ON A LEVEL RESTART */
RichardE 4:673eb9735d44 210 /***************************************************************************/
RichardE 4:673eb9735d44 211 // Pass pointer to array of pointers to GameObjects in objects.
RichardE 4:673eb9735d44 212 // Pass number of pointers in the array in objectCount.
RichardE 4:673eb9735d44 213 // All objects pointed to in the array that have their RetainOnLevelRestart property set
RichardE 4:673eb9735d44 214 // to false are removed by writing NULL into the array.
RichardE 4:673eb9735d44 215 void GameObject::RemoveUnretainedObjects( GameObject **objects, UInt8 objectCount ) {
RichardE 4:673eb9735d44 216 GameObject *object;
RichardE 4:673eb9735d44 217 for( UInt8 i = 0; i < objectCount; ++i ) {
RichardE 4:673eb9735d44 218 object = objects[ i ];
RichardE 4:673eb9735d44 219 if( ( object != (GameObject*)NULL ) && ! object->RetainOnLevelRestart ) {
RichardE 4:673eb9735d44 220 objects[ i ] = (GameObject*)NULL;
RichardE 4:673eb9735d44 221 }
RichardE 4:673eb9735d44 222 }
RichardE 4:673eb9735d44 223 }
RichardE 4:673eb9735d44 224
RichardE 4:673eb9735d44 225 /*******************************/
RichardE 4:673eb9735d44 226 /* MOVE TOWARDS ANOTHER OBJECT */
RichardE 4:673eb9735d44 227 /*******************************/
RichardE 4:673eb9735d44 228 // Pass object to move towards in object.
RichardE 4:673eb9735d44 229 // Pass speed at which to move in speed.
RichardE 4:673eb9735d44 230 void GameObject::MoveTowards( GameObject *object, Int16 speed ) {
RichardE 4:673eb9735d44 231 if( Xco <= object->Xco - speed ) {
RichardE 4:673eb9735d44 232 Xco += speed;
RichardE 4:673eb9735d44 233 }
RichardE 4:673eb9735d44 234 else if( Xco >= object->Xco + speed ) {
RichardE 4:673eb9735d44 235 Xco -= speed;
RichardE 4:673eb9735d44 236 }
RichardE 4:673eb9735d44 237 if( Yco <= object->Yco - speed ) {
RichardE 4:673eb9735d44 238 Yco += speed;
RichardE 4:673eb9735d44 239 }
RichardE 4:673eb9735d44 240 else if( Yco >= object->Yco + speed ) {
RichardE 4:673eb9735d44 241 Yco -= speed;
RichardE 4:673eb9735d44 242 }
RichardE 4:673eb9735d44 243 }