Windows Phone 7 : Using Accelerometer Data to Move a Ball

1/29/2011 6:53:03 PM
You will learn to use the captured accelerometer data to do something more useful: moving the image of a ball as you tilt the phone left, right, forward, and back. This demo has many uses in helping you understand how to translate the user input of the accelerometer data and apply it to UI elements. Figure 1 displays the basic UI of the MoveBallDemo.
Figure 1. MoveBallDemo UI

1. Creating the MoveBall Project

To set up the CaptureAccelerometerData project, follow the steps you've used for previous examples in this book.

  1. Open Microsoft Visual Studio 2010 Express for Windows Phone on your workstation.

  2. Create a new Windows Phone Application by selecting File => New Project in the Visual Studio command menu. Select the Windows Phone Application template, name the application "MoveBallDemo," and click OK.

  3. In order to use the accelerometer, add an assembly reference to Microsoft.Devices.Sensors by right-clicking the References folder in Solution Explorer and choose Microsoft.Devices.Sensors from the Add Reference window.

2. Building the User Interface

You will be building the user interface using the XAML in Visual Studio. For building simple controls, it is faster to work with the XAML code. Go to Solution Explorer, open MainPage.xaml, and replace the XAML you find there with the following codes.

2.1. Declaring the UI Resources

The namespaces you see here are typically declared by default when you first create the Windows Phone project, and the namespaces like xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" will allow you to add common Windows Phone controls.

FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"

2.2. Building the Main Page and Adding Components

The UI consists of Start and Stop buttons for stopping and starting the accelerometer and a ball that moves as the Windows Phone is tilted left, right, forward, and backward.

<Grid x:Name="LayoutRoot" Background="Transparent">
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>

<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="24,24,0,12">
<TextBlock x:Name="ApplicationTitle" Text="MoveBallDemo"
Style="{StaticResource PhoneTextNormalStyle}"/>
<Button Content="Start" Height="72"
HorizontalAlignment="Left" x:Name="btnStart"
VerticalAlignment="Top" Width="160"
Click="btnStart_Click" Margin="8,537,0,0"
Grid.Row="1" d:LayoutOverrides="HorizontalAlignment" />
<Button Content="Stop" Height="72"
HorizontalAlignment="Left" x:Name="btnStop"
VerticalAlignment="Top" Width="160"
Click="btnStop_Click" Margin="168,537,0,0"

Grid.Row="1" />

<Canvas x:Name="ContentGrid" Margin="0,8,8,0"
Grid.Row="1" HorizontalAlignment="Right"
Width="472" Height="479" VerticalAlignment="Top">
<Ellipse x:Name="ball" Canvas.Left="126"
Fill="#FF963C3C" HorizontalAlignment="Left"
Height="47" Stroke="Black" StrokeThickness="1"
VerticalAlignment="Top" Width="46"


Once you've loaded the XAML code, you should see the layout shown in Figure 2. Now it's time to animate the ball and add the sound effect by wiring up some events, which you'll do next.

Figure 2. MoveBall demo design view

3. Coding the Application

In Solution Explorer, open MainPage.xaml.cs and replace the code there with the following code C# code blocks.

3.1. Specifying the Namespaces

Begin by listing the namespaces the application will use. Notice our inclusion of Microsoft.Devices.Sensors that will allow us to start and stop Windows Phone's accelerometer.

using System;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Phone.Controls;
using Microsoft.Devices.Sensors;

namespace MoveBallDemo
public partial class MainPage : PhoneApplicationPage

3.2. Initializing Variables

The variable _ac, an Accelerometer object, will be used to start and stop the sensor, and retrieve x, y, z and time value. Also notice the ReadingChanged event, which sends the captured accelerometer data to be displayed in the UI. Also the starting position of the ball is set to the center of the canvas where the ball is placed.

private Accelerometer _ac;

public MainPage()

SupportedOrientations = SupportedPageOrientation.Portrait;

ball.SetValue(Canvas.LeftProperty, ContentGrid.Width / 2);
ball.SetValue(Canvas.TopProperty, ContentGrid.Height / 2);

_ac = new Accelerometer();
_ac.ReadingChanged += new

3.3. Handling Captured Accelerometer Data

Notice that here, as in the previous demo, you cannot directly change the UI elements upon receiving the accelerometer data because the accelerometer data comes from a different thread than the current UI thread. If you try to change the UI elements directly here, you will get an "Invalid cross-thread access" error. In order to overcome this problem, you must use the Dispatcher in the current UI thread, as shown in the following code.

private void ac_ReadingChanged(object sender, AccelerometerReadingEventArgs e)
Deployment.Current.Dispatcher.BeginInvoke(() => MyReadingChanged(e));

3.4. Applying Captured Accelerometer Data to the Ball

The following code achieves the behavior where if the phone is tilted in vertically with the display facing toward you, based on the algorithm specified in the method, the ball will fall straight very fast. But if you tilt the phone slightly while the display is facing up, the ball will slowly slide to the direction in which the phone is tilted.

private void MyReadingChanged(AccelerometerReadingEventArgs e)
double distanceToTravel = 2;
double accelerationFactor = Math.Abs(e.Z) == 0 ? 0.1 : Math.Abs(e.Z);
double ballX = (double)ball.GetValue(Canvas.LeftProperty) +
distanceToTravel * e.X / accelerationFactor;
double ballY = (double)ball.GetValue(Canvas.TopProperty) -
distanceToTravel * e.Y / accelerationFactor;

if (ballX < 0)
ballX = 0;
else if (ballX > ContentGrid.Width)
ballX = ContentGrid.Width;

if (ballY < 0)
ballY = 0;
else if (ballY > ContentGrid.Height)
ballY = ContentGrid.Height;

ball.SetValue(Canvas.LeftProperty, ballX);
ball.SetValue(Canvas.TopProperty, ballY);

3.5. Adding Start and Stop Button Events

Implement the button event for stopping and starting the accelerometer.

private void btnStart_Click(object sender, RoutedEventArgs e)
if (_ac == null)
_ac = new Accelerometer();


private void btnStop_Click(object sender, RoutedEventArgs e)
if (_ac == null)
_ac = new Accelerometer();

4. Testing the Finished Application

To test the finished application, press F5. Remember to choose to run the application on a Windows Phone 7 device, as shown in Figure 6-15 Once the application runs on the Windows Phone, click the Start button. Tilt the phone and watch the ball move in the direction the phone is being tilted.

  •  Server-Side Browser Detection and Content Delivery : Mobile Detection (part 4) - Device Libraries
  •  Server-Side Browser Detection and Content Delivery : Mobile Detection (part 3) - Transcoders
  •  Server-Side Browser Detection and Content Delivery : Mobile Detection (part 2) - Detecting the Context
  •  Server-Side Browser Detection and Content Delivery : Mobile Detection (part 1) - HTTP
  •  Using Windows Phone 7 Technologies : Retrieving Accelerometer Data (part 2)
  •  Using Windows Phone 7 Technologies : Retrieving Accelerometer Data (part 1)
  •  Using Windows Phone 7 Technologies : Understanding Orientation and Movement
  •  Programming the Mobile Web : HTML 5 (part 4) - Client Storage
  •  Programming the Mobile Web : HTML 5 (part 3) - Offline Operation
  •  Programming the Mobile Web : HTML 5 (part 2) - The canvas Element
  •  Programming the Mobile Web : HTML 5 (part 1)
  •  Windows Phone 7 : Submitting Your First Windows Phone Application to the Windows Phone Marketplace
  •  Windows Phone 7 : Packaging, Publishing, and Managing Applications
  •  Mobile Application Security : Windows Mobile Security - Development and Security Testing (part 3)
  •  Mobile Application Security : Windows Mobile Security - Development and Security Testing (part 2)
  •  Mobile Application Security : Windows Mobile Security - Development and Security Testing (part 1)
  •  Programming the Mobile Web : Mobile Rich Internet Applications (part 2) - JavaScript Mobile UI Patterns
  •  Programming the Mobile Web : Mobile Rich Internet Applications (part 1) - JavaScript UI Libraries
  •  Windows Mobile Security - Kernel Architecture
  •  Windows Mobile Security - Introduction to the Platform
    Top 10
    Algorithms for Compiler Design:
    Collaborating Within an Exchange Server Environment Using Microsoft Office SharePoint Server 2007 : Customizing and Developing MOSS Sites
    IIS 7.0 : Managing Configuration - Sharing Configuration Between Servers
    Algorithmic Run Time
    SQL Server 2008 : Explaining Advanced Query Techniques - Applying Ranking Functions (part 2) - Using RANK, DENSE_RANK and NTILE
    Determine Your Need for Server Core
    Backing Up the Exchange Server 2010 Environment : Understanding the Importance of Backups & Establishing Service Level Agreements
    Advanced ASP.NET : The Entity Framework (part 3) - Handling Errors & Navigating Relationships
    Establishing Mobile Connections in Vista
    Windows Phone Application Platform
    Most View
    Combine Multiple Events into a Single Event
    Algorithms for Compiler Design: Implementation
    Leveraging and Optimizing Search in SharePoint 2010 : Uninstalling FAST Search Server 2010 for SharePoint
    Understanding the Role of ASP.NET View State
    Designing and Configuring Unified Messaging in Exchange Server 2010 : Unified Messaging Architecture (part 3)
    WCF Services : Versioning
    Windows 7 : Indexing Your Computer for Faster Searches (part 3) - Optimizing File Properties for Indexing
    Programming .NET Components : Visual Studio 2005 and Security
    Mobile Application Security : SymbianOS Security - Permissions and User Controls
    Programming .NET Security : Programming Cryptographic Keys (part 3) - Key Exchange Formatting
    The SQL Programming Language : Complex Queries and Join Queries (part 1)
    Filtering Out Evil with Firewalls (part 2)
    Creating a Development Provisioning Profile on iPhone
    Parallel Programming with Microsoft .Net : Dynamic Task Parallelism - The Basics
    Permissions: Extending the .NET Framework
    Accessing XML Data in Silverlight
    What is compilation?
    jQuery 1.3 : Developing plugins - Adding jQuery Object Methods
    SQL Azure : Managing a Shard (part 1) - Managing Exceptions & Managing Performance
    High Availability in Exchange Server 2010 : Exchange Server database technologies