/truck/TankA/Screens/LoadingScreen.cs

https://bitbucket.org/kenzoix/tanka · C# · 162 lines · 79 code · 30 blank · 53 comment · 7 complexity · 68e1b35db169fcf1899a954d8896beb1 MD5 · raw file

  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // LoadingScreen.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 Microsoft.Xna.Framework;
  12. using Microsoft.Xna.Framework.Graphics;
  13. #endregion
  14. namespace TankA
  15. {
  16. /// <summary>
  17. /// The loading screen coordinates transitions between the menu system and the
  18. /// game itself. Normally one screen will transition off at the same time as
  19. /// the next screen is transitioning on, but for larger transitions that can
  20. /// take a longer time to load their data, we want the menu system to be entirely
  21. /// gone before we start loading the game. This is done as follows:
  22. ///
  23. /// - Tell all the existing screens to transition off.
  24. /// - Activate a loading screen, which will transition on at the same time.
  25. /// - The loading screen watches the state of the previous screens.
  26. /// - When it sees they have finished transitioning off, it activates the real
  27. /// next screen, which may take a long time to load its data. The loading
  28. /// screen will be the only thing displayed while this load is taking place.
  29. /// </summary>
  30. class LoadingScreen : GameScreen
  31. {
  32. #region Fields
  33. bool loadingIsSlow;
  34. bool otherScreensAreGone;
  35. GameScreen[] screensToLoad;
  36. #endregion
  37. #region Initialization
  38. /// <summary>
  39. /// The constructor is private: loading screens should
  40. /// be activated via the static Load method instead.
  41. /// </summary>
  42. private LoadingScreen(ScreenManager screenManager, bool loadingIsSlow,
  43. GameScreen[] screensToLoad)
  44. {
  45. this.loadingIsSlow = loadingIsSlow;
  46. this.screensToLoad = screensToLoad;
  47. TransitionOnTime = TimeSpan.FromSeconds(0.5);
  48. }
  49. /// <summary>
  50. /// Activates the loading screen.
  51. /// </summary>
  52. public static void Load(ScreenManager screenManager, bool loadingIsSlow,
  53. PlayerIndex? controllingPlayer,
  54. params GameScreen[] screensToLoad)
  55. {
  56. // Tell all the current screens to transition off.
  57. foreach (GameScreen screen in screenManager.GetScreens())
  58. screen.ExitScreen();
  59. // Create and activate the loading screen.
  60. LoadingScreen loadingScreen = new LoadingScreen(screenManager,
  61. loadingIsSlow,
  62. screensToLoad);
  63. screenManager.AddScreen(loadingScreen, controllingPlayer);
  64. }
  65. #endregion
  66. #region Update and Draw
  67. /// <summary>
  68. /// Updates the loading screen.
  69. /// </summary>
  70. public override void Update(GameTime gameTime, bool otherScreenHasFocus,
  71. bool coveredByOtherScreen)
  72. {
  73. base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
  74. // If all the previous screens have finished transitioning
  75. // off, it is time to actually perform the load.
  76. if (otherScreensAreGone)
  77. {
  78. ScreenManager.RemoveScreen(this);
  79. foreach (GameScreen screen in screensToLoad)
  80. {
  81. if (screen != null)
  82. {
  83. ScreenManager.AddScreen(screen, ControllingPlayer);
  84. }
  85. }
  86. // Once the load has finished, we use ResetElapsedTime to tell
  87. // the game timing mechanism that we have just finished a very
  88. // long frame, and that it should not try to catch up.
  89. ScreenManager.Game.ResetElapsedTime();
  90. }
  91. }
  92. /// <summary>
  93. /// Draws the loading screen.
  94. /// </summary>
  95. public override void Draw(GameTime gameTime)
  96. {
  97. // If we are the only active screen, that means all the previous screens
  98. // must have finished transitioning off. We check for this in the Draw
  99. // method, rather than in Update, because it isn't enough just for the
  100. // screens to be gone: in order for the transition to look good we must
  101. // have actually drawn a frame without them before we perform the load.
  102. if ((ScreenState == ScreenState.Active) &&
  103. (ScreenManager.GetScreens().Length == 1))
  104. {
  105. otherScreensAreGone = true;
  106. }
  107. // The gameplay screen takes a while to load, so we display a loading
  108. // message while that is going on, but the menus load very quickly, and
  109. // it would look silly if we flashed this up for just a fraction of a
  110. // second while returning from the game to the menus. This parameter
  111. // tells us how long the loading is going to take, so we know whether
  112. // to bother drawing the message.
  113. if (loadingIsSlow)
  114. {
  115. SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
  116. SpriteFont font = ScreenManager.Font;
  117. const string message = "Loading...";
  118. // Center the text in the viewport.
  119. Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
  120. Vector2 viewportSize = new Vector2(viewport.Width, viewport.Height);
  121. Vector2 textSize = font.MeasureString(message);
  122. Vector2 textPosition = (viewportSize - textSize) / 2;
  123. Color color = new Color(255, 255, 255, TransitionAlpha);
  124. // Draw the text.
  125. spriteBatch.Begin();
  126. spriteBatch.DrawString(font, message, textPosition, color);
  127. spriteBatch.End();
  128. }
  129. }
  130. #endregion
  131. }
  132. }