#region File Description
//-----------------------------------------------------------------------------
// MenuScreen.cs
//
// Microsoft 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 NetRumble
{
///
/// Base public 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.
///
///
/// This public class is similar to one in the GameStateManagement sample.
///
abstract public class MenuScreen : GameScreen
{
#region Fields
List menuEntries = new List();
int selectedEntry = 0;
#endregion
#region Properties
///
/// Gets the list of menu entry strings, so derived classes can add
/// or change the menu contents.
///
protected IList MenuEntries
{
get { return menuEntries; }
}
#endregion
#region Initialization
///
/// Constructor.
///
protected MenuScreen()
{
TransitionOnTime = TimeSpan.FromSeconds(1.0);
TransitionOffTime = TimeSpan.FromSeconds(1.0);
}
#endregion
#region Handle Input
///
/// Responds to user input, changing the selected entry and accepting
/// or cancelling the menu.
///
public override void HandleInput(InputState input)
{
// Move to the previous menu entry?
if (input.MenuUp)
{
selectedEntry--;
if (selectedEntry < 0)
selectedEntry = menuEntries.Count - 1;
AudioManager.PlaySoundEffect("menu_scroll");
}
// Move to the next menu entry?
if (input.MenuDown)
{
selectedEntry++;
if (selectedEntry >= menuEntries.Count)
selectedEntry = 0;
AudioManager.PlaySoundEffect("menu_scroll");
}
// Accept or cancel the menu?
if (input.MenuSelect)
{
AudioManager.PlaySoundEffect("menu_select");
OnSelectEntry(selectedEntry);
}
else if (input.MenuCancel)
{
OnCancel();
}
}
///
/// Notifies derived classes that a menu entry has been chosen.
///
protected abstract void OnSelectEntry(int entryIndex);
///
/// Notifies derived classes that the menu has been cancelled.
///
protected abstract void OnCancel();
#endregion
#region Draw
///
/// Draws the menu.
///
public override void Draw(GameTime gameTime)
{
Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
Vector2 viewportSize = new Vector2(viewport.Width, viewport.Height);
Vector2 position = new Vector2(0f, viewportSize.Y * 0.65f);
// Make the menu slide into place during transitions, using a
// power curve to make things look more interesting (this makes
// the movement slow down as it nears the end).
float transitionOffset = (float)Math.Pow(TransitionPosition, 2);
if (ScreenState == ScreenState.TransitionOn)
position.Y += transitionOffset * 256;
else
position.Y += transitionOffset * 512;
// Draw each menu entry in turn.
ScreenManager.SpriteBatch.Begin();
for (int i = 0; i < menuEntries.Count; i++)
{
Color color = Color.White;
float scale = 1.0f;
if (IsActive && (i == selectedEntry))
{
// The selected entry is yellow, and has an animating size.
double time = gameTime.TotalGameTime.TotalSeconds;
float pulsate = (float)Math.Sin(time * 6f) + 1f;
color = Color.Orange;
scale += pulsate * 0.05f;
}
// Modify the alpha to fade text out during transitions.
color = new Color(color.R, color.G, color.B, TransitionAlpha);
// Draw text, centered on the middle of each line.
Vector2 origin = new Vector2(0, ScreenManager.Font.LineSpacing / 2);
Vector2 size = ScreenManager.Font.MeasureString(menuEntries[i]);
position.X = viewportSize.X / 2f - size.X / 2f * scale;
ScreenManager.SpriteBatch.DrawString(ScreenManager.Font, menuEntries[i],
position, color, 0, origin, scale,
SpriteEffects.None, 0);
position.Y += ScreenManager.Font.LineSpacing;
}
ScreenManager.SpriteBatch.End();
}
#endregion
}
}