设为首页 收藏本站
查看: 953|回复: 0

Windows Phone 7范例游戏Platformer实战6——加速度传感器解读

[复制链接]

尚未签到

发表于 2015-5-8 11:47:08 | 显示全部楼层 |阅读模式
  Windows Phone 7范例游戏Platformer实战1——5大平台支持
Windows Phone 7范例游戏Platformer实战2——游戏设计初步
Windows Phone 7范例游戏Platformer实战3——游戏资源和内容管道
Windows Phone 7范例游戏Platformer实战4——冲突检测的实现
Windows Phone 7范例游戏Platformer实战5——多点触控编程
  
  加速度传感器在Windows Phone 7的硬件规格中已经成为一种标配,有了加速度传感器,我们就可以根据地球引力来仿真现实生活中的许多操作。比如说我们倾斜手机,就可以实现英雄的向倾斜的方向移动。还有我们可以挥动手机,实现游戏中保龄球的挥出操作等等功能。摇晃手机实现图片或者背景图片的变换,一切只限于你的想象力。因此掌握加速度传感器的编程也是XNA游戏开发的必经之路。
  
  WP7上的加速度传感器输出可以用一个三维空间的矢量来描述,这里要注意下,在XNA中存在三维的矢量类型,而Silverlight是不存的。本文除了将给出Platformer的加速度感应器代码外,还将深入WP7的加速度感应器的概念,让你在以后的项目开发中可以快速切入。
  
  当一个三维的点坐标(x,y,z)表示空间一个特定的位置时,矢量(x,y,z)代表的意义则更加丰富,它包含了方向和长度的概念。很明显点坐标和矢量是有关联的。矢量(x,y,z)的方向就是点(0,0,0)到点(x,y,z)的方向。但是矢量(x,y,z)并不是由点(0,0,0)到点(x,y,z)构成的那条直线,而只是代表这条直线的方向。
  
  矢量(x,y,z)的长度我们可以使用勾股定理快速获取,下面是计算的数学表达式。
  
DSC0000.jpg
  
  在使用加速度传感器时,我们可以把WP7手机想像成一个三维的坐标系统。无论电话放置的方向的什么,Y坐标轴是电话的底端(包含按钮的那端)到顶端的方向,而且这个走向是是X轴正方向。X坐标轴则是从左至右的走向,这个走向亦是正方向,Z坐标轴正走向则是面对你的方向。
  
  下面是WP7三维矢量坐标的标示图:
  
DSC0001.jpg
  
  
  这是一个我们在实际生活和数学中都经常使用的经典三维坐标系统,XNA中的3D编程也采用了这种坐标方法。这种坐标系统有一个专业术语,被称作笛卡尔右手坐标系统。
  
  笛卡尔右手坐标系统的意思就是将右手背对着手机屏幕放置,拇指即指向X轴的正方向。伸出食指和中指,食指指向Y轴的正方向,中指所指示的方向即是Z轴的正方向。有点类似面对自己的兰花指造型,大家可以看看示意图。
  
DSC0002.jpg
  
  这种坐标朝向永远是固定的,无论你是将手机是横拿还是竖放,又或者游戏是在Landscape和Portrait模式下运行,均如此。你只需要记住前面强调的两点,无论电话放置的方向的什么,Y坐标轴是电话的底端(具备开始按钮的那端)到顶端的走向,而且这个方向是是X轴正方向。X坐标轴则是从左至右的走向,这个走向亦是正方向。再使用右手定理,就可以很快地确定Z的坐标轴走向了。
  
  正如你想象的那样,Windows Phone 7应用程序的在屏幕选择时会自动切换正是由加速度传感器实现的。如果你的手机是静止的,加速度传感器的矢量方向永远是指向地心的,如果矢量的长度为1的话,我们称之为1G。当你着正拿着WP7手机时,加速度传感器的矢量为(0,-1,0),方向指向地心。逆时针旋转90度,加速度传感器矢量变为(-1,0,0)。再逆时针旋转90度又变为(0,1,0)。
  
  当你将手机朝上平放在桌面上时,加速度传感器矢量为(0,0,-1)。这些值也就是Windows Phone 7仿真器经常报告的矢量。
  

  
  正常拿着时,加速度传感器矢量为(0,-1,0)
  
DSC0003.jpg
  
  右Landscape模式时,加速度传感器矢量为(1,0,0)
  
DSC0004.jpg
  
  左Landscape时,加速度传感器矢量为(-1,0,0)
  
   DSC0005.jpg
  
  向右倾斜45度时,加速度传感器矢量为(0.7,-0.7,0)。这样使用勾股定理正好得到矢量长度为1
  
  当然,加速度传感器矢量很少能达到这种类似(0,-1.0)这种精确度,其长度不可避免会有些出入。在WP7手机静止时,加速度传感器矢量长度会有一定的误差。当你在访问月球时使用WP7的话,你可能会认为矢量速度为0.17这个大概的区域(月球重力为地球的1/6),但是这个数值主要还是取决于手机的加速度传感器品质。
  
  前面谈论的加速度感应器矢量都是在手机静止状态下发生的,加速度感应器矢量还可以指向其它的一些方向,当手机在快速运动时其矢量长度也会发生或大或小的变化。
  
  比如说,当你猛地将手机向左移动时,如果手机的速度一直处于增大时,加速度传感器矢量将指向右。但当手机的移动速度稳定时,加速度传感器矢量的长度又变为重力大小。当你最后减速时,加速度传感器矢量的方向一直保持左边,直到手机完全停止为止。
  
  还有一种情况就是当手机自由落体时,原理上可认为此时加速度传感器矢量的长度为0。
  
  在程序开发过程中需要和加速度传感器打交道时,你首先要引用Microsoft.Devices.Sensors这个dll文件。此外,WMAppManifest.xml这个文件还需要包含这个描述。一般来说这个描述是在项目创建时就已存在,这里和大家提醒下。
  
  我们知道Platformer游戏中,是使用加速度传感器的来确定英雄的移动方向,以及移动的速度,这和你倾斜手机的角度有着密切的关系。我们需要对加速度传感器返回的矢量值进行处理,以实现仿真现实场景的移动效果。此外,当程序运行在模拟器上时,我们可以使用电脑键盘的方向键来仿真加速度传感器。
  


  1 #region File Description
  2 //-----------------------------------------------------------------------------
  3 // Accelerometer.cs
  4 //
  5 // Microsoft XNA Community Game Platform
  6 // Copyright (C) Microsoft Corporation. All rights reserved.
  7 //-----------------------------------------------------------------------------
  8 #endregion
  9
10 #region Using Statements
11 using System;
12 using Microsoft.Xna.Framework;
13 using Microsoft.Xna.Framework.Input;
14 #endregion
15
16 namespace Platformer
17 {
18     ///
19     /// 加速度传感器封装类
20     ///
21     public static class Accelerometer
22     {
23 #if WINDOWS_PHONE
24         // 实例化加速度传感器对象
25         private static Microsoft.Devices.Sensors.Accelerometer accelerometer = new Microsoft.Devices.Sensors.Accelerometer();
26         
27         //因为加速度传感器的ReadingChanged事件可以由不同的线程触发
28         //为此我们在游戏中要对传感器进行锁定(Lock),以便需要时单独享用。
29         private static object threadLock = new object();
30
31         //用于保存加速度传感器最后反馈的数据
32         private static Vector3 nextValue = new Vector3();
33 #endif
34
35         // 为防止加速度传感器初始化两次引入的变量
36         private static bool isInitialized = false;
37
38         // 加速度传感器是否开启
39         private static bool isActive = false;
40
41         ///
42         /// 为当前游戏初始化加速度传感器. 这个方法只能在游戏中调用一次
43         ///
44         public static void Initialize()
45         {
46             // 确保加速度传感器是第一次初始化,如果已经初始化过了,则抛出异常。
47             if (isInitialized)
48             {
49                 throw new InvalidOperationException("Initialize can only be called once");
50             }
51
52 #if WINDOWS_PHONE
53             // 如果是实际的WP7设备,则开始加速度传感器的初始化工作。
54             if (Microsoft.Devices.Environment.DeviceType == Microsoft.Devices.DeviceType.Device)            
55             {
56                 try
57                 {
58                     accelerometer.ReadingChanged += new EventHandler(sensor_ReadingChanged);
59                     accelerometer.Start();
60                     isActive = true;
61                 }
62                 catch (Microsoft.Devices.Sensors.AccelerometerFailedException)
63                 {
64                     isActive = false;
65                 }
66             }
67             else
68             {
69                 // 因为在模拟器上我们可以使用方向键控制英雄的移动和跳跃
70                 // 所以假定加速度传感器的已经处于激活的状态
71                 isActive = true;
72             }
73 #endif
74
75             // 保存已被初始化的信息
76             isInitialized = true;
77         }
78         
79 #if WINDOWS_PHONE
80         ///
81         /// 加速度传感器数据发生变化后的矢量值
82         ///
83         ///
84         ///
85         private static void sensor_ReadingChanged(object sender, Microsoft.Devices.Sensors.AccelerometerReadingEventArgs e)
86         {
87             //保存加速度传感器的返回值,这样可以在下一次游戏状态更新时使用。
88             lock (threadLock)
89             {
90                 nextValue = new Vector3((float)e.X, (float)e.Y, (float)e.Z);
91             }
92         }
93 #endif
94
95         ///
96         /// 获得当前加速度传感器的状态
97         ///
98         /// 获得加速度传感器的当前状态.
99         public static AccelerometerState GetState()
100         {
101             // 在开始获得加速度传感器状态时,我们必须确保加速度传感器已经初始化
102             if (!isInitialized)
103             {
104                 throw new InvalidOperationException("You must Initialize before you can call GetState");
105             }
106
107             //为加速度传感器的状态创建一个新矢量对象
108             Vector3 stateValue = new Vector3();
109
110 #if WINDOWS_PHONE
111             // 如果加速度传感器被激活
112             if (isActive)
113             {
114                 if (Microsoft.Devices.Environment.DeviceType == Microsoft.Devices.DeviceType.Device)
115                 {
116                     // 如果游戏是在WP7手机上运行,读取加速度传感器的矢量值
117                     lock (threadLock)
118                     {
119                         stateValue = nextValue;
120                     }
121                 }
122                 else
123                 {
124                     //如果是在模拟器上,我们可以使用方向键来仿真加速度传感器的矢量值。
125                     //你可以使用pause/break键来切换到键盘操作。
126                     KeyboardState keyboardState = Keyboard.GetState();
127
128                     stateValue.Z = -1;
129
130                     if (keyboardState.IsKeyDown(Keys.Left))
131                         stateValue.X--;
132                     if (keyboardState.IsKeyDown(Keys.Right))
133                         stateValue.X++;
134                     if (keyboardState.IsKeyDown(Keys.Up))
135                         stateValue.Y++;
136                     if (keyboardState.IsKeyDown(Keys.Down))
137                         stateValue.Y--;
138
139                     stateValue.Normalize();
140                 }
141             }
142 #endif
143
144             return new AccelerometerState(stateValue, isActive);
145         }
146     }
147
148     ///
149     /// 对加速度传感器当前状态的封装
150     ///
151     public struct AccelerometerState
152     {
153         ///
154         /// 获得加速度传感器当前的重力
155         ///
156         public Vector3 Acceleration { get; private set; }
157
158         ///
159         /// 查看加速度传感器是否激活和运行
160         ///
161         public bool IsActive { get; private set; }
162
163         ///
164         //  构造函数
165         ///
166         /// 当前加速度传感器的加速度值
167         /// 加速度传感器是否激活
168         public AccelerometerState(Vector3 acceleration, bool isActive)
169             : this()
170         {
171             Acceleration = acceleration;
172             IsActive = isActive;
173         }
174
175         ///
176         /// 返回一个包含加速度值和是否激活的字符串
177         ///
178         /// 描述加速度传感器状态的字符串.
179         public override string ToString()
180         {
181             return string.Format("Acceleration: {0}, IsActive: {1}", Acceleration, IsActive);
182         }
183     }
184 }
185   
  好了,加速度传感器的使用暂时就结束到这里了,轩辕会在后续的章节中介绍如何使用返回的矢量值来控制英雄的移动方向和移动速度。下一节开始讲解游戏的动画类和动画的绘制了,敬请期待。
  
  喜欢本文的读者们请劳驾点击下文章下面的“推荐”,非常感谢哈。周末放弃休息,继续加更,拉下票,希望dudu手下留情。哈哈
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-64958-1-1.html 上篇帖子: Windows Phone 7 开发探索笔记3——触控操作之GestureListener 下篇帖子: Windows phone 7应用之代码性能分析工具——Profile.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表