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
Revision 7:e72691603fd3, committed 2013-06-08
- Comitter:
- RichardE
- Date:
- Sat Jun 08 16:44:54 2013 +0000
- Parent:
- 6:8bbdb70bc11c
- Child:
- 8:82d88f9381f3
- Commit message:
- Now have grunts wandering around on level 1. They follow the player but since no collision detection logic yet nobody ever gets killed.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Animations.cpp Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,20 @@ +/* + * SOURCE FILE : Animations.cpp + * + * Animations consisting of arrays of sprite image numbers in program memory. + * + */ + +#include "Animations.h" +#include "SpriteImageId.h" + +const UInt8 Animations::WomanAnimation[] = { Woman0Image, Woman1Image, Woman2Image, Woman1Image }; +const UInt8 Animations::ManAnimation[] = { Man0Image, Man1Image, Man2Image, Man1Image }; + +// Array containing addresses of all the human animations. +const UInt8 *Animations::HumanAnimations[ HumanAnimationCount ] = { + WomanAnimation, + ManAnimation, +}; + +const UInt8 Animations::CrusherAnimation[] = { Crusher0Image, Crusher1Image, Crusher2Image, Crusher1Image };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Animations.h Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,35 @@ +/* + * SOURCE FILE : Animations.h + * + * Animations consisting of arrays of sprite image numbers in program memory. + * + */ + +#ifndef AnimationsIncluded + + #define AnimationsIncluded + + #include "Types.h" + + class Animations { + + public : + + static const UInt8 WomanAnimation[]; + static const UInt8 ManAnimation[]; + + enum { + HumanAnimationCount = 2, // number of animations there are for humans + }; + + // Array containing addresses of all the human animations. + static const UInt8 *HumanAnimations[ HumanAnimationCount ]; + + static const UInt8 CrusherAnimation[]; + + }; + +#endif + +// END of Animations.h +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BrainBulletObject.cpp Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,38 @@ +/* + * SOURCE FILE : BrainBulletObject.cpp + * + * Definition of class BrainBulletObject. + * + */ + +#include "BrainBulletObject.h" + +/***************/ +/* CONSTRUCTOR */ +/***************/ +BrainBulletObject::BrainBulletObject() : + HVelocity( 0 ), + VVelocity( 0 ) +{ + DeleteWhenRestricted = true; + RetainOnLevelRestart = false; + PixelWidth = 4; + PixelHeight = 4; +} + +/************************/ +/* DRAW THE GAME OBJECT */ +/************************/ +// Note if Visible is false this should not draw anything +// and/or hide the visible object. +void BrainBulletObject::Draw( Gameduino *gd ) { + gd->sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), BrainBulletImage, 0, Gameduino::None, BadGuy ); +} + +/************************/ +/* MOVE THE GAME OBJECT */ +/************************/ +void BrainBulletObject::ProtectedMove( void ) { + Xco += HVelocity; + Yco += VVelocity; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BrainBulletObject.h Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,62 @@ +/* + * SOURCE FILE : BrainBulletObject.h + * + * Definition of class BrainBulletObject. + * This is the enemy object used as a bullet fired by BrainObject enemies. + * + */ + +#ifndef BrainBulletObjectDefined + + #define BrainBulletObjectDefined + + #include "EnemyObject.h" + + class BrainBulletObject : public EnemyObject { + + public : + + // Horizontal and vertical velocities at which bullet is moving. + // NOT pixel velocities. + Int16 HVelocity, VVelocity; + + /***************/ + /* CONSTRUCTOR */ + /***************/ + BrainBulletObject(); + + /*****************************/ + /* GET TYPE OF ENEMY THIS IS */ + /*****************************/ + // Returns enemy type. + virtual EnemyType GetEnemyType( void ) { + return BrainBullet; + } + + /*******************************************************/ + /* GET NUMBER OF POINTS AWARDED FOR KILLING THIS ENEMY */ + /*******************************************************/ + // Returns number of points (in BCD). + virtual UInt8 GetPoints( void ) { + return 0x10; + } + + /************************/ + /* DRAW THE GAME OBJECT */ + /************************/ + // Note if Visible is false this should not draw anything + // and/or hide the visible object. + virtual void Draw( Gameduino *gd ); + + protected : + + /************************/ + /* MOVE THE GAME OBJECT */ + /************************/ + virtual void ProtectedMove( void ); + + }; + +#endif + +/* END of BrainBulletObject.h */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BrainObject.cpp Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,128 @@ +/* + * 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" + +/***************/ +/* 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; + // Restrict bullet to boundary of arena. + bullet.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. +BrainBulletObject *BrainObject::StartBullet( UInt8 spriteNumber ) { + // Give bullet same coordinates as the brain that fired it. + bullet.Xco = Xco; + bullet.Yco = Yco; + // Set correct sprite number. + bullet.SpriteNumber = spriteNumber; + // Must make it visible because last time bullet was + // killed off this property may have been set to false. + bullet.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. + bullet.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, &bullet.HVelocity, &bullet.VVelocity + ); + } + return • +} + +/************************/ +/* 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 ); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BrainObject.h Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,90 @@ +/* + * SOURCE FILE : BrainObject.h + * + * Represents a wandering human. + * + */ + +#ifndef BrainObjectIncluded + + #define BrainObjectIncluded + + #include "Types.h" + #include "EnemyObject.h" + #include "GameObjectTypes.h" + #include "BrainBulletObject.h" + + class BrainObject : public EnemyObject { + + public : + + // Points to an array of humans to chase. + GameObject **HumansToChase; + + /***************/ + /* CONSTRUCTOR */ + /***************/ + BrainObject(); + + /**************/ + /* DESTRUCTOR */ + /**************/ + virtual ~BrainObject(); + + /*****************************/ + /* GET TYPE OF ENEMY THIS IS */ + /*****************************/ + // Returns enemy type. + virtual EnemyType GetEnemyType( void ) { + return Brain; + } + + /*******************************************************/ + /* GET NUMBER OF POINTS AWARDED FOR KILLING THIS ENEMY */ + /*******************************************************/ + // Returns number of points. + virtual UInt8 GetPoints( void ) { + return 0x20; // BCD! + } + + /************************/ + /* MOVE THE GAME OBJECT */ + /************************/ + virtual void ProtectedMove( void ); + + /************************/ + /* DRAW THE GAME OBJECT */ + /************************/ + // This is only called after it has been established that the + // game object is visible. + virtual void Draw( Gameduino *gd ); + + private : + + enum { + BrainSpeed = 24, // speed at which brains move towards their prey + }; + + bool bulletActive; // true if a bullet fired by this brain is zipping around + UInt8 bulletIndex; // index of active bullet in enemies array + BrainBulletObject bullet; // the bullet belonging to this brain + + /******************************************************/ + /* 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. + static bool ValidHuman( GameObject *object ); + + /******************/ + /* START A BULLET */ + /******************/ + // Pass sprite number to use in spriteNumber. + // Returns pointer to bullet object or NULL on failure. + BrainBulletObject *StartBullet( UInt8 spriteNumber ); + + }; + +#endif + +/* END of BrainObject.h */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BulletVelocityCalculator.cpp Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,63 @@ +/* + * SOURCE FILE : BulletVelocityCalculator.cpp + * + * Definition of class BulletVelocityCalculator. + * + */ + +#include <stdlib.h> // for abs +#include "BulletVelocityCalculator.h" + +// A few constants. +#define COS11_25 0.980785 +#define SIN11_25 0.195090 +#define COS33_75 0.831470 +#define SIN33_75 0.555570 +#define COS56_25 0.555570 +#define SIN56_25 0.831470 +#define COS78_75 0.195090 +#define SIN78_75 0.980785 + +/*******************************/ +/* CALCULATE BULLET VELOCITIES */ +/*******************************/ +// Pass distances to target in dx and dy. +// Pass velocity at which bullet moves in v. +// Horizontal and vertical velocities returned in variables pointed to by hv and vv. +void BulletVelocityCalculator::CalculateVelocities( Int16 dx, Int16 dy, Int16 v, Int16 *hv, Int16 *vv ) { + Int16 ax = abs( dx ); + Int16 ay = abs( dy ); + if( ax < 8 ) { + *hv = 0; + *vv = v; + } + else if( ay < 8 ) { + *hv = v; + *vv = 0; + } + else { + float ratio = (float)ay / (float)ax; + if( ratio < 0.5f ) { + *hv = v * COS11_25; + *vv = v * SIN11_25; + } + else if( ratio < 1.0f ) { + *hv = v * COS33_75; + *vv = v * SIN33_75; + } + else if( ratio < 2.0f ) { + *hv = v * COS56_25; + *vv = v * SIN56_25; + } + else { + *hv = v * COS78_75; + *vv = v * SIN78_75; + } + } + if( dx < 0 ) { + *hv = -(*hv); + } + if( dy < 0 ) { + *vv = -(*vv); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BulletVelocityCalculator.h Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,33 @@ +/* + * SOURCE FILE : BulletVelocityCalculator.h + * + * Definition of class BulletVelocityCalculator. + * Used to calculate the horizontal and vertical velocities necessary for a bullet to + * hit a target, + * + */ + +#ifndef BulletVelocityCalculatorDefined + + #define BulletVelocityCalculatorDefined + + #include "Types.h" + + class BulletVelocityCalculator { + + public : + + /*******************************/ + /* CALCULATE BULLET VELOCITIES */ + /*******************************/ + // Pass distances to target in dx and dy. + // Pass velocity at which bullet moves in v. + // Horizontal and vertical velocities returned in variables pointed to by hv and vv. + static void CalculateVelocities( Int16 dx, Int16 dy, Int16 v, Int16 *hv, Int16 *vv ); + + }; + +#endif + +/* END of BulletVelocityCalculator.h */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CrusherObject.cpp Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,77 @@ +/* + * SOURCE FILE : CrusherObject.cpp + * + * Represents a big square robot that crushes humans. + * + */ + +#include "CrusherObject.h" +#include "Gameduino.h" +#include "FrameCounter.h" +#include "ArenaConst.h" +#include "Animations.h" +#include "Walker.h" + +/***************/ +/* CONSTRUCTOR */ +/***************/ +CrusherObject::CrusherObject() : + animationData( Animations::CrusherAnimation ), + stunCountdown( 0 ), + stunFrameCount( 0 ) +{ + // Initialise horizontal and vertical speeds. + Walker::InitialiseVelocities( &hSpeed, &vSpeed ); + // Movement is always restricted (property of GameObject). + MovementRestricted = true; + // Restrict to boundary of arena. + Bounds = &ArenaRectangle; + // Crushers are indestructable. + HitPoints = Indestructable; + // Crushers squash humans. + SquashesHumans = true; +} + +/**************/ +/* DESTRUCTOR */ +/**************/ +CrusherObject::~CrusherObject() { +} + +/************************/ +/* MOVE THE GAME OBJECT */ +/************************/ +void CrusherObject::ProtectedMove( void ) { + if( stunCountdown > 0 ) { + stunCountdown--; + } + else { + Walker::Walk( &Xco, &Yco, &hSpeed, &vSpeed, RestrictionFlags ); + } +} + +/************************/ +/* 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 CrusherObject::Draw( Gameduino *gd ) { + // Only update stunFrameCount when not stunned. + // This halts animation when in stunned state. + if( stunCountdown == 0 ) { + stunFrameCount = FrameCounter >> 3; + } + Walker::Draw( gd, SpriteNumber, Xco, Yco, hSpeed, stunFrameCount, animationData ); +} + +/********************************************/ +/* INFORM ENEMY IT HAS BEEN HIT BY A BULLET */ +/********************************************/ +// Default implementation does nothing but if special behaviour +// is required in a derived class then this should be overridden. +// Note that this does NOT deal with determining if the enemy is dead or not. +// An enemy ALWAYS dies if HitPoints reaches zero. +void CrusherObject::RegisterHitByBullet( void ) { + stunCountdown = 10; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CrusherObject.h Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,87 @@ +/* + * SOURCE FILE : CrusherObject.h + * + * Represents a wandering human. + * + */ + +#ifndef CrusherObjectIncluded + + #define CrusherObjectIncluded + + #include "Types.h" + #include "EnemyObject.h" + #include "GameObjectTypes.h" + + class CrusherObject : public EnemyObject { + + public : + + /***************/ + /* CONSTRUCTOR */ + /***************/ + CrusherObject(); + + /**************/ + /* DESTRUCTOR */ + /**************/ + virtual ~CrusherObject(); + + /*****************************/ + /* GET TYPE OF ENEMY THIS IS */ + /*****************************/ + // Returns enemy type. + virtual EnemyType GetEnemyType( void ) { + return Crusher; + } + + /*******************************************************/ + /* GET NUMBER OF POINTS AWARDED FOR KILLING THIS ENEMY */ + /*******************************************************/ + // Returns number of points. + virtual UInt8 GetPoints( void ) { + return 0x10; // BCD! + } + + /************************/ + /* MOVE THE GAME OBJECT */ + /************************/ + virtual void ProtectedMove( void ); + + /************************/ + /* DRAW THE GAME OBJECT */ + /************************/ + // Pass pointer to a Gameduino to draw on in gd. + // This is only called after it has been established that the + // game object is visible. + virtual void Draw( Gameduino *gd ); + + /********************************************/ + /* INFORM ENEMY IT HAS BEEN HIT BY A BULLET */ + /********************************************/ + // Default implementation does nothing but if special behaviour + // is required in a derived class then this should be overridden. + // Note that this does NOT deal with determining if the enemy is dead or not. + // An enemy ALWAYS dies if HitPoints reaches zero. + virtual void RegisterHitByBullet( void ); + + private : + + // Address of animation data in program memory. + const UInt8 *animationData; + + // Horizontal and vertical velocities. + Int16 hSpeed, vSpeed; + + // Stun countdown. Crusher does not move until this reaches zero. + UInt8 stunCountdown; + + // Frame count at the moment crusher was stunned. + UInt8 stunFrameCount; + + }; + +#endif + +/* END of CrusherObject.h */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EnemyObject.cpp Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,30 @@ +/* + * SOURCE FILE : EnemyObject.cpp + * + * Base class for enemy objects. + * + */ + +#include "EnemyObject.h" + +// Default object to chase. +PlayerObject EnemyObject::defaultChaseObject; + +/*****************************************************/ +/* CHECK IF ALL SURVIVING ENEMIES ARE INDESTRUCTABLE */ +/*****************************************************/ +// Pass pointer to array of pointers to EnemyObjects in enemies. +// Pass number of pointers in the array in enemyCount. +bool EnemyObject::AreAllIndestructable( const EnemyObject **enemies, UInt8 enemyCount ) { + const EnemyObject *enemy; + bool foundMortal = false; + UInt8 i = 0; + while( ! foundMortal && ( i < enemyCount ) ) { + enemy = enemies[ i ]; + if( ( enemy != (EnemyObject*)NULL ) && ( enemy->HitPoints != Indestructable ) ) { + foundMortal = true; + } + i++; + } + return ! foundMortal; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EnemyObject.h Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,112 @@ +/* + * SOURCE FILE : EnemyObject.h + * + * Base class for enemy objects. + * + */ + +#ifndef EnemyObjectIncluded + + #define EnemyObjectIncluded + + #include "GameObject.h" + #include "PlayerObject.h" + #include "EnemyType.h" + + class EnemyObject : public GameObject { + + public : + + enum { + Indestructable = 0xFF, + }; + + // Number of hit points remaining. + // When this reaches zero the enemy dies. + // However, if this has the special value Indestructable then enemy cannot be killed. + UInt8 HitPoints; + + // Set to true of the enemy squashes humans. + bool SquashesHumans; + + // Pointer to array of pointers to enemies. + // Some enemies may need to add new enemies (such as bullets or new spawning enemies) to this array. + GameObject **Enemies; + + /***************/ + /* CONSTRUCTOR */ + /***************/ + EnemyObject() : + HitPoints( 1 ), + SquashesHumans( false ), + Enemies( (GameObject**)NULL ), + chaseObject( &defaultChaseObject ) + { + } + + /**************/ + /* DESTRUCTOR */ + /**************/ + virtual ~EnemyObject() { + } + + /************************/ + /* GET GAME OBJECT TYPE */ + /************************/ + // Returns type of game object. + virtual GameObjectTypes GetType( void ) { + return EnemyObjectType; + } + + /*****************************/ + /* GET TYPE OF ENEMY THIS IS */ + /*****************************/ + // Returns enemy type. + virtual EnemyType GetEnemyType( void ) = 0; + + /*******************************************************/ + /* GET NUMBER OF POINTS AWARDED FOR KILLING THIS ENEMY */ + /*******************************************************/ + // Returns number of points (in BCD). + virtual UInt8 GetPoints( void ) = 0; + + /***********************/ + /* SET OBJECT TO CHASE */ + /***********************/ + // Pass pointer to object to chase in co. + void SetChaseObject( GameObject *co ) { + chaseObject = co; + } + + /********************************************/ + /* INFORM ENEMY IT HAS BEEN HIT BY A BULLET */ + /********************************************/ + // Default implementation does nothing but if special behaviour + // is required in a derived class then this should be overridden. + // Note that this does NOT deal with determining if the enemy is dead or not. + // An enemy ALWAYS dies if HitPoints reaches zero. + virtual void RegisterHitByBullet( void ) {} + + /*****************************************************/ + /* CHECK IF ALL SURVIVING ENEMIES ARE INDESTRUCTABLE */ + /*****************************************************/ + // Pass pointer to array of pointers to EnemyObjects in enemies. + // Pass number of pointers in the array in enemyCount. + static bool AreAllIndestructable( const EnemyObject **enemies, UInt8 enemyCount ); + + protected : + + // Object to chase. + GameObject *chaseObject; + + private : + + // Default object to chase. + static PlayerObject defaultChaseObject; + + }; + +#endif + +/* END of EnemyObject.h */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EnemyType.h Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,23 @@ +/* + * SOURCE FILE : EnemyType.h + * + * Enumeration of all the possible enemy types. + * + */ + +#ifndef EnemyTypeIncluded + + #define EnemyTypeIncluded + + enum EnemyType { + Grunt, + BlueMeany, + Crusher, + Brain, + BrainBullet, + }; + +#endif + +/* END of EnemyType.h */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GruntObject.cpp Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,19 @@ +/* + * SOURCE FILE : GruntObject.cpp + * + * Represents the grunt enemy object. + * + */ + +#include "GruntObject.h" + +// Speed at which grunt moves. +Int16 GruntObject::gruntSpeed = FromPixel( 1 ) >> 2; + +/************************/ +/* MOVE THE GAME OBJECT */ +/************************/ +void GruntObject::ProtectedMove( void ) { + MoveTowards( chaseObject, gruntSpeed ); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GruntObject.h Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,74 @@ +/* + * SOURCE FILE : GruntObject.h + * + * Represents the grunt enemy object. + * + */ + +#ifndef GruntObjectIncluded + + #define GruntObjectIncluded + + #include "EnemyObject.h" + #include "SpriteImageId.h" + #include "FrameCounter.h" + + class GruntObject : public EnemyObject { + + public : + + /***************/ + /* CONSTRUCTOR */ + /***************/ + GruntObject() { + } + + /**************/ + /* DESTRUCTOR */ + /**************/ + virtual ~GruntObject() { + } + + /*****************************/ + /* GET TYPE OF ENEMY THIS IS */ + /*****************************/ + // Returns enemy type. + virtual EnemyType GetEnemyType( void ) { + return Grunt; + } + + /*******************************************************/ + /* GET NUMBER OF POINTS AWARDED FOR KILLING THIS ENEMY */ + /*******************************************************/ + // Returns number of points. + virtual UInt8 GetPoints( void ) { + return 0x5; // In BCD! + } + + /************************/ + /* MOVE THE GAME OBJECT */ + /************************/ + virtual void ProtectedMove( void ); + + /************************/ + /* DRAW THE GAME OBJECT */ + /************************/ + // Pass Gameduino to draw on in gd. + // This is only called after it has been established that the + // game object is visible. + virtual void Draw( Gameduino *gd ) { + Gameduino::Rotation transform = ( FrameCounter & 8 ) ? Gameduino::FlipX : Gameduino::None; + gd->sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), GruntImage, 0, transform, BadGuy ); + } + + private : + + // Speed at which grunts move. + static Int16 gruntSpeed; + + }; + +#endif + +/* END of GruntObject.h */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HumanObject.cpp Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,92 @@ +/* + * SOURCE FILE : HumanObject.cpp + * + * Represents a wandering human. + * + */ + +#include "HumanObject.h" +#include "Gameduino.h" +#include "FrameCounter.h" +#include "ArenaConst.h" +#include "Animations.h" +#include "Walker.h" + +// Index of next animation to use when constructing. +UInt8 HumanObject::nextAnimationIndex = 0; + +/***************/ +/* CONSTRUCTOR */ +/***************/ +// Pass number of sprite to use in sn. +// Pass address of animation data in ad. +// Animation data must consist of AnimationStages bytes which gives the sprite +// image numbers used for each state of the animation. +HumanObject::HumanObject() : + CurrentState( WalkingAbout ), + animationData( Animations::HumanAnimations[ nextAnimationIndex++ ] ), + countdown( 100 ) +{ + // Wrap around animation index. + nextAnimationIndex %= Animations::HumanAnimationCount; + // Initialise horizontal and vertical speeds. + Walker::InitialiseVelocities( &hSpeed, &vSpeed ); + // Movement is always restricted (property of GameObject). + MovementRestricted = true; + // Restrict to boundary of arena. + Bounds = &ArenaRectangle; +} + +/**************/ +/* DESTRUCTOR */ +/**************/ +HumanObject::~HumanObject() { +} + +/*****************************/ +/* GET TYPE OF HUMAN THIS IS */ +/*****************************/ +// Returns type of human. +HumanObject::HumanType HumanObject::GetHumanType( void ) { + return ( animationData == Animations::WomanAnimation ) ? Woman : Man; +} + +/************************/ +/* MOVE THE GAME OBJECT */ +/************************/ +void HumanObject::ProtectedMove( void ) { + switch( CurrentState ) { + case WalkingAbout : + // Make human bounce of edges of restriction area. + Walker::Walk( &Xco, &Yco, &hSpeed, &vSpeed, RestrictionFlags ); + break; + case Rescued : + case Dead : + // Count down and when count reaches zero make human invisible. + if( countdown > 0 ) { + countdown--; + } + Visible = ( countdown > 0 ); + break; + } +} + +/************************/ +/* DRAW THE GAME OBJECT */ +/************************/ +// Pass pointer to a Gameduino to draw on in gd. +// This is only called after it has been established that the +// game object is visible. +void HumanObject::Draw( Gameduino *gd ) { + switch( CurrentState ) { + case WalkingAbout : + Walker::Draw( gd, SpriteNumber, Xco, Yco, hSpeed, FrameCounter >> 3, animationData ); + break; + case Rescued : + gd->sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), FiftyImage, 0, Gameduino::None, GoodGuy ); + break; + case Dead : + gd->sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), SkullImage, 0, Gameduino::None, GoodGuy ); + break; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HumanObject.h Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,100 @@ +/* + * SOURCE FILE : HumanObject.h + * + * Represents a wandering human. + * + */ + +#ifndef HumanObjectIncluded + + #define HumanObjectIncluded + + #include "Types.h" + #include "GameObject.h" + #include "GameObjectTypes.h" + + class HumanObject : public GameObject { + + public : + + // States a human can be in. + // Each human starts in the WalkingAbout state and keeps wandering around as + // long as it is in this state. + // If the player touches a human than it changes to the Rescued state and + // it stops walking and its appearance changes to show the number of points + // awarded. Eventually this disappears and the Visible property inherited from + // GameObject is set to false. On next draw the human will be removed from the + // array of humans and replaced with NULL. + enum State { + WalkingAbout, + Rescued, + Dead, + }; + + // Different kinds of human. + enum HumanType { + Woman, + Man, + }; + + // Current state of human. + State CurrentState; + + /***************/ + /* CONSTRUCTOR */ + /***************/ + HumanObject(); + + /**************/ + /* DESTRUCTOR */ + /**************/ + virtual ~HumanObject(); + + /************************/ + /* GET GAME OBJECT TYPE */ + /************************/ + // Returns type of game object. + virtual GameObjectTypes GetType( void ) { + return HumanObjectType; + } + + /*****************************/ + /* GET TYPE OF HUMAN THIS IS */ + /*****************************/ + // Returns type of human. + HumanType GetHumanType( void ); + + /************************/ + /* MOVE THE GAME OBJECT */ + /************************/ + virtual void ProtectedMove( void ); + + /************************/ + /* 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. + virtual void Draw( Gameduino *gd ); + + private : + + // Address of animation data in program memory. + const UInt8 *animationData; + + // Horizontal and vertical velocities. + Int16 hSpeed, vSpeed; + + // Countdown used when in rescued or dead states. + UInt8 countdown; + + // Index of next animation to use when constructing. + // Cycles around all human animations. + static UInt8 nextAnimationIndex; + + }; + +#endif + +/* END of HumanObject.h */ +
--- a/Level.h Sat Jun 08 15:50:38 2013 +0000 +++ b/Level.h Sat Jun 08 16:44:54 2013 +0000 @@ -21,14 +21,15 @@ #include "CharFrame.h" #include "PanelControls.h" #include "PlayerObject.h" -#if 0 #include "ArenaConst.h" #include "SpriteImageId.h" #include "GameObject.h" + #include "HumanObject.h" #include "GruntObject.h" - #include "BlueMeanyObject.h" #include "CrusherObject.h" #include "BrainObject.h" +#if 0 + #include "BlueMeanyObject.h" #include "SoundManager.h" #include "Sounds.h" #endif
--- a/Level1.cpp Sat Jun 08 15:50:38 2013 +0000 +++ b/Level1.cpp Sat Jun 08 16:44:54 2013 +0000 @@ -15,7 +15,6 @@ // Returns code indicating how level ended. Level::LevelExitCode Level1::Play( void ) { LevelData dataForThisLevel; -#if 0 GameObject **ptr = dataForThisLevel.Enemies; UInt8 i, humanCount, enemyCount = 0; // Enemies of type GruntObject. @@ -44,7 +43,6 @@ for( i = 0; i < humanCount; ++i ) { *ptr++ = humans + i; } -#endif DataForLevel = &dataForThisLevel; return PlayLoop(); }
--- a/Level2.cpp Sat Jun 08 15:50:38 2013 +0000 +++ b/Level2.cpp Sat Jun 08 16:44:54 2013 +0000 @@ -14,7 +14,6 @@ /**************/ // Returns code indicating how level ended. Level::LevelExitCode Level2::Play( void ) { -#if 0 LevelData dataForThisLevel; GameObject **ptr = dataForThisLevel.Enemies; UInt8 i, humanCount, enemyCount = 0; @@ -46,7 +45,4 @@ } DataForLevel = &dataForThisLevel; return PlayLoop(); -#else - return Completed; -#endif }
--- a/LevelNormal.cpp Sat Jun 08 15:50:38 2013 +0000 +++ b/LevelNormal.cpp Sat Jun 08 16:44:54 2013 +0000 @@ -57,7 +57,6 @@ // Use next free sprite number for player. player->SpriteNumber = PlayerSprite; // Do futher initialisation for all enemies. -#if 0 EnemyObject *object; for( UInt8 e = 0; e < LevelData::MaxEnemies; ++e ) { object = (EnemyObject*)DataForLevel->Enemies[ e ]; @@ -72,7 +71,6 @@ } } } -#endif // Put player in the centre of the arena. player->Xco = PLAYER_START_X; player->Yco = PLAYER_START_Y; @@ -317,9 +315,9 @@ #endif // Redraw the player's score and number of lives. DrawScoreAndLives(); + // Draw all the enemies. + GameObject::DrawAll( gd, DataForLevel->Enemies, LevelData::MaxEnemies ); #if 0 - // Draw all the enemies. - GameObject::DrawAll( DataForLevel->Enemies, LevelData::MaxEnemies ); // Draw all the humans. GameObject::DrawAll( DataForLevel->Humans, LevelData::MaxHumans ); // Draw all the explosions. @@ -364,7 +362,6 @@ } } else { -#if 0 // Move all the enemies and check if all dead. allEnemiesAreDead = ! GameObject::MoveAll( DataForLevel->Enemies, LevelData::MaxEnemies ); // If there are still some enemies alive then check if those that remain are indestructable. @@ -377,6 +374,7 @@ LevelData::MaxEnemies ); } +#if 0 // Move all the humans. GameObject::MoveAll( DataForLevel->Humans, LevelData::MaxHumans ); // Move (update) all the explosions.
--- a/PlayerObject.cpp Sat Jun 08 15:50:38 2013 +0000 +++ b/PlayerObject.cpp Sat Jun 08 16:44:54 2013 +0000 @@ -172,11 +172,11 @@ // 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 ) ) { #if 0 - if( ( digit != (UInt8)( ( Score & 0xF000 ) >> 12 ) ) && ( Lives < 255 ) ) { SoundManager::Instance.PlaySound( Sounds::ExtraLife, 0, 0 ); +#endif Lives++; } -#endif }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Walker.cpp Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,64 @@ +/* + * SOURCE FILE : Walker.cpp + * + * Methods for objects that walk sideways on (like humans and crushers). + * + */ + +#include "Gameduino.h" // Gameduino stuff +#include "GDConst.h" +#include "Walker.h" +#include "Random.h" + +/*************************************************/ +/* INITIALISE HORIZONTAL AND VERTICAL VELOCITIES */ +/*************************************************/ +// Pass pointers to horizontal and vertical velocities in hv and vv. +void Walker::InitialiseVelocities( Int16 *hv, Int16 *vv ) { + // Initialise horizontal and vertical speeds. + UInt8 rnd = Random::Get( 4 ); + *hv = GameObject::FromPixel( 1 ) >> 2; + if( rnd & 1 ) { + *hv = -(*hv); + } + *vv = GameObject::FromPixel( 1 ) >> 4; + if( rnd & 2 ) { + *vv = -(*vv); + } +} + +/*********************************************************/ +/* UPDATE COORDINATES AND VELOCITIES TO MAKE OBJECT WALK */ +/*********************************************************/ +// Pass pointers to x and y coordinates in x and y. +// Pass pointers to horizontal and vertical velocities in hv and vv. +// Pass restriction flags (as defined in GameObject.h) in restriction Flags. +void Walker::Walk( Int16 *x, Int16 *y, Int16 *hv, Int16 *vv, UInt8 restrictionFlags ) { + // Make object bounce of edges of restriction area. + if( restrictionFlags & (UInt8)( GameObject::LeftRestriction | GameObject::RightRestriction ) ) { + *hv = -(*hv); + } + if( restrictionFlags & (UInt8)( GameObject::UpRestriction | GameObject::DownRestriction ) ) { + *vv = -(*vv); + } + *x += *hv; + *y += *vv; +} + +/*************************/ +/* DRAW A WALKING OBJECT */ +/*************************/ +// Pass pointer to Gameduino to draw on in gd. +// Pass sprite number in spriteNumber. +// Pass x and y coordinates in x and y (NOT pixel coordinates). +// Pass counter used to pace animation in frameCounter. +// Pass pointer to animation data (array of AnimationStages sprite image numbers) in animationData. +void Walker::Draw( Gameduino *gd, UInt8 spriteNumber, Int16 x, Int16 y, Int16 hv, UInt8 frameCounter, const UInt8 *animationData ) { + // Reverse sprite image horizontally if horizontal speed is positive. + Gameduino::Rotation transform = ( hv < 0 ) ? Gameduino::None : Gameduino::FlipX; + // Image number changes with the frame counter. + const UInt8 *address = animationData + frameCounter % AnimationStages; + // Update sprite location and image. Note the last parameter is BadGuy so that it is possible + // for player to collide with a human. GoodGuy would mean collisions would be ignored. + gd->sprite( spriteNumber, GameObject::ToPixel( x ), GameObject::ToPixel( y ), *address, 0, transform, BadGuy ); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Walker.h Sat Jun 08 16:44:54 2013 +0000 @@ -0,0 +1,55 @@ +/* + * SOURCE FILE : Walker.h + * + * Methods for objects that walk sideways on (like humans and crushers). + * + */ + +#ifndef WalkerDefined + + #define WalkerDefined + + #include "Types.h" + #include "GameObject.h" + + class Walker { + + public : + + enum { + AnimationStages = 4, + }; + + /*************************************************/ + /* INITIALISE HORIZONTAL AND VERTICAL VELOCITIES */ + /*************************************************/ + // Pass pointers to horizontal and vertical velocities in hv and vv. + static void InitialiseVelocities( Int16 *hv, Int16 *vv ); + + /*********************************************************/ + /* UPDATE COORDINATES AND VELOCITIES TO MAKE OBJECT WALK */ + /*********************************************************/ + // Pass pointers to x and y coordinates in x and y. + // Pass pointers to horizontal and vertical velocities in hv and vv. + // Pass restriction flags (as defined in GameObject.h) in restriction Flags. + static void Walk( Int16 *x, Int16 *y, Int16 *hv, Int16 *vv, UInt8 restrictionFlags ); + + /*************************/ + /* DRAW A WALKING OBJECT */ + /*************************/ + // Pass pointer to Gameduino to draw on in gd. + // Pass sprite number in spriteNumber. + // Pass x and y coordinates in x and y (NOT pixel coordinates). + // Pass horizontal velocity in hv. + // Pass counter used to pace animation in frameCounter. + // Pass pointer to animation data (array of AnimationStages sprite image numbers) in animationData. + static void Draw( Gameduino *gd, UInt8 spriteNumber, Int16 x, Int16 y, Int16 hv, UInt8 frameCounter, const UInt8 *animationData ); + + private : + + }; + +#endif + +/* END of Walker.h */ +