Tuesday, December 15, 2009

Template Method Design Pattern

In XNA, the Update() and Draw() methods are invoked, by default, 60 frames per second. During each frame, a general algorithm for both the Update() and Draw() methods could be applied in game code as follows:

Update AlgorithmDraw Algorithm
  • update input
  • update objects
  • update HUD (heads up display)
  • draw background
  • draw objects
  • draw HUD (heads up display)

Here we have defined a template for both the Update() and Draw() methods. A template is a method that defines an algorithm as a set of steps. One or more of these steps can be implemented by the main game code, or deferred to a subclass where appropriate. This ensures that the structure of the algorithm stays the same, while subclasses can provide some part of the implementation as required.

By definition, the Template Method design pattern defines the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.

Let’s complete the discussion with a simple code sample.

First, create the skeleton of an algorithm for both the Update() and Draw() methods in the main game code:
// Template method for Update.
public void Update(Microsoft.Xna.Framework.GameTime gameTime)
{
 if (IsActive)
 {
  return;
 }

 UpdateInput(gameTime); 
 UpdateObjects(gameTime);
 UpdateHUD(gameTime);
}

// Template method for Draw.
public void Draw(Microsoft.Xna.Framework.GameTime gameTime)
{
 if (IsActive)
 {
  return;
 }

 DrawBackground(); 
 DrawObjects();
 DrawHUD();
}
Next, create the steps to be implemented by the template methods in the main game code:
public virtual void UpdateInput(GameTime gameTime) {}
public virtual void UpdateObjects(GameTime gameTime) {}
public virtual void UpdateHUD(GameTime gameTime) {}

public virtual void DrawBackground() {}
public virtual void DrawObjects() {}
public virtual void DrawHUD() {}
As this is a simple example, none of the steps will be deferred to subclasses; each step would execute the same game code each frame.

However, the Template Method can be used in conjunction with the State design pattern to redefine certain steps of the algorithm without changing the algorithm’s structure.

First, define an interface to be implemented by all game state objects. This interface contains all actions that each game state object will implement. In our example, the 2x actions Update() and Draw(), are now defined as template methods; this ensures that the structure of the Update() and Draw() algorithms stays the same while subclasses can provide some part of the implementation as required:
public class AbstractGameState
{   
 protected readonly Game game;   
  
 protected AbstractGameState(Game game)   
 {   
  this.game = game;   
 }   
 public void Update(GameTime gameTime)
 {
  if (IsActive)
  {
   return;
  }

 UpdateInput(gameTime); 
 UpdateObjects(gameTime);
 UpdateHUD(gameTime);
}

public void Draw(Microsoft.Xna.Framework.GameTime gameTime)
{
 if (IsActive)
 {
  return;
 }

 DrawBackground(); 
 DrawObjects();
 DrawHUD();
}
Next, construct one concrete implementation class for each state in the game. Each step in both the Update() and Draw() template methods can now be deferred to the concrete implementation class as required.

For example, imagine the Splash Screen game state concrete implementation class is responsible for detecting the Start button press and displaying the splash screen only:
public class SplashScreenState : AbstractGameState
{
 public override void UpdateInput(GameTime gameTime)
 {
  // Detect player press Start button.
 }

 public override void DrawHUD (GameTime gameTime)
 {
  // Draw splash screen
 }
}
Note: the remaining steps in both the Update() and Draw() template methods are invoked automatically by the algorithms contained in the base game state class.

To summarize, the Template Method design pattern offers algorithm encapsulation so that subclasses can hook themselves right into a computation anytime they want.

No comments:

Post a Comment