欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Windows Phone 开发中重力感应的简单使用示例

程序员文章站 2022-04-12 08:40:16
    现在智能手机的交互都是通过一个大屏幕,开发手机游戏或应用时,对程序的操作在某些情况下使用加速度感应器会提高用户体验。   windowsphone...

 

 

现在智能手机的交互都是通过一个大屏幕,开发手机游戏或应用时,对程序的操作在某些情况下使用加速度感应器会提高用户体验。

 

windowsphone sdk 7.1也提供了加速度模拟器,可以更好地测试程序。

 

以下是在一个xna程序中简单的使用加速度感应的方法:

 

使用加速度感应器需要先引入命名空间

 

 

   1: using microsoft.devices.sensors;

并给用来提供程序控制(操作)的类添加一个属性用来存放感应器实例

 

   1: accelerometer accelerometer;

同时,此例中,简单的将对手机重力的变化归结到 上下左右的四向操作中,所以这里添加四个类属性用来表示四个方向是否被触发

 

   1: private static boolean trunup = false;

   2: private static boolean trundown = false;

   3: private static boolean trunleft = false;

   4: private static boolean trunright = false;

 

 

然后在类的初始化函数(initialize)中对accelerometer进行初始化

 

   1: //检测是否支持加速度感应(如果不支持这里简单做异常抛出来)

   2: if (!accelerometer.issupported)

   3: {

   4:    // the device on which the application is running does not support

   5:    // the accelerometer sensor. alert the user and disable the

   6:    // start and stop buttons.

   7:    throw new exception("device does not support accelerometer");

   8: }

   9: //初始化accelerometer

  10: if (accelerometer == null)

  11: {

  12:    // instantiate the accelerometer.

  13:    accelerometer = new accelerometer();

  14:    //设置感应器检测间隔 单位是毫秒 (the default value is 2 milliseconds.[msdn])

  15:    accelerometer.timebetweenupdates = timespan.frommilliseconds(20);

  16:    //[个人理解] 添加监听事件的回调函数 (accelerometer_currentvaluechanged),

  17:    //          即每次检测的到的结果交给此方法进行处理(本例中用来更新四个方向指示属性)

  18:    accelerometer.currentvaluechanged += new eventhandler<sensorreadingeventargs<accelerometerreading>>(accelerometer_currentvaluechanged);

  19: }

  20: try

  21: {

  22:    //开始感应器检测

  23:    accelerometer.start();

  24: }

  25: catch (invalidoperationexception ex)

  26: {

  27:    throw new exception("unable to start accelerometer.", ex);

  28: }

编写回调函数来处理感应器的变化(将变化对应到四个方向属性上。【注意!本例只考虑横屏情况,竖屏情况坐标系略有不同】)

 

   1: void accelerometer_currentvaluechanged(object sender, sensorreadingeventargs<accelerometerreading> e)

   2: {

   3:   

   4:    //将方向属性归位

   5:    trunup = false;

   6:    trundown = false;

   7:    trunleft = false;

   8:    trunright = false;

   9: 

  10:    //将重力感应器得到的数据映射到单位三维矢量上

  11:    // (得到的加速度方向矢量三维均是0--1的数值表示xyz轴向的偏转)

  12:    //   如图x=-1 y=0 z=0 表示手机横向直立的状态

  13:    vector3 acceleration = e.sensorreading.acceleration;

  14: 

  15:    //设置偏转力度阀域(由于方向矢量是一个0到1的数值,偏转力度表

  16:    //  示当某一唯独的偏转矢量大于这个阀域值时,认为手机向这个方向倾斜)

  17:    double power = 0.2;

  18: 

  19:    //手机z轴向负方向倾斜 认为是向上(如图)

  20:    if (acceleration.z < - power)  21:    {

  22:        trunup = true;

  23:    }

  24:    //手机z轴向正方向倾斜 认为是向下(如图)

  25:    else if (acceleration.z > power)

  26:    {

  27:        trundown = true;

  28:    }

  29: 

  30:    //手机y轴向正方向倾斜 认为是向左(如图)

  31:    if (acceleration.y > power)

  32:    {

  33:        trunleft = true;

  34:    }

  35:    //手机z轴向负方向倾斜 认为是向右(如图)

  36:    else if (acceleration.y < - power)

  37:    {

  38:        trunright = true;

  39:    }

  40: }

 

 

 

Windows Phone 开发中重力感应的简单使用示例

【tips】实际操作中为了更加人性化(为了用户体验可以认为并不是手机屏幕斜线上45度为默认状态)实际应用中可以修改power值 或者分别指定各个方向的power值范围,方法类似 本例中只简单举例

Windows Phone 开发中重力感应的简单使用示例Windows Phone 开发中重力感应的简单使用示例

Windows Phone 开发中重力感应的简单使用示例Windows Phone 开发中重力感应的简单使用示例

【tips】可以认为 x正方向为水平向内,z轴正方向为垂直向下,y为手持手机屏幕保证水平对自己向左倾斜90度为正

【个人见解】可见,为了提高用户体验,(通常用户游戏时习惯手机约45度手持 。所以很明显本例方向判断阈值设置方式有问题。根据本人体验 左右倾斜阀域约25度角 向上的阀域值约为手机倾斜角30以内 向下的阀域约为手机倾斜60度以上)

下图为根据本人体验后得出的图示(比较拙略,将就看。上面两想象成面对手机屏幕,下面两想想成从侧面看手机屁股。。) ,仅供参考(具体阀域转换成坐标未计算出。。。)

Windows Phone 开发中重力感应的简单使用示例Windows Phone 开发中重力感应的简单使用示例

Windows Phone 开发中重力感应的简单使用示例Windows Phone 开发中重力感应的简单使用示例

 

以上做好后可以在控制逻辑中加入对方向的操作了

 

 

   1: //(示例程序片段)控制逻辑 更新摄像头位置

   2: public override void update(gametime gametime)

   3: {

   4:     // 根据四向属性的值 来设定逻辑

   5:     if (trunup)

   6:     {

   7:         cameraposition += cameradirection * speed;

   8:     }

   9:     if (trundown)

  10:     {

  11:         cameraposition -= cameradirection * speed;

  12:     }

  13:     if (trunleft)

  14:     {

  15:         cameraposition += vector3.cross(cameraup,cameradirection) * speed;

  16:     }

  17:     if (trunright)

  18:     {

  19:         cameraposition -= vector3.cross(cameraup, cameradirection) * speed;

  20:     }

  21: 

  22:     ...

  23: 

  24:     base.update(gametime);

  25: }

 

 

本方案通过 sdk7.1 模拟器测试、真机测试,均可用。

完毕

作者:lightingcui

<script></script>