Silverlight Games 101

Write games in Silverlight 2 using C# by Bill Reiss
Our upcoming Silverlight book for beginners (includes a great chapter on game development in Silverlight!) Hello! Silverlight 2 with Dave Campbell, available online now!



Pages

    Recent posts

    Navigation

    Archive

    Blogroll

      Tampa Divorce Lawyer

      North of Tampa in Lutz, Florida. A Tampa Divorce Lawyer focusing on family, divorce, and real estate law.

      Disclaimer

      The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

      Silverlight CompositionTarget.Rendering Game Loop

      Sample code: http://www.bluerosegames.com/silverlight-games-101/samples/CompositionTargetGameLoop.zip

      So far we have a game loop implementation based on the DispatcherTimer, and another based on and empty Storyboard. Silverlight 2 RTW introduces another option, the CompositionTarget.Rendering event. Since it’s been a while, first let’s take another look at the GameLoop base class in BlueRoseGames.Helpers.Timers:

      using System;
       
      namespace BlueRoseGames.Helpers.Timers
      {
          public abstract class GameLoop
          {
              protected DateTime lastTick;
              public delegate void UpdateHandler(object sender, TimeSpan elapsed);
              public event UpdateHandler Update;
       
              public void Tick()
              {
                  DateTime now = DateTime.Now;
                  TimeSpan elapsed = now - lastTick;
                  lastTick = now;
                  if (Update != null) Update(this, elapsed);
              }
       
              public virtual void Start()
              {
                  lastTick = DateTime.Now;
              }
       
              public virtual void Stop()
              {
              }
          }
      }

      This base class has the logic and data to keep track of the elapsed time between updates of the game loop and calls the Update event. The inherited classes only need to implement their specific start and stop logic, and they need to call the GameLoop’s Tick method when events fire.

      The CompositionTarget.Rendering event fires just before each frame is rendered, so it’s a good way to create a game loop since that’s when we really need to update everything. Here is our new CompositionTargetGameLoop based on this event:

      using System;
      using System.Windows.Media;
       
      namespace BlueRoseGames.Helpers.Timers
      {
          public class CompositionTargetGameLoop : GameLoop
          {
              public CompositionTargetGameLoop()
              {
              }
       
              void CompositionTarget_Rendering(object sender, EventArgs e)
              {
                  base.Tick();            
              }
       
              public override void Start()
              {
                  CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
                  base.Start();
              }
       
              public override void Stop()
              {
                  CompositionTarget.Rendering -= new EventHandler(CompositionTarget_Rendering);
                  base.Stop();
              }
          }
      }

      So in the Start event, we attach an event handler to the Rendering event, and in the Stop event we remove the event handler. Then in the Rendering event, we simply call the GameLoop’s Tick method which fires the Update event.

      Then to use this timer in the Space Rocks game sample. Here’s the new Page.xaml.cs after the changes:

      using System;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Input;
      using BlueRoseGames.Helpers.Timers;
      using BlueRoseGames.Helpers.Keyboard;
       
      namespace SpaceRocks
      {
          public partial class Page : UserControl
          {
              CompositionTargetGameLoop gameLoop;
              KeyHandler keyHandler;
              double rotationSpeed = 150;
              public Page()
              {
                  InitializeComponent();
                  this.GotFocus += new RoutedEventHandler(Page_GotFocus);
                  this.LostFocus += new RoutedEventHandler(Page_LostFocus);
                  this.MouseLeftButtonDown += new MouseButtonEventHandler(Page_MouseLeftButtonDown);
                  gameLoop = new CompositionTargetGameLoop();
                  gameLoop.Update += new GameLoop.UpdateHandler(gameLoop_Update);
                  keyHandler = new KeyHandler(this);
              }
       
              void Page_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
              {
                  clickToStart.Visibility = Visibility.Collapsed;
                  gameLoop.Start();
              }
       
              void Page_LostFocus(object sender, RoutedEventArgs e)
              {
                  clickToStart.Visibility = Visibility.Visible;
                  gameLoop.Stop();            
              }
       
              void Page_GotFocus(object sender, RoutedEventArgs e)
              {
                  clickToStart.Visibility = Visibility.Collapsed;
                  gameLoop.Start();
              }
       
              void gameLoop_Update(object sender, TimeSpan elapsed)
              {
                  // do your game loop processing here
                  if (keyHandler.IsKeyPressed(Key.A) || keyHandler.IsKeyPressed(Key.Left))
                  {
                      ship.RotationAngle -= rotationSpeed * elapsed.TotalSeconds;
                  }
                  else if (keyHandler.IsKeyPressed(Key.D) || keyHandler.IsKeyPressed(Key.Right))
                  {
                      ship.RotationAngle += rotationSpeed * elapsed.TotalSeconds;
                  }
              }
       
          }
      }
       

      It’s now included in BlueRoseGames.Helpers.Timers so that you can use it in your own projects.

      Posted: Nov 23 2008, 08:19 by Bill Reiss | Comments (21) RSS comment feed |
      • Currently 0/5 Stars.
      • 1
      • 2
      • 3
      • 4
      • 5
      Filed under:

      Comments

      Comments are closed