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.

Published Sunday, June 01, 2008 6:55 PM by gabouy
Filed under:

Comments

# breakout

Monday, June 02, 2008 11:21 PM by breakout

Pingback from  breakout

# re: How to develop a casual game with Silverlight 2

Thursday, June 05, 2008 9:11 AM by Miguel Saez

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.

# re: How to develop a casual game with Silverlight 2

Thursday, June 05, 2008 10:57 AM by gabouy

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 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.

# re: How to develop a casual game with Silverlight 2

Friday, June 06, 2008 10:17 AM by Miguel Saez

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 :(

# re: How to develop a casual game with Silverlight 2

Friday, July 04, 2008 8:45 PM by Nokola

Hi Miguel,

I also started a "casual" breakout clone sometime ago and this is where it all ended up: http://www.nokola.com/shock - a full-blown playable game with lots of features.. :)

Thanks for the post! It's great to know people interested in Silverlight gaming!

About embedding: if you have access to the raw HTML for your blog (usually from the editor), just add the IFRAME from Silverlight streaming (like in here: blogs.msdn.com/.../building-the-reallistic-water-ripples-sample-in-silverlight.aspx)

Leave a Comment

(required) 
(required) 
(optional)
(required)