using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Devices.Sensors; /* * XNA Windows Phone Easy Accelerometer Access * by Brian MacIntosh for ThunderFish Entertainment/BoneFish Studios * * Version: 1.0 * * 11/23/2011: Version 1.0 * - Created * * 11/21/2012 * - Distributed * * This library is provided free of charge for commercial and noncommercial use. * No warranty of fitness for any purpose, express or implied, is given. */ /* * This class greatly simplifies access to the accelerometer on the * Windows Phone. Simply call ThunderFish.TAccelerometer.Initialize() * when the game is initialized (such as in the OnNavigateTo method) and * call ThunderFish.TAccelerometer.Deinitialize() when the game is * unloaded (OnNavigateFrom). * * The class provides access to the basic accelerometer reader with * Reading and an event that is called when the phone is shaken * (ShakeEvent). See method descriptions for more usage details. */ namespace Thunderfish { /// /// This class provides methods for accessing the phone accelerometer /// static class TAccelerometer { private static Accelerometer accelSensor; private static Vector3 accelReading; private static Vector3 center; private static DateTimeOffset lastUpdate; private static bool doZero; private static Vector3 oldReading; private static int waitCount; private static float rateOfChange; private static float lastRateOfChange; private static float shakeThreshold = 0.5f; private static bool accelActive; public delegate void ShakeEventHandler(float intensity); /// /// Event that is called when the phone is shaken. /// Be aware this event may be called a few times in quick succession. /// public static event ShakeEventHandler ShakeEvent; private static void AccelerometerReadingChanged(object sender, SensorReadingEventArgs e) { oldReading = accelReading; lastRateOfChange = rateOfChange; accelReading.X = (float)e.SensorReading.Acceleration.X; accelReading.Y = (float)e.SensorReading.Acceleration.Y; accelReading.Z = (float)e.SensorReading.Acceleration.Z; lastUpdate = e.SensorReading.Timestamp; if (doZero) { doZero = false; center = accelReading; } //Update rocs rateOfChange = oldReading.Length() - accelReading.Length(); if (Math.Abs(rateOfChange - lastRateOfChange) > shakeThreshold && ShakeEvent != null && waitCount <= 0) ShakeEvent(Math.Abs(rateOfChange / shakeThreshold)); if (waitCount > 0) waitCount--; } /// /// Get the last reading from the accelerometer. /// public static Vector3 Reading { get { return accelReading - center; } } /// /// Get the time of the last reading from the accelerometer. /// public static DateTimeOffset LastReadingTime { get { return lastUpdate; } } /// /// Get the amount the accelerometer has moved since the last reading. /// public static Vector3 RateOfChange { get { return accelReading - oldReading; } } /// /// Get the amount of time since the last reading from the accelerometer. /// public static TimeSpan TimeSinceLastReading { get { return DateTimeOffset.UtcNow - lastUpdate; } } /// /// Zero the accelerometer to the current reading. /// public static void ZeroAccelerometer() { doZero = true; } /// /// Zero the accelerometer to the given reading. /// /// public static void ZeroAccelerometer(Vector3 zero) { center = zero; } /// /// Start the accelerometer sensor. /// /// True if the sensor was started successfully public static bool Initialize() { waitCount = 10; try { accelSensor = new Accelerometer(); accelSensor.CurrentValueChanged += new EventHandler>(AccelerometerReadingChanged); accelSensor.Start(); accelActive = true; } catch (AccelerometerFailedException) { accelActive = false; } return accelActive; } /// /// Stop the accelerometer sensor. /// /// True if the sensor was stopped successfully public static bool Deinitialize() { bool success = false; if (accelActive) { try { accelSensor.Stop(); success = true; } catch (AccelerometerFailedException) { success = false; } } return success; } } }