2
0

LoadingScreen.cs 6.3 KB

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