1.调用cclayer的方法setAccelerometerEnabled(true)在层里启用重力感应。
2.启用重力感应后,重力方向变化时,会回调cclayer的方法didAccelerate( CCAcceleration* pAccelerationValue ),在自己派生的层里重写此方法.
pAccelerationValue包含x,y,z三个方向的重力值(由手机在这3个方向的偏移决定)
一般在这个回调函数里得到一次重力感应主角的偏移距离,然后在update里把主角的当前位置加上这个距离
7.5 加速度计(1)
除了触摸,移动设备上一个很重要的输入来源是设备的方向,因此大多数设备都配备了加速度计,用于测量设备静止或匀速运动时所受到的重力方向。
目前,加速度计在传统PC平台上尚未提供支持,因此在正式开始探索重力感应之前,还请读者参考附录A,将Cocos2d-x工程部署到手机或其他移动设备上。现在,Android或iOS平台均支持加速度计。
重力感应来自于移动设备的加速度计,通常支持X、Y和Z三个方向的加速度感应,所以又称为三向加速度计。在实际应用中,可以根据3个方向的力度大小来计算手机倾斜的角度或方向。
和触摸事件一样,重力感应的处理先被引擎抽象为一个触摸代理协议,然后由CCLayer提供了一个简化的实现,屏蔽了注册到重力感应器等一系列细节。在开发中,我们只需要重载一个简单的事件即可:
- virtual void didAccelerate(CCAcceleration* pAccelerationValue);
其中CCAcceleration是一个结构体,包含了加速度计获得的3个方向的加速度,相关代码如下:
- typedef struct
- {
- double x;
- double y;
- double z;
- double timestamp;
- } CCAcceleration;
为了便于游戏开发的使用,这个结构体中每个方向的加速度大小都以一个重力加速度为单位(即CCAcceleration结构中1单位的加速度等于重力加速度约9.8 m/s2)。举例来说,把手机平放在桌子上时,获得的加速度应该是(0,1,0)。正常使用时,总的加速值应该在1上下拨动。如果检测到一个大幅度偏离1的加速度时,则可以判断为突然动作:摇动手机时,会在一个或多个方向上出现很大的加速;投掷或坠落则容易检测到很小的加速。我们可以利用这些特性为游戏添加一些很有趣的控制效果。
我们可以尝试引入两个新特性:根据手机的倾斜方向转动炮台的方向,摇动手机来开火。和处理触摸事件时类似,我们建立一个加速检测层,将检测到的事件交由代理处理,相关代码如下:
- class AccelerationLayerDelegate
- {
- public:
- virtual void swing(int direction)=0;
- virtual void shakes()=0;
- };
- class AccelerationLayer : public CCLayer
- {
- int swingCnt; //记录连续的倾斜
- int shakeCnt; //记录连续的摇晃
- public:
- CC_SYNTHESIZE(AccelerationLayerDelegate*, m_pDelegate, Delegate);
- public:
- LAYER_NODE_FUNC(AccelerationLayer);
- bool init();
- virtual void didAccelerate(CCAcceleration* pAccelerationValue);
- };
这里我们使用了两个成员变量来记录摇晃和倾斜的次数,其作用为对重力感应事件产生缓冲,从后面的处理函数可以看到我们做了三个处理。
首先,需要区分正常加速和用力摇晃设备,它们的区别就在于总加速度是否异常。我们设定用力摇晃设备时的总加速度大小应该大于2倍重力加速度,这样的处理忽略了手机在下落中处于失重状态,因为通常我们只会左右摇晃设备。