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@5:0b0651ac7832, 2013-06-08 (annotated)
- 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?
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 | 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 | } |