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:
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?

UserRevisionLine numberNew 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 }