Source code: http://www.bluerosegames.com/SpaceRocks/SpaceRocks_1_GameLoop.zip
Most games require a game loop which is simply a method that executes on a timer. This method can contain things like input handling, repositioning sprites, checking for collisions, or spawning particles. In Silverlight there are a few options for this, including using a zero duration Storyboard, a DispatcherTimer, or the CompositionTarget.Rendering event.
We’ll be using the SilverSprite core assembly for this project, you can learn more about it here:
The SilverSprite core assembly contains a general purpose game loop you can use. This game loop uses the CompositionTarget.Rendering event. This event fires once per frame so it’s a good choice for a game loop.
It’s also useful to keep track of how long it’s been since the last time the game loop executed so that you can handle things like running at different frame rates. The SilverSprite game loop does this for you too. This will probably get even more important when Silverlight moves to other platforms like Windows Phone.
First let’s create a new Silverlight application and call it SpaceRocks. Take the defaults for creating a web application.
In order to use the SilverSprite core assembly we need at add a reference to the Silverlight project. The reference we need is to SilverArcade.SilverSprite.dll.
UPDATE: I had a typo in the name of the SilverSprite core assembly. The assembly we really need is SilverArcade.SilverSprite.Core.dll.
You can get this assembly from this link:
http://silversprite.codeplex.com/releases/view/41574
or you can get it from the source code included at the top of this post.
Next in the SpaceRocks project, add a new Silverlight User Control called Game.xaml. It’s a good idea to keep logic out of your MainPage.xaml and just use it as a container for other controls. Then in MainPage.xaml we’ll add the Game control:
<UserControl x:Class="SpaceRocks.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
xmlns:local="clr-namespace:SpaceRocks">
<Grid x:Name="LayoutRoot">
<local:Game VerticalAlignment="Top" HorizontalAlignment="Left"/>
</Grid>
</UserControl>
Notice the xmlns:local attribute. This tells Silverlight to look in the SpaceRocks namespace to find any elements that start with the local: prefix. Then we add the Game control to the LayoutRoot Grid. In the Game.xaml we can add our game loop object to the user control’s resources and while we’re in there we can set the width, height, and background color. We’ll also add a TextBlock to display something so that we can see the loop is executing.
<UserControl x:Class="SpaceRocks.Game"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="640" Height="480"
xmlns:local="clr-namespace:SpaceRocks"
xmlns:silverSprite="clr-namespace:SilverArcade.SilverSprite;assembly=SilverArcade.SilverSprite.Core">
<UserControl.Resources>
<silverSprite:GameLoop x:Key="gameLoop" Update="GameLoop_Update" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="Black">
<TextBlock x:Name="text" Foreground="White"/>
</Grid>
</UserControl>
Now for the Game control’s code behind file. In the code we’ll implement the GameLoop_Update event and put some code in to increment a number every time it executes and set the TextBlock’s text to that value.
using System;
using System.Windows.Controls;
namespace SpaceRocks
{
public partial class Game : UserControl
{
int count = 0;
public Game()
{
InitializeComponent();
}
private void GameLoop_Update(object sender, SilverArcade.SilverSprite.SimpleEventArgs<TimeSpan> e)
{
text.Text = count.ToString();
count++;
}
}
}
Now if you run the program (we can’t really call it a game yet) you should see the number change as it gets incremented every time through the game loop.
We’ll do more interesting things with the game loop going forward, but this is a good starting point. If this works then we know that the SilverSprite core assembly has been referenced properly and that the game loop is firing once per frame.