adding enemies

Add moving objects for the player to shoot at

We’re flying through the clouds with the greatest of ease – but what is a game without a challenge? It’s time to add some other characters that are flying, too; we have an enemy graphic ready-made for this purpose. It’s up to you to create a class that can represent these flying enemies, then add them to the game loop the same as you have for the player and the backgrounds.

The enemies will be represented by an Animation and will have a Position, the same as the player does, only they’ll move from right to left. And we’ll need more than one alive at the same time, so we’ll have to manage a list. Finally, we’ll throw in a bit of a twist, and have them appear at random vertical positions when they come in. Ready? Let’s go!

Add a new class to your project by pressing SHIFT + ALT + C, and typing in the name Enemy.cs. Press ENTER.

inside enemy.cs

We’re inside our brand-new enemy class. Let’s get to work on the basics. Delete all the using statements at the top, and replace them with the following lines:

This is starting to get pretty familiar. Only a few surprises here, such as a few interesting variables for health, score, and damage. We’ll get to those in a later step, but we need to focus on the basics first: managing animation, and position. Let’s start with the Initialize() method.

Replace the Initialize() method you just stubbed in with this version:

// We initialize the enemy to be active so it will be update in the gameActive = true;

// Set the health of the enemyHealth = 10;

// Set the amount of damage the enemy can doDamage = 10;

// Set how fast the enemy movesenemyMoveSpeed = 6f;

// Set the score value of the enemyValue = 100;

}

There are those score, health, and damage variables again. They’re going to come in handy in a future step when we start implementing collision and damage. For now, let’s stay on track and move onto the Update() method which will manage moving the enemies and deciding if they’ve gone off the edge of the screen.

Replace the Update() method you just stubbed in with this version:

public void Update(GameTime gameTime)
{ // The enemy always moves to the left so decrement it's xpositionPosition.X -= enemyMoveSpeed;

// Update the position of the AnimationEnemyAnimation.Position = Position;

// Update AnimationEnemyAnimation.Update(gameTime);

// If the enemy is past the screen or its health reaches 0 then deactivateitif (Position.X < -Width || Health <= 0){// By setting the Active flag to false, the game will remove this objet fromthe// active game listActive = false;}
}

The top three lines are familiar – we need to move the enemy by their fixed rate, then send the new Position to its Animation and update it. Finally, we are checking to see if the position is past the left edge of the screen. The reference to –Width means a value equal to -1 * Width, which is the width of the enemy graphic. This will happen when the enemy graphic’s rightmost pixel touches the left hand side of the screen, so the rest of the graphic will have smoothly slid off the edge of the screen by this time.

Setting Active = false; is what will get rid of the enemy when it slides off the screen. We’ll do the removing based off this flag in the Game1 class. On to drawing!

A simple draw call, just like the way we draw Player. They’re using the same Animation code, and that’s the value of encapsulating functions like animation in their own classes – everything can use the same basic functions.

We’re done with our Enemy class for now – we need to get them set up in our game loop, so it’s off to Game1.cs for the rest of this step.

Switch to the Game1 class by double-clicking the Game1.cs file in the Solution Explorer in Visual Studio.

inside game1.cs

We’re back inside our Game1 class. Now, if we were just interested in a single enemy like we have a single player, things would be pretty simple. We’d add one Enemy class and get it into the Draw() and Update() loops, and be done!

However, in Shooter, there are a lot of enemies. We want to be able to track as many as we want, all moving at the same time.

To do this, we need something like an array – we’ll use a special class that acts like an array but can grow and shrink automatically to fit any number of objects we want (within a certain limit). It’s called a List and setting it up isn’t too hard. It also behaves like an array at times; we can walk through it using for loops just like we do with arrays.

Look for the first { mark under the start of the Game1 class, and go just below ParallaxingBackground bgLayer2; you added in the previous step. Add a new line and then add the following:

// Enemies

Texture2D enemyTexture;List<Enemy> enemies;

// The rate at which the enemies appear

TimeSpan enemySpawnTime;TimeSpan previousSpawnTime;

// A random number generator

Random random;

We’re not just adding a list of enemies, we’re adding some variables that are going to help control the rate at which we add new enemies, as well as a Random class, which spits out random numbers that we can use any time we like; we’ll use them in this game to mix up the vertical position of enemies when they spawn in so they appear to be coming from everywhere. We’ll need to do some initializing on these new variables.

Look down the code, find the Initialize() method. Inside that method, add these lines:

Now, since the enemy has graphics associated with it, we’ll need to add a line to the LoadContent() method, the same as we do for the backgrounds and the player.

Look down the code, find the LoadContent() method. Inside that method, below the bgLayer2.Initialize call, add these lines:

enemyTexture = Content.Load<Texture2D>("mineAnimation");

No problem! Now it’s time to get a little more complicated. We’re going to create our own method called AddEnemy(). This is the method we’re going to call when we’re ready to add a new enemy to the game. It will have to do some initialization and position setting.

To do this, you’ll need some empty space inside the Game1 class, but not inside any other method. Just like when you added UpdatePlayer(), look for the Update() method, find the first { mark underneath the function name. Then, follow it down until you find a corresponding } mark that’s got the same indentation level. Then, go one line below that, make a new line, and you’re ready to go.

This method doesn’t do too much that’s different, except the randomization of the position.Y value – the 100 values are tightening the actual area that the enemy is allowed to spawn in; not too high and not too low, but closer to the center of the screen.

Now that we have the adding method, we need to make a method that updates all the enemies we have, as well as determines whether or not we should add a new enemy based on the amount of time that’s passed. Just like AddEnemy, get some open space inside the Game1 class.

This method does two things – first, it checks the GameTime; if a second or more has passed since an enemy has been added, it adds another enemy and resets the spawn timer. Second, it uses a for loop to walk through all of the current enemies and check their Active flag. Remember the check we made in Enemy.cs that would set Active to false if the enemy went off the screen? Now we check this value and do something with it. We call RemoveAt which takes the Enemy object out of the list, deleting it.

By deleting “dead” objects, we keep the amount of memory we use down to a reasonable level. If we didn’t remove the objects at some point, the list would grow forever, eventually maxing out the memory available on your device and causing an error. Conserving memory is important!

Now that we’ve written UpdateEnemies(), we need to get our main game loop to call it at some point, so we need to get it into Update().

Look for the Update() method inside the Game1 class, and after the bgLayer2.Update() call, add the following lines:

// Update the enemies
UpdateEnemies(gameTime);

Finally, we’re down to the last method – like the Player and the Background, we need to draw the enemies inside the Draw() method.

Now, where the enemies draw is up to you, just as long as it’s after the background. If you draw after the Player, the enemies will appear on top of the player’s ship. If you draw before the Player, the enemies will appear behind the player’s ship.

Look for the Draw() method. Inside the method, after you call bgLayer2.Draw(), add these lines:

running the game

This was a big step; let’s have a look! Build and run your game by pressing CTRL+F5. You should now see enemy mines moving across the screen like the screenshot below. If you have compiler errors, or you don’t see the mines, don’t worry! We’re at a checkpoint, so you can get an update to your code if you need it.

Next, we’ll teach you how to add collision to your game so that you can hit the enemies for damage.