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