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

Files at this revision

API Documentation at this revision

Comitter:
RichardE
Date:
Sat Jun 08 17:51:33 2013 +0000
Parent:
7:e72691603fd3
Child:
9:fa7e7b37b632
Commit message:
Enemies, humans, explosions, collisions all working now. Sound is still missing and there are only 2 levels.

Changed in this revision

BlueMeanyObject.cpp Show annotated file Show diff for this revision Revisions of this file
BlueMeanyObject.h Show annotated file Show diff for this revision Revisions of this file
Direction4.h Show annotated file Show diff for this revision Revisions of this file
ExplosionManager.cpp Show annotated file Show diff for this revision Revisions of this file
ExplosionManager.h Show annotated file Show diff for this revision Revisions of this file
ExplosionObject.h Show annotated file Show diff for this revision Revisions of this file
GameObject.h Show annotated file Show diff for this revision Revisions of this file
Level.h Show annotated file Show diff for this revision Revisions of this file
LevelData.h Show annotated file Show diff for this revision Revisions of this file
LevelNormal.cpp Show annotated file Show diff for this revision Revisions of this file
MathFuncs.h Show annotated file Show diff for this revision Revisions of this file
MutantObject.cpp Show annotated file Show diff for this revision Revisions of this file
MutantObject.h Show annotated file Show diff for this revision Revisions of this file
OneShotObject.cpp Show annotated file Show diff for this revision Revisions of this file
OneShotObject.h Show annotated file Show diff for this revision Revisions of this file
SpriteNumber.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BlueMeanyObject.cpp	Sat Jun 08 17:51:33 2013 +0000
@@ -0,0 +1,43 @@
+/*
+ * SOURCE FILE : BlueMeanyObject.cpp
+ *
+ * Represents the BlueMeany enemy object.
+ *
+ */
+
+#include "BlueMeanyObject.h"
+#include "MathFuncs.h"
+
+/************************/
+/* MOVE THE GAME OBJECT */
+/************************/
+void BlueMeanyObject::ProtectedMove( void ) {
+  // If being restricted horizontally then make horizontal velocity zero.
+  if( RestrictionFlags & ( LeftRestriction | RightRestriction ) ) {
+    hVelocity = 0;
+  }
+  // If being restricted vertically then make vertical velocity zero.
+  if( RestrictionFlags & ( UpRestriction | DownRestriction ) ) {
+    vVelocity = 0;
+  }
+  // Update coordinates by adding velocities.
+  Xco += hVelocity;
+  Yco += vVelocity;
+  // Accelerate towards chase object horizontally.
+  if( Xco > chaseObject->Xco ) {
+    hVelocity--;
+  }
+  else {
+    hVelocity++;
+  }
+  // Accelerate towards chase object vertically.
+  if( Yco > chaseObject->Yco ) {
+    vVelocity--;
+  }
+  else {
+    vVelocity++;
+  }
+  // Don't let speed get too fast.
+  hVelocity = MathFuncs::Constrain( hVelocity, -MaxBlueMeanyVelocity, MaxBlueMeanyVelocity );
+  vVelocity = MathFuncs::Constrain( vVelocity, -MaxBlueMeanyVelocity, MaxBlueMeanyVelocity );
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BlueMeanyObject.h	Sat Jun 08 17:51:33 2013 +0000
@@ -0,0 +1,79 @@
+/*
+ * SOURCE FILE : BlueMeanyObject.h
+ *
+ * Represents the BlueMeany enemy object.
+ *
+ */
+
+#ifndef BlueMeanyObjectIncluded
+  
+  #define BlueMeanyObjectIncluded
+
+  #include "EnemyObject.h"
+  #include "SpriteImageId.h"
+  #include "FrameCounter.h"
+  
+  class BlueMeanyObject : public EnemyObject {
+    
+  public :
+
+    /***************/
+    /* CONSTRUCTOR */
+    /***************/
+    BlueMeanyObject() :
+      hVelocity( 0 ),
+      vVelocity( 0 )
+    {
+    }
+
+    /**************/
+    /* DESTRUCTOR */
+    /**************/
+    virtual ~BlueMeanyObject() {
+    }
+    
+        /*****************************/
+        /* GET TYPE OF ENEMY THIS IS */
+        /*****************************/
+        // Returns enemy type.
+        virtual EnemyType GetEnemyType( void ) {
+            return BlueMeany;
+        }
+
+    /*******************************************************/
+    /* 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 */
+    /************************/
+    // This is only called after it has been established that the
+    // game object is visible.
+    virtual void Draw( Gameduino *gd ) {
+      Gameduino::Rotation transform = ( Xco < chaseObject->Xco ) ? Gameduino::FlipX : Gameduino::None;
+      gd->sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), BlueMeanyImage, 0, transform, BadGuy );
+    }
+   
+  private :
+  
+        enum {
+            MaxBlueMeanyVelocity = 64,
+        };
+        
+    // Horizontal and vertical velocities. NOT in pixels.
+    Int16 hVelocity, vVelocity;
+    
+  };
+    
+#endif
+
+/* END of BlueMeanyObject.h */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Direction4.h	Sat Jun 08 17:51:33 2013 +0000
@@ -0,0 +1,22 @@
+/*
+ * SOURCE FILE : Direction4.h
+ *
+ * Definition of enumeration Direction4.
+ *
+ */
+
+#ifndef Direction4Defined
+
+  #define Direction4Defined
+
+    enum Direction4 {
+        UpDir4,
+        RightDir4,
+        DownDir4,
+        LeftDir4,
+    };
+
+#endif
+
+/* END of Direction4.h */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ExplosionManager.cpp	Sat Jun 08 17:51:33 2013 +0000
@@ -0,0 +1,62 @@
+/*
+ * SOURCE FILE : ExplosionManager.cpp
+ *
+ * Responsible for managing a collection of explosions.
+ *
+ */
+
+#include "ExplosionManager.h"
+#include "SpriteNumber.h"
+
+// An instance of this class.
+ExplosionManager ExplosionManager::Instance( FirstExplosionSprite );
+
+/***************/
+/* CONSTRUCTOR */
+/***************/
+// Pass index of first sprite used for explosions in fsn.
+ExplosionManager::ExplosionManager( UInt8 fsn ) :
+    firstSpriteNumber( fsn )
+{
+  KillAllExplosions();
+}
+    
+/**************/
+/* DESTRUCTOR */
+/**************/
+ExplosionManager::~ExplosionManager() {
+}
+
+/**************************/
+/* START AN EXPLOSION OFF */
+/**************************/
+// Pass start coordinates in x and y (NOT pixel coordinates).
+// Returns pointer to an ExplosionObject if it was started successfully or NULL if
+// no more explosions are available at the moment.
+ExplosionObject *ExplosionManager::StartExplosion( Int16 x, Int16 y ) {
+  // Find a free explosion slot.
+  UInt8 i = 0;
+  ExplosionObject *explosion = (ExplosionObject*)NULL;
+  while( ( i < MaxExplosions ) && ( explosion == (ExplosionObject*)NULL ) ) {
+    if( explosionPointers[ i ] == (GameObject*)NULL ) {
+      explosion = explosions + i;
+      explosionPointers[ i ] = explosion;
+      explosion->SpriteNumber = firstSpriteNumber + i;
+      explosion->Xco = x;
+      explosion->Yco = y;
+      explosion->Restart();
+    }
+    i++;
+  }
+  return explosion;
+}
+
+/***********************/
+/* KILL ALL EXPLOSIONS */
+/***********************/
+void ExplosionManager::KillAllExplosions( void ) {
+  for( UInt8 i = 0; i < MaxExplosions; ++i ) {
+    explosionPointers[ i ] = (GameObject*)NULL;
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ExplosionManager.h	Sat Jun 08 17:51:33 2013 +0000
@@ -0,0 +1,74 @@
+/*
+ * SOURCE FILE : ExplosionManager.h
+ *
+ * Responsible for managing a collection of explosions.
+ *
+ */
+
+#ifndef ExplosionManagerIncluded
+  
+  #define ExplosionManagerIncluded
+  
+  #include "Types.h"
+  #include "ExplosionObject.h"
+  
+  class ExplosionManager {
+  
+  public :
+
+    // An instance of this class.
+    static ExplosionManager Instance;
+    
+    enum {
+      MaxExplosions = 10,
+    };
+    
+    /***************/
+    /* CONSTRUCTOR */
+    /***************/
+        // Pass index of first sprite used for explosions in fsn.
+    ExplosionManager( UInt8 fsn );
+    
+    /**************/
+    /* DESTRUCTOR */
+    /**************/
+    ~ExplosionManager();
+
+    /**************************/
+    /* START AN EXPLOSION OFF */
+    /**************************/
+    // Pass start coordinates in x and y (NOT pixel coordinates).
+    // Returns pointer to an ExplosionObject if it was started successfully or NULL if
+    // no more explosions are available at the moment.
+    ExplosionObject *StartExplosion( Int16 x, Int16 y );
+    
+    /***********************/
+    /* KILL ALL EXPLOSIONS */
+    /***********************/
+    void KillAllExplosions( void );
+    
+    /**********************************************/
+    /* GET ARRAY OF POINTERS TO EXPLOSION OBJECTS */
+    /**********************************************/
+    // Returns an array of pointers containing MaxExplosions items.
+    GameObject **GetExplosions( void ) {
+      return explosionPointers;
+    }
+
+  private :
+
+        // Sprite number for first sprite used for explosions.
+        UInt8 firstSpriteNumber;
+        
+    // Bank of explosion objects.
+    ExplosionObject explosions[ MaxExplosions ];
+    
+    // Pointers to explosion objects.
+    GameObject *explosionPointers[ MaxExplosions ];
+
+  };
+  
+#endif
+
+/* END of ExplosionManager.h */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ExplosionObject.h	Sat Jun 08 17:51:33 2013 +0000
@@ -0,0 +1,45 @@
+/*
+ * SOURCE FILE : ExplosionObject.h
+ *
+ * Represents an explosion.
+ *
+ */
+
+#ifndef ExplosionObjectIncluded
+  
+  #define ExplosionObjectIncluded
+
+  #include "OneShotObject.h"
+  #include "SpriteImageId.h"
+  
+  class ExplosionObject : public OneShotObject {
+    
+  public :
+
+    /***************/
+    /* CONSTRUCTOR */
+    /***************/
+    ExplosionObject() {
+      SetImageRange( Explosion0Image, Explosion9Image, 7 );
+    }
+
+    /**************/
+    /* DESTRUCTOR */
+    /**************/
+    virtual ~ExplosionObject() {
+    }
+    
+    /************************/
+    /* GET GAME OBJECT TYPE */
+    /************************/
+    // Returns type of game object.
+    virtual GameObjectTypes GetType( void ) {
+      return ExplosionObjectType;
+    }
+    
+  };
+    
+#endif
+
+/* END of ExplosionObject.h */
+
--- a/GameObject.h	Sat Jun 08 16:44:54 2013 +0000
+++ b/GameObject.h	Sat Jun 08 17:51:33 2013 +0000
@@ -223,7 +223,7 @@
     // Pass pointer to a function that takes two UInt8 parameters in func.
     // The first parameter is the index of the object in the objects array that hit something.
     // The second parameter is the sprite number of the sprite which it hit.
-    void FindCollisions( Gameduino *gd, GameObject **objects, UInt8 objectCount, void (*func)( UInt8, UInt8 ) );
+    static void FindCollisions( Gameduino *gd, GameObject **objects, UInt8 objectCount, void (*func)( UInt8, UInt8 ) );
     
     /*************************************************************************/
     /* FIND AN OBJECT WITH A PARTICULAR SPRITE NUMBER IN AN ARRAY OF OBJECTS */
--- a/Level.h	Sat Jun 08 16:44:54 2013 +0000
+++ b/Level.h	Sat Jun 08 17:51:33 2013 +0000
@@ -28,8 +28,9 @@
   #include "GruntObject.h"
   #include "CrusherObject.h"
   #include "BrainObject.h"
+  #include "MutantObject.h"
+  #include "BlueMeanyObject.h"
 #if 0
-  #include "BlueMeanyObject.h"
   #include "SoundManager.h"
   #include "Sounds.h"
 #endif
--- a/LevelData.h	Sat Jun 08 16:44:54 2013 +0000
+++ b/LevelData.h	Sat Jun 08 17:51:33 2013 +0000
@@ -10,9 +10,9 @@
   #define LevelDataDefined
 
   #include "GameObject.h"
-  // #include "EnemyObject.h"
-  // #include "HumanObject.h"
-  // #include "MutantObject.h"
+  #include "EnemyObject.h"
+  #include "HumanObject.h"
+  #include "MutantObject.h"
   
   class LevelData {
 
@@ -21,7 +21,7 @@
     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
+      MaxMutants = MaxHumans,    // Maximum number of mutant humans you can have in a level
     };
     
     // Array containing pointers to all the enemies in a level.
@@ -35,7 +35,7 @@
     // 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 ];
+    MutantObject Mutants[ MaxMutants ];
 
     /***************/
     /* CONSTRUCTOR */
--- a/LevelNormal.cpp	Sat Jun 08 16:44:54 2013 +0000
+++ b/LevelNormal.cpp	Sat Jun 08 17:51:33 2013 +0000
@@ -77,7 +77,7 @@
     // Kill off all player's bullets.
     player->KillAllBullets( gd );
     // Kill off all explosions.
-    // ExplosionManager::Instance.KillAllExplosions();
+    ExplosionManager::Instance.KillAllExplosions();
 }
 
 /**********************************/
@@ -126,7 +126,6 @@
 // Pass sprite number of sprite that it hit in spriteNumber.
 void LevelNormal::HandleHumanCollision( UInt8 humanIndex, UInt8 spriteNumber )
 {
-#if 0
     // Point to array of enemy object pointers.
     GameObject **enemies = currentInstance->DataForLevel->Enemies;
     EnemyObject *enemy;
@@ -143,8 +142,10 @@
             if( enemy->SquashesHumans ) {
                 // Change human to dead state.
                 human->CurrentState = HumanObject::Dead;
+                #if 0
                 // Make a noise.
                 SoundManager::Instance.PlaySound( Sounds::HumanDies, 0, 0 );
+                #endif
             } else if( enemy->GetEnemyType() == Brain ) {
                 // Kill human by inserting a null into humans array.
                 humans[ humanIndex ] = (GameObject*)NULL;
@@ -160,12 +161,11 @@
                     // TODO : SoundManager::Instance.PlaySound( Sounds::HumanMutates, 0, 0 );
                 } else {
                     // Could not find a free slot for a new enemy so just erase the human sprite.
-                    GDExtra::HideSprite( human->SpriteNumber );
+                    GDExtra::HideSprite( currentInstance->gd, human->SpriteNumber );
                 }
             }
         }
     }
-#endif
 }
 
 /********************************************************/
@@ -175,7 +175,6 @@
 // Pass sprite number of sprite that it hit in spriteNumber.
 void LevelNormal::HandleBulletCollision( UInt8 bulletIndex, UInt8 spriteNumber )
 {
-#if 0
     // Point to array of enemy object pointers.
     GameObject **enemies = currentInstance->DataForLevel->Enemies;
     EnemyObject *enemy;
@@ -191,7 +190,7 @@
                 // Kill enemy by inserting a NULL into enemies array.
                 enemies[ enemyIndex ] = (GameObject*)NULL;
                 // Hide the enemy sprite.
-                GDExtra::HideSprite( enemy->SpriteNumber );
+                GDExtra::HideSprite( currentInstance->gd, enemy->SpriteNumber );
                 // Add points to player's score.
                 currentInstance->player->AddToScore( enemy->GetPoints() );
             }
@@ -199,13 +198,14 @@
         // Tell enemy it has been hit by a bullet.
         enemy->RegisterHitByBullet();
         // Kill off the bullet.
-        currentInstance->player->KillBullet( bulletIndex );
+        currentInstance->player->KillBullet( currentInstance->gd, bulletIndex );
+        #if 0
         // Make a noise.
         SoundManager::Instance.PlaySound( Sounds::Explosion, 0, 0 );
+        #endif
         // Start explosion animation using coordinates of enemy.
         ExplosionManager::Instance.StartExplosion( enemy->Xco, enemy->Yco    );
     }
-#endif
 }
 
 /*********************************************************/
@@ -214,10 +214,9 @@
 // Pass pointer to a flag that will be set true if player is dead in isDead parameter.
 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 );
+    UInt8 hitSpriteNumber = gd->rd( Gameduino::COLLISION + player->SpriteNumber );
     // If you get 0xFF then no collision found.
     if( hitSpriteNumber != 0xFF ) {
         // Check for collision with an enemy.
@@ -241,12 +240,13 @@
                 human->CurrentState = HumanObject::Rescued;
                 // Give player 50 points (in BCD!).
                 player->AddToScore( 0x50 );
+                #if 0
                 // Make a noise.
                 SoundManager::Instance.PlaySound( Sounds::RescueHuman, 0, 0 );
+                #endif
             }
         }
     }
-#endif
 }
 
 /***********************************************************************************/
@@ -307,22 +307,18 @@
             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 );
+            GameObject::FindCollisions( gd, DataForLevel->Humans, LevelData::MaxHumans, &LevelNormal::HandleHumanCollision );
             // Check for collisions between player bullets and enemies.
-            GameObject::FindCollisions( player->GetBullets(), BulletManager::MaxBullets, &LevelNormal::HandleBulletCollision );
-#endif
+            GameObject::FindCollisions( gd, player->GetBullets(), BulletManager::MaxBullets, &LevelNormal::HandleBulletCollision );
             // 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 humans.
-            GameObject::DrawAll( DataForLevel->Humans, LevelData::MaxHumans );
+            GameObject::DrawAll( gd, DataForLevel->Humans, LevelData::MaxHumans );
             // Draw all the explosions.
-            GameObject::DrawAll( ExplosionManager::Instance.GetExplosions(), ExplosionManager::MaxExplosions );
-#endif
+            GameObject::DrawAll( gd, ExplosionManager::Instance.GetExplosions(), ExplosionManager::MaxExplosions );
             // Draw the player.
             player->Draw( gd );
             // Draw the player's bullets.
@@ -374,12 +370,10 @@
                         LevelData::MaxEnemies
                     );
                 }
-#if 0
                 // 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.
@@ -396,4 +390,3 @@
         return Completed;
     }
 }
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MathFuncs.h	Sat Jun 08 17:51:33 2013 +0000
@@ -0,0 +1,43 @@
+/*
+ * SOURCE FILE : MathFuncs.h
+ *
+ * Definition of class MathFuncs.
+ *
+ */
+
+#ifndef MathFuncsDefined
+
+    #define MathFuncsDefined
+    
+    #include "Types.h"
+    
+    /** Various useful maths related functions. */
+    class MathFuncs {
+    
+    public :
+
+        /** Constrain a number to be between 2 values.
+         *
+         * @param x Number to constrain.
+         * @param min Minimum value.
+         * @param max Maximum value.
+         * @returns A number between min and max.
+         */
+        static Int16 Constrain( Int16 x, Int16 min, Int16 max ) {
+            if( x < min ) {
+                return min;
+            }
+            else if( x > max ) {
+                return max;
+            }
+            else {
+                return x;
+            }
+        }
+            
+    };
+
+#endif
+
+/* END of MathFuncs.h */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MutantObject.cpp	Sat Jun 08 17:51:33 2013 +0000
@@ -0,0 +1,64 @@
+/*
+ * SOURCE FILE : MutantObject.cpp
+ *
+ * Represents a mutated human.
+ *
+ */
+
+#include "MutantObject.h"
+#include "SpriteImageId.h"
+
+// Speed at which grunt moves.
+Int16 MutantObject::mutantSpeed = FromPixel( 1 );
+
+/**********************/
+/* START OFF A MUTANT */
+/**********************/
+// Pass pointer to human mutant will replace in human.
+// Pass pointer to object it will chase in player.
+void MutantObject::Start( HumanObject *human, GameObject *player ) {
+    // Copy coordinate of human to mutant.
+    Xco = human->Xco;
+    Yco = human->Yco;
+    // Use the same sprite number as the human.
+    SpriteNumber = human->SpriteNumber;
+    // Use an appropriate sprite image.
+    SpriteImage = ( human->GetHumanType() == HumanObject::Woman ) ? MutantWomanImage : MutantManImage;
+    // Make it chase the player.
+    SetChaseObject( player );
+    // Set initial direction as either up or down.
+    direction = ( Yco > chaseObject->Yco ) ? UpDir4 : DownDir4;
+}
+
+/************************/
+/* MOVE THE GAME OBJECT */
+/************************/
+void MutantObject::ProtectedMove( void ) {
+    switch( direction ) {
+    case UpDir4 :
+        Yco -= mutantSpeed;
+        if( Yco <= chaseObject->Yco ) {
+            direction = ( Xco > chaseObject->Xco ) ? LeftDir4 : RightDir4;
+        }
+        break;
+    case RightDir4 :
+        Xco += mutantSpeed;
+        if( Xco >= chaseObject->Xco ) {
+            direction = ( Yco > chaseObject->Yco ) ? UpDir4 : DownDir4;
+        }
+        break;
+    case DownDir4 :
+        Yco += mutantSpeed;
+        if( Yco >= chaseObject->Yco ) {
+            direction = ( Xco > chaseObject->Xco ) ? LeftDir4 : RightDir4;
+        }
+        break;
+    case LeftDir4 :
+        Xco -= mutantSpeed;
+        if( Xco <= chaseObject->Xco ) {
+            direction = ( Yco > chaseObject->Yco ) ? UpDir4 : DownDir4;
+        }
+        break;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MutantObject.h	Sat Jun 08 17:51:33 2013 +0000
@@ -0,0 +1,91 @@
+/*
+ * SOURCE FILE : MutantObject.h
+ *
+ * Represents a mutated human.
+ *
+ */
+
+#ifndef MutantObjectIncluded
+  
+  #define MutantObjectIncluded
+
+  #include "EnemyObject.h"
+  #include "SpriteImageId.h"
+  #include "FrameCounter.h"
+  #include "Direction4.h"
+  #include "HumanObject.h"
+  
+  class MutantObject : public EnemyObject {
+    
+  public :
+
+        // Number for sprite image used.
+        UInt8 SpriteImage;
+        
+    /***************/
+    /* CONSTRUCTOR */
+    /***************/
+    MutantObject() :
+            SpriteImage( MutantWomanImage ),
+            direction( UpDir4 )
+        {
+    }
+
+    /**************/
+    /* DESTRUCTOR */
+    /**************/
+    virtual ~MutantObject() {
+    }
+    
+        /*****************************/
+        /* 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!
+    }
+
+        /**********************/
+        /* START OFF A MUTANT */
+        /**********************/
+        // Pass pointer to human mutant will replace in human.
+        // Pass pointer to object it will chase in player.
+        void Start( HumanObject *human, GameObject *player );
+        
+    /************************/
+    /* 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 ) {
+      Gameduino::Rotation transform = ( FrameCounter & 8 ) ? Gameduino::FlipX : Gameduino::None;
+      gd->sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), SpriteImage, 0, transform, BadGuy );
+    }
+   
+  private :
+  
+    // Speed at which mutants move.
+    static Int16 mutantSpeed;
+    
+        // Direction mutant is moving.
+        Direction4 direction;
+        
+  };
+    
+#endif
+
+/* END of MutantObject.h */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OneShotObject.cpp	Sat Jun 08 17:51:33 2013 +0000
@@ -0,0 +1,29 @@
+/*
+ * SOURCE FILE : OneShotObject.cpp
+ *
+ * Base class for all objects that do not move and play an animation once before vanishing.
+ * Useful for explosions and popup scores.
+ *
+ */
+
+#include "OneShotObject.h"
+
+/************************/
+/* MOVE THE GAME OBJECT */
+/************************/
+void OneShotObject::ProtectedMove( void ) {
+  if( imageCountdown > 0 ) {
+    // Not time to change image yet.
+    imageCountdown--;
+  }
+  else if( imageNumber >= lastImageNumber ) {
+    // Animation completed. Make game object invisible.
+    Visible = false;
+  }
+  else {
+    // Move on to next image in the animation.
+    imageNumber++;
+    imageCountdown = maxCountdown;
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OneShotObject.h	Sat Jun 08 17:51:33 2013 +0000
@@ -0,0 +1,96 @@
+/*
+ * SOURCE FILE : OneShotObject.h
+ *
+ * Base class for all objects that do not move and play an animation once before vanishing.
+ * Useful for explosions and popup scores.
+ *
+ */
+
+#ifndef OneShotObjectIncluded
+  
+  #define OneShotObjectIncluded
+
+  #include "GameObject.h"
+  #include "SpriteImageId.h"
+  
+  class OneShotObject : public GameObject {
+    
+  public :
+
+    /***************/
+    /* CONSTRUCTOR */
+    /***************/
+    OneShotObject() :
+      imageNumber( Explosion0Image ),
+      firstImageNumber( Explosion0Image ),
+      lastImageNumber( Explosion9Image ),
+      maxCountdown( 7 ),
+      imageCountdown( 7 )
+    {
+      MovementRestricted = false;
+      DeleteWhenRestricted = false;
+    }
+
+    /**************/
+    /* DESTRUCTOR */
+    /**************/
+    virtual ~OneShotObject() {
+    }
+    
+    /**************************************************************/
+    /* SET RANGE OF SPRITE IMAGES TO USE AND DELAY FOR EACH IMAGE */
+    /**************************************************************/
+    // Pass first sprite image used in first.
+    // Pass last sprite image used in last.
+    // Pass delay count between images in count.
+    void SetImageRange( UInt8 first, UInt8 last, UInt8 count ) {
+      firstImageNumber = first;
+      lastImageNumber = last;
+      maxCountdown = count;
+      Restart();
+    }
+    
+    /************************/
+    /* 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 ) {
+      gd->sprite( SpriteNumber, ToPixel( Xco ), ToPixel( Yco ), imageNumber, 0, Gameduino::None, GoodGuy );
+    }
+
+    /****************************/
+    /* RESTART FROM FIRST IMAGE */
+    /****************************/
+    void Restart( void ) {
+      imageNumber = firstImageNumber;
+      imageCountdown = maxCountdown;
+      Visible = true;
+    }
+    
+  private :
+  
+    // Image number currently in use.
+    UInt8 imageNumber;
+    
+    // Image numbers of first and last images.
+    UInt8 firstImageNumber, lastImageNumber;
+    
+    // Maximum countdown to next image change.
+    // Determines speed of explosion animation.
+    UInt8 maxCountdown;
+    
+    // Countdown to next image.
+    UInt8 imageCountdown;
+
+  };
+    
+#endif
+
+/* END of OneShotObject.h */
+
--- a/SpriteNumber.h	Sat Jun 08 16:44:54 2013 +0000
+++ b/SpriteNumber.h	Sat Jun 08 17:51:33 2013 +0000
@@ -12,16 +12,14 @@
   #define SpriteNumberDefined
 
   #include "LevelData.h"
-  // #include "ExplosionManager.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