Presentation is loading. Please wait.

Presentation is loading. Please wait.

2.3. Architectural Design I

Similar presentations


Presentation on theme: "2.3. Architectural Design I"— Presentation transcript:

1 2.3. Architectural Design I
Example approach for game screen management

2 Question Clinic: FAQ In lecture exploration of answers to frequently asked student questions

3 Game Screen Management
Exploration of an example game screen manager

4 The need for screen management
The front-end to most games will feature a series of navigatable screens (e.g. configuration, high- score, etc.). Additionally, whilst being played, many games will permit other screens (e.g. options screen) to sometimes appear on top of the main game screen. Also, the different levels, etc. within a game can also be viewed as a set of screens. It is desirable to have some means of easily controlling the management (adding, removing, displaying, etc.) of screens.

5 The following draws upon the Game State Management XNA tutorial
Management Overview Game Screen Update { Update objects() } Draw { Draw objects() Game Engine loop { ScreenManager.Update() ScreenManager.Draw() } Screen Manager Update() { Update screens } Draw() { Consider screen rendering The core game engine makes use of a screen manager that is responsible for updating and rendering game screens. The screen manager contains a list of screens to be managed. The following draws upon the Game State Management XNA tutorial

6 The Screen Manager Design/implementation highlights of a screen manager class

7 The Screen Manager The ScreenManager contains a list of managed GameScreens. A stack of GameScreens to be updated is formed each update. Input (InputState) and output (SpriteBatch) setup is handled within the Screen Manager and made available to each screen. public class ScreenManager { List<GameScreen> screens = new List<GameScreen>(); Stack<GameScreen> screensToUpdate = new Stack<GameScreen>(); InputState input = new InputState(); SpriteBatch spriteBatch; } The Game State Management XNA tutorial uses a second list to hold the screens to be updated – but uses the list as an effective stack. I’m unsure why a Stack instance was not used – maybe it was felt that some readers would not be that familiar with a stack – although the code is arguably more straightforward and simple using a Stack instance. ScreenManager screenManager = new ScreenManager(this); Components.Add(screenManager); Aside: The ScreenManager is added to the Game instance as a drawable game component

8 Screen Manager (Update() method)
The input state is evolved for the update tick. GameScreens are pushed onto the update stack (screens added last will be updated first) Flags are assigned initial values. public override void Update(GameTime gameTime) { input.Update(); foreach (GameScreen screen in screens) screensToUpdate.Push(screen); bool otherScreenHasFocus = !Game.IsActive; bool coveredByOtherScreen = false; // Update screens... } One good reason to make a copy of the screens list into screensToUpdate is that it avoid the horror of iterating over a collection that could change (i.e. if a GameScreen decides to add an extra GameScreen to the screens collection, then it needs to do so in a manner that does not clash with the iteration). Personally, I would prefer to maintain an addList which would be merged with the screens list at the end of the update. The Game.IsActive will return false (on Windows) if the game is minimised or something else has the input focus. On an XBox360, it will return false if the user is playing with the Dashboard.

9 The flags permit context specific screen update
Each screen is updated in reverse add order (those added last are updated first) The flags permit context specific screen update Only the topmost ‘active’ screen is permitted to handle user input. while (screensToUpdate.Count > 0) { GameScreen screen = screensToUpdate.Pop(); screen.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen); if (screen.ScreenState == ScreenState.TransitionOn || screen.ScreenState == ScreenState.Active) if (!otherScreenHasFocus) screen.HandleInput(input); otherScreenHasFocus = true; } if (!screen.IsPopup) coveredByOtherScreen = true;

10 Screen Manager (Draw / Add / Remove)
public override void Draw(GameTime gameTime) { foreach (GameScreen screen in screens) if (screen.ScreenState != ScreenState.Hidden) screen.Draw(gameTime); } All non-hidden screens are asked to draw themselves. GameScreens can be added to the manager public void AddScreen(GameScreen screen) { screen.ScreenManager = this; screens.Add(screen); } Aside: It is intended that the GameScreen instance will decide when to remove itself by calling a RemoveScreen method. Think about the usage assumptions this design decision introduces.

11 The Game Screen Design/implementation highlights of a game screen class

12 The GameScreen An enumerated type of the valid screen states is defined. The GameScreen holds flags defining if it is a pop-up screen (assumed persistent), or if it is currently exiting (valid over several frames), or another screen has the input focus (valid for this update only). A fade transition time for the screen appearing and disappearing is also defined. public enum ScreenState { TransitionOn, Active, TransitionOff, Hidden } bool isPopup = false; bool isExiting = false; bool otherScreenHasFocus; ScreenState screenState = ScreenState.TransitionOn; TimeSpan transitionOnTime = TimeSpan.Zero; TimeSpan transitionOffTime = TimeSpan.Zero;

13 GameScreen (Update() method)
The update firstly checks to see if the GameScreen is exiting. If not, it then checks to see if it is a covered screen If not, it finally checks to see if the screen needs to transition on and become active Why is it good to declare this as virtual? public virtual void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen) { if (isExiting) // Deal with exit } else if (coveredByOtherScreen) // Deal with covered screen else // Check for transition on It is good to declare this as virtual as it communicate to the user of the class that the class designer expects them to provide a use specific implementation, i.e. it communicates to the user that this method is partial in its implementation. It is introduces an assumption that the user will ‘remember’ to call the base update method (problems will arise if this is not the case) Extending classes will extend Update() to provide screen specific behaviour

14 If exiting, wait until the fade is complete and then remove the screen
If covered, fade screen out and enter hidden state Otherwise, if screen is not already active, fade it in and make active if (isExiting) { screenState = ScreenState.TransitionOff; if (!UpdateTransition(gameTime, transitionOffTime, 1)) ScreenManager.RemoveScreen(this); } else if (coveredByOtherScreen) { if (UpdateTransition(gameTime, transitionOffTime, 1)) screenState = ScreenState.TransitionOff; else screenState = ScreenState.Hidden; } else { if (UpdateTransition(gameTime, transitionOnTime, -1)) screenState = ScreenState.TransitionOn; screenState = ScreenState.Active; } The UpdateTransition method fades the screen in / out, returning true whilst doing this and false when finished

15 GameScreen (Draw() method)
The Draw method is declared virtual, with no inheritable implementation – i.e. it’s up to each game screen how it will be drawn public virtual void Draw(GameTime gameTime) { } To explore this tutorial in greater depth, see the Game State Management tutorial from:

16 Summary Today we explored: An example implemen- tation of a game screen manager To do: Submit Project Development Report with details of game idea, team, development language Complete setup of development environment (XNA / Java) and play about with some tutorials, etc.


Download ppt "2.3. Architectural Design I"

Similar presentations


Ads by Google