3. Simulating the Accelerometer in the Emulator
If you want to work with an accelerometer in the
Windows Phone 7 emulator, there is an obvious problem: the emulator has
no access to an accelerometer so always returns a vector containing the
values (0, 0, - 1). This makes it very hard to test your game unless on
a real device.
There have been various clever workarounds for this
problem suggested on the Internet (including hooking a Nintendo Wii
controller up to the PC and using its accelerometer), but they involve
a fairly considerable amount of effort to get working. We can take
advantage of a couple of much simpler options: use the touch screen to
simulate accelerometer data or use the keyboard to simulate rotation of
the device.
Either way, we want to ensure that this happens only
when running on the emulator, not on a real device. Microsoft has
provided a way to determine whether we are running in the emulator, and
it can be accessed by adding a reference to the Microsoft.Phone DLL. Once this has been added, we can query the Microsoft.Devices.Environment.DeviceType property, which will return either Device or Emulator as appropriate.
Having determined that we are running in the
emulator, we can now apply either of the two accelerometer simulation
methods described. The first of these, using the touch screen, is shown
in Listing 6.
It calculates the position of the touch point across the width and
height of the screen and uses this position to derive a value for the AccelerometerData vector. It sets just the x and y axis values, leaving the z value set permanently at 0.
Example 6. Simulating the accelerometer using touch screen input
void AccelerometerReadingChanged(object sender, AccelerometerReadingEventArgs e) { if (Microsoft.Devices.Environment.DeviceType == Microsoft.Devices.DeviceType.Device) { AccelerometerData = new Vector3((float)e.X, (float)e.Y, (float)e.Z); } else {
// Use the touch screen to simulate the accelerometer float x, y; TouchCollection touches; touches = TouchPanel.GetState(); if (touches.Count > 0) { x = (touches[0].Position.X - Window.ClientBounds.Width / 2) / (Window.ClientBounds.Width / 2); y = -(touches[0].Position.Y - Window.ClientBounds.Height / 2) / (Window.ClientBounds.Height / 2); AccelerometerData = new Vector3(x, y, 0);
} } }
|
This code provides an intuitive method for providing
simulated accelerometer data, but has the problem that it requires
touch screen interaction, which could interfere with other parts of
your game that rely on the touch screen. The second method avoids this
problem by using the keyboard cursor keys. They are much less likely to
be used in a game and so reduce the likelihood of interference.
The problem with using the cursor keys like this is
that it is much harder to keep track of which way the simulated
accelerometer vector is pointing. For this reason it is very useful to
add a text object to the game and use it to display the content of the AccelerometerData
property on the screen. You can then refer to this in order to get your
bearings. The keyboard-based simulation code is shown in Listing 7.
Example 7. Simulating the accelerometer using touch keyboard input
void AccelerometerReadingChanged(object sender, AccelerometerReadingEventArgs e) { if (Microsoft.Devices.Environment.DeviceType == Microsoft.Devices.DeviceType.Device) { AccelerometerData = new Vector3((float)e.X, (float)e.Y, (float)e.Z); } else { // Use the cursor keys on the keyboard to simulate the accelerometer Vector3 accData = AccelerometerData; if (Keyboard.GetState().IsKeyDown(Keys.Left)) accData.X -= 0.05f; if (Keyboard.GetState().IsKeyDown(Keys.Right)) accData.X += 0.05f; if (Keyboard.GetState().IsKeyDown(Keys.Up)) accData.Y += 0.05f; if (Keyboard.GetState().IsKeyDown(Keys.Down)) accData.Y -= 0.05f; // Ensure that the data stays within valid bounds of −1 to 1 on each axis accData.X = MathHelper.Clamp(accData.X, −1, 1); accData.Y = MathHelper.Clamp(accData.Y, −1, 1); // Put the vector back into the AccelerometerData property AccelerometerData = accData; } // Display the accelerometer data in a text object _accText.Text = "Accelerometer data: " + AccelerometerData.X.ToString("0.000") + ", " + AccelerometerData.Y.ToString("0.000") + ", " + AccelerometerData.Z.ToString("0.000"); }
|
Both of these mechanisms are present in the Accelerometer example project, though the keyboard mechanism is commented out. Try swapping between them to see how each one feels.