_titleFont = ScreenManager.Content.Load<SpriteFont>
_textFont = ScreenManager.Content.Load<SpriteFont>
_buttonB = ScreenManager.Content.Load<Texture2D>
public override void Initialize()
_achievements = new
public override void HandleInput(InputState input, GameTime gameTime)
if (input.CurrentGamePadState.Buttons.B ==
Microsoft.Xna.Framework.Input.ButtonState.Pressed &&
input.LastGamePadState.Buttons.B ==
//check for scrolling
if (input.CurrentGamePadState.DPad.Up ==
Microsoft.Xna.Framework.Input.ButtonState.Pressed &&
input.LastGamePadState.DPad.Up ==
_topIndex = (int)MathHelper.Clamp(_topIndex, 0,
if (input.CurrentGamePadState.DPad.Down ==
Microsoft.Xna.Framework.Input.ButtonState.Pressed &&
input.LastGamePadState.DPad.Down ==
_topIndex = (int)MathHelper.Clamp(_topIndex, 0,
516 Chapter 15
base.HandleInput(input, gameTime);
public override void Draw(GameTime gameTime)
Vector2 textPosition;
Color.Black, 0, 0);
Color color = new Color(0, 255, 0, TransitionAlpha);
//draw title
Vector2 titleSize = _titleFont.MeasureString("Achievements");
textPosition = new
/ 2 - titleSize.X / 2, 5);
ScreenManager.SpriteBatch.DrawString(_titleFont, "Achievements",
textPosition, color);
color = new Color(255, 255, 255, TransitionAlpha);
int numDisplayed = (int)MathHelper.Clamp(_achievements.Count, 0,
//draw headers
ScreenManager.SpriteBatch.DrawString(_textFont, "Name", _nameLoc,
ScreenManager.SpriteBatch.DrawString(_textFont, "Points",
_pointsLoc, Color.White);
ScreenManager.SpriteBatch.DrawString(_textFont, "Date Unlocked",
_dateLoc, Color.White);
//loop through list and draw each item
for (int i = _topIndex; i < numDisplayed; i++)
_iconLoc + new Vector2(0, (i + 1) * 75), Color.White);
_achievements[i].Name, _nameLoc + new Vector2(0, (i + 1) *
75), Color.White);
Creating an Achievement System 517
_achievements[i].Points, _pointsLoc + new Vector2(0, (i +
1) * 75), Color.White);
_achievements[i].DateUnlocked, _dateLoc + new Vector2(0,
(i + 1) * 75), Color.White);
ScreenManager.SpriteBatch.Draw(_buttonB, new Rectangle(800, 700,
48, 48), Color.White);
ScreenManager.SpriteBatch.DrawString(ScreenManager.Font, "Back",
new Vector2(855, 700), Color.White);
if (TransitionPosition > 0)
ScreenManager.FadeBackBufferToBlack(255 - TransitionAlpha);
The screen holds a list of a class that’s used just for displaying the
combination of base achievement and player achievement informa-
tion, the AchievementDisplay class:
Listing 15-6
public class AchievementDisplay
public Texture2D Icon;
public string Name;
public string Points;
public string DateUnlocked;
Simple, huh? It just holds the four pieces of data we use in the
screen. The AchievementManager creates this list for us by calling
the Achievements method.
We use four Vector2 objects to hold the location of our headers
(_iconLoc, _nameLoc, _pointsLoc, and _dateLoc), and in our draw
ing code we add a Vector2 object to each that draws each
achievement detail line 75 pixels below the previous line.
Although we only have four achievements, the class is set up to
account for more than this. The screen can fit up to six achieve
ments in the space we have, so we use a const int variable to use in
our code, MaxAchievementsDisplayed, and another variable,
_topIndex, to indicate which achievement is the first to be
518 Chapter 15
displayed. The HandleInput method changes this variable as the
user presses the Up and Down DPad controls, using the
Math.Clamp method to ensure that the value is never less than zero
and never more than one minus the number of achievements we
have minus the number of achievements we can display:
Listing 15-7
_topIndex = (int)MathHelper.Clamp(_topIndex, 0, _achievements.Count 1
Our drawing code similarly clamps the number of achievements
actually drawn to be between zero and MaxAchievementsDisplayed:
Listing 15-8
int numDisplayed = (int)MathHelper.Clamp(_achievements.Count, 0,
Access to this screen is quickly implemented by adding a menu
item to our main menu:
Listing 15-9
public MainMenuScreen()
_menuEntries.Add("Play Game");
_menuEntries.Add("High Scores");
The OnSelectEntry() function of the MainMenu class is also
Listing 15-10
protected override void OnSelectEntry(int entryIndex)
switch (entryIndex)
case 0:
// Play the game.
_screenManager.AddScreen(new DifficultyScreen());
Creating an Achievement System 519

Get Essential XNA Game Studio 2.0 Programming now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.