Counting Hazards Passed
The XNA Framework provides a nice way to display text in a game. To begin the process, you need to add a new item to your project. So right-click on your project and choose Add New Item from the context menu. In the Add New Item dialog box (see
Figure 8), select the SpriteFont object. Name it
myFont and click Add.
 | |
Figure 8: Adding the sprite font to the game project. |
 | |
Figure 9: Modifying the sprite font XML file. |
That adds a new SpriteFont object to your project, which is basically an XML file that provides some information about a system font that you want to use in your game. You'll need to edit that information to indicate which font to use as well as the size and style of the font. Edit the SpriteFont XML file as shown in
Figure 9.
To show the count (score) onscreen, add two new objects to the top of the
Game1.cs class:
private int mHazardsPassed;
private SpriteFont mFont;
The
mHazardsPassed integer keeps track of how many hazards a player has passed successfully. The SpriteFont object lets you to load a font into the game, which you can use to write text to the screen.
The code snippet below initializes the number of hazards passed in the
StartGame method. That way, every time the user starts or restarts the game, the number of hazards passed resets to
0. Add the following line of code to the StartGame method:
mHazardsPassed = 0;
Next, load the font into the SpriteFont object in the
LoadGraphicsContent method using this code:
mFont = content.Load<SpriteFont>("myFont");
Every time a hazard scrolls off-screen (meaning the player successfully passed it), you need to increment the
mHazardsPassed counter. To do that you'll enhance the
UpdateHazard method. You'll also increase the velocity every time the player successfully passes a hazard just to add an extra level of complexity to the game.
Add the following code to the
UpdateHazard method within the
if block that checks to see if the hazard has exited the viewing area:
mHazardsPassed += 1;
mVelocityY += 0.1F;
Finally, this snippet displays the number of hazards the player has passed. Add the following code to the
Draw method:
mSpriteBatch.DrawString(mFont,
"Hazards: " + mHazardsPassed.ToString(),
new Vector2(5, 25), Color.White, 0, new
Vector2(0, 0),
1.0f, SpriteEffects.None, 0);
Build the game and check your handiwork. As the hazards scroll off the screen, you should see the number in the upper left of the window display the number of hazards (and increase) as shown in
Figure 10.
You're almost ready to start making it a little harder to run right over the hazards, but first there's one more concept to add to the game. When working on a game, you reach a point where you realize that—depending on what's going on—you need to display certain things at certain times, but not at others. This brings me to the topic of game state.
Game State
Game state, in its simplest form, is just a way of keeping track of what state your game is in. Complex games may have many states, but this game has only two states:
Running and
Crash. You'll create an enum to define the various states the game can be in, and an object to indicate which state the game currently is in at the top of the
Game1.cs class.
private enum State
{
Running,
Crash
}
private State mCurrentState;
When the game starts you initialize the current state to
Running in the
StartGame method.
mCurrentState = State.Running;
Next, enhance the
Update method to respond to the various states. Using the state information, you'll update certain things only when the game is running:
KeyboardState aCurrentKeyboardState =
Keyboard.GetState();
GamePadState aCurrentGamePadState =
GamePad.GetState(PlayerIndex.One);
if (aCurrentKeyboardState.IsKeyDown(Keys.Escape)
== true ||
aCurrentGamePadState.Buttons.Back ==
ButtonState.Pressed)
{
this.Exit();
}
switch (mCurrentState)
{
case State.Running:
{
If ((aCurrentKeyboardState.IsKeyDown(Keys.Space) == true &&
mPreviousKeyboardState.IsKeyDown(Keys.Space) == false) ||
(aCurrentGamePadState.Buttons.X == ButtonState.Pressed &&
mPreviousGamePadState.Buttons.X == ButtonState.Released))
{
mCarPosition.X += mMoveCarX;
mMoveCarX *= -1;
}
ScrollRoad(gameTime);
UpdateHazard(gameTime);
break;
}
case State.Crash:
{
break;
}
}
mPreviousKeyboardState = aCurrentKeyboardState;
mPreviousGamePadState = aCurrentGamePadState;
Basically, the preceding code wraps the existing code in the
Update method in a
switch block when the current state is
Running. The Keyboard state remains outside of the block, but was shown for context.
Currently, the game doesn't do anything when a crash occurs; in fact, there is no way to detect a crash. You'll change that in the next section, but first, quickly build the game just to make sure everything still runs as it should with the newly added game state code.