PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/FarseerPhysics-r78100/Samples/DemoBaseXNA/ScreenSystem/ScreenManager.cs

#
C# | 310 lines | 175 code | 51 blank | 84 comment | 22 complexity | b1a8cd40a7f2818c29faf9d3011fb7dd MD5 | raw file
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // ScreenManager.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Diagnostics;
  13. using Microsoft.Xna.Framework;
  14. using Microsoft.Xna.Framework.Content;
  15. using Microsoft.Xna.Framework.Graphics;
  16. #endregion
  17. namespace FarseerPhysics.DemoBaseXNA.ScreenSystem
  18. {
  19. /// <summary>
  20. /// The screen manager is a component which manages one or more <see cref="GameScreen"/>
  21. /// instances. It maintains a stack of _screens, calls their Update and Draw
  22. /// methods at the appropriate times, and automatically routes _input to the
  23. /// topmost active screen.
  24. /// </summary>
  25. public class ScreenManager : DrawableGameComponent
  26. {
  27. public MainMenuScreen MainMenuScreen = new MainMenuScreen();
  28. private Texture2D _blankTexture;
  29. private IGraphicsDeviceService _graphicsDeviceService;
  30. private InputState _input = new InputState();
  31. private List<GameScreen> _screens = new List<GameScreen>();
  32. private List<GameScreen> _screensToUpdate = new List<GameScreen>();
  33. private SpriteFonts _spriteFonts;
  34. /// <summary>
  35. /// Constructs a new screen manager component.
  36. /// </summary>
  37. /// <exception cref="InvalidOperationException">No graphics device service.</exception>
  38. public ScreenManager(Game game)
  39. : base(game)
  40. {
  41. ContentManager = new ContentManager(game.Services);
  42. ContentManager.RootDirectory = "Content";
  43. _graphicsDeviceService = (IGraphicsDeviceService) game.Services.GetService(
  44. typeof (IGraphicsDeviceService));
  45. game.Exiting += Game_Exiting;
  46. if (_graphicsDeviceService == null)
  47. throw new InvalidOperationException("No graphics device service.");
  48. }
  49. public SpriteFonts SpriteFonts
  50. {
  51. get { return _spriteFonts; }
  52. }
  53. /// <summary>
  54. /// A content manager used to load data that is shared between multiple
  55. /// screens. This is never unloaded, so if a screen requires a large amount
  56. /// of temporary data, it should create a local content manager instead.
  57. /// </summary>
  58. public ContentManager ContentManager { get; private set; }
  59. /// <summary>
  60. /// A default SpriteBatch shared by all the screens. This saves
  61. /// each screen having to bother creating their own local instance.
  62. /// </summary>
  63. public SpriteBatch SpriteBatch { get; private set; }
  64. public Vector2 ScreenCenter
  65. {
  66. get
  67. {
  68. return new Vector2(_graphicsDeviceService.GraphicsDevice.Viewport.Width / 2f,
  69. _graphicsDeviceService.GraphicsDevice.Viewport.Height / 2f);
  70. }
  71. }
  72. public int ScreenWidth
  73. {
  74. get { return _graphicsDeviceService.GraphicsDevice.Viewport.Width; }
  75. }
  76. public int ScreenHeight
  77. {
  78. get { return _graphicsDeviceService.GraphicsDevice.Viewport.Height; }
  79. }
  80. /// <summary>
  81. /// If true, the manager prints out a list of all the screens
  82. /// each time it is updated. This can be useful for making sure
  83. /// everything is being added and removed at the right times.
  84. /// </summary>
  85. public bool TraceEnabled { get; set; }
  86. /// <summary>
  87. /// Goes to main menu.
  88. /// Removes all active screens and add a main menu
  89. /// </summary>
  90. public void GoToMainMenu()
  91. {
  92. _screens.Clear();
  93. _screensToUpdate.Clear();
  94. AddScreen(MainMenuScreen);
  95. }
  96. private void Game_Exiting(object sender, EventArgs e)
  97. {
  98. //Make sure to dispose ALL screens when the game is forcefully closed
  99. //We do this to ensure that open resources and threads created by screens are closed.
  100. foreach (GameScreen screen in _screens)
  101. {
  102. screen.Dispose();
  103. }
  104. _screens.Clear();
  105. _screensToUpdate.Clear();
  106. }
  107. /// <summary>
  108. /// Allows the game component to perform any initialization it needs to before starting
  109. /// to run. This is where it can query for any required services and load content.
  110. /// </summary>
  111. public override void Initialize()
  112. {
  113. _spriteFonts = new SpriteFonts(ContentManager);
  114. base.Initialize();
  115. }
  116. /// <summary>
  117. /// Load your graphics content.
  118. /// </summary>
  119. protected override void LoadContent()
  120. {
  121. // Load content belonging to the screen manager.
  122. SpriteBatch = new SpriteBatch(GraphicsDevice);
  123. _blankTexture = ContentManager.Load<Texture2D>("Common/blank");
  124. // Tell each of the _screens to load their content.
  125. foreach (GameScreen screen in _screens)
  126. {
  127. screen.LoadContent();
  128. }
  129. }
  130. /// <summary>
  131. /// Unload your graphics content.
  132. /// </summary>
  133. protected override void UnloadContent()
  134. {
  135. ContentManager.Unload();
  136. // Tell each of the _screens to unload their content.
  137. foreach (GameScreen screen in _screens)
  138. {
  139. screen.UnloadContent();
  140. }
  141. }
  142. /// <summary>
  143. /// Allows each screen to run logic.
  144. /// </summary>
  145. public override void Update(GameTime gameTime)
  146. {
  147. // Read the keyboard and gamepad.
  148. _input.Update();
  149. // Make a copy of the master screen list, to avoid confusion if
  150. // the process of updating one screen adds or removes others.
  151. _screensToUpdate.Clear();
  152. for (int i = 0; i < _screens.Count; i++)
  153. _screensToUpdate.Add(_screens[i]);
  154. bool otherScreenHasFocus = !Game.IsActive;
  155. bool coveredByOtherScreen = false;
  156. // Loop as long as there are _screens waiting to be updated.
  157. while (_screensToUpdate.Count > 0)
  158. {
  159. // Pop the topmost screen off the waiting list.
  160. GameScreen screen = _screensToUpdate[_screensToUpdate.Count - 1];
  161. _screensToUpdate.RemoveAt(_screensToUpdate.Count - 1);
  162. // Update the screen.
  163. screen.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
  164. if (screen.ScreenState == ScreenState.TransitionOn ||
  165. screen.ScreenState == ScreenState.Active)
  166. {
  167. // If this is the first active screen we came across,
  168. // give it a chance to handle _input.
  169. if (!otherScreenHasFocus)
  170. {
  171. screen.HandleInput(_input);
  172. otherScreenHasFocus = true;
  173. }
  174. // If this is an active non-popup, inform any subsequent
  175. // _screens that they are covered by it.
  176. if (!screen.IsPopup)
  177. coveredByOtherScreen = true;
  178. }
  179. }
  180. // Print debug trace?
  181. if (TraceEnabled)
  182. TraceScreens();
  183. }
  184. /// <summary>
  185. /// Prints a list of all the screens, for debugging.
  186. /// </summary>
  187. private void TraceScreens()
  188. {
  189. List<string> screenNames = new List<string>();
  190. foreach (GameScreen screen in _screens)
  191. screenNames.Add(screen.GetType().Name);
  192. Trace.WriteLine(string.Join(", ", screenNames.ToArray()));
  193. }
  194. /// <summary>
  195. /// Tells each screen to draw itself.
  196. /// </summary>
  197. public override void Draw(GameTime gameTime)
  198. {
  199. for (int i = 0; i < _screens.Count; i++)
  200. {
  201. if (_screens[i].ScreenState == ScreenState.Hidden)
  202. continue;
  203. _screens[i].Draw(gameTime);
  204. }
  205. }
  206. /// <summary>
  207. /// Adds a new screen to the screen manager.
  208. /// </summary>
  209. public void AddScreen(GameScreen screen)
  210. {
  211. screen.ScreenManager = this;
  212. screen.Initialize();
  213. // If we have a graphics device, tell the screen to load content.
  214. if ((_graphicsDeviceService != null) &&
  215. (_graphicsDeviceService.GraphicsDevice != null))
  216. {
  217. screen.LoadContent();
  218. }
  219. _screens.Add(screen);
  220. IDemoScreen demoScreen = screen as IDemoScreen;
  221. if (demoScreen != null && screen.firstRun)
  222. {
  223. AddScreen(new PauseScreen(demoScreen.GetTitle(), demoScreen.GetDetails()));
  224. screen.firstRun = false;
  225. }
  226. }
  227. /// <summary>
  228. /// Removes a screen from the screen manager. You should normally
  229. /// use <see cref="GameScreen"/>.ExitScreen instead of calling this directly, so
  230. /// the screen can gradually transition off rather than just being
  231. /// instantly removed.
  232. /// </summary>
  233. public void RemoveScreen(GameScreen screen)
  234. {
  235. // If we have a graphics device, tell the screen to unload content.
  236. if ((_graphicsDeviceService != null) &&
  237. (_graphicsDeviceService.GraphicsDevice != null))
  238. {
  239. screen.UnloadContent();
  240. }
  241. _screens.Remove(screen);
  242. _screensToUpdate.Remove(screen);
  243. screen.Dispose();
  244. }
  245. /// <summary>
  246. /// Helper draws a translucent black full screen sprite, used for fading
  247. /// screens in and out, and for darkening the background behind popups.
  248. /// </summary>
  249. public void FadeBackBufferToBlack(int alpha)
  250. {
  251. Viewport viewport = GraphicsDevice.Viewport;
  252. SpriteBatch.Begin();
  253. SpriteBatch.Draw(_blankTexture,
  254. new Rectangle(0, 0, viewport.Width, viewport.Height),
  255. new Color(0, 0, 0, (byte) alpha));
  256. SpriteBatch.End();
  257. }
  258. }
  259. }