MOBILE

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.

<phone:PhoneApplicationPage
x:Class="MoveBallDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
shell:SystemTray.IsVisible="True">


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">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="24,24,0,12">
<TextBlock x:Name="ApplicationTitle" Text="MoveBallDemo"
Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
<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"
Canvas.Top="222"/>
</Canvas>
</Grid>

</phone:PhoneApplicationPage>

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()
{
InitializeComponent();

SupportedOrientations = SupportedPageOrientation.Portrait;

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

_ac = new Accelerometer();
_ac.ReadingChanged += new
EventHandler<AccelerometerReadingEventArgs>(ac_ReadingChanged);
}

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();

}
_ac.Start();
}

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

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.

Other  
  •  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