zoukankan      html  css  js  c++  java
  • Windows Phone 开发中重力感应的简单使用示例

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

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

    1

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

    23

    45

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

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

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

    11122

    222444

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

       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 模拟器测试、真机测试,均可用。

    完毕

    作者:Lighting Cui

    出处:http://tugeler.cnblogs.com/

    本文版权归作者所,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    【如何写商业计划书?】
    JBoss Messaging简介
    jstack 查看java线程调用及死锁状状况
    如何在 JBoss 里配置 IBM MQ
    Linux(Centos )的网络内核参数优化来提高服务器并发处理能力
    三星系列产品开源地址
    WGET下载https链接及WGET命令的详解
    手机天线入门
    MTK MMS
    centos/redhat下如何快速绑定ip段
  • 原文地址:https://www.cnblogs.com/tugeler/p/2200316.html
Copyright © 2011-2022 走看看