Sunday, April 21, 2013

Screen Management

An important part of developing a game (and engine) is a robust system for screen management. My desire to add a basic 'player health' next led to the obvious requirement to actually display that health, but I hadn't developed any sort of HUD (head-up-display) system yet.

How much health do I have left? Where am I?

There's nothing inherently complex about developing a HUD compared to other elements in the game. In a way, it's even simpler, because the HUD elements don't move that much, don't collide, and don't need too much programming behind them; presumably they're just interface elements (like health) that update their display based on some sort of background model (the game state). But what about moving around and animating these elements?

I realized quickly that there's no reason not to leverage all of my existing infrastructure for new screens. Although the 'Sections' (levels) in Super Obelisk are designed in the editor and loaded from disk, this is merely a convenience--Sections can be generated on-the-fly in code, and entities that can move, animate, create other entities, and react to input can be dynamically added. So I decided that this dynamic creation would be used to create Sections that serve other purposes besides gameplay!

I actually decided to tackle a very simple screen management task first: pausing the game. Check the video below for a very short demo of...well, pausing. I know, it's not super exciting, but a lot of game development work isn't that flashy.

Feel the thrill of watching a game get paused multiple times in mere seconds

So, what does this look like underneath the hood?

  • The IGameInterface interface, available from any BehaviorTemplate (see previous blog entries, this is the code that controls all game logic), now supports a NewSection method that pushes a new Section onto a list of Sections that the main game loop controls. Theoretically, you could use this to divide the screen up into 4 quadrants and play 4 totally separate games at once (or, if the cameras overlapped, they'd just kind of all merge into each other)
  • So, when the player presses Start, a helper class called 'PauseScreen' with a single method 'Create'--which takes in an instance of the current section and the IGameInterface--creates a 'Pause' Section. It also calls a special 'pause' method on the existing section (the gameplay) which tells the engine to stop updating entities.
  • The helper class adds a few entities to the Pause section. A transparent black solid rectangle that fills the entire view (which makes it darker), some text that says 'Paused' (with a fancy entrance--see the previous blog post), and an invisible entity which will handle input.
  • The invisible entity is given an Update handler which will react to the player pressing Start again by unsetting the 'pause' property on the gameplay section, and destroying the current section.
And that's it! For those who are code-inclined, here is the entire source code for what I just described.

I've used these enhancements to the infrastructure to create a very simple HUD with a few hearts in the top-right corner. But when does a HUD get created? Shouldn't it always be there with the game? In almost all cases, yes. So, at the Entry Point for the game (which will, in the future, create a Section for a startup screen), I create two sections: the level (hard coded for now, or provided by the editor), and the HUD. Behold, the world's ugliest HUD until I get proper graphics for it:

So, back to what started this in the first place: I have a health bar now, so...what is it displaying? Why are there 4 hearts? Well, right now, it's because I hard coded 4 hearts in there. So, how do I get real game data--the player's health, inventory, number of times they've died, the status of all of the bosses, the walls you've blown up, and a myriad of other various bits of info, both temporary and persistent--from a section? Do sections communicate with each other?

Who owns the Game Model and how is the model implemented? Does the main game instance own a single model (red line), or do sections have access to it directly (gray lines)?

I don't think so. A better approach is to have a Game Model of some sort that Sections can access. I'll be tackling this architecture problem over the next few days, which should result in a demo of my player actually taking damage until they run out of health! Stay tuned!

No comments:

Post a Comment