Zune HD: XNA Accelerometer
My Zune HD arrived last week and after getting over the initial disappointment of a disgracefully empty marketplace for it, I was really itching to try out some XNA and play around with the accelerometer. First things first, I needed to download the XNA extensions that would provide the necessary framework to use the accelerometer in the Zune HD; these can be found right here. As far as I’m aware, XNA for the older Zune won’t let you use the 3D API (I could be wrong??) and I don’t think this has been rectified by the XNA 3.1 Zune Extensions however hopefully an XNA 3.2 or 4.0 will come along in the near future and open that up.
UPDATE:
I verified that the 3D API isn’t available. The likes of the Effect class aren’t available on the Zune.
In order to play with the accelerometer, I made a quick test project that allows the user to roll a ball about in a lovely blank black background. See this video:
Ok, so it’s not quite a ball….its a big white dot! Who cares?
This was actually incredibly simple to achieve and was much easier than I had originally anticipated. The XNA extensions provide a new class under Microsoft.Xna.Framework.Input called Accelerometer. As with the other input devices, this class provides a GetState() method so it very much keeps in line with what XNA developers are already used to. This method returns an object of type AccelerometerState which has a Vector3 property called Acceleration. This property holds all the information you need for detecting tilt on the device.
Since the code is so simple, I don’t think I will walk through it step by step but rather I will just post my very quick code below. Please ignore the rubbish boundary collisions – I didn’t feel like it was very important to make them perfect. Rough and ready…just the way I like it!
- using System;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Graphics;
- using Microsoft.Xna.Framework.Input;
- namespace AccelerometerTest
- {
- public class Game1 : Microsoft.Xna.Framework.Game
- {
- private const float rollSpeed = 50f;
- private GraphicsDeviceManager graphics;
- private SpriteBatch spriteBatch;
- private Rectangle boundary;
- private Texture2D ballTexture;
- private Vector2 ballPosition;
- public Game1()
- {
- graphics = new GraphicsDeviceManager(this);
- Content.RootDirectory = “Content”;
- // Frame rate is 30 fps by default for Zune.
- TargetElapsedTime = TimeSpan.FromSeconds(1 / 30.0);
- }
- protected override void Initialize()
- {
- boundary = GraphicsDevice.Viewport.TitleSafeArea;
- base.Initialize();
- }
- protected override void LoadContent()
- {
- spriteBatch = new SpriteBatch(GraphicsDevice);
- ballTexture = Content.Load<Texture2D>(“ball”);
- ballPosition = new Vector2(boundary.Width / 2, boundary.Height / 2);
- }
- protected override void UnloadContent()
- {
- // TODO: Unload any non ContentManager content here
- }
- protected override void Update(GameTime gameTime)
- {
- if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
- this.Exit();
- Vector3 acceleration = Accelerometer.GetState().Acceleration;
- Vector2 velocity = new Vector2(acceleration.X, -acceleration.Y) * rollSpeed;
- Vector2 projectedPosition = ballPosition + velocity;
- Rectangle projectedRectangle = new Rectangle((int)projectedPosition.X, (int)projectedPosition.Y, ballTexture.Width, ballTexture.Height);
- if (projectedRectangle.Left < boundary.Left || projectedRectangle.Right > boundary.Right)
- velocity.X = 0;
- if (projectedRectangle.Top < boundary.Top || projectedRectangle.Bottom > boundary.Bottom)
- velocity.Y = 0;
- ballPosition += velocity;
- base.Update(gameTime);
- }
- protected override void Draw(GameTime gameTime)
- {
- GraphicsDevice.Clear(Color.Black);
- spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
- spriteBatch.Draw(ballTexture, ballPosition, Color.White);
- spriteBatch.End();
- base.Draw(gameTime);
- }
- }
- }

Don’t like the way that add in for Live Writer cut out all my blank lines!