This post is one of a series that shows how to take the basic Platform Starter Kit from the XNA Games Studio and turn it into a more full featured game by taking advantage of the many tutorials and game examples published on the XNA Creators Club.
As is the Platform Starter kit gives you platform style game start from execution. However, games don’t usually start like that. You usually have at least some options to configure, an opportunity to review high scores and exit. Not to mention a splash screen to look at while the game loads up resources.
All of this functionality is presented in the Game State Management example up on XNA Creators Club.
The example is very straight forward, it provides a ScreenManager class that is used to coordinate the loading and closing of different screens including the game which is presented as a GameScreen type to the ScreenManager. The ScreenManager then fronts the Game object so that your code can still access things like Game Services and other Game properties.
Initially, I looked at this example and thought I should have implemented its infrastructure from the start of building my game – which would have been a right pain given my game is an enhanced version of the Platform Starter kit! But once I looked beneath the covers it was clear that the Game State Management project is a great example of the flexibility in the XNA architecture.
To start with, you just need to add the ScreenManager and the Screens folders and contents to your existing project. Then there are only a few mods to make. To change the PlatformerGame class to start the ScreenManager rather than the game, to move your game methods from the PlatformGame type of Game class to the ScreenManager’s GameplayScreen type of GameScreen class. This is a pretty straightforward thing to do with the only serious modification being a change to the HandleInput method with the addition of the InputState parameter. The InputState class is part of the ScreenManager functionality and is used to distribute the latest input state from the ScreenManagers own HandleInput method across to all other screens which require the input by being active in the ScreenManagers stack of screens.
The PlatformerGame class becomes a shadow of its former self with very little code left after the move:
graphics = new GraphicsDeviceManager(this);
graphics.PreferredBackBufferWidth = BackBufferWidth;
graphics.PreferredBackBufferHeight = BackBufferHeight;
Content.RootDirectory = "Content";
// Create the screen manager component.
screenManager = new ScreenManager(this);
// Activate the first screens.
screenManager.AddScreen(new BackgroundScreen(), null);
screenManager.AddScreen(new MainMenuScreen(), null);
// Framerate differs between platforms.
TargetElapsedTime = TimeSpan.FromTicks(TimeSpan.TicksPerSecond / TargetFrameRate);
Plus the minimalist Draw:
protected override void Draw(GameTime gameTime)
// The real drawing happens inside the screen manager component.
The included screen implementations then just require modification to fit your purposes. There are several to make use of and the Menu implementation complete with MenuItem class is a very useful thing to have.
Being able to construct Screens through the composition of Screens with a BackgroundScreen and transitions really starts to make the game feel more polished.
It also means that to further finish off your game with some impressive ATTRACT graphics on the opening screens is pretty simple. Just add the graphics to the BackgroundScreen and LoadingScreen to use them.
Once again, the hardest bit of work is purely the creation of these graphics. Its amazing just how much coding work there isn’t to do thanks to the enormous volume of tutorials, samples and examples but also the XNA architecture and core functionality.
Ok, so just how am I going to solve my artistic failings…