MOBILE

Windows Phone 7 : Reading the Accelerometer (part 1) - Initializing the Accelerometer, Using the Accelerometer Data

9/23/2013 9:25:16 PM

An accelerometer is a device contained within the phone that can report the device's current orientation or position. In other words, it can tell if the device is lying flat on a desk, being held upright, rotated onto its side, or is in any position in between. Accelerometers have become common in mobile devices over the last couple of years and are a required component of all Windows Phone 7 devices, so they can be used in games as another interesting input device.

This information presents all sorts of opportunities for games. If we can tell the angle of the device, we can use it as a control mechanism. Instead of touching the screen or pressing a button to move objects on the screen, the player can simply tilt the device in whatever direction is needed to affect the gameplay.

In this section we will investigate how to read and interpret the data from the Windows Phone 7 device accelerometer. The code presented here can be found in the Accelerometer example project, an image from which is shown in Figure 1.

Figure 1. Rolling a ball around the screen using the accelerometer

1. Initializing the Accelerometer

The classes that provide access to the accelerometer are not actually part of XNA, but are instead provided via one of the standard Windows Phone 7 libraries: Microsoft.Devices.Sensors. In order to access it, you must first add a reference to it.

Once the reference has been added, we can add a using directive, as shown in Listing 1, to save having to fully qualify the namespace each time we want to refer to the sensor classes.

Example 1. Adding a using directive for the Microsoft.Devices.Sensors namespace
using Microsoft.Devices.Sensors;

Next we declare a class-level variable to hold an instance of the Accelerometer object, as shown in Listing 1. This will be created during initialization and will remain for the duration of the game.

Example 2. Declaring a class variable to hold the Accelerometer object instance
private Accelerometer _accelerometer;

With these code sections in place, we can now instantiate and initialize the Accelerometer object inside the game's Initialize method. The code required for this is shown in Listing 2. After creating an instance, the code adds an event handler for the accelerometer's ReadingChanged event. Unlike touch panel and keyboard input, the accelerometer provides data updates using an event rather than allowing us to poll it. In the event we can store the most recent reading, however, and then query this on demand whenever we want, which gives just the same effect from the perspective of our game code.

Once the object has been created and set up, we call its Start method so that it begins feeding information to us.

Example 2. Instantiating and initializing the accelerometer object
// Instantiate the accelerometer
_accelerometer = new Accelerometer();
// Add an event handler
_accelerometer.ReadingChanged += AccelerometerReadingChanged;
// Start the accelerometer
_accelerometer.Start();

Finally we need to provide the AccelerometerReadingChanged event handler that we provided to the accelerometer object. This is very simple and is shown in Listing 3. The accelerometer provides three values, consisting of a reading for the X, Y, and Z axes. These are stored into a Vector3 structure stored in the class-level variable _accelerometerData.

Example 3. Storing the data from the accelerometer each time it provides an updated reading.
void AccelerometerReadingChanged(object sender, AccelerometerReadingEventArgs e)
{
AccelerometerData = new Vector3((float)e.X, (float)e.Y, (float)e.Z);
}



2. Using the Accelerometer Data

We can now read the x, y, and z axis readings from the accelerometer. Together they provide a reading of the acceleration of the device relative to freefall. What exactly does that mean?

First, let's look at the vector itself. It contains three properties that can be used to interrogate the device orientation: X, Y, and Z. Each of them is a float value that represents the movement of the device in the real world in the appropriate axis. If the device is lying flat and face up on a table, the values returned for the vector will be approximately as follows:

X = 0, Y = 0, Z = −1

The value - 1 represents the full force of gravity applied along the appropriate axis. The x axis represents the direction between the left and right edges of the device, the y axis the direction between the top and bottom of the device, and the z axis the direction between the front and back of the device. As gravity is pulling the device toward its back while it lies flat on the table, the accelerometer shows a value of - 1 on the z axis (-1 on this axis represents the back of the device, whereas +1 represents the front of the device, and this is what would appear if the device were put face down on the table).

This z value reading is very useful because it means we always get a movement reading relative to the force of gravity, even when the device is not in motion. By working out which of the x, y, and z axes the reading applies to, we can therefore work out which way up the device is.

As you've seen, with the device face up, we get a negative reading on the z axis. With the device upright, the accelerometer returns a value of - 1 on the y axis (and upright but upside down, it returns the opposite value, 1). Turn the device on its side and you'll get a value between - 1 and 1 on the x axis, depending on which way the device has rotated. All orientations between these extremes return values spread across the three axes.

Because our screen is only two-dimensional, we can for the most part ignore the value on the z axis. We can instead read out the x and y values and apply them as acceleration to objects in the game. When the device is flat on the desk, x and y are 0, so our objects don't move at all. Tip the device up, and the x and y values change based on the tilt angle, providing acceleration for our objects—the steeper the tilt, the faster the acceleration.

The Accelerometer project in the accompanying downloads includes all the code required to move a ball around on the screen under control of the accelerometer. It also displays the vector values on the screen, so you can easily see the data coming back from the accelerometer as you change the orientation of your device.

The project contains a single game object: BallObject, which is mostly just the same as the objects we have looked at in earlier projects. The ball offers a Velocity vector, and in its Update method it adds this to the ball position, bouncing if the edges of the screen are hit.

The one new addition is the use of the accelerometer data within the Update code. It retrieves the data from the game class, adds the accelerometer's x axis reading to its horizontal velocity and subtracts its y axis reading from its vertical velocity, as shown in Listing 4. This is what makes the ball move in response to the device being rotated. As you can see, we observe only the x and y axis readings because the z axis doesn't do anything useful in this 2D environment.

Example 4. Applying the accelerometer data to the ball velocity
// Add the accelerometer vector to the velocity
Velocity += new Vector2(_game.AccelerometerData.X, -_game.AccelerometerData.Y);


You now have all the code that is required to simulate a ball rolling around a virtual desktop. Try running the project on a device and see how the ball reacts to the device being tilted. Observe the way the ball moves faster when the device is tilted at a steeper angle.

There are a couple of additional things to be aware of when using the accelerometer. First, unlike touch input, the returned vector is not automatically rotated to match the orientation of the screen. The values will be completely unaffected by rotating the device, so you will have to compensate for this in your game code if your game plays in a non-portrait orientation.

Second, if your game has been configured to allow multiple orientations , XNA will automatically rotate your display whenever it detects that the device has been rotated to a different orientation. This might be useful for non-accelerometer-based games, but if the screen flips upside down every time the player tries to roll a ball toward the top of the screen, it will quickly become very annoying. To cure this, ensure that you explicitly specify a single supported orientation when working with the accelerometer.

Other  
  •  Windows Phone 7 : Reading the Keyboard and Text Input (part 2) - Prompting the User to Enter Text
  •  Windows Phone 7 : Reading the Keyboard and Text Input (part 1) - Using a Hardware Keyboard
  •  Galaxy Note II vs Galaxy Mega
  •  It's Not Finished Yet!
  •  Looking For Advice On Choosing The Best Phone?
  •  Windows Phone 8 : Working with the Camera (part 3) - Camera Lens App
  •  Windows Phone 8 : Working with the Camera (part 2) - Raw Hardware Access
  •  Windows Phone 8 : Working with the Camera (part 1) - Using the PhotoCamera Class
  •  BlackBerry Development : Pushing Data to External Users - Web Signals (part 6) - Building a Web Signal - Unsubscribing from a Subscription
  •  BlackBerry Development : Pushing Data to External Users - Web Signals (part 5) - Building a Web Signal - Requesting the Status of a Subscription
  •  
    Top 10
    Review : Sigma 24mm f/1.4 DG HSM Art
    Review : Canon EF11-24mm f/4L USM
    Review : Creative Sound Blaster Roar 2
    Review : Philips Fidelio M2L
    Review : Alienware 17 - Dell's Alienware laptops
    Review Smartwatch : Wellograph
    Review : Xiaomi Redmi 2
    Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
    Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
    3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
    REVIEW
    - First look: Apple Watch

    - 3 Tips for Maintaining Your Cell Phone Battery (part 1)

    - 3 Tips for Maintaining Your Cell Phone Battery (part 2)
    VIDEO TUTORIAL
    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
    Popular Tags
    Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8