#region File Description //----------------------------------------------------------------------------- // LoadingScreen.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion #region Using Statements using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; #endregion namespace NetRumble { /// /// The loading screen coordinates transitions between the menu system and the /// game itself. Normally one screen will transition off at the same time as /// the next screen is transitioning on, but for larger transitions that can /// take a longer time to load their data, we want the menu system to be entirely /// gone before we start loading the game. This is done as follows: /// /// - Tell all the existing screens to transition off. /// - Activate a loading screen, which will transition on at the same time. /// - The loading screen watches the state of the previous screens. /// - When it sees they have finished transitioning off, it activates the real /// next screen, which may take a long time to load its data. The loading /// screen will be the only thing displayed while this load is taking place. /// /// /// This public class is similar to one in the GameStateManagement sample. /// public class LoadingScreen : GameScreen { #region Fields bool loadingIsSlow; bool otherScreensAreGone; EventHandler loadNextScreen; #endregion #region Initialization /// /// The constructor is private: loading screens should /// be activated via the static Load method instead. /// private LoadingScreen() { TransitionOnTime = TimeSpan.FromSeconds(0.5); } /// /// Activates the loading screen. /// public static void Load(ScreenManager screenManager, EventHandler loadNextScreen, bool loadingIsSlow) { // Tell all the current screens to transition off. foreach (GameScreen screen in screenManager.GetScreens()) screen.ExitScreen(); // Create and activate the loading screen. LoadingScreen loadingScreen = new LoadingScreen(); loadingScreen.loadingIsSlow = loadingIsSlow; loadingScreen.loadNextScreen = loadNextScreen; screenManager.AddScreen(loadingScreen); } #endregion #region Update and Draw /// /// Updates the loading screen. /// public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen) { base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen); // If all the previous screens have finished transitioning // off, it is time to actually perform the load. if (otherScreensAreGone) { ScreenManager.RemoveScreen(this); loadNextScreen(this, EventArgs.Empty); } } /// /// Draws the loading screen. /// public override void Draw(GameTime gameTime) { // If we are the only active screen, that means all the previous screens // must have finished transitioning off. We check for this in the Draw // method, rather than in Update, because it isn't enough just for the // screens to be gone: in order for the transition to look good we must // have actually drawn a frame without them before we perform the load. if ((ScreenState == ScreenState.Active) && (ScreenManager.GetScreens().Length == 1)) { otherScreensAreGone = true; } // The gameplay screen takes a while to load, so we display a loading // message while that is going on, but the menus load very quickly, and // it would look silly if we flashed this up for just a fraction of a // second while returning from the game to the menus. This parameter // tells us how long the loading is going to take, so we know whether // to bother drawing the message. if (loadingIsSlow) { const string message = "Loading..."; // Center the text in the viewport. Viewport viewport = ScreenManager.GraphicsDevice.Viewport; Vector2 viewportSize = new Vector2(viewport.Width, viewport.Height); Vector2 textSize = ScreenManager.Font.MeasureString(message); Vector2 textPosition = (viewportSize - textSize) / 2; Color color = new Color(255, 255, 255, TransitionAlpha); // Draw the text. ScreenManager.SpriteBatch.Begin(); ScreenManager.SpriteBatch.DrawString(ScreenManager.Font, message, textPosition, color); ScreenManager.SpriteBatch.End(); } } #endregion } }