Part 2 - The Enemy Class
In this walkthrough, create a new Enemy class and use it to display a moving enemy on the screen.
Adding ScreenHeight and ScreenWidth Properties to the ArcadeFlyerGame Class
Before creating an enemy, it will be necessary to add two properties to the ArcadeFlyerGame class: ScreenHeight and ScreenWidth. This will allow the Enemy objects to know where the screen starts and ends. A simple way to create these properties is to use the propfull code snippet.
- Open the ArcadeFlyerGame.cs file
- Make a new line in the body of the
ArcadeFlyerGameclass, under the existing private fields - If using VS Code with the C# extension, type in "propfull" and press
Enter. The following code should appear automatically:private int myVar; public int MyProperty { get { return myVar; } set { myVar = value; } } - Press the
Tabkey to tab through and update the property values;myVarshould bescreenWidth, andMyPropertyshould beScreenWidth:private int screenWidth; public int ScreenWidth { get { return screenWidth; } set { screenWidth = value; } } - Set the initial field value to be
1600, the preferred width of the screen - Add the
privatekeyword in front of thesetaccessor, so that only theArcadeFlyerGameclass can set the screen width - Repeat the steps above for the
ScreenHeightproperty, using900for the preferred height - In the
ArcadeFlyerGameconstructor, replace the hard-coded1600and900with the field values
Code
ArcadeFlyerGame class:
private int screenWidth = 1600;
public int ScreenWidth
{
get { return screenWidth; }
private set { screenWidth = value; }
}
private int screenHeight = 900;
public int ScreenHeight
{
get { return screenHeight; }
private set { screenHeight = value; }
}
ArcadeFlyerGame constructor:
graphics.PreferredBackBufferWidth = screenWidth;
graphics.PreferredBackBufferHeight = screenHeight;
Loading an Enemy Image Asset
To create an enemy, it will be necessary to have an image for the enemy! Use the following evil ball image, or any other image:

- Save a new image named Enemy.png in the "Content" folder
- Open up the Content.mgcb file in the MonoGame Pipeline Tool
- Click the "Add Existing Item" button
- Select the Enemy.png file
- Click the "Build" button
Now the "Enemy" asset should be loadable in the game!
Defining the Enemy Class
Now it's time to create an Enemy class. This will be very similar to creating the Player class.
Setup
Start with the basic setup for the class.
- Create a new file named Enemy.cs in the "src" folder
- Add
usingstatements forMicrosoft.Xna.FrameworkandMicrosoft.Xna.Framework.Graphics - Create a
namespacewrapper forArcadeFlyer2D - In the body of the
ArcadeFlyer2Dnamespace, define aclassnamedEnemy
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace ArcadeFlyer2D
{
class Enemy
{
}
}
Basic Fields
Add some basic private fields for the Enemy class:
- A reference to the
rootArcadeFlyerGameobject - A
positionstored in aVector2object - A
spriteImagestored in aTexture2Dobject - A
spriteWidthstored in afloat - A two-dimensional
velocitystored in aVector2object
private ArcadeFlyerGame root;
private Vector2 position;
private Texture2D spriteImage;
private float spriteWidth;
private Vector2 velocity;
Calculated Properties
Some properties can be calculated based on the private fields:
- A
SpriteHeightproperty that calculates the properly scaled heightfloatbased on the image dimensions and sprite width - A
PositionRectangleproperty that returns aRectanglerepresenting the location of the enemy on the screen
Because they are calculated, these properties should only have get accessors, and no set accessors.
public float SpriteHeight
{
get
{
float scale = spriteWidth / spriteImage.Width;
return spriteImage.Height * scale;
}
}
public Rectangle PositionRectangle
{
get
{
return new Rectangle((int)position.X, (int)position.Y, (int)spriteWidth, (int)SpriteHeight);
}
}
Construction and Content Loading
Next, create the constructor for the Enemy class, and a LoadContent method for loading the "Enemy" image asset.
- Define a
publicconstructor for theEnemyclass that takes in anArcadeFlyerGame rootobject and aVector2 positionobject - In the body of the constructor, set the
rootandpositionprivate fields to the parameter values - Under those statements, set the
spriteWidthfield to128.0f - Set the
velocityfield to a newVector2object with-1.0fand5.0f- This means the enemy will move left and down
- Define a new method named
LoadContentwith a return type ofvoidand no parameters - In the body of the
LoadContentmethod, useroot.Content.Loadto load the "Enemy" asset - Under that, set the
spriteImagefield to the loaded "Enemy" asset - Back in the constructor, at the bottom of the body, call the
LoadContentmethod
public Enemy(ArcadeFlyerGame root, Vector2 position)
{
this.root = root;
this.position = position;
this.spriteWidth = 128.0f;
this.velocity = new Vector2(-1.0f, 5.0f);
LoadContent();
}
public void LoadContent()
{
this.spriteImage = root.Content.Load<Texture2D>("Enemy");
}
The Update Method
To make an enemy move from frame to frame, it will be necessary to update the position field. This should happen in a method named Update. The enemy should move according to the velocity field, and the velocity should update so the enemy bounces off the top and bottom of the screen.
- In the body of the
Enemyclass, define a new method namedUpdate- The method should have a
voidreturn type, and it should take in aGameTimeparameter
- The method should have a
- In the body of the
Updatemethod, update thepositionfield by adding thevelocityto it:position += velocity; - Under the
positionupdate, create anifstatement - In the condition for the
ifstatement, check if the enemy is hitting the top or the bottom of the screen. Either of the following:- Its Y position is less than
0 - Its Y position is greater than the height of the screen minus its own height
- Its Y position is less than
- In the body of the
ifstatement, flip the Y velocity by multiplying it by-1
Now, the sprite should be able to move and bounce properly!
public void Update(GameTime gameTime)
{
position += velocity;
if (position.Y < 0 || position.Y > (root.ScreenHeight - SpriteHeight))
{
velocity.Y *= -1;
}
}
The Draw Method
The last thing the Enemy class needs to do is actually draw the enemy on the screen!
- In the body of the
Enemyclass, define a new method namedDraw- The method should have a
voidreturn type, and it should take in aGameTimeparameter and aSpriteBatchparameter
- The method should have a
- In the body of the
Drawmethod, call thespriteBatch.Drawmethod- Pass in the
spriteImagefield, thePositionRectangleproperty, andColor.White
- Pass in the
That's all that's needed to draw the sprite!
public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
{
spriteBatch.Draw(spriteImage, PositionRectangle, Color.White);
}
The Enemy Class
The code in the Enemy.cs file should look something like this:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace ArcadeFlyer2D
{
class Enemy
{
private ArcadeFlyerGame root;
private Vector2 position;
private Texture2D spriteImage;
private float spriteWidth;
private Vector2 velocity;
public float SpriteHeight
{
get
{
float scale = spriteWidth / spriteImage.Width;
return spriteImage.Height * scale;
}
}
public Rectangle PositionRectangle
{
get
{
return new Rectangle((int)position.X, (int)position.Y, (int)spriteWidth, (int)SpriteHeight);
}
}
public Enemy(ArcadeFlyerGame root, Vector2 position)
{
this.root = root;
this.position = position;
this.spriteWidth = 128.0f;
this.velocity = new Vector2(-1.0f, 5.0f);
LoadContent();
}
public void LoadContent()
{
this.spriteImage = root.Content.Load<Texture2D>("Enemy");
}
public void Update(GameTime gameTime)
{
position += velocity;
if (position.Y < 0 || position.Y > (root.ScreenHeight - SpriteHeight))
{
velocity.Y *= -1;
}
}
public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
{
spriteBatch.Draw(spriteImage, PositionRectangle, Color.White);
}
}
}
Using the Enemy Class to Create an Enemy
Now that the Enemy class has been defined, all that's left is to use it in the ArcadeFlyerGame class to make an enemy in the game!
- Open the ArcadeFlyerGame.cs file
- In the body of the
ArcadeFlyerGameclass, add a private field namedenemyof typeEnemy - In the body of the
ArcadeFlyerGameconstructor, initialize a newEnemyobject - Pass in
this, and a newVector2object for the position to make it appear on the right side of the screen:enemy = new Enemy(this, new Vector2(screenWidth, 0)); - In the
Updatemethod, call theEnemy'sUpdatemethod on theenemyfield - In the
Drawmethod, call theEnemy'sDrawmethod on theenemyfield
Run the game, and the new enemy should appear! It should move to the left, and bounce off the bottom and top of the screen.
Final Code
The final code for this walkthrough is available on GitHub.