Cocos2d-x物理引擎碰撞和接触设置的有关问题
本文将深入探讨Cocos2d-x物理引擎中碰撞和接触设置的相关问题,这些设置对Box2d和Cocos2d-x 3.2自带的物理引擎均适用。
碰撞设置的三个函数
1. setGroup(int group)
- 调用方式及作用范围:该函数可由
body
或shape
调用。若由body
调用,会设置这个body
上所有的shape
;若由shape
调用,则仅设置单个shape
。 - 碰撞规则
- 同组情况:处于同一组的物体总是会发生碰撞,无论后续的掩码如何设置。
- 不同组情况:不同组的物体是否碰撞取决于掩码设置。并且,
setGroup
的优先级高于碰撞掩码。
示例代码:
sp2->getPhysicsBody()->setGroup(1);
sp3->getPhysicsBody()->setGroup(2);
2. 掩码三个函数(兼具检测碰撞和检测触发函数两个作用)
在默认情况下,这三个掩码函数的值都被设置为FF
。
setCategoryBitmask(uint32_t mask)
:用于设置物体的种类掩码。setCollisionBitmask(uint32_t mask)
:用于设置物体的碰撞掩码,决定物体是否会发生不可穿透的碰撞。setContactTestBitmask(uint32_t mask)
:用于设置物体的接触掩码,触发接触检测函数。
示例代码:
sp3->getPhysicsBody()->setCategoryBitmask(0x01); // 种类
sp3->getPhysicsBody()->setCollisionBitmask(0x02); // 碰撞(不可穿透)
sp3->getPhysicsBody()->setContactTestBitmask(0x01); // 接触(触发检测函数)
掩码运算规则
- 两种状态:在物理引擎中,存在碰撞(不可穿透)和接触(触发检测函数)两种状态。
- 运算方式
- 碰撞运算:要判断是否发生碰撞,需将当前物体的碰撞值与对方的种类值进行按位与运算,此运算与接触无关。
- 接触运算:要判断是否触发接触,需将当前物体的接触值与对方的种类值进行按位与运算。
- 特殊情况
- 若将种类掩码设置为
0
,则该物体与任何物体都不会发生碰撞,可能会跑出边界外。 - 种类与碰撞:当按位与运算结果为
1
时会发生碰撞,为0
则不碰撞。例如,种类设置为01
,碰撞设置为02
,按位与运算结果为0
,则不会发生碰撞。 - 种类与接触:当按位与运算结果为
1
时会触发碰撞检测,否则不检测。例如,种类设置为01
,接触设置为02
,按位与运算结果为0
,则不会触发检测。
3. 两个精灵的碰撞和接触判断
对于两个精灵,需同时考虑A的种类与B的碰撞、B的种类与A的碰撞以及A的种类与B的接触、B的种类与A的接触。只要其中有一个按位与运算结果不为1
,就不会发生碰撞或触发接触检测。
示例代码(碰撞判断):
A->setCategoryBitmask(1); // 种类
A->setCollisionBitmask(5); // 碰撞
B->setCategoryBitmask(1); // 种类
B->setCollisionBitmask(2); // 碰撞
示例代码(接触判断):
A->setCategoryBitmask(5); // 种类
A->setContactTestBitmask(1); // 接触
B->setCategoryBitmask(2); // 种类
B->setContactTestBitmask(4); // 接触
使用技巧
1. 数值选择
一般建议使用2的N次方的数进行设置,这样可以减少种类数量。若将某些物体的相关值设置为相同的2的N次方数,它们就会发生碰撞或接触。
2. 避免碰撞
若不想让物体发生碰撞,可将碰撞值设置为一个2的N次方的数,而其他物体的相关值设置得比它小。
示例代码:
shape1->setCategoryBitmask(2); // 种类
shape1->setCollisionBitmask(64); // 碰撞
shape1->setContactTestBitmask(8); // 接触
3. 避免接触
若不想让物体触发接触检测,可将接触值设置为一个2的N次方的数,其他物体的相关值设置得比它小。
示例代码:
shape2->setCategoryBitmask(2); // 种类
shape2->setCollisionBitmask(8); // 碰撞
shape2->setContactTestBitmask(64); // 接触
4. 实现特定碰撞
若要实现特定的碰撞效果,可直接对调两个SHAPE
的种类值和碰撞值,这种方法在处理多个不同shape
时非常有用,对于接触设置同样适用。
示例场景:A类精灵有两个SHAPE
(A1和A2),B类精灵有两个SHAPE
(B1和B2),要求A1只和B2碰撞,B1只和A2碰撞,其他情况不碰撞。
实现步骤:
- A类精灵设置:为避免A类精灵内部的
SHAPE
之间发生碰撞,使用不同的2的N次方的数进行设置。shapeA1->setCategoryBitmask(2); // 种类 shapeA1->setCollisionBitmask(4); // 碰撞 shapeA1->setContactTestBitmask(64); // 接触
shapeA2->setCategoryBitmask(16); // 种类 shapeA2->setCollisionBitmask(8); // 碰撞 shapeA2->setContactTestBitmask(64); // 接触
- **B类精灵设置**:通过对调`SHAPE`的种类值和碰撞值,实现A1只和B2碰撞,B1只和A2碰撞。
shapeB1->setCategoryBitmask(8); // 种类 shapeB1->setCollisionBitmask(16); // 碰撞 shapeB1->setContactTestBitmask(64); // 接触
shapeB2->setCategoryBitmask(4); // 种类 shapeB2->setCollisionBitmask(2); // 碰撞 shapeB2->setContactTestBitmask(64); // 接触
通过以上设置和技巧,开发者可以灵活地控制Cocos2d-x物理引擎中物体的碰撞和接触行为。