XAML Playground
about XAML and other Amenities

The Reactive Snake for Windows Phone 7

2011-05-04T22:57:43+01:00 by codeblock

CaptureContinuing my experiments with Reactive Extension I put together a small example that show an alternative use of the library to create a little game. The game is the widely known Snake that many of us have played on his own Nokia when it is the sole game in the ancient models. Please take note that the game I wrote is not complete since it is first of all an example of the use of a technology and how it can simplify the development of a slightly complex logic like the one that is behind this game.

The core of the game is based on two separate uses of the Reactive Extensions. From one side I have a main loop that is based on a frequent timeout that in a complete version of the game could be used to change the game speed. In this version it is set to 75 milliseconds. Every time the timeout is elapsed I move forward the Snake of one position saved in two variables XDirection and YDirection. This variable can assume the values of 1 or -1 if the snake is moving along the direction and 0 if the snake is moving along the opposite direction.

Using this variables the GenerateWithTime method of the RX generate a stream of points that are the positions where the Snake have passed during its move. The length of the snake is determined by the TrailWhile method that evaluate the length using a third variable that is incremented every time the Snake eats a gem.

The other use of the RX is to handle the Manipulation events that are used to detect if the user touches the screen basing on this touches the XDirection and YDirection are updated to reflect the touch. As an example if when the snake is moving along the y axis like the screenshot the touch on the right side of the screen make change the direction to right and the touch on the left to left.

Here is the code of the main game loop:

Observable.GenerateWithTime(
    new Point(0, 0),
    p => this.IsRunning,
    p => p,
    p => TimeSpan.FromMilliseconds(75),
    p => this.NewPoint(p))
    .ObserveOnDispatcher()
    .TrailWhile(o => o > this.Length)
    .Subscribe(this.EvaluateAndDrawSnake);
 
private Point NewPoint(Point point)
{
    double x = point.X + XDirection;
    double y = point.Y + YDirection;
 
    if (x < 0) x = 22;
    if (x > 22) x = 0;
    if (y < 0) y = 36;
    if (y > 36) y = 0;
 
    return new Point(x, y);
}

The method EvaluateAndDraw is the part of the code that check when the snake eats itself to end the game and then redraw the snake on the screen. Here is the management of the screen:

Observable.FromEvent<ManipulationStartedEventArgs>(
    ev => this.ManipulationStarted += ev,
    ev => this.ManipulationStarted -= ev)
    .Select(
    o =>
    {
        return new
        { 
            X = Math.Sign(o.EventArgs.ManipulationOrigin.X - 240), 
            Y = Math.Sign(o.EventArgs.ManipulationOrigin.Y - 400) 
        };
    })
    .Subscribe(
    o =>
    {
        if (this.XDirection != 0 && this.YDirection == 0)
        {
            this.XDirection = 0;
            this.YDirection = o.Y != 0 ? o.Y : this.YDirection;
        }
        else if (this.XDirection == 0 && this.YDirection != 0)
        {
            this.XDirection = o.X != 0 ? o.X : this.XDirection;
            this.YDirection = 0;
        }
    });

The following link lets you download the complete source of the example. My highest score is 510. Have a good game.

Download: SLPG.ReactiveSnake.zip (140kb)