Building a main menu and loading screens in XNA

There are probably many other ways to build menus and loading screens in XNA game development but this is how I currently do it.
For this guide you need:
  • XNA 4.0
  • Visual Studio 2010 or express edition
  • C# and some XNA knowledge
My full project is linked at the end of this guide, this code is for demo purposes, feel free to use or adjust it as you see fit. If this guide helps you you can always help my reputation by mentioning me on your blog, Twitter or other social media.
All right, let's get things started! This guide builds a Windows game but also works for Windows Phone 7 and Xbox360 games, just replace the mouse code with controller or touch code.
In Visual Studio start a new XNA game by selecting File > New > Project. In the XNA templates select "Windows Game (4.0)" and name it XNAMenuLoadingDemo.

Once the project has loaded you have created a Windows game, if we run this now all we see is a blue screen (this is a good thing in this case). As you can see the mouse pointer doesn't work in the game, the menu we'll create in this guide uses the mouse so we will have to activate it first. This is done in the Initialize method by adding this line of code:
 1: //enable the mousepointer
 2: IsMouseVisible = true;

Next step is adding some global variables that will contain textures.
Global variables are declared right after the opening bracket of the class, before the constructor. There should allready be 2 global variables in the game called “graphics” and “spriteBatch”, place the following code after these two:

 1: private Texture2D  orb;
 2: private Texture2D startButton;
 3: private Texture2D exitButton;
 4: private Texture2D pauseButton;
 5: private Texture2D resumeButton;
 6: private Texture2D loadingScreen;

As you may notice we declared five textures for buttons, that’s because in XNA there’s no such thing as a button.
So as a workaround we create images that look like buttons and make them
do something.

All right, next step is declaring some vectors. Vectors are often used in XNA for positioning elements because a Vector2 has two properties called X and Y. Add the following lines of code under the textures:

 1: private Vector2 orbPosition;
 2: private Vector2 startButtonPosition;
 3: private Vector2 exitButtonPosition;
 4: private Vector2 resumeButtonPosition;

I deliberately only use vectors to position three of the five buttons because I want to show both ways of positioning an element in an XNA game.

Next up is some floats for the game:

 1: private const float OrbWidth = 50f;
 2: private const float OrbHeight = 50f;
 3: private float speed = 1.5f;

The game that we’re building won’t be anything playable, it’s just a red orb bouncing back and forth horizontally. But it will have a start menu, a loading screen and a pause button that are fully functional. The floats that we declared are contain the dimensions of the orb and the speed by which the orb moves back and forth.

We’re almost there, just a few more variables and we can start making some magic happen. Add these variables:

 1: private Thread backgroundThread;
 2: private bool isLoading = false;
 3: MouseState  mouseState;
 4: MouseState  previousMouseState;

I will explain about these variables when we use them.

Now before we continue, let me explain something about XNA that you maybe already know.
XNA has 2 specific methods called Update() and Draw(). These two methods are called 60 times per second in Windows and Xbox360 games and 30 times per second in Windows Phone 7 games. All the game’s logic should go in the Update() method while everything concerning what is showing on the screen should go in the Draw() method. So a game doesn’t really have an implementation for menus and pausing, it’s up to the developer to create something that will take care of that.

The method I’m describing here uses game states, this is something that you can find in the game examples on  

Game state isn’t something that’s build in to XNA, we have to build it ourselves. Best way to do this is by using an Enumerator. This code goes in the same place as the global variables we declared a minute ago.

 1: enum GameState
 2:         {
 3:             StartMenu,
 4:             Loading,
 5:             Playing,
 6:             Paused
 7:         }

Let's go on to the next page where we'll finally see something happen ->

This is an imported post. It was imported from my old blog using an automated tool and may contain formatting errors and/or broken images.