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 11:24:05 2013 +0000
Revision:
4:673eb9735d44
Child:
5:0b0651ac7832
Pulled in more code. Now panel controls are working. Level 0 (attract mode) now goes round an endless loop sending state of panel controls up serial port to PC.

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