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;
}
}
}