Created
April 18, 2011 14:43
-
-
Save koenbollen/925477 to your computer and use it in GitHub Desktop.
A simple but complete ScreenManager for XNA.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Xna.Framework; | |
using System.Linq; | |
namespace Screens | |
{ | |
/// <summary> | |
/// This is a screen that can be added to the ScreenManager. Extend it and add components | |
/// to it in the Initialize() method. You can also override the Update() and Draw() method. | |
/// </summary> | |
public class Screen : DrawableGameComponent | |
{ | |
/// <summary> | |
/// This member tells if this screen is initialized. | |
/// </summary> | |
public bool Initialized { get; private set; } | |
/// <summary> | |
/// Set this member to true if this screen doesn't cover the entire screen. | |
/// </summary> | |
public bool Translucent { get; set; } | |
/// <summary> | |
/// A reference to the ScreenManager. | |
/// </summary> | |
public ScreenManager Manager { get; internal set; } | |
/// <summary> | |
/// The GameComponentCollection, add components for this screen. | |
/// </summary> | |
public GameComponentCollection Components { get; private set; } | |
public Screen(Game game) | |
: base(game) | |
{ | |
this.Components = new GameComponentCollection(); | |
Translucent = false; | |
} | |
/// <summary> | |
/// This method is called when this screen is back at the top of the stack. | |
/// </summary> | |
public virtual void Activated() | |
{ | |
} | |
/// <summary> | |
/// This method is called when a screen is deactivated by an other screen. | |
/// </summary> | |
public virtual void Deactivated() | |
{ | |
} | |
/// <summary> | |
/// Initialize every Component of this screen. | |
/// </summary> | |
public override void Initialize() | |
{ | |
foreach (GameComponent gc in this.Components) | |
gc.Initialize(); | |
Initialized = true; | |
base.Initialize(); | |
} | |
/// <summary> | |
/// Update every Enabled Component of this screen. | |
/// </summary> | |
public override void Update(GameTime gameTime) | |
{ | |
// Major credits to Nils Dijk: | |
foreach (IUpdateable gc in this.Components.OfType<IUpdateable>().Where<IUpdateable>(x => x.Enabled).OrderBy<IUpdateable, int>(x => x.UpdateOrder)) | |
gc.Update(gameTime); | |
base.Update(gameTime); | |
} | |
/// <summary> | |
/// Draw every Visible Component of this screen. | |
/// </summary> | |
public override void Draw(GameTime gameTime) | |
{ | |
// Major credits to Nils Dijk: | |
foreach (IDrawable gc in this.Components.OfType<IDrawable>().Where<IDrawable>(x => x.Visible).OrderBy<IDrawable,int>(x => x.DrawOrder) ) | |
gc.Draw(gameTime); | |
base.Draw(gameTime); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using Microsoft.Xna.Framework; | |
namespace Screens | |
{ | |
/// <summary> | |
/// This class is a collection/stack of active screens in the game. | |
/// A game should have one screen manager and control the active screens by | |
/// adding and removing screens from this manager. | |
/// | |
/// The top screen of the stack will be updated and the top screens that are | |
/// translucent will be drawn. The first screen on the stack that isn't translucent | |
/// will stop the drawing. | |
/// | |
/// In Game: | |
/// public ScreenManager Screens { get; private set; } | |
/// | |
/// In Game.Initialize(): | |
/// this.Components.Add( this.Screens = new ScreenManager(this, new StartScreen(this)) ); | |
/// | |
/// </summary> | |
/// By Koen Bollen, 2011 | |
public class ScreenManager : DrawableGameComponent | |
{ | |
/// <summary> | |
/// This boolean is set when the Initialize() method is called. | |
/// </summary> | |
public bool Initialized { get; private set; } | |
/// <summary> | |
/// This is the list of active screens in the game. | |
/// </summary> | |
private Stack<Screen> screens; | |
/// <summary> | |
/// The current active screen. | |
/// </summary> | |
public Screen ActiveScreen | |
{ | |
get { return this.Peek(); } | |
} | |
public ScreenManager(Game game, Screen start) | |
: base(game) | |
{ | |
this.screens = new Stack<Screen>(); | |
if( start != null ) | |
this.Push(start); | |
this.Initialized = false; | |
} | |
/// <summary> | |
/// Initialize all screens in the active screen list. | |
/// </summary> | |
public override void Initialize() | |
{ | |
foreach (Screen s in this.screens) | |
s.Initialize(); | |
this.Initialized = true; | |
base.Initialize(); | |
} | |
/// <summary> | |
/// Only update the top of the screen stack. | |
/// </summary> | |
/// <param name="gameTime">Provides a snapshot of timing values.</param> | |
public override void Update(GameTime gameTime) | |
{ | |
this.screens.Peek().Update(gameTime); | |
base.Update(gameTime); | |
} | |
/// <summary> | |
/// Draw all visible screens. A screen that is not translucent will stop the iteration of screens. | |
/// </summary> | |
/// <param name="gameTime">Provides a snapshot of timing values.</param> | |
public override void Draw(GameTime gameTime) | |
{ | |
List<Screen> visible = new List<Screen>(); | |
foreach (Screen s in this.screens) | |
{ | |
visible.Add(s); | |
if (!s.Translucent) | |
break; | |
} | |
// Draw from back to front: | |
for( int i = visible.Count-1; i >= 0; i-- ) | |
visible[i].Draw(gameTime); | |
base.Draw(gameTime); | |
} | |
/// <summary> | |
/// Add a screen to the top of the stack, if the manager is initialized but the screen isn't initialize it. | |
/// Also set it's manager to this. | |
/// </summary> | |
/// <param name="screen">The screen to add.</param> | |
public void Push(Screen screen) | |
{ | |
screen.Manager = this; | |
if (!screen.Initialized && this.Initialized) | |
screen.Initialize(); | |
if( this.ActiveScreen != null ) | |
this.ActiveScreen.Deactivated(); | |
this.screens.Push(screen); | |
} | |
/// <summary> | |
/// Get the top of the screen stack. The most active screen. | |
/// </summary> | |
/// <returns>The active screen.</returns> | |
public Screen Peek() | |
{ | |
if (this.screens.Count < 1 ) | |
return null; | |
return this.screens.Peek(); | |
} | |
/// <summary> | |
/// Remove a screen from the screen stack. | |
/// </summary> | |
/// <returns>The removed screen.</returns> | |
public Screen Pop() | |
{ | |
if (this.screens.Count < 1) | |
return null; | |
Screen prev = this.screens.Pop(); | |
if (this.ActiveScreen != null) | |
this.ActiveScreen.Activated(); | |
return prev; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment