Windows Phone 7 摇动检测
文章信息
代码示例
测试基于
兼容于
文章
在日常的手机使用的过程中,我们经常会进行人机交互,摇动手机也是其中一种。 本文将演示如何在Windows Phone 7程序中获取手机摇动的数据,主要演示左右摇动和上下摇动的获取.
Contents |
摇动支持
首先我设置了摇动的Enum:
public enum ActionEnum
{
None = 0,
LeftRightShake = 1,
UpDownShake = 2
}
然后,我就可以使用以下代码来设置支持的Action
accHelper.SupportedAction = ActionEnum.LeftRightShake | ActionEnum.UpDownShake;
然后,我可以使用以下来匹配,是否支持这个Action,这里是是否匹配LeftRightShake
(SupportedAction & ActionEnum.LeftRightShake).Equals(ActionEnum.LeftRightShake)
这样做的原理是二进制匹配: None = 0000,
LeftRightShake = 0001,
UpDownShake = 0010
ActionEnum.LeftRightShake | ActionEnum.UpDownShake = 0011
当需要判断的时候,如下:
SupportedAction & ActionEnum.LeftRightShake = 0001,去掉了属于UpDownShake的那个1
所以最终,只需要
(SupportedAction & ActionEnum.LeftRightShake).Equals(ActionEnum.LeftRightShake)
来匹配即可.
Windows Phone 7重力系统概要
重力是由于加速度产生的,加速度值采用 3 维矢量表示,该矢量表示在 X、Y 和 Z 轴中的加速度分量(采用重力单位)。 当设备面朝平台时,加速度的方向相对于设备以便对 Z 轴应用 -1g,当垂直于平台顶部放置设备时,对 Y 轴应用 -1g。 加速度计传感器将检测重力以及由于手机运动而产生的任何力。
重力坐标类Axis
重力坐标类提供了一个重力最基本的X,Y,Z方向,同时还提供了记录坐标的时间和记录坐标时,手机的移动方向.
public class Axis
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
public DateTime CurrentDateTime { get; set; }
public AccelerationDirection AccDirection { get; set; }
}
以下是坐标的方向的Enum,因为我们就监控两种摇动,所以仅提供了4个方向.
public enum ActionEnum
{
None = 0,
LeftRightShake = 1,
UpDownShake = 2
}
重力坐标集合类AxisCollection
AxisCollection是最主要的一个类,提供了很多的方法,为了重力判断的使用.
在AxisCollection中的Add方法并没有这么容易添加,这个需要是判断为有一定幅度的震动的时候,猜可以判断为新的行为:
public void Add(Axis axis)
{
var Gravity = axis.X * axis.X + axis.Y * axis.Y + axis.Z * axis.Z;
if (Gravity < 0.8 || Gravity > 1.2)
{
AxisList.Add(axis);
if (-0.3 > axis.X || axis.X > 0.3)
{
if (axis.X < -0.3) axis.AccDirection = AccelerationDirection.Left;
else if (axis.X > 0.3) axis.AccDirection = AccelerationDirection.Right;
}
else
{
if ((axis.Y * axis.Y + axis.Z * axis.Z > 1.2)) axis.AccDirection = AccelerationDirection.Up;
else if (axis.Y * axis.Y + axis.Z * axis.Z < 0.8) axis.AccDirection = AccelerationDirection.Down;
}
axis.CurrentDateTime = DateTime.Now;
}
}
这些个数字中的0.3,1.2,0.8都是对用户震动的检测.
然后是IsMoving方法,这个方法是用来判断手机时候在Action.如果为True,那么就是在移动.如果为False,那么就是有一定时间没有进行移动了.
public bool IsMoving()
{
if (AxisList.Count != 0)
{
if (DateTime.Now.Subtract(AxisList.Last().CurrentDateTime).TotalMilliseconds > 666)
{
return false;
}
}
return true;
}
最后就是最最重要的CheckCurrentAction方法了.通过Check方法,可以Check当前的操作是左右晃动,还是上下晃动,我们这里设置的是2,我们也可以改变这个数值,使得需要更加多的晃动,才判断为一次行为.
public void CheckCurrentAction()
{
if (AxisList.Count == 0) CurrentActionEnum = ActionEnum.None;
else
{
if (!(CurrentActionEnum .Equals( ActionEnum.None)))
{
return;
}
if ((SupportedAction & ActionEnum.LeftRightShake).Equals(ActionEnum.LeftRightShake) &&
AxisList.Where(al => al.AccDirection.Equals(AccelerationDirection.Left)).Count() > 2 && AxisList.Where(al => al.AccDirection.Equals(AccelerationDirection.Right)).Count() > 2)
CurrentActionEnum = ActionEnum.LeftRightShake;
else if ((SupportedAction & ActionEnum.UpDownShake).Equals(ActionEnum.UpDownShake) &&
AxisList.Where(al => al.AccDirection.Equals(AccelerationDirection.Up)).Count() > 2 && AxisList.Where(al => al.AccDirection.Equals(AccelerationDirection.Down)).Count() > 2)
CurrentActionEnum = ActionEnum.UpDownShake;
}
}
最后,是Reset方法,重置所有的Child,当进过一段时间不移动后,那么就需要进行Reset.
public bool Reset()
{
try
{
AxisList.Clear();
}
catch (Exception)
{
return false;
}
return true;
}
帮助类AccHelper
AccHelper类的主要功能就是帮助我们进行中心控制,封装一些我们不需要处理的操作. 下面,就是整个WPAcchelper类
namespace AccHelper
{
public class WPAccHelper
{
private Accelerometer accelerometer = new Accelerometer();
private AxisCollection axisCollection = new AxisCollection();
public ActionEnum SupportedAction
{
get { return axisCollection.SupportedAction; }
set { axisCollection.SupportedAction = value; }
}
public WPAccHelper()
{
accelerometer.Start();
accelerometer.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<AccelerometerReading>>(accelerometer_CurrentValueChanged);
}
void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
{
var newAxis = new Axis() { X = e.SensorReading.Acceleration.X, Y = e.SensorReading.Acceleration.Y, Z = e.SensorReading.Acceleration.Z };
axisCollection.Add(newAxis);
if (!axisCollection.IsMoving())
{
axisCollection.Reset();
return;
}
axisCollection.CheckCurrentAction();
}
public string GetInfo()
{
return axisCollection.CurrentActionEnum.ToString();
}
}
}
通过这个类,我们可以不用手动调用AxisCollection中的方法,而全部交给Helper类,所有的Reset和Check都不用我们手动来.
GamePage页面
接着我们看下我们需要在主页面中做什么:
- 声明一个WPAcchelper类,并设定支持的晃动类型是什么
WPAccHelper accHelper;accHelper = new WPAccHelper();
accHelper.SupportedAction = ActionEnum.LeftRightShake | ActionEnum.UpDownShake;
然后,直接在OnDraw方法中写出当前的晃动是什么,即可.不需要更多的操作.
private void OnDraw(object sender, GameTimerEventArgs e)
{
SharedGraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin();
spriteBatch.DrawString(MySprite, accHelper.GetInfo(), new Vector2(0, 0), Color.White);
spriteBatch.End();
// TODO: Add your drawing code here
}
项目截图
项目文件和总结
本项目指在提供一种思想,如何通过重力,检测当前的行为,重力的检测,在游戏中经常的用到,是非常重要的一部分.


(no comments yet)