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 5:0b0651ac7832, committed 2013-06-08
- Comitter:
- RichardE
- Date:
- Sat Jun 08 14:40:47 2013 +0000
- Parent:
- 4:673eb9735d44
- Child:
- 6:8bbdb70bc11c
- Commit message:
- Now got first real level starting and player can be controlled using joysticks. No bullets, enemies, humans or sound yet.
Changed in this revision
--- a/BulletManager.cpp Sat Jun 08 11:24:05 2013 +0000 +++ b/BulletManager.cpp Sat Jun 08 14:40:47 2013 +0000 @@ -6,8 +6,8 @@ */ #include "BulletManager.h" -// #include "BulletObject.h" -// #include "ArenaConst.h" +#include "BulletObject.h" +#include "ArenaConst.h" #include "GDExtra.h" /***************/ @@ -16,7 +16,6 @@ // Pass number of sprite to use for first bullet. // MaxBullets consequtive sprites will be used for bullets. BulletManager::BulletManager( UInt8 firstSpriteNumber ) { -#if 0 // Initialise aspects of bullets that never change. BulletObject *bullet; for( UInt8 b = 0; b < MaxBullets; ++b ) { @@ -25,8 +24,9 @@ bullet->PixelWidth = 6; bullet->PixelHeight = 6; bullet->Bounds = &ArenaRectangle; + // Make sure entry in bulletPointers array is NULL. + bulletPointers[ b ] = (GameObject*)NULL; } -#endif } /**********************/ @@ -36,7 +36,6 @@ // Pass bullet velocities in hv and vv (NOT pixel velocities). // Returns true if bullet was started successfully. bool BulletManager::StartBullet( Int16 x, Int16 y, Int16 hv, Int16 vv ) { -#if 0 // Try and find an unused bullet slot. UInt8 index; if( GameObject::FindUnusedObject( bulletPointers, MaxBullets, &index ) ) { @@ -50,32 +49,28 @@ // No free bullet slots. return false; } -#else -return false; -#endif } /************************/ /* KILL A SINGLE BULLET */ /************************/ +// Pass pointer to Gameduino that displays bullets in gd. // Pass index of bullet in b. -void BulletManager::KillBullet( UInt8 b ) { -#if 0 +void BulletManager::KillBullet( Gameduino *gd, UInt8 b ) { GameObject *bullet = bulletPointers[ b ]; if( bullet != (GameObject*)NULL ) { bulletPointers[ b ] = (BulletObject*)NULL; // Hide bullet sprite by setting y coordinate to 400. - GDExtra::HideSprite( bullet->SpriteNumber ); + GDExtra::HideSprite( gd, bullet->SpriteNumber ); } -#endif } /********************/ /* KILL ALL BULLETS */ /********************/ -void BulletManager::KillAllBullets( void ) { +// Pass pointer to Gameduino that displays bullets in gd. +void BulletManager::KillAllBullets( Gameduino *gd ) { for( UInt8 b = 0; b < MaxBullets; ++b ) { - KillBullet( b ); + KillBullet( gd, b ); } } -
--- a/BulletManager.h Sat Jun 08 11:24:05 2013 +0000 +++ b/BulletManager.h Sat Jun 08 14:40:47 2013 +0000 @@ -11,6 +11,7 @@ #include "Types.h" #include "BulletObject.h" + #include "Gameduino.h" class BulletManager { @@ -38,13 +39,15 @@ /************************/ /* KILL A SINGLE BULLET */ /************************/ + // Pass pointer to Gameduino that displays bullets in gd. // Pass index of bullet in b. - void KillBullet( UInt8 b ); + void KillBullet( Gameduino *gd, UInt8 b ); /********************/ /* KILL ALL BULLETS */ /********************/ - void KillAllBullets( void ); + // Pass pointer to Gameduino that displays bullets in gd. + void KillAllBullets( Gameduino *gd ); /************************************************/ /* GET ARRAY CONTAINING POINTERS TO ALL BULLETS */
--- a/BulletObject.h Sat Jun 08 11:24:05 2013 +0000 +++ b/BulletObject.h Sat Jun 08 14:40:47 2013 +0000 @@ -64,10 +64,11 @@ /************************/ /* 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( void ) { - // GD.sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), imageNumber, 0, 0, spriteGroup ); + virtual void Draw( Gameduino *gd ) { + gd->sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), imageNumber, 0, Gameduino::None, spriteGroup ); } private :
--- a/GDConst.h Sat Jun 08 11:24:05 2013 +0000 +++ b/GDConst.h Sat Jun 08 14:40:47 2013 +0000 @@ -1,41 +1,30 @@ -/* - * SOURCE FILE : GDConst.h - * - * A few more constants associated with the Gameduino hardware. - * - */ - -#ifndef GDConstIncluded - - #define GDConstIncluded - - #define RAM_PIC_SIZE 4096 // size of screen picture RAM - #define RAM_CHR_SIZE 4096 // size of character set pixel data RAM - #define RAM_PAL_SIZE 2048 // size of character set palette data RAM - - #define SCREEN_CHAR_WIDTH 64 // character width of screen (entire screen, not just visible bit) - #define SCREEN_CHAR_HEIGHT 64 // character height of screen (entire screen, not just visible bit) - - #define VISIBLE_CHAR_WIDTH 50 // character width of visible screen - #define VISIBLE_CHAR_HEIGHT 37 // character height of visible screen (actually 37.5) - - #define SPRITE_PIXEL_WIDTH 16 - #define SPRITE_PIXEL_HEIGHT 16 - - #define SPRITE_COUNT 256 - - enum SpriteTransform { - STNormal = 0, - STRotate90FlipY = 1, - STFlipX = 2, - STRotate90 = 3, - STFlipY = 4, - STRotate270 = 5, - STRotate180 = 6, - STRotate270FlipY = 7, - }; - -#endif - -/* END of GDConst.h */ +/* + * SOURCE FILE : GDConst.h + * + * A few more constants associated with the Gameduino hardware. + * + */ + +#ifndef GDConstIncluded + + #define GDConstIncluded + + #define RAM_PIC_SIZE 4096 // size of screen picture RAM + #define RAM_CHR_SIZE 4096 // size of character set pixel data RAM + #define RAM_PAL_SIZE 2048 // size of character set palette data RAM + #define SCREEN_CHAR_WIDTH 64 // character width of screen (entire screen, not just visible bit) + #define SCREEN_CHAR_HEIGHT 64 // character height of screen (entire screen, not just visible bit) + + #define VISIBLE_CHAR_WIDTH 50 // character width of visible screen + #define VISIBLE_CHAR_HEIGHT 37 // character height of visible screen (actually 37.5) + + #define SPRITE_PIXEL_WIDTH 16 + #define SPRITE_PIXEL_HEIGHT 16 + + #define SPRITE_COUNT 256 + +#endif + +/* END of GDConst.h */ +
--- a/GameObject.cpp Sat Jun 08 11:24:05 2013 +0000 +++ b/GameObject.cpp Sat Jun 08 14:40:47 2013 +0000 @@ -46,16 +46,22 @@ // Pass number of pointers in the array in objectCount. // Returns true if any non-null objects were found in the array. bool GameObject::MoveAll( GameObject **objects, UInt8 objectCount ) { - GameObject *object; - bool foundNonNull = false; - for( UInt8 i = 0; i < objectCount; ++i ) { - object = objects[ i ]; - if( object != (GameObject*)NULL ) { - foundNonNull = true; - object->Move(); - } - } - return foundNonNull; + if( objects != (GameObject**)NULL ) { + GameObject *object; + bool foundNonNull = false; + for( UInt8 i = 0; i < objectCount; ++i ) { + object = objects[ i ]; + if( object != (GameObject*)NULL ) { + foundNonNull = true; + object->Move(); + } + } + return foundNonNull; + } + else { + // A null pointer was passed. Do nothing. + return false; + } } /****************************/
--- a/GameObject.h Sat Jun 08 11:24:05 2013 +0000 +++ b/GameObject.h Sat Jun 08 14:40:47 2013 +0000 @@ -62,10 +62,10 @@ // Indicates which Gameduino sprite is being used for this object. UInt8 SpriteNumber; - // Determines if object is retained on a level restart. - // Most enemy objects are retained on a level restart, although their positions change. - // However, enemy bullets (for example) are killed off on a level restart. - bool RetainOnLevelRestart; + // Determines if object is retained on a level restart. + // Most enemy objects are retained on a level restart, although their positions change. + // However, enemy bullets (for example) are killed off on a level restart. + bool RetainOnLevelRestart; /***************/ /* CONSTRUCTOR */ @@ -81,7 +81,7 @@ DeleteWhenRestricted( false ), RestrictionFlags( 0 ), SpriteNumber( 0 ), - RetainOnLevelRestart( true ) + RetainOnLevelRestart( true ) { } @@ -172,9 +172,10 @@ /************************/ /* DRAW THE GAME OBJECT */ /************************/ + // Pass pointer to Gameduino to draw on in gd. // Note if Visible is false this should not draw anything // and/or hide the visible object. - virtual void Draw( void ) = 0; + virtual void Draw( Gameduino *gd ) = 0; /**********************************/ /* INITIALISE AN ARRAY OF OBJECTS */
--- a/GameRobotRic.cpp Sat Jun 08 11:24:05 2013 +0000 +++ b/GameRobotRic.cpp Sat Jun 08 14:40:47 2013 +0000 @@ -138,8 +138,6 @@ levelNumber++; break; } - // Wait a bit. - wait( (float)2 ); } }
--- a/Level0.cpp Sat Jun 08 11:24:05 2013 +0000 +++ b/Level0.cpp Sat Jun 08 14:40:47 2013 +0000 @@ -8,9 +8,6 @@ #include "Level0.h" #include "CharBlocks.h" -// REMOVE THIS! -extern Serial pc; - /***************/ /* CONSTRUCTOR */ /***************/ @@ -98,10 +95,8 @@ do { controls->Read(); inputs = controls->GetInputs(); - pc.printf( "Inputs = %04X\r\n", (int)inputs ); - } while( true /* inputs == 0 */ ); + } while( inputs == 0 ); } } return Completed; } -
--- a/Level1.cpp Sat Jun 08 11:24:05 2013 +0000 +++ b/Level1.cpp Sat Jun 08 14:40:47 2013 +0000 @@ -14,8 +14,8 @@ /**************/ // Returns code indicating how level ended. Level::LevelExitCode Level1::Play( void ) { + LevelData dataForThisLevel; #if 0 - LevelData dataForThisLevel; GameObject **ptr = dataForThisLevel.Enemies; UInt8 i, humanCount, enemyCount = 0; // Enemies of type GruntObject. @@ -44,10 +44,8 @@ for( i = 0; i < humanCount; ++i ) { *ptr++ = humans + i; } +#endif DataForLevel = &dataForThisLevel; return PlayLoop(); -#else - return Completed; -#endif }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LevelData.cpp Sat Jun 08 14:40:47 2013 +0000 @@ -0,0 +1,30 @@ +/* + * SOURCE FILE : LevelData.cpp + * + * Definition of class LevelData. + * + */ + +#include "LevelData.h" + +/***************/ +/* CONSTRUCTOR */ +/***************/ +LevelData::LevelData() { + UInt8 i; + // Ensure all enemies are NULL initially. + for( i = 0; i < MaxEnemies; ++i ) { + Enemies[ i ] = (GameObject*)NULL; + } + // Ensure all humans are NULL initially. + for( i = 0; i < MaxHumans; ++i ) { + Humans[ i ] = (GameObject*)NULL; + } +} + +/**************/ +/* DESTRUCTOR */ +/**************/ +LevelData::~LevelData() { +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LevelData.h Sat Jun 08 14:40:47 2013 +0000 @@ -0,0 +1,55 @@ +/* + * SOURCE FILE : LevelData.h + * + * Definition of class LevelData. + * + */ + +#ifndef LevelDataDefined + + #define LevelDataDefined + + #include "GameObject.h" + // #include "EnemyObject.h" + // #include "HumanObject.h" + // #include "MutantObject.h" + + class LevelData { + + public : + + enum { + MaxEnemies = 64, // Maximum number of enemies you can have in a level + MaxHumans = 24, // maximum number of humans you can have in a level + MaxMutants = MaxHumans, // Maximum number of mutant humans you can have in a level + }; + + // Array containing pointers to all the enemies in a level. + // A null pointer indicates an unused or dead enemy. + GameObject *Enemies[ MaxEnemies ]; + + // Array containing pointers to all the humans in a level. + // A null pointer indicates an unused or rescued human. + GameObject *Humans[ MaxHumans ]; + + // Array containing mutant humans (NOT pointers to mutants). + // Pointer to the mutants in this array are written into the Enemies array + // whenever a human is mutated by a brain. + // MutantObject Mutants[ MaxMutants ]; + + /***************/ + /* CONSTRUCTOR */ + /***************/ + LevelData(); + + /**************/ + /* DESTRUCTOR */ + /**************/ + virtual ~LevelData(); + + }; + +#endif + +/* END of LevelData.h */ +
--- a/LevelNormal.cpp Sat Jun 08 11:24:05 2013 +0000 +++ b/LevelNormal.cpp Sat Jun 08 14:40:47 2013 +0000 @@ -9,12 +9,19 @@ * */ +// Define this for debugging messages. +#define CHATTY + +#ifdef CHATTY + #include "mbed.h" + extern Serial pc; +#endif + #include "LevelNormal.h" -#if 0 - #include "GameObjectLocator.h" - #include "FrameCounter.h" - #include "SpriteNumber.h" -#endif +#include "GameObjectLocator.h" +#include "FrameCounter.h" +#include "SpriteNumber.h" +#include "ArenaConst.h" // Current instance being processed. LevelNormal *LevelNormal::currentInstance; @@ -22,93 +29,96 @@ /***************/ /* CONSTRUCTOR */ /***************/ -LevelNormal::LevelNormal() { +LevelNormal::LevelNormal() +{ } /**************/ /* DESTRUCTOR */ /**************/ -LevelNormal::~LevelNormal() { +LevelNormal::~LevelNormal() +{ } /********************/ /* INITIALISE LEVEL */ /********************/ -void LevelNormal::InitialiseLevel( void ) { -#if 0 +// Pass pointer to Gameduino to draw on in gd. +void LevelNormal::InitialiseLevel( Gameduino *gd ) +{ // Note that if you re-arrange the following code you may need to adjust the // SpriteNumber enumeration in SpriteNumber.h. - UInt8 spriteNumber = FirstEnemySprite; - // Initialise enemies. - GameObject::InitialiseAll( DataForLevel->Enemies, LevelData::MaxEnemies, &spriteNumber ); - // Initialise humans. + UInt8 spriteNumber = FirstEnemySprite; + // Initialise enemies. + GameObject::InitialiseAll( DataForLevel->Enemies, LevelData::MaxEnemies, &spriteNumber ); + // Initialise humans. spriteNumber = FirstHumanSprite; - GameObject::InitialiseAll( DataForLevel->Humans, LevelData::MaxHumans, &spriteNumber ); - // Use next free sprite number for player. - player->SpriteNumber = PlayerSprite; - // Do futher initialisation for all enemies. - EnemyObject *object; - for( UInt8 e = 0; e < LevelData::MaxEnemies; ++e ) { - object = (EnemyObject*)DataForLevel->Enemies[ e ]; - if( object != (EnemyObject*)NULL ) { + GameObject::InitialiseAll( DataForLevel->Humans, LevelData::MaxHumans, &spriteNumber ); + // 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 ]; + if( object != (EnemyObject*)NULL ) { // Get enemy to chase the player. - object->SetChaseObject( player ); + object->SetChaseObject( player ); // Pass array of all enemies to this enemy. object->Enemies = DataForLevel->Enemies; // If enemy is a brain then tell it about the humans to chase. if( object->GetEnemyType() == Brain ) { ((BrainObject*)object)->HumansToChase = DataForLevel->Humans; } + } } - } - // Put player in the centre of the arena. - player->Xco = PLAYER_START_X; - player->Yco = PLAYER_START_Y; - // Kill off all player's bullets. - player->KillAllBullets(); - // Kill off all explosions. - ExplosionManager::Instance.KillAllExplosions(); #endif + // Put player in the centre of the arena. + player->Xco = PLAYER_START_X; + player->Yco = PLAYER_START_Y; + // Kill off all player's bullets. + player->KillAllBullets( gd ); + // Kill off all explosions. + // ExplosionManager::Instance.KillAllExplosions(); } /**********************************/ /* DRAW SCORE AND NUMBER OF LIVES */ /**********************************/ -void LevelNormal::DrawScoreAndLives( void ) { -#if 0 - GDExtra::WriteBCDNumber( 16, 0, player->Score, 8 ); - // Display number of lives but limit this to 20 lives displayed. - UInt8 lives = ( player->Lives > 20 ) ? 20 : player->Lives; - GD.fill( RAM_PIC + VISIBLE_CHAR_WIDTH - lives, MiniPlayer, lives ); -#endif +void LevelNormal::DrawScoreAndLives( void ) +{ + GDExtra::WriteBCDNumber( gd, 16, 0, player->Score, 8 ); + // Display number of lives but limit this to 20 lives displayed. + UInt8 lives = ( player->Lives > 20 ) ? 20 : player->Lives; + gd->fill( Gameduino::RAM_PIC + VISIBLE_CHAR_WIDTH - lives, MiniPlayer, lives ); } /******************/ /* DRAW THE LEVEL */ /******************/ -void LevelNormal::DrawLevel( void ) { - // Set screen background to black. - gd->wr( Gameduino::BG_COLOR, Gameduino::RGB( 0, 0, 0 ) ); - // Clear the screen to zero characters. - GDExtra::ClearScreen( gd, TransparentChar ); - // Hide all sprties. - GDExtra::HideAllSprites( gd ); - // Display level number. - GDExtra::WriteProgString( gd, 0, 0, StringData::LevelString ); - GDExtra::WriteUInt16( gd, 6, 0, LevelNumber, 10, 2 ); - // Display score. - GDExtra::WriteProgString( gd, 10, 0, StringData::ScoreString ); - #if 0 - // Update score and lives. - DrawScoreAndLives(); - // Draw border around screen. - CharFrame::Draw( - ARENA_BORDER_X, - ARENA_BORDER_Y, - ARENA_BORDER_WIDTH, - ARENA_BORDER_HEIGHT - ); - #endif +void LevelNormal::DrawLevel( void ) +{ + // Set screen background to black. + gd->wr( Gameduino::BG_COLOR, Gameduino::RGB( 0, 0, 0 ) ); + // Clear the screen to zero characters. + GDExtra::ClearScreen( gd, TransparentChar ); + // Hide all sprties. + GDExtra::HideAllSprites( gd ); + // Display level number. + GDExtra::WriteProgString( gd, 0, 0, StringData::LevelString ); + GDExtra::WriteUInt16( gd, 6, 0, LevelNumber, 10, 2 ); + // Display score. + GDExtra::WriteProgString( gd, 10, 0, StringData::ScoreString ); + // Update score and lives. + DrawScoreAndLives(); + // Draw border around screen. + CharFrame::Draw( + gd, + ARENA_BORDER_X, + ARENA_BORDER_Y, + ARENA_BORDER_WIDTH, + ARENA_BORDER_HEIGHT + ); } /************************************************/ @@ -116,16 +126,17 @@ /************************************************/ // Pass index of human in level's humans array in humanIndex. // Pass sprite number of sprite that it hit in spriteNumber. -void LevelNormal::HandleHumanCollision( UInt8 humanIndex, UInt8 spriteNumber ) { +void LevelNormal::HandleHumanCollision( UInt8 humanIndex, UInt8 spriteNumber ) +{ #if 0 - // Point to array of enemy object pointers. - GameObject **enemies = currentInstance->DataForLevel->Enemies; - EnemyObject *enemy; - UInt8 enemyIndex, mutantIndex; - // Find an enemy with given sprite number. - if( GameObject::FindSpriteNumber( enemies, LevelData::MaxEnemies, spriteNumber, &enemyIndex ) ) { - // Found enemy. Check if it squashes humans. - enemy = (EnemyObject*)enemies[ enemyIndex ]; + // Point to array of enemy object pointers. + GameObject **enemies = currentInstance->DataForLevel->Enemies; + EnemyObject *enemy; + UInt8 enemyIndex, mutantIndex; + // Find an enemy with given sprite number. + if( GameObject::FindSpriteNumber( enemies, LevelData::MaxEnemies, spriteNumber, &enemyIndex ) ) { + // Found enemy. Check if it squashes humans. + enemy = (EnemyObject*)enemies[ enemyIndex ]; // Get hold of the human that is doomed. GameObject **humans = currentInstance->DataForLevel->Humans; HumanObject *human = (HumanObject*)humans[ humanIndex ]; @@ -136,8 +147,7 @@ human->CurrentState = HumanObject::Dead; // Make a noise. SoundManager::Instance.PlaySound( Sounds::HumanDies, 0, 0 ); - } - else if( enemy->GetEnemyType() == Brain ) { + } else if( enemy->GetEnemyType() == Brain ) { // Kill human by inserting a null into humans array. humans[ humanIndex ] = (GameObject*)NULL; // Find a free slot for a new enemy. @@ -150,8 +160,7 @@ mutant->Start( human, currentInstance->player ); // Make a noise. // TODO : SoundManager::Instance.PlaySound( Sounds::HumanMutates, 0, 0 ); - } - else { + } else { // Could not find a free slot for a new enemy so just erase the human sprite. GDExtra::HideSprite( human->SpriteNumber ); } @@ -166,16 +175,17 @@ /********************************************************/ // Pass index of bullet in player's bullet array in bulletIndex. // Pass sprite number of sprite that it hit in spriteNumber. -void LevelNormal::HandleBulletCollision( UInt8 bulletIndex, UInt8 spriteNumber ) { +void LevelNormal::HandleBulletCollision( UInt8 bulletIndex, UInt8 spriteNumber ) +{ #if 0 - // Point to array of enemy object pointers. - GameObject **enemies = currentInstance->DataForLevel->Enemies; - EnemyObject *enemy; - UInt8 enemyIndex; - // Find an enemy with given sprite number. - if( GameObject::FindSpriteNumber( enemies, LevelData::MaxEnemies, spriteNumber, &enemyIndex ) ) { - // Found enemy. Check if it is indestructable. - enemy = (EnemyObject*)enemies[ enemyIndex ]; + // Point to array of enemy object pointers. + GameObject **enemies = currentInstance->DataForLevel->Enemies; + EnemyObject *enemy; + UInt8 enemyIndex; + // Find an enemy with given sprite number. + if( GameObject::FindSpriteNumber( enemies, LevelData::MaxEnemies, spriteNumber, &enemyIndex ) ) { + // Found enemy. Check if it is indestructable. + enemy = (EnemyObject*)enemies[ enemyIndex ]; if( enemy->HitPoints != EnemyObject::Indestructable ) { // Enemy is not indestructable. Decrement hit points and die when it reaches zero. enemy->HitPoints--; @@ -196,7 +206,7 @@ SoundManager::Instance.PlaySound( Sounds::Explosion, 0, 0 ); // Start explosion animation using coordinates of enemy. ExplosionManager::Instance.StartExplosion( enemy->Xco, enemy->Yco ); - } + } #endif } @@ -204,29 +214,30 @@ /* CHECK FOR COLLISIONS BETWEEN PLAYER AND OTHER OBJECTS */ /*********************************************************/ // Pass pointer to a flag that will be set true if player is dead in isDead parameter. -void LevelNormal::CheckPlayerCollisions( bool *isDead ) { +void LevelNormal::CheckPlayerCollisions( bool *isDead ) +{ #if 0 - UInt8 enemyIndex, humanIndex; - // Check if player sprite has hit another sprite. - UInt8 hitSpriteNumber = GD.rd( COLLISION + player->SpriteNumber ); - // If you get 0xFF then no collision found. - if( hitSpriteNumber != 0xFF ) { - // Check for collision with an enemy. - if( - GameObject::FindSpriteNumber( - DataForLevel->Enemies, LevelData::MaxEnemies, hitSpriteNumber, &enemyIndex - ) - ) { - // Hit an enemy. Player is dead. - *isDead = true; - } - // Check for collision with a human that has not already been rescued or killed. - else if( - GameObject::FindSpriteNumber( - DataForLevel->Humans, LevelData::MaxHumans, hitSpriteNumber, &humanIndex - ) - ) { - HumanObject *human = (HumanObject*)DataForLevel->Humans[ humanIndex ]; + UInt8 enemyIndex, humanIndex; + // Check if player sprite has hit another sprite. + UInt8 hitSpriteNumber = GD.rd( COLLISION + player->SpriteNumber ); + // If you get 0xFF then no collision found. + if( hitSpriteNumber != 0xFF ) { + // Check for collision with an enemy. + if( + GameObject::FindSpriteNumber( + DataForLevel->Enemies, LevelData::MaxEnemies, hitSpriteNumber, &enemyIndex + ) + ) { + // Hit an enemy. Player is dead. + *isDead = true; + } + // Check for collision with a human that has not already been rescued or killed. + else if( + GameObject::FindSpriteNumber( + DataForLevel->Humans, LevelData::MaxHumans, hitSpriteNumber, &humanIndex + ) + ) { + HumanObject *human = (HumanObject*)DataForLevel->Humans[ humanIndex ]; if( human->CurrentState == HumanObject::WalkingAbout ) { // Change human state to rescued. human->CurrentState = HumanObject::Rescued; @@ -235,8 +246,8 @@ // Make a noise. SoundManager::Instance.PlaySound( Sounds::RescueHuman, 0, 0 ); } - } - } + } + } #endif } @@ -244,23 +255,24 @@ /* WAIT UNTIL SLOT FREE FOR A NEW SOUND, PLAY IT AND WAIT FOR ALL SOUNDS TO FINISH */ /***********************************************************************************/ // Pass sound to play in soundToPlay parameter. -void LevelNormal::PlaySoundAndWait( const UInt8 *soundToPlay ) { +void LevelNormal::PlaySoundAndWait( const UInt8 *soundToPlay ) +{ #if 0 - // Keep trying to play sound until it works and meanwhile - // keep currently playing sounds going. - while( ! SoundManager::Instance.PlaySound( soundToPlay, 0, 0 ) ) { - // Update sound manager. - SoundManager::Instance.Update(); - // Wait for frame flyback. - GD.waitvblank(); - } - // Now wait until all sounds have finished. - while( SoundManager::Instance.CountSoundsPlaying() > 0 ) { - // Update sound manager. - SoundManager::Instance.Update(); - // Wait for frame flyback. - GD.waitvblank(); - } + // Keep trying to play sound until it works and meanwhile + // keep currently playing sounds going. + while( ! SoundManager::Instance.PlaySound( soundToPlay, 0, 0 ) ) { + // Update sound manager. + SoundManager::Instance.Update(); + // Wait for frame flyback. + GD.waitvblank(); + } + // Now wait until all sounds have finished. + while( SoundManager::Instance.CountSoundsPlaying() > 0 ) { + // Update sound manager. + SoundManager::Instance.Update(); + // Wait for frame flyback. + GD.waitvblank(); + } #endif } @@ -271,108 +283,119 @@ // This method should be called from the Play method after the // level data has been initialised and the return value returned // by the Play method. -Level::LevelExitCode LevelNormal::PlayLoop( void ) { - // Do nothing if Gameduino has not been specified, level data is NULL or player has not been specified. - if( ( gd != (Gameduino*)NULL ) /* || ( DataForLevel != (LevelData*)NULL ) || ( player == (PlayerObject*)NULL ) */ ) { - // Point static pointer to current instance. - currentInstance = this; - // Do some initialisation first. - InitialiseLevel(); - // Redraw the screen. - DrawLevel(); - // Wait for frame flyback once before entering loop so collision data is recalculated. - // At this point there should not be any sprites on the screen so no collisions - // should be found. - gd->waitvblank(); +Level::LevelExitCode LevelNormal::PlayLoop( void ) +{ + // Do nothing if Gameduino has not been specified, level data is NULL or player has not been specified. + if( ( gd != (Gameduino*)NULL ) || ( DataForLevel != (LevelData*)NULL ) || ( player == (PlayerObject*)NULL ) ) { + // Point static pointer to current instance. + currentInstance = this; + // Do some initialisation first. + InitialiseLevel( gd ); + // Redraw the screen. + DrawLevel(); + // Wait for frame flyback once before entering loop so collision data is recalculated. + // At this point there should not be any sprites on the screen so no collisions + // should be found. + gd->waitvblank(); + // Repeat until all enemies are dead or player is dead. + bool allEnemiesAreDead = false; + bool playerIsDead = false; + bool gameIsOver = false; + bool firstDraw = true; + while( ! allEnemiesAreDead && ! gameIsOver ) { + // Update sound manager. + // SoundManager::Instance.Update(); + // Wait for frame flyback. + gd->waitvblank(); + // Check for collisions between player and other objects. + CheckPlayerCollisions( &playerIsDead ); +#if 0 + // Check for collisions between humans and enemies that squash. + GameObject::FindCollisions( DataForLevel->Humans, LevelData::MaxHumans, &LevelNormal::HandleHumanCollision ); + // Check for collisions between player bullets and enemies. + GameObject::FindCollisions( player->GetBullets(), BulletManager::MaxBullets, &LevelNormal::HandleBulletCollision ); +#endif + // Redraw the player's score and number of lives. + DrawScoreAndLives(); #if 0 - // Repeat until all enemies are dead or player is dead. - bool allEnemiesAreDead = false; - bool playerIsDead = false; - bool gameIsOver = false; - bool firstDraw = true; - while( ! allEnemiesAreDead && ! gameIsOver ) { - // Update sound manager. - SoundManager::Instance.Update(); - // Wait for frame flyback. - GD.waitvblank(); - // Check for collisions between player and other objects. - CheckPlayerCollisions( &playerIsDead ); - // Check for collisions between humans and enemies that squash. - GameObject::FindCollisions( DataForLevel->Humans, LevelData::MaxHumans, &LevelNormal::HandleHumanCollision ); - // Check for collisions between player bullets and enemies. - GameObject::FindCollisions( player->GetBullets(), BulletManager::MaxBullets, &LevelNormal::HandleBulletCollision ); - // Redraw the player's score and number of lives. - DrawScoreAndLives(); - // Draw all the enemies. - GameObject::DrawAll( DataForLevel->Enemies, LevelData::MaxEnemies ); - // Draw all the humans. - GameObject::DrawAll( DataForLevel->Humans, LevelData::MaxHumans ); - // Draw all the explosions. - GameObject::DrawAll( ExplosionManager::Instance.GetExplosions(), ExplosionManager::MaxExplosions ); - // Draw the player. - player->Draw(); - // Draw the player's bullets. - GameObject::DrawAll( player->GetBullets(), BulletManager::MaxBullets ); - // Increment the frame counter. - FrameCounter++; - // After first redraw play level start sound and wait for it to end. - if( firstDraw ) { - PlaySoundAndWait( Sounds::StartLevel ); - firstDraw = false; - } - // If player was killed then play death march and wait for it to finish. - if( playerIsDead ) { - // Player got killed. - PlaySoundAndWait( Sounds::PlayerDead ); - // One less life for player. - if( player->Lives > 0 ) { - player->Lives--; + // Draw all the enemies. + GameObject::DrawAll( DataForLevel->Enemies, LevelData::MaxEnemies ); + // Draw all the humans. + GameObject::DrawAll( DataForLevel->Humans, LevelData::MaxHumans ); + // Draw all the explosions. + GameObject::DrawAll( ExplosionManager::Instance.GetExplosions(), ExplosionManager::MaxExplosions ); +#endif + // Draw the player. + player->Draw( gd ); + // Draw the player's bullets. + GameObject::DrawAll( player->GetBullets(), BulletManager::MaxBullets ); + // Increment the frame counter. + FrameCounter++; + // After first redraw play level start sound and wait for it to end. + if( firstDraw ) { + // PlaySoundAndWait( Sounds::StartLevel ); + firstDraw = false; } - // Game is over when player has no more lives. - gameIsOver = ( player->Lives == 0 ); - // If game is not over then re-initialise level using any remaining enemies. - if( ! gameIsOver ) { - // Remove all objects that do not survive a level restart (like enemy bullets). - GameObject::RemoveUnretainedObjects( DataForLevel->Enemies, LevelData::MaxEnemies ); - InitialiseLevel(); - DrawLevel(); - GD.waitvblank(); - playerIsDead = false; - firstDraw = true; + // If player was killed then play death march and wait for it to finish. + if( playerIsDead ) { + #ifdef CHATTY + pc.puts( "Player got killed.\r\n" ); + #endif + // Player got killed. + // PlaySoundAndWait( Sounds::PlayerDead ); + // One less life for player. + if( player->Lives > 0 ) { + player->Lives--; + } + // Game is over when player has no more lives. + gameIsOver = ( player->Lives == 0 ); + // If game is not over then re-initialise level using any remaining enemies. + if( ! gameIsOver ) { + #ifdef CHATTY + pc.puts( "Game is over.\r\n" ); + #endif + // Remove all objects that do not survive a level restart (like enemy bullets). + GameObject::RemoveUnretainedObjects( DataForLevel->Enemies, LevelData::MaxEnemies ); + InitialiseLevel( gd ); + DrawLevel(); + gd->waitvblank(); + playerIsDead = false; + firstDraw = true; + } + } + 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. + // If only indestructable enemies survive then act as if all enemies are dead. + // You need to do this or you would never be able to complete a level that had indestructable + // enemies on it. + if( ! allEnemiesAreDead ) { + allEnemiesAreDead = EnemyObject::AreAllIndestructable( + (const EnemyObject**)DataForLevel->Enemies, + LevelData::MaxEnemies + ); + } + // Move all the humans. + GameObject::MoveAll( DataForLevel->Humans, LevelData::MaxHumans ); + // Move (update) all the explosions. + GameObject::MoveAll( ExplosionManager::Instance.GetExplosions(), ExplosionManager::MaxExplosions ); +#endif + // Read the player's controls. + player->ReadControls(); + // Move the player. + player->Move(); + // Move the player's bullets. + GameObject::MoveAll( player->GetBullets(), BulletManager::MaxBullets ); } } - else { - // 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. - // If only indestructable enemies survive then act as if all enemies are dead. - // You need to do this or you would never be able to complete a level that had indestructable - // enemies on it. - if( ! allEnemiesAreDead ) { - allEnemiesAreDead = EnemyObject::AreAllIndestructable( - (const EnemyObject**)DataForLevel->Enemies, - LevelData::MaxEnemies - ); - } - // Move all the humans. - GameObject::MoveAll( DataForLevel->Humans, LevelData::MaxHumans ); - // Move (update) all the explosions. - GameObject::MoveAll( ExplosionManager::Instance.GetExplosions(), ExplosionManager::MaxExplosions ); - // Read the player's controls. - player->ReadControls(); - // Move the player. - player->Move(); - // Move the player's bullets. - GameObject::MoveAll( player->GetBullets(), BulletManager::MaxBullets ); - } + // Player completed level or game is over. + return gameIsOver ? GameOver : Completed; } -#endif - // Player completed level or game is over. - return /* gameIsOver ? GameOver : */ Completed; - } - else { - // Level data or player were not specified. - return Completed; - } + else { + // Level data or player were not specified. + return Completed; + } }
--- a/LevelNormal.h Sat Jun 08 11:24:05 2013 +0000 +++ b/LevelNormal.h Sat Jun 08 14:40:47 2013 +0000 @@ -14,8 +14,8 @@ #define LevelNormalDefined #include "Level.h" + #include "LevelData.h" #if 0 - #include "LevelData.h" #include "ExplosionManager.h" #endif @@ -37,7 +37,7 @@ // Data defining the level. // You should write to this before calling PlayLoop. - // LevelData *DataForLevel; + LevelData *DataForLevel; /*************/ /* PLAY LOOP */ @@ -56,7 +56,8 @@ /********************/ /* INITIALISE LEVEL */ /********************/ - void InitialiseLevel( void ); + // Pass pointer to Gameduino to draw on in gd. + void InitialiseLevel( Gameduino *gd ); /**********************************/ /* DRAW SCORE AND NUMBER OF LIVES */
--- a/PlayerObject.cpp Sat Jun 08 11:24:05 2013 +0000 +++ b/PlayerObject.cpp Sat Jun 08 14:40:47 2013 +0000 @@ -5,10 +5,18 @@ * */ +// 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" +#include "FrameCounter.h" // Bullet velocity information. BulletVelocities PlayerObject::bulletVelocities( FromPixel( 2 ), FromPixel( 2 ) ); @@ -38,15 +46,20 @@ /* MOVE THE GAME OBJECT */ /************************/ void PlayerObject::ProtectedMove( void ) { -#if 0 // 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; @@ -64,24 +77,25 @@ // Try and start a new bullet. if( playerBullets.StartBullet( Xco, Yco, pair->X, pair->Y ) ) { // If bullet was started then make a bullet sound. + #if 0 SoundManager::Instance.PlaySound( Sounds::FireGun, 0, 0 ); + #endif } // Reset countdown until another bullet can start. bulletCountdown = 8; } } } -#endif } /************************/ /* 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( void ) { -#if 0 - SpriteTransform transform; +void PlayerObject::Draw( Gameduino *gd ) { + Gameduino::Rotation transform; SpriteImageId imageId; // Check controls have been specified. if( controls != (PanelControls*)NULL ) { @@ -92,7 +106,7 @@ bool leftFootUp = ( ( FrameCounter & 4 ) != 0 ); if( map & PanelControls::Left2 ) { // Firing to the left. - transform = STNormal; + transform = Gameduino::None; if( map & PanelControls::Up2 ) { // Firing left and up. imageId = leftFootUp ? PlayerGunUpLeftFootUpImage : PlayerGunUpRightFootUpImage; @@ -108,7 +122,7 @@ } else if( map & PanelControls::Right2 ) { // Firing to the right. - transform = STFlipX; + transform = Gameduino::FlipX; if( map & PanelControls::Up2 ) { // Firing right and up. Image is flipped so left foot becomes right foot. imageId = leftFootUp ? PlayerGunUpRightFootUpImage : PlayerGunUpLeftFootUpImage; @@ -124,18 +138,17 @@ } else { // Firing up, down or not firing. - transform = leftFootUp ? STNormal : STFlipX; + 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 = STNormal; + transform = Gameduino::None; imageId = PlayerImage; } - GD.sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), imageId, 0, transform, GoodGuy ); -#endif + gd->sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), imageId, 0, transform, GoodGuy ); } /*************************/
--- a/PlayerObject.h Sat Jun 08 11:24:05 2013 +0000 +++ b/PlayerObject.h Sat Jun 08 14:40:47 2013 +0000 @@ -77,23 +77,26 @@ /************************/ /* 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( void ); + virtual void Draw( Gameduino *gd ); /*********************************/ /* KILL A SINGLE PLAYER'S BULLET */ /*********************************/ + // Pass pointer to Gameduino to draw on in gd. // Pass index of bullet in b. - void KillBullet( UInt8 b ) { - playerBullets.KillBullet( b ); + void KillBullet( Gameduino *gd, UInt8 b ) { + playerBullets.KillBullet( gd, b ); } /*****************************/ /* KILL ALL PLAYER'S BULLETS */ /*****************************/ - void KillAllBullets( void ) { - playerBullets.KillAllBullets(); + // Pass pointer to Gameduino to draw on in gd. + void KillAllBullets( Gameduino *gd ) { + playerBullets.KillAllBullets( gd ); } /*********************************************************/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SpriteNumber.h Sat Jun 08 14:40:47 2013 +0000 @@ -0,0 +1,29 @@ +/* + * SOURCE FILE : SpriteNumber.h + * + * Enumeration containing sprite numbers. + * Note that these are sprite numbers, NOT sprite image numbers. + * Each sprite can have any sprite image number it wants. + * + */ + +#ifndef SpriteNumberDefined + + #define SpriteNumberDefined + + #include "LevelData.h" + // #include "ExplosionManager.h" + + enum SpriteNumber { + FirstEnemySprite = 0, + FirstHumanSprite = FirstEnemySprite + LevelData::MaxEnemies, + PlayerSprite = FirstHumanSprite + LevelData::MaxHumans, + #if 0 + FirstExplosionSprite = PlayerSprite + 1, + NextFreeSprite = FirstExplosionSprite + ExplosionManager::MaxExplosions, + #endif + }; + +#endif + +/* END of SpriteNumber.h */