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

Committer:
RichardE
Date:
2013-06-17
Revision:
18:70190f956a24
Parent:
10:bfa1c307c99d

File content as of revision 18:70190f956a24:

/*
 * SOURCE FILE : BrainObject.cpp
 *
 * Represents a big square robot that crushes humans.
 *
 */

#include "BrainObject.h"
#include "Gameduino.h"
#include "FrameCounter.h"
#include "ArenaConst.h"
#include "Animations.h"
#include "LevelData.h"
#include "SpriteNumber.h"
#include "BulletVelocityCalculator.h"
#include "HumanObject.h"
#include "Random.h"
#include "EnemyFactory.h"

/***************/
/* CONSTRUCTOR */
/***************/
BrainObject::BrainObject() :
    HumansToChase( (GameObject**)NULL ),
    bulletActive( false ),
    bulletIndex( 0 )
{
  // Movement is always restricted (property of GameObject).
  MovementRestricted = true;
  // Restrict to boundary of arena.
  Bounds = &ArenaRectangle;
}

/**************/
/* DESTRUCTOR */
/**************/
BrainObject::~BrainObject() {
}

/******************************************************/
/* DETERMINE IF A HUMAN IS A VALID TARGET FOR A BRAIN */
/******************************************************/
// Returns true if object is a human that is valid for targeting by brain.
bool BrainObject::ValidHuman( GameObject *object ) {
    HumanObject *human = (HumanObject*)object;
    return ( human != (HumanObject*)NULL ) && ( human->CurrentState == HumanObject::WalkingAbout );
}

/******************/
/* START A BULLET */
/******************/
// Pass sprite number to use in spriteNumber.
// Returns pointer to bullet object or NULL on failure.
// Memory is dynamically allocated since Brain bullet is an EnemyObject.
BrainBulletObject *BrainObject::StartBullet( UInt8 spriteNumber ) {
    // Create a new bullet.
    BrainBulletObject *newBullet = (BrainBulletObject*)EnemyFactory::Instance.MakeEnemy( BrainBullet );
    if( newBullet != (BrainBulletObject*)NULL ) {
        // Give bullet same coordinates as the brain that fired it.
        newBullet->Xco = Xco;
        newBullet->Yco = Yco;
        // Restrict bullet to boundary of arena.
        newBullet->Bounds = &ArenaRectangle;
        // Set correct sprite number.
        newBullet->SpriteNumber = spriteNumber;
        // Must make it visible because last time bullet was
        // killed off this property may have been set to false.
        newBullet->Visible = true;
        // Similarly hit points may already be at zero.
        // If you don't do this then bullet hit points gets decremented to -1 (0xFF)
        // and it becomes indestructible.
        newBullet->HitPoints = 1;
        // Calculate bullet velocities.
        // Aim for a point somewhere in the vicinity of the chase object.
        if( chaseObject != (GameObject*)NULL ) {
            UInt16 targetX = chaseObject->Xco + (Int16)Random::Get( -128, +128 );
            UInt16 targetY = chaseObject->Yco + (Int16)Random::Get( -128, +128 );
            BulletVelocityCalculator::CalculateVelocities(
                targetX - Xco, targetY - Yco,
                80, &(newBullet->HVelocity), &(newBullet->VVelocity)
            );
        }
    }
    return newBullet;
}

/************************/
/* MOVE THE GAME OBJECT */
/************************/
void BrainObject::ProtectedMove( void ) {
    UInt8 humanIndex, newBulletIndex;
    BrainBulletObject *newBullet;
    // Make sure you have some humans to chase.
    // Locate the nearest human.
    if(
        ( HumansToChase != (GameObject**)NULL ) &&
        GameObject::FindNearestObject( HumansToChase, LevelData::MaxHumans, Xco, Yco, &ValidHuman, &humanIndex )
    ) {
        // Move towards target human.
        GameObject *human = HumansToChase[ humanIndex ];
        MoveTowards( human, BrainSpeed );
    }
    // If no humans to chase then chase chaseObject instead (player).
    else if( chaseObject != (GameObject*)NULL ) {
        MoveTowards( chaseObject, BrainSpeed );
    }
    // Skip next bit if enemies have not been specified.
    if( Enemies != (GameObject**)NULL ) {
        // Check if bullet was active but has now gone away.
        if( bulletActive && ( Enemies[ bulletIndex ] == (GameObject*)NULL ) ) {
            bulletActive = false;
        }
        // See if a new bullet should be started.
        if(
            ! bulletActive && ( Random::Get( 40 ) == 0 ) &&
            GameObject::FindUnusedObject( Enemies, LevelData::MaxEnemies, &newBulletIndex ) &&
            ( ( newBullet = StartBullet( FirstEnemySprite + newBulletIndex ) ) != (BrainBulletObject*)NULL )
        ) {
            Enemies[ newBulletIndex ] = newBullet;
            bulletIndex = newBulletIndex;
            bulletActive = true;
        }
    }
}

/************************/
/* DRAW THE GAME OBJECT */
/************************/
// This is only called after it has been established that the
// game object is visible.
void BrainObject::Draw( Gameduino *gd ) {
  Gameduino::Rotation transform = ( FrameCounter & 8 ) ? Gameduino::FlipX : Gameduino::None;
  gd->sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), BrainImage, 0, transform, BadGuy );
}