#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;
using Microsoft.Xna.Framework.Content;
#endregion
namespace RolePlaying
{
///
/// 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.
///
///
/// Similar to a class found in the Game State Management sample on the
/// XNA Creators Club Online website (http://creators.xna.com).
///
class LoadingScreen : GameScreen
{
#region Screens Data
bool loadingIsSlow;
bool otherScreensAreGone;
GameScreen[] screensToLoad;
#endregion
#region Graphics Data
private Texture2D loadingTexture;
private Vector2 loadingPosition;
private Texture2D loadingBlackTexture;
private Rectangle loadingBlackTextureDestination;
#endregion
#region Initialization
///
/// The constructor is private: loading screens should
/// be activated via the static Load method instead.
///
private LoadingScreen(ScreenManager screenManager, bool loadingIsSlow,
GameScreen[] screensToLoad)
{
this.loadingIsSlow = loadingIsSlow;
this.screensToLoad = screensToLoad;
TransitionOnTime = TimeSpan.FromSeconds(0.5);
}
///
/// Activates the loading screen.
///
public static void Load(ScreenManager screenManager, bool loadingIsSlow,
params GameScreen[] screensToLoad)
{
// 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(screenManager,
loadingIsSlow,
screensToLoad);
screenManager.AddScreen(loadingScreen);
}
public override void LoadContent()
{
ContentManager content = ScreenManager.Game.Content;
loadingTexture = content.Load(@"Textures\MainMenu\LoadingPause");
loadingBlackTexture =
content.Load(@"Textures\GameScreens\FadeScreen");
Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
loadingBlackTextureDestination = new Rectangle(viewport.X, viewport.Y,
viewport.Width, viewport.Height);
loadingPosition = new Vector2(
viewport.X + (float)Math.Floor((viewport.Width -
loadingTexture.Width) / 2f),
viewport.Y + (float)Math.Floor((viewport.Height -
loadingTexture.Height) / 2f));
base.LoadContent();
}
#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);
foreach (GameScreen screen in screensToLoad)
{
if (screen != null)
{
ScreenManager.AddScreen(screen);
}
}
// Once the load has finished, we use ResetElapsedTime to tell
// the game timing mechanism that we have just finished a very
// long frame, and that it should not try to catch up.
ScreenManager.Game.ResetElapsedTime();
}
}
///
/// 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)
{
SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
// Center the text in the viewport.
Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
Vector2 viewportSize = new Vector2(viewport.Width, viewport.Height);
Color color = new Color(255, 255, 255, TransitionAlpha);
spriteBatch.Begin();
spriteBatch.Draw(loadingBlackTexture, loadingBlackTextureDestination,
Color.White);
spriteBatch.Draw(loadingTexture, loadingPosition, Color.White);
spriteBatch.End();
}
}
#endregion
}
}