Jun 27

Last weekend was about getting my simple game engine working on Windows Phone 7 and showing off some of Diane Leeper’s artwork for Popper 2. This weekend was about getting a page together to choose one of the great new themes. I decided to use a pivot control and started with the really nice free control available on codeplex:

http://phone.codeplex.com/

I was able to use this control pretty much straight out of the box, and from what I understand there will be a control released by Microsoft before the phone goes live so this one will probably be replaced by that.

One thing I failed to mention last time is that this game is being written in Silverlight and is leveraging XNA libraries for Vector2 and other data types as well as the XNA sound effect classes. I felt that for this game Silverlight gives me everything I need and I get to take advantage of cool controls like the pivot control. I also will be using data binding for the menu screens. The game screen itself uses a simple game engine that I’m working on that I plan to make work in both Silverlight and XNA so that I can more easily port the game to Xbox later.

I think the page turned out really well so with no more ado let’s get to the screenshots:

 

SNAGHTML18d0b50e 

SNAGHTML18d14d95

SNAGHTML18d20224

SNAGHTML18d28dc0

SNAGHTML18d3039a

Jun 22

Some of you may know that I released Dr. Popper on Xbox Live Independent games in late 2008. It was based on a game that my daughter loved to play after school so I hoped others would like it as well. It’s a simple bubble popper game but deceptively requires some strategy to get big scores.

One of the issues with Dr. Popper was that it was full of “developer graphics” since I was a one person team on it. After meeting Diane Leeper at a users group meeting she agreed to create some new themes for Dr. Popper, but after some discussions I decided that it would be even better to create a sequel with some new game elements to create a game that was deserving of the great new graphics.

So a few months have gone by, and life has gotten in the way, but I’m glad to say that I am actively working on Popper 2 for the Windows Phone which will be followed by a version for Xbox.

You can find Diane’s blog here: http://42stars.com/blog/ and some more of her great work here: http://42stars.com/

Here are some screenshots of the new themes (text for the score and some buttons to follow).

SNAGHTML4192b256

SNAGHTML418f55f4

SNAGHTML41906b96

SNAGHTML418e0584

SNAGHTML4190cc3c

Apr 23

Source code: http://www.bluerosegames.com/spacerocks/spacerocks_11_start_level.zip

Things are coming along pretty well on displaying the asteroids, we have collection of Rock objects that are bound to an ItemsControl and we’re updating these in the game loop. The next step is to actually create the right amount of asteroids at the right locations to start the first level.

While we’re at it, we might as well create a NewGame method and handle the starting of all of the levels, not just the first one. The first level should start with 4 large asteroids, the second starts with 6, then 8, 10, 11, and every level after that is also 11. This is why people could rack up ridiculous scores on the game, after level 5 it doesn’t really get any harder.

In the Game constructor (for now, we’ll move this later) let’s replace the loops to add the test rocks with a call to a NewGame method:

public Game()
{
    InitializeComponent();
    rocksControl.DataContext = rocks;
    ship = new Ship();
    ship.Position = new Vector2(320,240);
    LayoutRoot.Children.Add(ship);
    NewGame();
}

Then in the NewGame methods we’ll reset the level, score, ship position, rotation, and velocity, and call a StaertLevel method:

int level = 0;
int score = 0;

void NewGame()
{
    ship.Position = new Vector2(320, 240);
    ship.Velocity = Vector2.Zero;
    ship.Rotation = 0;
    level = 0;
    score = 0;
    StartLevel();
}

The StartLevel method is going to need to create the correct number of rocks for the current level, and the rocks should be distributed along the edges of the screen randomly but evenly distributed.

void AddRock()
{
    Rock rock = new Rock(1, rand.Next(3));
    if (rand.Next(1000) < 480)
    {
        rock.Position = new Vector2(0, rand.Next(480));
    }
    else
    {
        rock.Position = new Vector2(rand.Next(640), 0);
    }
    float angle = (rand.Next(0, 360) / 180f) * MathHelper.Pi;
    rock.Velocity = RadiansToVector(angle) * rand.Next(20, 60);
    rocks.Add(rock);
}

void StartLevel()
{
    int rockCount = 4 + level * 2;
    if (rockCount > 11) rockCount = 11;
    for (int i = 0; i < rockCount; i++)
    {
        AddRock();
    }
}

There are a couple of things to point out here, first of all if set the rock count to some large number in the StartLevel method you can do some stress testing. On my system setting the rock count to 200 still performs pretty well, it gets a bit jittery at 500, so there shouldn’t be an issue with the smaller number of rocks we need to support for this game. Here is what it looks like with 200:

image

Now the next thing to point out is how we’re calculating the velocity of the rock. We can generate a random angle in radians and then convert this to a normalized vector and them multiply it by a random magnitude.

NOTE: There was a bug in the RadiansToVector method listed in step 7, it has been fixed and the correct version is here:

Vector2 RadiansToVector(float radians)
{
    return new Vector2(-(float)Math.Sin(radians), -(float)Math.Cos(radians));
}

There is another option for calculating a vector from a rotation and if you aren’t up to speed on your high school trigonometry the XNA framework (or SilverSprite in our case) can help. Consider this alternate version of RadiansToVector:

Vector2 RadiansToVector(float radians)
{
    Vector2 v = Vector2.Transform(new Vector2(0, 1), Matrix.CreateRotationZ(radians));
    v.Y = -v.Y;
    return v;
}

What we’re doing here is creating a rotation matrix and then transforming a normalized vector using this rotation matrix. We then need to take the negative of the Y component of the vector to account for the fact that screen coordinates for the Y axis are reversed.

We rotate around the Z axis since this is the axis that is perpendicular to the screen. If we take a look at the matrix that is generated by calling the CreateRotationZ method things become a bit clearer about how this works. From the Wikipedia page on rotation matrixes:

 

You can see that the sin and cos are still being used, they’re just being put into the matrix before being applied in the transformation of the vector, so the same math is being done that was being done before. Take a look at the other static methods that are available on the Matrix type, they can be very useful for game development.

Here is how the screen now looks a few seconds after the game starts:

image

Apr 19

Source code: http://www.bluerosegames.com/spacerocks/spacerocks_10_rocks_2.zip

In the last step we created a Rock sprite class which allowed us to create asteroids of varying sizes and 3 different shape patterns. To test this we hardcoded a couple of loops to test creating asteroids of the 3 desired sizes and 3 patterns and added them directly to the root canvas.

This isn’t desirable for our game since we will need to track which asteroids are currently being displayed and update them in the game loop based on velocity and check for collisions and whatever else we need to do. One thing we could do is keep a list of Rock objects and add each added rock to both the root canvas and this list. Then when we want to get rid of a rock we can remove it from both the list and the root canvas. This is a little messy so there is a batter way. We can use data binding and an ItemsControl so that we only have to keep track of the asteroids in one place.

An ItemsControl is the building block that the ListBox is based on, and by default displays a list of items in a vertical StackPanel. So how does this help us with our asteroids? Well the StackPanel is only the default container for ItemsControl elements and you can change this to use any kind of panel, including a Canvas. First in the Game.xaml let’s add an ItemsControl as follows:

<Canvas x:Name="LayoutRoot" Background="Black" Width="640" Height="480">
    <Canvas.Clip>
        <RectangleGeometry Rect="0,0,640,480"/>
    </Canvas.Clip>
    <ItemsControl x:Name="rocksControl" ItemsSource="{Binding}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</Canvas>

By setting the ItemsSource to {Binding} the list of elements to display will come from the DataContext of the ItemsControl. Make sure you save the XAML file so that the code behind can know about the new ItemsControl.  Now let’s add some code to the code behind of the Game class to set the data context. First we need a list of rocks. Let’s make this of type ObservableCollection. This way the ItemsControl will automatically be notified if the collection changes. Declare a new field in the Game class:

System.Collections.ObjectModel.ObservableCollection<Rock> rocks =     new System.Collections.ObjectModel.ObservableCollection<Rock>();

And then in the constructor after the InitializeComponent method we can set the DataContext of the ItemsControl to this collection:

public Game()
{
    InitializeComponent();
    rocksControl.DataContext = rocks;
    ship = new Ship();
    ship.Position = new Vector2(320,240);
    LayoutRoot.Children.Add(ship);
    for (int i = 0; i < 3; i++)
    {
        double scale=1;
        for (int j = 0; j < 3; j++)
        {

            Rock rock = new Rock(scale, i);
            rock.Position = new Vector2(30 + i * 60, 30 + j * 60);
            LayoutRoot.Children.Add(rock);
            scale /= 2;
        }
    }
}

Now instead of adding new rocks to the Children of the LayoutRoot we can add them to the rocks collection.

for (int i = 0; i < 3; i++)
{
    double scale=1;
    for (int j = 0; j < 3; j++)
    {

        Rock rock = new Rock(scale, i);
        rock.Position = new Vector2(30 + i * 60, 30 + j * 60);
        rocks.Add(rock);
        scale /= 2;
    }
}

And if you run this you should see the same results we had before. Let’s now take this a step further and after the setting of the rock’s Position we can also set its Velocity.

rock.Velocity = new Vector2(rand.Next(-30, 30), rand.Next(-30, 30));

For this Velocity to do anything, we need to also call the Rock sprites’ Update method from the game loop. After the ship.Update method call add the following:

foreach (Rock rock in rocks)
{
    rock.Update(seconds);
}

Now if you run the game again you should see the asteroids move off in random directions.

image

By simply adding or removing asteroids from the rocks collection we can make new asteroids appear or remove existing rocks. There is some extra overhead from implementing and ObservableCollection and using data binding but it’s much cleaner so you should do what’s best for your game and if this is an unacceptable performance hit then you can handle the adding and removing of sprites from the canvas yourself.

In the next step we’ll look at initializing the correct number of asteroids for the start of the first level.

Apr 18

Source code: http://www.bluerosegames.com/spacerocks/spacerocks_9_rocks.zip

Everything we’ve done so far has to do with the ship, but there is some good plumbing in place to get the asteroids themselves going, and that’s going to be our next step. For now we’ll just get some asteroids on the screen. In later steps we’ll worry about placement, movement, and collisions.

Just like with the ship, we can create a Silverlight Templated Control for the asteroids and then change it to inherit from Sprite. By inheriting from Sprite we’ll get support for movement based on a velocity and wrapping at the edges of the screen. So create a new Silverlight Templated Control from the new item wizard and call it Rock.cs. As we previously saw with the ship, this creates a new entry in Generic.xaml which contains the control template for the Rock sprite. You can edit this in Blend or by hand to make it look how you want. The asteroids are a bit different from the ship since there are 3 different shapes for the asteroids. Even the smaller versions (asteroids come in large, medium, and small) have those same 3 shapes. You could create a different Silverlight Templated Control for each variation and have them all inherit from Rock (which inherits from Sprite) but since they are so similar we can do a little visual magic instead.

What we can do is define the visuals for each of the asteroid shapes and put them all into the Rock template. Then in OnApplyTemplate we can show one and hide the others. First the Rock XAML template:

<Style TargetType="local:Rock">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:Rock">
                <Canvas x:Name="LayoutRoot" Width="60" Height="60" RenderTransformOrigin=".5,.5">
                    <Path x:Name="rock0"
                        Data="M-4.125,9.75 L9.375,-4.25 L24.645,2.67 L37.875,-1.75 L49.375,10.75 L40.875,16.75 L50.875,27.25 L38.625,46 L14.125,41 L5.875,45.5 L-2.875,37 L2.375,24.25 z" Stretch="Fill" Stroke="White" UseLayoutRounding="False" Margin="3,3,1,5.75" StrokeThickness="2"/>
                    <Path x:Name="rock1"
                        Data="M-6.75,19.75 L9.375,-4.25 L31.75,-5 L49.375,10.75 L49.75,29.25 L32.5,49.75 L19.25,51.5 L19.35429,30 L5.875,45.5 L-5.5,30.25 L6,24 z" Stretch="Fill" Stroke="White" UseLayoutRounding="False" StrokeThickness="{Binding StrokeThickness, ElementName=rock0}" Margin="0.375,2.25,2.125,0.25"/>
                    <Path x:Name="rock2"
                        Data="M-4.125,9.75 L11.5,9.5 L4.75,0 L26,-5.75 L49.375,10.75 L51,19 L32.75,26.25 L46.75,36 L40,45.75 L31,38.5 L5.75,46.25 L-6.5,27 z" Stretch="Fill" Stroke="White" UseLayoutRounding="False" StrokeThickness="{Binding StrokeThickness, ElementName=rock0}" Margin="0.625,1.5,0.875,5.5"/>
                </Canvas>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

By naming each of the paths we can find the one we want to show in the OnApplyTemplate method. Note that rock0 specifies a StrokeThickness and the other two use element to element binding to reference the rock0 StrokeThickness. This means that if we want to set the StrokeThickness we only have to set it one place. The reason we need this will become evident soon.

Now for the code for the Rock, we can modify it as follows:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace SpaceRocks
{
    public class Rock : Sprite
    {
        int rockType = 0;

        public double Scale { get; private set; }

        public Rock() : this(1, 0)
        {
        }

        public Rock(double scale, int rockType)
        {
            this.DefaultStyleKey = typeof(Rock);
            Scale = scale;
            this.rockType = rockType;
        }

        public override void OnApplyTemplate()
        {
            var rock0 = this.GetTemplateChild("rock0") as Path;
            var LayoutRoot = this.GetTemplateChild("LayoutRoot") as Panel;
            LayoutRoot.Width = 60 * Scale;
            LayoutRoot.Height = 60 * Scale;
            ScaleTransform scaleTransform = new ScaleTransform();
            scaleTransform.ScaleX = scaleTransform.ScaleY = Scale;
            LayoutRoot.RenderTransform = scaleTransform;
            rock0.StrokeThickness = 2 / Scale;
            var currentRock = this.GetTemplateChild(string.Format("rock{0}", rockType)) as FrameworkElement;
            foreach (FrameworkElement element in LayoutRoot.Children)
            {
                if (element == currentRock)
                {
                    element.Visibility = Visibility.Visible;
                }
                else
                {
                    element.Visibility = Visibility.Collapsed;
                }
            }
            base.OnApplyTemplate();
        }
    }
}

The scale value allows us to handle the 3 sizes of rocks. The large rock will have a scale of 1, the medium a scale of .5, and the small a scale of .25. So for each smaller size of rock the scale changes by a factor of 2. We need to set the width and height of the root element so that the base Sprite class centers the sprite properly at different scales. Then we can actually scale the visuals using a ScaleTransform.

If we just used a ScaleTransform to make the rock smaller, the StrokeThickness would also be made narrower based on the scale. To make the StrokeThickness consistent at all scales we need to divide the desired thickness by the current scale. This will make the asteroid always have a final stroke thickness of 2 no matter what the scale. By setting the StrokeThickness on rock0 the other two shapes will also get that value through data binding.

The rockType value can be 0, 1, or 2 and will be passed in when the asteroid is created. Based on this, we’ll find the desired element to show in the template and hide the others. Finally we need to call the OnApplyTemplate method of the base class because it does some important things related to centering the sprites based on the width and height of the sprite.

To test out the rock types and sizes, let’s just add some test code to the Game constructor for now. This code will draw all combinations of sizes and shapes, 9 in total.

for (int i = 0; i < 3; i++)
{
    double scale=1;
    for (int j = 0; j < 3; j++)
    {
        Rock rock = new Rock(scale, i);
        rock.Position = new Vector2(30 + i * 60, 30 + j * 60);
        LayoutRoot.Children.Add(rock);
        scale /= 2;
    }
}

And this is the resulting output:

image

In the next step we’ll work on generating the asteroids needed for the start of a level.

Apr 17

I have gone back and converted and recompiled all of the solutions for the Space Rocks series to use Silverlight 4 and Visual Studio 2010. This required no code changes and all of the content for the steps so far is still valid. The links for source code in each of the steps points to the new versions.

Congratulations to the Silverlight team on the new release and look for more parts to this series soon.

Apr 10

Source code: http://www.bluerosegames.com/spacerocks/spacerocks_8_hyperspace.zip

Ok so one more quick keyboard handling related post for now, and then we’ll get into displaying some more sprites. In the original Asteroids game there are four buttons, rotating left and right, firing a shot, and hyperspace. We’ll deal with shooting after we have something to shoot at, but let’s at least take care of hyperspace.

The behavior of hyperspace is that the ship stops completely and is randomly repositioned on the screen. It is possible for the jump to hyperspace to put the ship smack dab inside an asteroid or a flying saucer which makes it a bit more risky but also easier to code. All we need to do is set the velocity to 0 and generate a random new position. We’ll also put in some logic to make sure that the ship moves at least 100 pixels. First let’s add a DoHyperspace method to the Game class:

Random rand = new Random();

void DoHyperspace()
{
    ship.Velocity = Vector2.Zero;
    while (true)
    {
        Vector2 newPosition = new Vector2(rand.Next(50, 590), rand.Next(50, 430));
        if (Vector2.Distance(newPosition, ship.Position) > 100)
        {
            ship.Position = newPosition;
            break;
        }
    }
}

Using the Vector2.Distance static method is an easy way of determining how far apart two locations are, and we’ll use this again later when checking for collisions.

Now to call this method. In the GameLoop_Update method where we’ve been doing our other keyboard handling we can check to see if the down cursor or S buttons are pressed, and if so engage hyperspace. One other thing we’ll want to do is only engage hyperspace if the down button wasn’t pressed in the previous iteration through the game loop. This will prevent us from hopping into hyperspace repeatedly until the button is released, and for the player to enter hyperspace again they will have to release the button and press it again.

To do this we will have a flag that indicates whether the down button was already pressed. Here is the flag declaration and the modified GameLoop_Update method:

 

bool downPressed = false;

private void GameLoop_Update(object sender, SilverArcade.SilverSprite.SimpleEventArgs<TimeSpan> e)
{
    double seconds = e.Result.TotalSeconds;
    KeyboardState keyState = Keyboard.GetState();
    if (keyState.IsKeyDown(Keys.Down) || keyState.IsKeyDown(Keys.S))
    {
        if (downPressed == false) DoHyperspace();
        downPressed = true;
    }
    else
    {
        downPressed = false;
    }
    if (keyState.IsKeyDown(Keys.Left) || keyState.IsKeyDown(Keys.A))
    {
        ship.Rotation += (float)(rotationSpeed * seconds);
    }
    else if (keyState.IsKeyDown(Keys.Right) || keyState.IsKeyDown(Keys.D))
    {
        ship.Rotation -= (float)(rotationSpeed * seconds);
    }
    if (keyState.IsKeyDown(Keys.Up) || keyState.IsKeyDown(Keys.W))
    {
        UpdateShipVelocity(seconds);
    }
    ship.Update(seconds);
}

So basically if down is pressed, we check to see if it was already pressed and if not, we do hyperspace. We then set the flag to indicate that down was already pressed. If down isn’t pressed we clear the flag so that next time it is pressed we’ll be able to run the hyperspace code again.

Now if you run the game and get up some speed and press the down key or the S key the ship should stop and reposition. If you release the key and press it again the process should repeat.

Mar 30

Source code: http://www.bluerosegames.com/spacerocks/spacerocks_7_moving_ship.zip

In the last step we added logic to rotate the ship based on key presses. Moving the ship isn’t that different but we need to do a little trigonometry to get it moving in the right direction. The first thing we need is to check for the up key being pressed. We’ll use this as the key press to fire the ship’s engines. Here is our game loop with the added check for the cursor up key (and the W key):

private void GameLoop_Update(object sender, SilverArcade.SilverSprite.SimpleEventArgs<TimeSpan> e)
{
    double seconds = e.Result.TotalSeconds;
    KeyboardState keyState = Keyboard.GetState();
    if (keyState.IsKeyDown(Keys.Left) || keyState.IsKeyDown(Keys.A))
    {
        ship.Rotation += (float)(rotationSpeed * seconds);
    }
    else if (keyState.IsKeyDown(Keys.Right) || keyState.IsKeyDown(Keys.D))
    {
        ship.Rotation -= (float)(rotationSpeed * seconds);
    }
    if (keyState.IsKeyDown(Keys.Up) || keyState.IsKeyDown(Keys.W))
    {
        UpdateShipVelocity(seconds);
    }
    ship.Update(seconds);
}

So when the up cursor key or W is pressed we’ll update the ship’s velocity by calling the UpdateShipVelocity method.This hasn’t been defined yet, so let’s define it:

float maxShipSpeed = 500;
float shipAcceleration = 100;

Vector2 RadiansToVector(float radians)
{
    return new Vector2(-(float)Math.Sin(radians), -(float)Math.Cos(radians));
}

void UpdateShipVelocity(double seconds)
{
    Vector2 normal = RadiansToVector(ship.Rotation);
    ship.Velocity += normal * (float)seconds * shipAcceleration;
    if (ship.Velocity.Length() > maxShipSpeed)
    {
        ship.Velocity = Vector2.Normalize(ship.Velocity) * maxShipSpeed;
    }
}

UPDATE: Fixed issue with RadiansToVector method. It was always using the ship’s rotation instead of using the passed in value.

The RadiansToVector method returns a normalized Vector2 based on the ship’s rotation in the direction that the ship is facing. Normalized means that if you calculate the length of the vector, the length would be 1. From the pythagorean theorem (remember that from high school math?) we know that the length of the vector is the square root of the sum of the squared of the X and Y component. This normalized vector can be calculated from taking the sine and the cosine of the angle of rotation (that trigonometry stuff I was talking about).

NOTE: To do the opposite and find the angle from the vector you can use the Math.Atan2 method.

We can then combine this direction vector with the elapsed time and the ship’s acceleration to calculate a change in velocity. We can add this to the current velocity to create a new velocity.

Finally we need a maximum speed for the ship, otherwise it could just go to ludicrous speed after a while. If the speed goes above the max, we can get the normal of this velocity vector (explained above) and multiply that by the max speed.

If you run the game now you should be able to move the ship.

Mar 28

Source code: http://www.bluerosegames.com/spacerocks/spacerocks_6_keyboard.zip

Your Silverlight game is probably going to need some way to get input, otherwise it won’t be much of a game. In web based games the two major forms of input are keyboard or mouse. In this step we’ll add keyboard input, but mouse input would be very similar.

In Silverlight, keyboard handling is event driven. An event fires when you press a key, and another fires when you release it. There are also events that fire when a key repeats from being held for a longer period of time. This isn’t really what a game needs. In a game typically you’re interested in whether a key is currently pressed. To help with this, the SilverSprite core library implements the XNA keyboard state classes. These classes handle the key up and key down events for you and let you check whether a key is currently pressed.

Let’s add keyboard handling for turning the ship. In the previous step we just rotated the ship every time the game loop executes. Instead let’s see if the left or right key is pressed and if so rotate in that direction. First we need a using statement in Game.xaml.cs for the key handler’s namespace:

using Microsoft.Xna.Framework.Input;

Then in the GameLoop_Update method we’ll add code to get the current keyboard state and use it to set the rotation speed:

double rotationSpeed = 4.75;

private void GameLoop_Update(object sender, SilverArcade.SilverSprite.SimpleEventArgs<TimeSpan> e)
{
    double seconds = e.Result.TotalSeconds;
    KeyboardState keyState = Keyboard.GetState();
    if (keyState.IsKeyDown(Keys.Left) || keyState.IsKeyDown(Keys.A))
    {
        ship.Rotation += (float)(rotationSpeed * seconds);
    }
    else if (keyState.IsKeyDown(Keys.Right) || keyState.IsKeyDown(Keys.D))
    {
        ship.Rotation -= (float)(rotationSpeed * seconds);
    }
}

We check for both Keys.Left and Keys.A (and Keys.Right and Keys.D) because some keyboards may not have cursor keys or they may be only available by pressing a control or function key. This way either will work, and W, A, S, and D are the commonly accepted keys for Up,  Left,  Down, and Right respectively.

Now if you run this the game might not respond to your key presses. This is because the Silverlight plug-in won’t have focus when the page loads. We’ll look at ways to make this happen in a later step but for now if you click on the game you will then be able to use the keyboard.

We’re not using mouse handling in this game, but if you wanted to you can get the mouse state in much the same way as keyboard handling works above:

MouseState mouseState = Mouse.GetState();
if (mouseState.LeftButton == ButtonState.Pressed)
{
}

The Mouse class also allows you to get the position of the mouse.

Mar 27

Testing a game in the Windows Phone emulator that uses the accelerometer can be tricky since that data can be hard to simulate. Peter Blois in his labyrinth sample uses mouse movement to simulate it, but this only allows for 2 directions of movement. This got me thinking about how we could better simulate the accelerometer, and I considered using an Xbox gamepad or other device but then realized I could use an actual accelerometer which is readily available and relatively affordable. You might also already have one. This accelerometer can be found inside the game controller for the Wii.

What makes the Wii controller even more attractive is that it communicates over Bluetooth and so can be hooked up to any PC with a Bluetooth adapter. Additionally Brian Peek put together a great library to access Wii controller data with .NET.

Since Windows Phone in the emulator doesn’t have access to this data, I created a simple console app that can get data off of the Wiimote and serve it up over HTTP. On the client side if starting the device accelerometer fails, the code will instead make requests to this HTTP server to get the accelerometer data.

There is some latency here because of the nature of making HTTP requests so if anyone has suggestions on reducing this latency please let me know.

You can download the source code for the console app and a modified version of Peter Blois’ labyrinth app that uses this accelerometer proxy code here:

http://www.bluerosesystems.com/wiimoteaccelerometersample.zip

Make sure to run the console app as administrator or you won’t be able to listen on the HTTP port. Note that this code is a quick sample and I’ll be working on a more robust version that I will post on Codeplex.

preload preload preload