Simplify menus in XNA game development

It’s something most, if not all games needs, a good menu. So I was quite surprised when I searched for existing solutions to creating a good menu in XNA, and there were not a lot of resources that involved creating a class that would handle all the menu creation, display, and actions. This blog post will detail my solution to this issue.

First I will describe the basic structure of our classes we will use for our menu in XNA. We will have a Menu class that will hold a number of MenuItems. Each MenuItem will have a title, a description, and an action to perform. The Menu class will handle the rest of the logic regarding which MenuItem is currently selected, and navigating between MenuItems.

MenuItem Class

So first I will show my MenuItem class. It makes sense to create this first so we can use it in our containing Menu class.

This is very simple. We just want three Properties, and no logic inside here. Our first is a string for our Title. This will be what appears as the name for the MenuItem in our Menu. The second is a description, which will be something that appears elsewhere on the screen describing what the current menu item does (if required). The third is our action, this takes an Action, which requires a Button parameter (the button which was pressed). This is very powerful as it allows us to perform almost any action when the MenuItem is actioned, and also allows us to perform different actions based on which button was pressed. The class also requires importing some of the XNA framework so we include using Microsoft.Xna.Framework.Input; as we require the Buttons class in this namespace.

Menu Class

Next I will look at the Menu class. This is much more in depth, and therefore I will go through it bit by bit. First lets add the basic properties for our list:

The initialized at the top just allows us to make sure we don’t perform some logic until the class is fully instantiated (you will see the use of this later). We set it to false here, and true once the class is ready. The next two are simple. We create a basic property for our list of MenuItems, and then provide a Count property on the class that returns the count of our list, to make it slightly easier to call.

These are again three simple properties. Title is the heading of our menu, InfoText is a bit of sub information we can set, and finally lastNavigated is an integer that will store (as an int) the last gametime the menu was navigated so we can make sure we don’t respond too quickly to button presses and make our menu impossible to navigate. If you don’t check this a quick push on an analogue stick will cause the selected item to scroll very quickly.

Here we deal with the logic for the item that is currently selected. This is made up of two parts. First we have a private field to store the index of our selected item, and then a public property to make this accessible. The set is protected as we want to handle navigation with the class however, and we also check that the value is within the limits of our class. Finally we create a readonly property for our selected item, which simply returns the MenuItem at the selectedIndex of our list.

Constructors

Now we want to create constructors for our class. We will create two constructors, one to handle a title, and one to handle both a title and some description text.

This doesn’t need much explaining. Simply, the List for the menuItems is instantiated, and the Title and the InfoText is set.

Adding Items

I decided that the List of menuItems should be private to keep the inner workings of the menu class hidden. Therefore we need to provide methods to add items to our menu:

As you can see, these are pretty simple, the first method just calls it’s overload. All we do is create the MenuItem and add it to the list. I chose that when an item is added the selectedIndex is set to 0, but you may choose this isn’t required. These methods are also virtual so they can be overriden in child classes.

Drawing the Menu on Screen

Next we need to consider drawing our menu:

This method takes in seven parameters, a XNA SpriteBatch to do the drawing, the width of the screen (to center the menu), a XNA SpriteFont to use for the menu, the Y Position to draw the top of the menu from, and a Vector2 for a position to draw the selectedItem description. The last two are just the colors to draw normal menu items, and then the selected menu item.

The logic is simple. We initially draw the title, in the center of the screen, using  SpriteFont.MeasureString() to determine how wide the text is. This is a useful method within the XNA framework that lets us determine the width of the string when we draw it. Then we add the height of the Title + 10 onto our Y position so the menu is drawn below. We then loop through our MenuItems and output them, checking if the item is selected, and drawing the selected menu item in our selectedColor, whilst the rest are drawn in our itemColour. We then move the Y Position down by the height of the string + 10 as we did after the title.

Handling Navigation

Finally all that is left is to provide a way to handle Navigation:

This code may look horribly unwieldy, but in essence it’s simple. We only need to pass in the GamePadState from the XNA Framework, and the GameTime into the method. We then use our initialized field to check whether we have Navigated before, if not, we set the lastNavigated time to the current GameTime (in milliseconds) and set initialized to true so we don’t do this again.

The next step checks that it’s been long enough since we last navigated. this is set to a quarter of a second between navigations, but it’s really up to you what time you set here, it just prevents continuous navigation from a small button press.

The first two if statements check whether the user is trying to navigate with either the analogue sticks, or the DPad and adjusts our selected index appropriately. Finally after this we check each of the Buttons in turn and see if any are pressed. If they are we execute the action associated with the selected menu item, passing in the button that was pressed. If we perform an action in anyway here, we set the lastNavigated time to the current GameTime to again make sure our navigation stays smooth.

Example Usage in XNA Game

Now all that is left is an example of how to use the class within your XNA game.

Simply initialise the menu with a title, then add the menu items. For information on the Actions here if you want to know more, then have a look at the MSDN documentation. The examples simply check whether the pressed button was the A button and if it was either change the state of the Game to the correct screen, or exits the game.

Finally in the Update() method of your game in your default XNA game class, if you are on the menu screen, you can just call the menu’s Navigate() method, and pass in the GamePad you want to use to control it.

That concludes the menu class. I hope this can be of some use when developing for the Xbox in XNA. For other devices in XNA the code is the same, just change the navigation methods.

Download Files

You can download the complete files here: Download

Leave a Reply