Developers guide to writing a simple Silverlight game
Animations
The first worry I had was how to animate the characters, specifically the Olop - the player. Traditionally I'd have used a set of sprite states and drawn them in sequence as the user moves the character, but Silverlight already has animations built in so could I use them? Again I turned to Hannah to supply the storyboards of the character moving. It then became a trivial task to issue the Begin when the user moved the character. In OO fashion I let the character (user control) look after starting the animation when the Move() method was called. One gotcha with this is if the animation takes longer to complete than two Move requests the animation will look clipped and unnatural. To protect against this I added a little guard which is only removed in the storyboards Completed event;
...
if (!this.animationRunning)
{
this.animationRunning = true;
this.BearWalk.Begin();
}
?
void BearWalk_Completed(object sender, EventArgs e)
{
this.animationRunning = false;
}
Another worry I had was how was I going to keep all the different animations running in synch', and yet allow them to run concurrently and independently? Fortunately Silverlight just takes care of this for me, are they sure it isn't a game framework?
Once the move animations were working I could turn my attention to the "fun" storyboards. To start this I just added some code into the characters to randomly select a storyboard, given that each language has it's own random generator I thought I'd show how I did that;
// in the constructor...
this.random = new Random(this.GetHashCode());
?
private void FunnyAnimation()
{
if (!isAnimated && random.Next(100) == 5)
{
int animationFrame = random.Next(animations.Length);
string animationName = animations[animationFrame];
Storyboard storyboard = (Storyboard)this.Resources[animationName];
storyboard.AutoReverse = true;
storyboard.Completed += this.storyBoardCompleted;
storyboard.Begin();
isAnimated = true;
}
}
As normal, the secret to a good random number is to seed the generator with a unique-ish value. If you don't you may end up with all your monsters playing out exactly the same animation at the same time, more synchronized dancing the gaming.

Shrinking ice
Olop needed a way to show that you were running out of time/lives so we plumped for a slowly decaying chunk of ice. Hannah supplied me with another user control with lots of interesting paths and gradient fills, but how to make it shrink? Simply changing the dimensions of the outer canvas saw the ice shrink towards the middle, a nice affect but not the gauge we were hoping for. So I turned to RenderTransform with ScaleTranform in the y-axis. This was fine but still the whole canvas shrank towards the middle. The key to solving this problem was discovering the RenderTransformOrigin property. Setting this allowed me to anchor the transform and to finally produce the gauge effect;
Xaml
<Canvas x:Name="LayoutRoot">
<Canvas x:Name="Ice" RenderTransformOrigin="0,1" VerticalAlignment="Bottom">
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="IceValue" ScaleY="-1.0"/>
</TransformGroup>
</Canvas.RenderTransform>
?
.cs
this.IceValue.ScaleY = -1 * newIceValue;
