LoadingScreen.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. //-----------------------------------------------------------------------------
  2. // LoadingScreen.cs
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7. using System;
  8. using Microsoft.Xna.Framework;
  9. using Microsoft.Xna.Framework.Graphics;
  10. using Microsoft.Xna.Framework.Content;
  11. namespace RolePlaying
  12. {
  13. /// <summary>
  14. /// The loading screen coordinates transitions between the menu system and the
  15. /// game itself. Normally one screen will transition off at the same time as
  16. /// the next screen is transitioning on, but for larger transitions that can
  17. /// take a longer time to load their data, we want the menu system to be entirely
  18. /// gone before we start loading the game. This is done as follows:
  19. ///
  20. /// - Tell all the existing screens to transition off.
  21. /// - Activate a loading screen, which will transition on at the same time.
  22. /// - The loading screen watches the state of the previous screens.
  23. /// - When it sees they have finished transitioning off, it activates the real
  24. /// next screen, which may take a long time to load its data. The loading
  25. /// screen will be the only thing displayed while this load is taking place.
  26. /// </summary>
  27. /// <remarks>
  28. /// Similar to a class found in the Game State Management sample on the
  29. /// XNA Creators Club Online website (http://creators.xna.com).
  30. /// </remarks>
  31. class LoadingScreen : GameScreen
  32. {
  33. bool loadingIsSlow;
  34. bool otherScreensAreGone;
  35. GameScreen[] screensToLoad;
  36. private Texture2D loadingTexture;
  37. private Vector2 loadingPosition;
  38. private Texture2D loadingBlackTexture;
  39. private Rectangle loadingBlackTextureDestination;
  40. /// <summary>
  41. /// The constructor is private: loading screens should
  42. /// be activated via the static Load method instead.
  43. /// </summary>
  44. private LoadingScreen(ScreenManager screenManager, bool loadingIsSlow,
  45. GameScreen[] screensToLoad)
  46. {
  47. this.loadingIsSlow = loadingIsSlow;
  48. this.screensToLoad = screensToLoad;
  49. TransitionOnTime = TimeSpan.FromSeconds(0.5);
  50. }
  51. /// <summary>
  52. /// Activates the loading screen.
  53. /// </summary>
  54. public static void Load(ScreenManager screenManager, bool loadingIsSlow,
  55. params GameScreen[] screensToLoad)
  56. {
  57. // Tell all the current screens to transition off.
  58. foreach (GameScreen screen in screenManager.GetScreens())
  59. screen.ExitScreen();
  60. // Create and activate the loading screen.
  61. LoadingScreen loadingScreen = new LoadingScreen(screenManager,
  62. loadingIsSlow,
  63. screensToLoad);
  64. screenManager.AddScreen(loadingScreen);
  65. }
  66. public override void LoadContent()
  67. {
  68. ContentManager content = ScreenManager.Game.Content;
  69. loadingTexture = content.Load<Texture2D>(@"Textures\MainMenu\LoadingPause");
  70. loadingBlackTexture =
  71. content.Load<Texture2D>(@"Textures\GameScreens\FadeScreen");
  72. Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
  73. loadingBlackTextureDestination = new Rectangle(viewport.X, viewport.Y,
  74. viewport.Width, viewport.Height);
  75. loadingPosition = new Vector2(
  76. viewport.X + (float)Math.Floor((viewport.Width -
  77. loadingTexture.Width) / 2f),
  78. viewport.Y + (float)Math.Floor((viewport.Height -
  79. loadingTexture.Height) / 2f));
  80. base.LoadContent();
  81. }
  82. /// <summary>
  83. /// Updates the loading screen.
  84. /// </summary>
  85. public override void Update(GameTime gameTime, bool otherScreenHasFocus,
  86. bool coveredByOtherScreen)
  87. {
  88. base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
  89. // If all the previous screens have finished transitioning
  90. // off, it is time to actually perform the load.
  91. if (otherScreensAreGone)
  92. {
  93. ScreenManager.RemoveScreen(this);
  94. foreach (GameScreen screen in screensToLoad)
  95. {
  96. if (screen != null)
  97. {
  98. ScreenManager.AddScreen(screen);
  99. }
  100. }
  101. // Once the load has finished, we use ResetElapsedTime to tell
  102. // the game timing mechanism that we have just finished a very
  103. // long frame, and that it should not try to catch up.
  104. ScreenManager.Game.ResetElapsedTime();
  105. }
  106. }
  107. /// <summary>
  108. /// Draws the loading screen.
  109. /// </summary>
  110. public override void Draw(GameTime gameTime)
  111. {
  112. // If we are the only active screen, that means all the previous screens
  113. // must have finished transitioning off. We check for this in the Draw
  114. // method, rather than in Update, because it isn't enough just for the
  115. // screens to be gone: in order for the transition to look good we must
  116. // have actually drawn a frame without them before we perform the load.
  117. if ((ScreenState == ScreenState.Active) &&
  118. (ScreenManager.GetScreens().Length == 1))
  119. {
  120. otherScreensAreGone = true;
  121. }
  122. // The gameplay screen takes a while to load, so we display a loading
  123. // message while that is going on, but the menus load very quickly, and
  124. // it would look silly if we flashed this up for just a fraction of a
  125. // second while returning from the game to the menus. This parameter
  126. // tells us how long the loading is going to take, so we know whether
  127. // to bother drawing the message.
  128. if (loadingIsSlow)
  129. {
  130. SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
  131. // Center the text in the viewport.
  132. Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
  133. Vector2 viewportSize = new Vector2(viewport.Width, viewport.Height);
  134. Color color = new Color((byte)255, (byte)255, (byte)255, TransitionAlpha);
  135. spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, ScreenManager.GlobalTransformation);
  136. spriteBatch.Draw(loadingBlackTexture, loadingBlackTextureDestination,
  137. Color.White);
  138. spriteBatch.Draw(loadingTexture, loadingPosition, Color.White);
  139. spriteBatch.End();
  140. }
  141. }
  142. }
  143. }