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
BrainObject.cpp@18:70190f956a24, 2013-06-17 (annotated)
- Committer:
- RichardE
- Date:
- Mon Jun 17 15:10:43 2013 +0000
- Revision:
- 18:70190f956a24
- Parent:
- 10:bfa1c307c99d
Improved response to button 1 when entering high scores (HighScoreEntry.cpp).
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
RichardE | 7:e72691603fd3 | 1 | /* |
RichardE | 7:e72691603fd3 | 2 | * SOURCE FILE : BrainObject.cpp |
RichardE | 7:e72691603fd3 | 3 | * |
RichardE | 7:e72691603fd3 | 4 | * Represents a big square robot that crushes humans. |
RichardE | 7:e72691603fd3 | 5 | * |
RichardE | 7:e72691603fd3 | 6 | */ |
RichardE | 7:e72691603fd3 | 7 | |
RichardE | 7:e72691603fd3 | 8 | #include "BrainObject.h" |
RichardE | 7:e72691603fd3 | 9 | #include "Gameduino.h" |
RichardE | 7:e72691603fd3 | 10 | #include "FrameCounter.h" |
RichardE | 7:e72691603fd3 | 11 | #include "ArenaConst.h" |
RichardE | 7:e72691603fd3 | 12 | #include "Animations.h" |
RichardE | 7:e72691603fd3 | 13 | #include "LevelData.h" |
RichardE | 7:e72691603fd3 | 14 | #include "SpriteNumber.h" |
RichardE | 7:e72691603fd3 | 15 | #include "BulletVelocityCalculator.h" |
RichardE | 7:e72691603fd3 | 16 | #include "HumanObject.h" |
RichardE | 7:e72691603fd3 | 17 | #include "Random.h" |
RichardE | 10:bfa1c307c99d | 18 | #include "EnemyFactory.h" |
RichardE | 7:e72691603fd3 | 19 | |
RichardE | 7:e72691603fd3 | 20 | /***************/ |
RichardE | 7:e72691603fd3 | 21 | /* CONSTRUCTOR */ |
RichardE | 7:e72691603fd3 | 22 | /***************/ |
RichardE | 7:e72691603fd3 | 23 | BrainObject::BrainObject() : |
RichardE | 7:e72691603fd3 | 24 | HumansToChase( (GameObject**)NULL ), |
RichardE | 7:e72691603fd3 | 25 | bulletActive( false ), |
RichardE | 7:e72691603fd3 | 26 | bulletIndex( 0 ) |
RichardE | 7:e72691603fd3 | 27 | { |
RichardE | 7:e72691603fd3 | 28 | // Movement is always restricted (property of GameObject). |
RichardE | 7:e72691603fd3 | 29 | MovementRestricted = true; |
RichardE | 7:e72691603fd3 | 30 | // Restrict to boundary of arena. |
RichardE | 7:e72691603fd3 | 31 | Bounds = &ArenaRectangle; |
RichardE | 7:e72691603fd3 | 32 | } |
RichardE | 7:e72691603fd3 | 33 | |
RichardE | 7:e72691603fd3 | 34 | /**************/ |
RichardE | 7:e72691603fd3 | 35 | /* DESTRUCTOR */ |
RichardE | 7:e72691603fd3 | 36 | /**************/ |
RichardE | 7:e72691603fd3 | 37 | BrainObject::~BrainObject() { |
RichardE | 7:e72691603fd3 | 38 | } |
RichardE | 7:e72691603fd3 | 39 | |
RichardE | 7:e72691603fd3 | 40 | /******************************************************/ |
RichardE | 7:e72691603fd3 | 41 | /* DETERMINE IF A HUMAN IS A VALID TARGET FOR A BRAIN */ |
RichardE | 7:e72691603fd3 | 42 | /******************************************************/ |
RichardE | 7:e72691603fd3 | 43 | // Returns true if object is a human that is valid for targeting by brain. |
RichardE | 7:e72691603fd3 | 44 | bool BrainObject::ValidHuman( GameObject *object ) { |
RichardE | 7:e72691603fd3 | 45 | HumanObject *human = (HumanObject*)object; |
RichardE | 7:e72691603fd3 | 46 | return ( human != (HumanObject*)NULL ) && ( human->CurrentState == HumanObject::WalkingAbout ); |
RichardE | 7:e72691603fd3 | 47 | } |
RichardE | 7:e72691603fd3 | 48 | |
RichardE | 7:e72691603fd3 | 49 | /******************/ |
RichardE | 7:e72691603fd3 | 50 | /* START A BULLET */ |
RichardE | 7:e72691603fd3 | 51 | /******************/ |
RichardE | 7:e72691603fd3 | 52 | // Pass sprite number to use in spriteNumber. |
RichardE | 7:e72691603fd3 | 53 | // Returns pointer to bullet object or NULL on failure. |
RichardE | 10:bfa1c307c99d | 54 | // Memory is dynamically allocated since Brain bullet is an EnemyObject. |
RichardE | 7:e72691603fd3 | 55 | BrainBulletObject *BrainObject::StartBullet( UInt8 spriteNumber ) { |
RichardE | 10:bfa1c307c99d | 56 | // Create a new bullet. |
RichardE | 10:bfa1c307c99d | 57 | BrainBulletObject *newBullet = (BrainBulletObject*)EnemyFactory::Instance.MakeEnemy( BrainBullet ); |
RichardE | 10:bfa1c307c99d | 58 | if( newBullet != (BrainBulletObject*)NULL ) { |
RichardE | 10:bfa1c307c99d | 59 | // Give bullet same coordinates as the brain that fired it. |
RichardE | 10:bfa1c307c99d | 60 | newBullet->Xco = Xco; |
RichardE | 10:bfa1c307c99d | 61 | newBullet->Yco = Yco; |
RichardE | 10:bfa1c307c99d | 62 | // Restrict bullet to boundary of arena. |
RichardE | 10:bfa1c307c99d | 63 | newBullet->Bounds = &ArenaRectangle; |
RichardE | 10:bfa1c307c99d | 64 | // Set correct sprite number. |
RichardE | 10:bfa1c307c99d | 65 | newBullet->SpriteNumber = spriteNumber; |
RichardE | 10:bfa1c307c99d | 66 | // Must make it visible because last time bullet was |
RichardE | 10:bfa1c307c99d | 67 | // killed off this property may have been set to false. |
RichardE | 10:bfa1c307c99d | 68 | newBullet->Visible = true; |
RichardE | 10:bfa1c307c99d | 69 | // Similarly hit points may already be at zero. |
RichardE | 10:bfa1c307c99d | 70 | // If you don't do this then bullet hit points gets decremented to -1 (0xFF) |
RichardE | 10:bfa1c307c99d | 71 | // and it becomes indestructible. |
RichardE | 10:bfa1c307c99d | 72 | newBullet->HitPoints = 1; |
RichardE | 10:bfa1c307c99d | 73 | // Calculate bullet velocities. |
RichardE | 10:bfa1c307c99d | 74 | // Aim for a point somewhere in the vicinity of the chase object. |
RichardE | 10:bfa1c307c99d | 75 | if( chaseObject != (GameObject*)NULL ) { |
RichardE | 10:bfa1c307c99d | 76 | UInt16 targetX = chaseObject->Xco + (Int16)Random::Get( -128, +128 ); |
RichardE | 10:bfa1c307c99d | 77 | UInt16 targetY = chaseObject->Yco + (Int16)Random::Get( -128, +128 ); |
RichardE | 10:bfa1c307c99d | 78 | BulletVelocityCalculator::CalculateVelocities( |
RichardE | 10:bfa1c307c99d | 79 | targetX - Xco, targetY - Yco, |
RichardE | 10:bfa1c307c99d | 80 | 80, &(newBullet->HVelocity), &(newBullet->VVelocity) |
RichardE | 10:bfa1c307c99d | 81 | ); |
RichardE | 10:bfa1c307c99d | 82 | } |
RichardE | 7:e72691603fd3 | 83 | } |
RichardE | 10:bfa1c307c99d | 84 | return newBullet; |
RichardE | 7:e72691603fd3 | 85 | } |
RichardE | 7:e72691603fd3 | 86 | |
RichardE | 7:e72691603fd3 | 87 | /************************/ |
RichardE | 7:e72691603fd3 | 88 | /* MOVE THE GAME OBJECT */ |
RichardE | 7:e72691603fd3 | 89 | /************************/ |
RichardE | 7:e72691603fd3 | 90 | void BrainObject::ProtectedMove( void ) { |
RichardE | 7:e72691603fd3 | 91 | UInt8 humanIndex, newBulletIndex; |
RichardE | 7:e72691603fd3 | 92 | BrainBulletObject *newBullet; |
RichardE | 7:e72691603fd3 | 93 | // Make sure you have some humans to chase. |
RichardE | 7:e72691603fd3 | 94 | // Locate the nearest human. |
RichardE | 7:e72691603fd3 | 95 | if( |
RichardE | 7:e72691603fd3 | 96 | ( HumansToChase != (GameObject**)NULL ) && |
RichardE | 7:e72691603fd3 | 97 | GameObject::FindNearestObject( HumansToChase, LevelData::MaxHumans, Xco, Yco, &ValidHuman, &humanIndex ) |
RichardE | 7:e72691603fd3 | 98 | ) { |
RichardE | 7:e72691603fd3 | 99 | // Move towards target human. |
RichardE | 7:e72691603fd3 | 100 | GameObject *human = HumansToChase[ humanIndex ]; |
RichardE | 7:e72691603fd3 | 101 | MoveTowards( human, BrainSpeed ); |
RichardE | 7:e72691603fd3 | 102 | } |
RichardE | 7:e72691603fd3 | 103 | // If no humans to chase then chase chaseObject instead (player). |
RichardE | 7:e72691603fd3 | 104 | else if( chaseObject != (GameObject*)NULL ) { |
RichardE | 7:e72691603fd3 | 105 | MoveTowards( chaseObject, BrainSpeed ); |
RichardE | 7:e72691603fd3 | 106 | } |
RichardE | 7:e72691603fd3 | 107 | // Skip next bit if enemies have not been specified. |
RichardE | 7:e72691603fd3 | 108 | if( Enemies != (GameObject**)NULL ) { |
RichardE | 7:e72691603fd3 | 109 | // Check if bullet was active but has now gone away. |
RichardE | 7:e72691603fd3 | 110 | if( bulletActive && ( Enemies[ bulletIndex ] == (GameObject*)NULL ) ) { |
RichardE | 7:e72691603fd3 | 111 | bulletActive = false; |
RichardE | 7:e72691603fd3 | 112 | } |
RichardE | 7:e72691603fd3 | 113 | // See if a new bullet should be started. |
RichardE | 7:e72691603fd3 | 114 | if( |
RichardE | 7:e72691603fd3 | 115 | ! bulletActive && ( Random::Get( 40 ) == 0 ) && |
RichardE | 7:e72691603fd3 | 116 | GameObject::FindUnusedObject( Enemies, LevelData::MaxEnemies, &newBulletIndex ) && |
RichardE | 7:e72691603fd3 | 117 | ( ( newBullet = StartBullet( FirstEnemySprite + newBulletIndex ) ) != (BrainBulletObject*)NULL ) |
RichardE | 7:e72691603fd3 | 118 | ) { |
RichardE | 7:e72691603fd3 | 119 | Enemies[ newBulletIndex ] = newBullet; |
RichardE | 7:e72691603fd3 | 120 | bulletIndex = newBulletIndex; |
RichardE | 7:e72691603fd3 | 121 | bulletActive = true; |
RichardE | 7:e72691603fd3 | 122 | } |
RichardE | 7:e72691603fd3 | 123 | } |
RichardE | 7:e72691603fd3 | 124 | } |
RichardE | 7:e72691603fd3 | 125 | |
RichardE | 7:e72691603fd3 | 126 | /************************/ |
RichardE | 7:e72691603fd3 | 127 | /* DRAW THE GAME OBJECT */ |
RichardE | 7:e72691603fd3 | 128 | /************************/ |
RichardE | 7:e72691603fd3 | 129 | // This is only called after it has been established that the |
RichardE | 7:e72691603fd3 | 130 | // game object is visible. |
RichardE | 7:e72691603fd3 | 131 | void BrainObject::Draw( Gameduino *gd ) { |
RichardE | 7:e72691603fd3 | 132 | Gameduino::Rotation transform = ( FrameCounter & 8 ) ? Gameduino::FlipX : Gameduino::None; |
RichardE | 7:e72691603fd3 | 133 | gd->sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), BrainImage, 0, transform, BadGuy ); |
RichardE | 7:e72691603fd3 | 134 | } |