MOBILE

XNA Game Studio 4.0 : Windows Phone Sensors and Feedback (part 1) - Acceleration Data using the Accelerometer

8/14/2012 5:44:16 PM
Now we talk about APIs that are specific for Windows Phone devices. These APIs are part of the Microsoft.Devices.Sensors and System.Device.Location namespaces and require that you add a reference to your project. To use the APIs, perform the following steps for your game:

1.
Locate the Solution Explorer in Visual Studio.

2.
Right-click your project and select Add Reference (see Figure 1).
Figure 1. Project right-click menu displaying the add reference

3.
Locate and select the System.Device assembly from the list of assemblies under the .Net tab, and press Add.

4.
Repeat Steps 1, 2, and 3 to add the Microsoft.Devices.Sensors assembly.

5.
Repeat Steps 1, 2, and 3 to add the Microsoft.Phone assembly.

6.
At the top of code files, include the following lines of code after the existing using statement:

using Microsoft.Devices.Sensors;

using System.Device.Location;

Now you are ready to use all of the great sensors and location services that are available on Windows Phone devices. These include the accelerometer to read the acceleration changes that occur to the phone, location services to enable you to determine the phone’s position on the planet, and APIs to cause the phone to vibrate.

Because the following APIs are specific to Windows Phone devices, they are not available on all of the other platforms supported by XNA Game Studio. If you build a multiplatform game and want to share code, you need to write the Windows Phone-specific code blocks in #if WINDOWPHONE blocks:

#if WINDOWS_PHONE
    // Your Windows Phone specific code
#endif

Acceleration Data using the Accelerometer

All Windows Phone devices provide access to an accelerometer sensor. An accelerometer is used to measure force changes to the phone device from gravity or by forces exerted by the user. The accelerometer sensor is sensitive enough to determine when the user tilts the device slightly. It also works great to detect when the user shakes or swings the phone.

Reading Acceleration Data

To read acceleration data, you need to construct a new instance of an Accelerometer. The Accelerometer class is used to start, stop, and read back changes that occur to the accelerometer while it is currently running. Create a member variable to store the Accelerometer in your game class:

Accelerometer accelerometer;

This stores the instance across your game class so you can access the accelerometer in other parts of the game. To create an instance of the Accelerometer in your game’s Initialize method, add the following line of code:

accelerometer = new Accelerometer();

Unlike the XNA Game Studio input type, the Accelerometer uses an event-based model to return new data from the accelerometer. Data is returned by subscribing to the Accelerometer.ReadingChanged event and implementing an event handler method in your game. To subscribe to the ReadingChanged event, add the following lines of code after your previous line to create the instance of Accelerometer:

accelerometer.ReadingChanged += new
EventHandler<AccelerometerReadingEventArgs>(accelerometer_ReadingChanged);

Now, implement the accelerometer_ReadingChanged method that is called when the accelerometer receives new data. Add the following method to your game class:

public void accelerometer_ReadingChanged(object sender, AccelerometerReadingEventArgs e)
{
    Vector3 accelerometerReading;
    accelerometerReading.X = (float)e.X;
    accelerometerReading.Y = (float)e.Y;
    accelerometerReading.Z = (float)e.Z;
    // Update velocity
    spriteVelocity.X += accelerometerReading.X * spriteSpeed;
    spriteVelocity.Y += accelerometerReading.Y * spriteSpeed;
}

					  

The reading change event converts the AccelerometerReadingEventArgs parameter to something more useful for your game, which is a Vector3. In the previous case, you just used a local variable. In your game, you want to store this data or change another variable over successive calls.

To have the accelerometer start reading data, you must call the Start method. In the example, we start the accelerometer right away in the game’s Initialize method. For your game, you should not start to read accelerometer data until it is needed. For example, you don’t need to start the accelerometer when the game starts unless you use the accelerometer in your menus. Wait until your level starts before starting the accelerometer. Add the following lines of code after you set the ReadingChanged in your game’s Initialize method:

try
{
    accelerometer.Start();
}
catch (AccelerometerFailedException e)
{
    // Accelerometer not supported on this platform
    // We are going to exit.
    Exit();
}

The Start method throws a AccelerometerFailedException if the accelerometer is not supported on the platform or if you have already called the Start method. In the previous code, we exit the example game. In your game, you should determine what the best course of action is.

Now that the accelerometer has started, your game should start to revive reading changed events whenever the phone’s accelerometer detects changes.

When your game is not using the accelerometer, you should call the Stop method to help save battery life and to help your game’s performance. For our example, we use the Game classes OnExiting method to put the call to the Stop method. The default game template does not create an override for OnExiting, so you need to add the overridden method to your game class. In your game class, add the following method:

protected override void OnExiting(object sender, EventArgs args)
{
    try
    {
        accelerometer.Stop();
    }
    catch (AccelerometerFailedException e)
    {
        // Do nothing since we are already exiting
    }

    base.OnExiting(sender, args);
}

Similar to the Start method, the Stop method can also throw an exception. The AccelerometerFailedException is thrown when the accelerometer fails to stop or if it is already stopped.

Moving a Sprite Based on Accelerometer Data

Now that you have the basics of getting accelerometer data, let’s do something more fun and exciting. Like the previous examples, you move a sprite based on the user input, but in this case use the accelerometer data.

To build on the previous code example, you need some member variables to hold the sprite texture, position, and velocity. Add the following member variables to your game’s class:

Texture2D spriteTexture;
Vector2 spritePosition;
Vector2 spriteVelocity;
float spriteSpeed = 50.0f;
int screenWidth = 480;
int screenHeight = 800;

Next, load a texture to use as your sprite. In the game’s LoadContent method, add the following line of code:

spriteTexture = Content.Load<Texture2D>("XnaLogo");

Next, update the sprite’s velocity based on the returned acceleration data. To do this, update the accelerometer_ReadingChanged method you implemented previously. Add the following lines of code to the method:

// Update velocity
spriteVelocity.X += accelerometerReading.X * spriteSpeed;
spriteVelocity.Y += accelerometerReading.Y * spriteSpeed;

The sprite’s velocity is now updated based on the accelerometer reading changes and then scaled.

Now, create the sprite update logic that changes the sprite position based on the current velocity. In your game’s Update method, add the following lines of code:

// Update sprite position
spritePosition += spriteVelocity * (float)gameTime.ElapsedGameTime.TotalSeconds;

// Dampen velocity
spriteVelocity *= 1 - (float)gameTime.ElapsedGameTime.TotalSeconds;

// Check sprite bounds
if (spritePosition.X < 0)
{
    spritePosition.X = 0;
    spriteVelocity.X = 0;
}
else if (spritePosition.X > screenWidth - spriteTexture.Width)
{
    spritePosition.X = screenWidth - spriteTexture.Width;
    spriteVelocity.X = 0;
}
if (spritePosition.Y < 0)
{
    spritePosition.Y = 0;
    spriteVelocity.Y = 0;
}
else if (spritePosition.Y > screenHeight - spriteTexture.Height)
{
    spritePosition.Y = screenHeight - spriteTexture.Width;
    spriteVelocity.Y = 0;
}

					  

After you update the sprite’s position, you dampen the velocity so it slows over time. Then, check the bounds of the sprite so it can’t travel off the screen. Otherwise, it permanently flies off the screen. When the sprite hits one of the walls, set the velocity for that direction to 0 to enable the sprite to move easily off the wall.

The final step is to draw the sprite. To do this, add the following lines of code to your game’s Draw method:

// Draw the sprite
spriteBatch.Begin();
spriteBatch.Draw(spriteTexture, spritePosition, Color.White);
spriteBatch.End();

Autorotation and Acceleration Data

XNA Game Studio games on Windows Phone support autorotation that enable you as a developer to select which orientations work best for your game. Autorotation can cause a couple of challenges when creating a game that uses the accelerometer.

The first issue is that if your game supports multiple orientations and you expect the user to move and tilt the phone, it could cause the orientation of the game to switch when the user does not intend to change orientations. It is problematic if the screen rotates in the middle of playing a flight simulator evading incoming missiles. To address this concern, you can limit your supported orientations and test that the accelerometer actions you expect your users to use don’t trigger the orientations during normal game play. If you find that the orientations are triggered, you can set the supported orientations to just a single orientation and enable users to change the orientation using a menu option in your game.

The other issue is that when your game changes orientations, the acceleration data does not change. If your game supports multiple orientations, your game needs to take into account the current orientation and how that maps to the accelerometers X,Y, and Z coordinates.

Other  
  •  What Does The Ipad 3 Mean For IT Security Teams?
  •  Pocket Intel (Part 2)
  •  Pocket Intel (Part 1)
  •  Motorola S1LK TRBO : Sleeker Voice
  •  Motorola Atrix 2 : Tricks With Atrix 2
  •  HTC One X : Beauty With A Beast (Inside)
  •  Garmin NUVI 50LM
  •  CSL Switch Dual II MI357 : Bait And Switch
  •  Blackberry Curve 9360 Throws A Curve
  •  Learning jQuery 1.3 : The journey of an event
  •  Learning jQuery 1.3 : Compound events
  •  Programming the iPhone : Tables and Embedded Controls
  •  Programming the iPhone : Scrolling Controls
  •  BlackBerry Java Application Development : Networking - Testing for availability of transports
  •  XNA Game Studio 4.0 : Multitouch Input For Windows Phones (part 2) - Displaying GestureSample Data
  •  XNA Game Studio 4.0 : Multitouch Input For Windows Phones (part 1)
  •  Motorola Motoluxe
  •  Apple's Undiscovered Country : The future of the iPhone
  •  Apple's Undiscovered Country : The Future Of The Ipad
  •  Programming the iPhone : Standard Control Types (part 6) - Segmented Controls
  •  
    Most View
    Can You Go Viral?
    SQL Injection : Code-Level Defenses - Designing to Avoid the Dangers of SQL Injection
    Dell XPS 12 Convertible Ultrabook - Is Its Stunning Two-In-One Design?
    Aerocool Silent Master Blue
    Sony Speria Tablet S - Sony Makes A Comeback
    HP Elitebook Folio 9470 Business Ultrabook Review (Part 1)
    Windows Vista : Setting Up a Small Network - Setting Up a Peer-to-Peer Network
    Network-Attached Storage Solutions
    Graphics Cards for All Budgets (Part 2) - Radeon HD 7770, GeForce GTX 560, Radeon HD 7850, GeForce GTX 660
    Windows Vista : Installing and Running Applications - Launching Applications
    Top 10
    Managing Windows Server 2012 (part 13) - Using Remote Desktop - Supporting Remote Desktop Connection clients
    Managing Windows Server 2012 (part 12) - Using Remote Desktop - Remote Desktop essentials, Configuring Remote Desktop
    Managing Windows Server 2012 (part 11) - Optimizing toolbars
    Managing Windows Server 2012 (part 10) - Customizing the desktop and the taskbar - Using Auto Hide and locking, Controlling programs in the notification area
    Managing Windows Server 2012 (part 9) - Customizing the desktop and the taskbar - Configuring desktop items, Configuring the taskbar
    Managing Windows Server 2012 (part 8) - Using the System console
    Managing Windows Server 2012 (part 7) - Using Control Panel
    Managing Windows Server 2012 (part 6) - Working with Computer Management
    Managing Windows Server 2012 (part 5) - Working with Server Manager - Adding servers for management, Creating server groups, Enabling remote management
    Managing Windows Server 2012 (part 4) - Working with Server Manager - Getting to know Server Manager