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
GameObject.cpp@4:673eb9735d44, 2013-06-08 (annotated)
- 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?
User | Revision | Line number | New 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 | } |