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

PlayerObject.cpp

Committer:
RichardE
Date:
2013-06-17
Revision:
18:70190f956a24
Parent:
9:fa7e7b37b632

File content as of revision 18:70190f956a24:

/*
 * SOURCE FILE : PlayerObject.cpp
 *
 * Represents the player objects.
 *
 */

// Define this for debugging messages.
#undef CHATTY

#ifdef CHATTY
    #include "mbed.h"
    extern Serial pc;
#endif

#include "PlayerObject.h"
#include "SoundManager.h"
#include "Sounds.h"
#include "FrameCounter.h"

// Bullet velocity information.
BulletVelocities PlayerObject::bulletVelocities( FromPixel( 2 ), FromPixel( 2 ) );

// Player velocity information.
BulletVelocities PlayerObject::playerVelocities( FromPixel( 1 ), FromPixel( 1 ) );

/***************/
/* CONSTRUCTOR */
/***************/
PlayerObject::PlayerObject() :
  Lives( 5 ),
  Score( 0 ),
  controls( (PanelControls*)NULL ),
  playerBullets( 200 ),              // parameter is first sprite number used for bullets
  bulletCountdown( 0 )
{
}

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

/************************/
/* MOVE THE GAME OBJECT */
/************************/
void PlayerObject::ProtectedMove( void ) {
  // Do nothing if controls are not specified.
  if( controls != (PanelControls*)NULL ) {
    // Read joysticks and buttons. Buttons are not used.
    UInt16 map = controls->GetInputs();
    // Extract bits relating to joystick 1 (player movement).
    UInt16 joy1Map = ( map >> PanelControls::Joy1 ) & 0x0F;
    #ifdef CHATTY
        pc.printf( "Moving player. Joy 1 = %04X.\r\n", (int)joy1Map );
    #endif
    // Fetch velocities associated with this combination of joystick inputs.
    const Int16Pair *pair = playerVelocities.GetVelocities( joy1Map );
    #ifdef CHATTY
        pc.printf( "dx = %d. dy = %d.\r\n", (int)pair->X, (int)pair->Y );
    #endif
    // Add on velocities to player coordinates.
    Xco += pair->X;
    Yco += pair->Y;
    // Deal with starting a new bullet.
    if( bulletCountdown > 0 ) {
      bulletCountdown--;
    }
    else {
      // Extract bits relating to joystick 2 (bullet firing).
      UInt16 joy2Map = ( map >> PanelControls::Joy2 ) & 0x0F;
      // Only start a bullet if at least one joystick contact is closed.
      if( joy2Map != 0 ) {
        #ifdef CHATTY
            pc.puts( "Trying to start a new bullet.\r\n" );
        #endif
        // Fetch velocities associated with this combination of joystick inputs.
        pair = bulletVelocities.GetVelocities( joy2Map );
        // Try and start a new bullet.
        if( playerBullets.StartBullet( Xco, Yco, pair->X, pair->Y ) ) {
            #ifdef CHATTY
                pc.printf( "Bullet started at %d, %d with velocities %d, %d.\r\n", (int)Xco, (int)Yco, (int)pair->X, (int)pair->Y );
            #endif
          // If bullet was started then make a bullet sound.
          SoundManager::Instance.PlaySound( Sounds::FireGun, 0, 0 );
        }
        // Reset countdown until another bullet can start.
        bulletCountdown = 8;
      }
    }
  }
}

/************************/
/* DRAW THE GAME OBJECT */
/************************/
// Pass pointer to Gameduino to draw on in gd.
// This is only called after it has been established that the
// game object is visible.
void PlayerObject::Draw( Gameduino *gd ) {
  Gameduino::Rotation transform;
  SpriteImageId imageId;
  // Check controls have been specified.
  if( controls != (PanelControls*)NULL ) {
    // Read joysticks and buttons. Buttons are not used.
    UInt16 map = controls->GetInputs();
    // Work out which sprite image to use and how to transform it.
    // Player shifts from left to right foot every 4 frames.
    bool leftFootUp = ( ( FrameCounter & 4 ) != 0 );
    if( map & PanelControls::Left2 ) {
      // Firing to the left.
      transform = Gameduino::None;
      if( map & PanelControls::Up2 ) {
        // Firing left and up.
        imageId = leftFootUp ? PlayerGunUpLeftFootUpImage : PlayerGunUpRightFootUpImage;
      }
      else if( map & PanelControls::Down2 ) {
        // Firing left and down.
        imageId = leftFootUp ? PlayerGunDownLeftFootUpImage : PlayerGunDownRightFootUpImage;
      }
      else {
        // Firing left and level.
        imageId = leftFootUp ? PlayerGunLevelLeftFootUpImage : PlayerGunLevelRightFootUpImage;
      }
    }
    else if( map & PanelControls::Right2 ) {
      // Firing to the right.
      transform = Gameduino::FlipX;
      if( map & PanelControls::Up2 ) {
        // Firing right and up. Image is flipped so left foot becomes right foot.
        imageId = leftFootUp ? PlayerGunUpRightFootUpImage : PlayerGunUpLeftFootUpImage;
      }
      else if( map & PanelControls::Down2 ) {
        // Firing right and down. Image is flipped so left foot becomes right foot.
        imageId = leftFootUp ? PlayerGunDownRightFootUpImage : PlayerGunDownLeftFootUpImage;
      }
      else {
        // Firing right and level. Image is flipped so left foot becomes right foot.
        imageId = leftFootUp ? PlayerGunLevelRightFootUpImage : PlayerGunLevelLeftFootUpImage;
      }
    }
    else {
      // Firing up, down or not firing.
      transform = leftFootUp ? Gameduino::None : Gameduino::FlipX;
      // Use a different image if firing up.
      imageId = ( map & PanelControls::Up2 ) ? PlayerBothGunsUpImage : PlayerImage;
    }
  }
  else {
    // Controls have not been specified so use standing still image.
    transform = Gameduino::None;
    imageId = PlayerImage;
  }
  gd->sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), imageId, 0, transform, GoodGuy );
}

/*************************/
/* ADD TO PLAYER'S SCORE */
/*************************/
// Pass number of points to add in points (THIS IS BCD CODED!).
void PlayerObject::AddToScore( UInt16 points ) {
  // Get fourth digit from the right of the score.
  UInt8 digit = (UInt8)( ( Score & 0xF000 ) >> 12 );
  // Add on points.
  if( BCDNumber::Add( Score, points, &Score ) ) {
    // If score overflows then stick at maximum.
    Score = 0x99999999UL;
  }
  // Check if the fourth digit from the right has changed.
  // If it has then you must have passed through a thousand point
  // boundary so award an extra life but don't let it overflow.
  if( ( digit != (UInt8)( ( Score & 0xF000 ) >> 12 ) ) && ( Lives < 255 ) ) {
    SoundManager::Instance.PlaySound( Sounds::ExtraLife, 0, 0 );
    Lives++;
  }
}