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 14:40:47 2013 +0000
Revision:
5:0b0651ac7832
Parent:
4:673eb9735d44
Child:
6:8bbdb70bc11c
Now got first real level starting and player can be controlled using joysticks. No bullets, enemies, humans or sound yet.

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