How to develop a casual game with Silverlight 2

Game programming was my first love in computer science, and a couple of weeks ago I decided to give it a try with the new Silverlight 2 version available. To my surprise I could accomplish something fun with little effort, and maybe there's someone out there trying to do stuff like this, so let's go through the basics of building a casual game with silverlight 2. Our target will be to develop a mutant version of the old breakout classic. We are going to animate a paddle to prevent a ball from touching the ground while breaking bricks on top of each screen.

Assuming you have a Visual Studio 2008 installation, with the Silverlight Tools for VS2008 loaded, let's start by creating a Silverlight Application Project.

silverlight visual studio

 

silverlight visual studio web app

 

First we are going to modify the Page.xaml created page, to include all the elements our simple game will have, being those:

  1. a paddle,
  2. a ball,
  3. some bricks to destroy

Let's start by changing the default Grid layout, to use instead a Canvas layout, with some rectangles in it. Use the following xaml code:

<Canvas x:Name="GameCanvas" Background="LightGray" Width="400" Height="300">

    <Rectangle x:Name="paddle" Fill="Black" Width="60" Height="10" Canvas.Top="280" Canvas.Left="180"/>

    <Rectangle x:Name="ball" Fill="Black" Width="10" Height="10" RadiusX="5" RadiusY="5" Canvas.Left="200" Canvas.Top="250"/>

    <Rectangle x:Name="Brick1" Fill="Red" Width="40" Height="15" Canvas.Left="120" Canvas.Top="50"/>

    <Rectangle x:Name="Brick2" Fill="Blue" Width="40" Height="15" Canvas.Left="180" Canvas.Top="50"/>

    <Rectangle x:Name="Brick3" Fill="Green" Width="40" Height="15" Canvas.Left="240" Canvas.Top="50"/>

</Canvas>

You should be able to see something like this in the updated design preview,

silverlight casual game breakout 

Animating the paddle

To animate the paddle we are going to add an event handler for the KeyDown event, in the Canvas element of the Page user control. When doing this we'll come across a beta bug, adding the Canvas KeyDown event handler in the xaml doesn't work (at least, not for me), but if I register the event handler in the code behind it works.

So far, my code looks something like the following code block, and after build you should be able to happily move your paddle left and right ways.

public Page()

{

    InitializeComponent();

    this.KeyDown += new KeyEventHandler(GameCanvas_KeyDown);

}

 

private void GameCanvas_KeyDown(object sender, KeyEventArgs e)

{

    double currentX = (double)paddle.GetValue(Canvas.LeftProperty);

    double newX = 0;

    if (e.Key.Equals(Key.Left))

    {

        newX = currentX - 5;

        if (newX < 0)

        {

            newX = 0;

        }

    }

    else if (e.Key.Equals(Key.Right))

    {

        newX = currentX + 5;

        if ((newX + paddle.Width) > GameCanvas.Width)

        {

            newX = GameCanvas.Width - paddle.Width;

        }

    }

    paddle.SetValue(Canvas.LeftProperty, newX);

}

But there's still not much fun involved, everything still is pretty static, so let's animate the ball now.

Animating the ball

In Silverlight there might be a better way to do this with storyboards, but I'm going to go old school on this one and use a timer, and increment the ball coordinates with a vector.

System.Threading.Timer tick;

double vectorY = 10;

double vectorX = 10;

In the code of a new GotFocus handler for the Canvas element, we are going to set the timer. The timer invokes the OnTick handler on wake up, which in turn uses the beautiful Dispatcher.BeginInvoke(()=>UpdateBallPosition()) lambda expression to execute code in the UI thread, and be able to access safely all the UI elements in the canvas, and calculate the new coordinates of the ball and update them.

private void OnGotFocus(object source, EventArgs args)

{

    tick = new System.Threading.Timer(OnTick, null, 1000, 100);

}

void OnTick(object sender)

{

    this.Dispatcher.BeginInvoke(() => UpdateBallPosition());

}

 

void UpdateBallPosition()

{

    double x = (double)ball.GetValue(Canvas.LeftProperty);

    double y = (double)ball.GetValue(Canvas.TopProperty);

    double paddleX = (double)paddle.GetValue(Canvas.LeftProperty);

    double paddleY = (double)paddle.GetValue(Canvas.TopProperty);

    double maxX = GameCanvas.Width;

    double maxY = GameCanvas.Height;

    x += vectorX;

    y += vectorY;

 

    #region collision detection

    #region outer boundaries

    if (x <= 0 || x >= (maxX - ball.Width))

    {

        vectorX = -(vectorX);

        x = (x <= 0) ? 0 : x;

        x = x >= (maxX - ball.Width) ? (maxX - ball.Width) : x;

    }
 

    bool paddleHit = ((y + ball.Height) >= paddleY && x >= paddleX && x <= (paddleX + paddle.Width));

    if (y <= 0 || y >= (maxY - ball.Height) || paddleHit)

    {

        vectorY = -(vectorY);

        y = (y <= 0) ? 0 : y;

        y = y >= (maxY - ball.Height) ? (maxY - ball.Height) : y;

     }

    #endregion

    #endregion

    ball.SetValue(Canvas.TopProperty, y);

    ball.SetValue(Canvas.LeftProperty, x);

}

Then we add code like the following to enable collision detection with the bricks,

#region collision detection blocks

double blockY = (double)Brick1.GetValue(Canvas.TopProperty);

double blockX = (double)Brick1.GetValue(Canvas.LeftProperty);

if (y >= blockY && y <= (blockY + Brick1.Height) && x >= blockX && x <= (blockX + Brick1.Width))

{

    //block collision

    Brick1.Fill = new SolidColorBrush(Colors.Yellow);

    vectorY = -(vectorY);

}

#endregion

This is just for one brick, you do your thing to generalize this code for all three bricks.

And of course, it wouldn't be a game if there's no way to loose or win, so we add logic to control win or lose conditions.

#region gameover and win conditions

//GAME OVER?

if (y >= (maxY - ball.Height))

{

    //game over

    tick.Dispose();

    return;

}

#endregion

This is just the lose condition, but I hope you get the idea. Next week we'll pimp up this solution to add score handling and sounds to this breakout mutant. The source code from the developed casual game sample can be downloaded from here.

3 Comments

  • Bueniiiisimo. We have to publish the game in silverlight streaming and embed the game in the blog. It would be great to start working in a Silverlight Codeplex project for fun.

  • Thanks Miguel (can i call you mike ;), yeah it´d be cool to embed it in a blog, I've done some simple embedding tests with blogger with no luck :( I´m working on a more playable, pimped up, version, no available in http://www.happyclone-online-games.com/

    Regarding the CodePlex project it may be a good idea for a more sophisticated game, this sort of casual game should be easily achieved with the new popfly tools to create games.

  • I've been doing some tests with a Live Writer plugin to embed Silverlight apps right up from silverlight streaming. Not really good results either :(

Comments have been disabled for this content.