Last active
May 28, 2018 04:50
-
-
Save BrianMacIntosh/9a3db775c87b12478e479b32ec67b9e2 to your computer and use it in GitHub Desktop.
This class greatly simplifies access to the accelerometer on the Windows Phone with XNA. Features include easy zeroing and "shake" gesture detection.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
{ | |
/// <summary> | |
/// This class provides methods for accessing the phone accelerometer | |
/// </summary> | |
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); | |
/// <summary> | |
/// Event that is called when the phone is shaken. | |
/// Be aware this event may be called a few times in quick succession. | |
/// </summary> | |
public static event ShakeEventHandler ShakeEvent; | |
private static void AccelerometerReadingChanged(object sender, SensorReadingEventArgs<AccelerometerReading> 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--; | |
} | |
/// <summary> | |
/// Get the last reading from the accelerometer. | |
/// </summary> | |
public static Vector3 Reading { get { return accelReading - center; } } | |
/// <summary> | |
/// Get the time of the last reading from the accelerometer. | |
/// </summary> | |
public static DateTimeOffset LastReadingTime { get { return lastUpdate; } } | |
/// <summary> | |
/// Get the amount the accelerometer has moved since the last reading. | |
/// </summary> | |
public static Vector3 RateOfChange { get { return accelReading - oldReading; } } | |
/// <summary> | |
/// Get the amount of time since the last reading from the accelerometer. | |
/// </summary> | |
public static TimeSpan TimeSinceLastReading { get { return DateTimeOffset.UtcNow - lastUpdate; } } | |
/// <summary> | |
/// Zero the accelerometer to the current reading. | |
/// </summary> | |
public static void ZeroAccelerometer() | |
{ | |
doZero = true; | |
} | |
/// <summary> | |
/// Zero the accelerometer to the given reading. | |
/// </summary> | |
/// <param name="zero"></param> | |
public static void ZeroAccelerometer(Vector3 zero) | |
{ | |
center = zero; | |
} | |
/// <summary> | |
/// Start the accelerometer sensor. | |
/// </summary> | |
/// <returns>True if the sensor was started successfully</returns> | |
public static bool Initialize() | |
{ | |
waitCount = 10; | |
try | |
{ | |
accelSensor = new Accelerometer(); | |
accelSensor.CurrentValueChanged += | |
new EventHandler<SensorReadingEventArgs<AccelerometerReading>>(AccelerometerReadingChanged); | |
accelSensor.Start(); | |
accelActive = true; | |
} | |
catch (AccelerometerFailedException) | |
{ | |
accelActive = false; | |
} | |
return accelActive; | |
} | |
/// <summary> | |
/// Stop the accelerometer sensor. | |
/// </summary> | |
/// <returns>True if the sensor was stopped successfully</returns> | |
public static bool Deinitialize() | |
{ | |
bool success = false; | |
if (accelActive) | |
{ | |
try | |
{ | |
accelSensor.Stop(); | |
success = true; | |
} | |
catch (AccelerometerFailedException) | |
{ | |
success = false; | |
} | |
} | |
return success; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment