#region File Description
//-----------------------------------------------------------------------------
// MenuScreen.cs
//
// XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion
namespace RolePlaying
{
///
/// Base class for screens that contain a menu of options. The user can
/// move up and down to select an entry, or cancel to back out of the screen.
///
///
/// Similar to a class found in the Game State Management sample on the
/// XNA Creators Club Online website (http://creators.xna.com).
///
abstract class MenuScreen : GameScreen
{
#region Fields
List menuEntries = new List();
protected int selectedEntry = 0;
#endregion
#region Properties
///
/// Gets the list of menu entries, so derived classes can add
/// or change the menu contents.
///
protected IList MenuEntries
{
get { return menuEntries; }
}
protected MenuEntry SelectedMenuEntry
{
get
{
if ((selectedEntry < 0) || (selectedEntry >= menuEntries.Count))
{
return null;
}
return menuEntries[selectedEntry];
}
}
#endregion
#region Initialization
///
/// Constructor.
///
public MenuScreen()
{
TransitionOnTime = TimeSpan.FromSeconds(0.5);
TransitionOffTime = TimeSpan.FromSeconds(0.5);
}
#endregion
#region Handle Input
///
/// Responds to user input, changing the selected entry and accepting
/// or cancelling the menu.
///
public override void HandleInput()
{
int oldSelectedEntry = selectedEntry;
// Move to the previous menu entry?
if (InputManager.IsActionTriggered(InputManager.Action.CursorUp))
{
selectedEntry--;
if (selectedEntry < 0)
selectedEntry = menuEntries.Count - 1;
}
// Move to the next menu entry?
if (InputManager.IsActionTriggered(InputManager.Action.CursorDown))
{
selectedEntry++;
if (selectedEntry >= menuEntries.Count)
selectedEntry = 0;
}
// Accept or cancel the menu?
if (InputManager.IsActionTriggered(InputManager.Action.Ok))
{
AudioManager.PlayCue("Continue");
OnSelectEntry(selectedEntry);
}
else if (InputManager.IsActionTriggered(InputManager.Action.Back) ||
InputManager.IsActionTriggered(InputManager.Action.ExitGame))
{
OnCancel();
}
else if (selectedEntry != oldSelectedEntry)
{
AudioManager.PlayCue("MenuMove");
}
}
///
/// Handler for when the user has chosen a menu entry.
///
protected virtual void OnSelectEntry(int entryIndex)
{
menuEntries[selectedEntry].OnSelectEntry();
}
///
/// Handler for when the user has cancelled the menu.
///
protected virtual void OnCancel()
{
ExitScreen();
}
///
/// Helper overload makes it easy to use OnCancel as a MenuEntry event handler.
///
protected void OnCancel(object sender, EventArgs e)
{
OnCancel();
}
#endregion
#region Update and Draw
///
/// Updates the menu.
///
public override void Update(GameTime gameTime, bool otherScreenHasFocus,
bool coveredByOtherScreen)
{
base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
// Update each nested MenuEntry object.
for (int i = 0; i < menuEntries.Count; i++)
{
bool isSelected = IsActive && (i == selectedEntry);
menuEntries[i].Update(this, isSelected, gameTime);
}
}
///
/// Draws the menu.
///
public override void Draw(GameTime gameTime)
{
SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
spriteBatch.Begin();
// Draw each menu entry in turn.
for (int i = 0; i < menuEntries.Count; i++)
{
MenuEntry menuEntry = menuEntries[i];
bool isSelected = IsActive && (i == selectedEntry);
menuEntry.Draw(this, isSelected, gameTime);
}
spriteBatch.End();
}
#endregion
}
}