Game Initialization

Before we actually move into the game loop, we need to initialize the game - load all of its needed parts and set all initial values. The MonoGame Game class provides two virtual hook methods for doing this: Game.Initialize() and Game.LoadContent().

You might be wondering why we have two methods, or asking why the constructor is not included in this count. These are all good questions. First, in the documentation we see that Initialize():

Initializes attached GameComponent instances and calls LoadContent().

And, if we look at the template-generated Game.Initialize() method:

protected override void Initialize()
{
    // TODO: Add your initialization logic here
 
    base.Initialize();
}

We can see that the Game.Initialize() is only invoked after our own initialization logic. Thus, it is largely a matter of controlling timing. We only want content (i.e. sounds, textures, etc.) to be loaded once the game is fully initialized.

This is largely because we are using the 3D hardware, which has its own RAM (video memory). Ideally, textures should be stored there for the fastest and most efficient rendering. So we want to delay loading our graphics until we have finished configuring the graphics device. Thus, we do any graphics card configuration in the Initialize() method, before invoking base.Initialize().

And why not the constructor? What if we want the player to be able to, upon loosing, immediately restart the game? If our initialization logic is in Initialize(), we can simply re-invoke that method. We can’t re-construct the Game class though, as it is tied to the life of our application.

A Simple Example

Let’s look at a super-simple example demonstrating the game loop. We’ll have a ball that moves a bit each frame and bounces off the sides of the window.

Variable Declarations

First, we need to know the ball’s position and velocity. In a two-dimensional game, we would probably use a Vector2 Struct to represent these. We also need a Texture2D to be the image of the ball:

// The ball's information
private Vector2 _ballPosition;
private Vector2 _ballVelocity;
private Texture2D _ballTexture;

Add these lines to the top of the Game1 class definition, along with the other field declarations.

Initialize() Additions

Then, in our Initialize() method, let’s center the ball on the screen:

    // Position the ball in the center of the screen
    _ballPosition.X = GraphicsDevice.Viewport.Width / 2;
    _ballPosition.Y = GraphicsDevice.Viewport.Height / 2;

We’ll also give it a random velocity:

    // Give the ball a random velocity
    System.Random rand = new System.Random();
    _ballVelocity.X = (float)rand.NextDouble();
    _ballVelocity.Y = (float)rand.NextDouble();
    _ballVelocity.Normalize();
    _ballVelocity *= 100;

For now we’ll use the System.Random class you are used to. For some game purposes, it is sufficient, though its randomness is not as random as we’ll need for some kinds of games. Also, note that because Random.NextDouble() returns a double, and Vector2 uses floats, we need to implicitly cast the result. Finally, Vector2.Normalize() will shorten our velocity vector to be of length $ 1 $, which the _ballVelocity *= 100; line scales up to a length of $ 100 $. Eventually this will mean our ball will be traveling 100 pixels per second.

Adding the Image to the Project

As we said above, LoadContent() is where we load our assets. For now, we just need an image of a ball. However, getting this image into our game takes a bit of doing.

First, we need to find an image to use - a .jpeg, .gif, or .png will work fine. Feel free to use this one a golden ball a golden ball .

Look in the Content folder of your solution explorer in Visual Studio. You should also notice a file, Content.mgcb in the same folder. This is a listing of all content to bring into the game. Go ahead and open it; it will look something like:

The MGCB Editor The MGCB Editor

Tip

If instead of the editor program a text file is loaded in your VisualStudio instance, try right-click the file and choose “open with”. From the dialog, choose the mgcb-editor-wpf. If it is not listed, you may need to install it. From the command line:

> dotnet tool install --global dotnet-mgcb-editor 
> mgcb-editor --register

Click the “Add Existing Item” toolbar button:

Add Existing Item toolbar button Add Existing Item toolbar button

In the Open dialog that appears, select the ball image and click “Open”. Then in the next dialog, choose “Copy the file to the directory”:

Add File Dialog Add File Dialog

Finally, save the .mgcb file:

Save the .mgcb file Save the .mgcb file

Now the image will be built into a game-specific binary format as part of the build process. We’ll delve deeper into how this works in the chapter on the Content Pipeline.

LoadContent() Additions

To bring the ball texture into the game, we need to load it with a ContentManager class by invoking the ContentManager.Load<T>() method with the name of our content. The Game class has one already created and ready in the Game.Content property; we’ll use it:

_ballTexture = Content.Load<Texture2D>("ball");

Add this line just below the #TODO: use this.Content to load your game content here line in the LoadContent() method.

Note that we use the filename (sans extension) to identify the content file to load, and that we also specify the type of object it should be loaded as (in this case, Texture2D).

At this point, if we were to run the game everything would be initialized. Now we need to handle updating and rendering the game world.