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:
Sat Jun 08 15:50:38 2013 +0000
Revision:
6:8bbdb70bc11c
Parent:
5:0b0651ac7832
Child:
10:bfa1c307c99d
Player can now fire bullets and they move. Mayhem!

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