00001
00002
00003
00004
00005
00006 namespace NewGamePhysics.StateManager
00007 {
00008 using System;
00009 using System.Collections.Generic;
00010 using Microsoft.Xna.Framework;
00011 using Microsoft.Xna.Framework.Graphics;
00012 using NewGamePhysics.Utilities;
00013
00018 public abstract class MenuScreen : GameScreen
00019 {
00020 #region Fields
00021
00025 private List<MenuEntry> menuEntries = new List<MenuEntry>();
00026
00030 private int selectedEntry = 0;
00031
00035 private string menuTitle;
00036
00040 private bool waitForUncover = true;
00041
00045 private Texture2D paneTexture;
00046
00047 #endregion
00048
00049 #region Properties
00050
00055 protected IList<MenuEntry> MenuEntries
00056 {
00057 get { return this.menuEntries; }
00058 }
00059
00063 public int SelectedEntry
00064 {
00065 get { return this.selectedEntry; }
00066 set { this.selectedEntry = Math.Min(value, this.menuEntries.Count); }
00067 }
00068
00073 protected bool WaitForUncover
00074 {
00075 get { return this.waitForUncover; }
00076 set { this.waitForUncover = value; }
00077 }
00078
00079 #endregion
00080
00081 #region Initialization
00082
00086 public MenuScreen(string menuTitle)
00087 {
00088 this.menuTitle = menuTitle;
00089
00090 TransitionOnTime = TimeSpan.FromSeconds(0.5);
00091 TransitionOffTime = TimeSpan.FromSeconds(0.5);
00092 }
00093
00094 #endregion
00095
00096 #region Handle Input
00097
00102 public override void HandleInput(InputState input)
00103 {
00104
00105 if (input.IsNewInputUp(ControllingPlayer))
00106 {
00107 this.selectedEntry--;
00108
00109 if (this.selectedEntry < 0)
00110 {
00111 this.selectedEntry = this.menuEntries.Count - 1;
00112 }
00113 }
00114
00115
00116 if (input.IsNewInputDown(ControllingPlayer))
00117 {
00118 this.selectedEntry++;
00119
00120 if (this.selectedEntry >= this.menuEntries.Count)
00121 {
00122 this.selectedEntry = 0;
00123 }
00124 }
00125
00126
00127
00128
00129
00130
00131 PlayerIndex playerIndex;
00132
00133 if (input.IsMenuSelect(ControllingPlayer, out playerIndex))
00134 {
00135 OnSelectEntry(this.selectedEntry, playerIndex);
00136 }
00137 else if (input.IsMenuCancel(ControllingPlayer, out playerIndex))
00138 {
00139 OnCancel(playerIndex);
00140 }
00141 }
00142
00146 protected virtual void OnSelectEntry(int entryIndex, PlayerIndex playerIndex)
00147 {
00148 menuEntries[this.selectedEntry].OnSelectEntry(playerIndex);
00149 }
00150
00154 protected virtual void OnCancel(PlayerIndex playerIndex)
00155 {
00156 ExitScreen();
00157 }
00158
00162 protected void OnCancel(object sender, PlayerIndexEventArgs e)
00163 {
00164 OnCancel(e.PlayerIndex);
00165 }
00166
00167 #endregion
00168
00169 #region Update and Draw
00170
00177 public override void Update(GameTime gameTime, bool otherScreenHasFocus,
00178 bool coveredByOtherScreen)
00179 {
00180 base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
00181
00182
00183 for (int i = 0; i < menuEntries.Count; i++)
00184 {
00185 bool isSelected = IsActive && (i == selectedEntry);
00186
00187 menuEntries[i].Update(this, isSelected, gameTime);
00188 }
00189 }
00190
00191
00196 public override void Draw(GameTime gameTime)
00197 {
00198 SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
00199 SpriteFont font = ScreenManager.Fonts["menu"];
00200 Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
00201
00202
00203 float menuSize = 0.0f;
00204 for (int i = 0; i < menuEntries.Count; i++)
00205 {
00206 MenuEntry menuEntry = menuEntries[i];
00207 menuSize += (menuEntry.GetHeight(this) + 5);
00208 }
00209
00210
00211 Vector2 position = new Vector2(
00212 viewport.Width / 2 - 200,
00213 (viewport.Height - menuSize) / 2);
00214
00215
00216
00217
00218 float transitionOffset = (float)Math.Pow(TransitionPosition, 2);
00219
00220 if (ScreenState == ScreenState.TransitionOn)
00221 {
00222 position.X -= transitionOffset * 256;
00223 }
00224 else
00225 {
00226 position.X += transitionOffset * 512;
00227 }
00228
00229 spriteBatch.Begin();
00230
00231
00232 for (int i = 0; i < menuEntries.Count; i++)
00233 {
00234 MenuEntry menuEntry = menuEntries[i];
00235
00236 bool isSelected = IsActive && (i == selectedEntry);
00237
00238 menuEntry.Draw(this, position, isSelected, gameTime);
00239
00240
00241 position.Y += (menuEntry.GetHeight(this) + 5);
00242 }
00243
00244
00245 if (this.paneTexture == null)
00246 {
00247
00248 this.paneTexture = TextureHelpers.Create(ScreenManager.GraphicsDevice, new Color(64, 64, 64));
00249 }
00250
00251
00252 float titleScale = 1.5f;
00253 Vector2 titlePosition = new Vector2(position.X, viewport.Height/2);
00254 Vector2 titleSize = font.MeasureString(menuTitle);
00255 Vector2 titleOrigin = titleSize / 2;
00256 Color titleColor = new Color(255, 255, 255, TransitionAlpha);
00257 titlePosition.X -= titleSize.Y * titleScale;
00258 titlePosition.Y -= transitionOffset * 100;
00259 Color paneColor = new Color(4, 4, 4);
00260 Rectangle backgroundPane =
00261 new Rectangle(
00262 (int)(titlePosition.X - titleOrigin.Y), 0, (int)titleSize.Y, viewport.Height);
00263 spriteBatch.Draw(this.paneTexture, backgroundPane, new Color(paneColor, 128));
00264
00265 spriteBatch.DrawString(font, menuTitle, titlePosition, titleColor, 3.0f*(float)Math.PI/2.0f,
00266 titleOrigin, titleScale, SpriteEffects.None, 0);
00267
00268 spriteBatch.End();
00269 }
00270
00271 #endregion
00272 }
00273 }