Cocos2d-x物理引擎碰撞和接触设置的有关问题

2015年03月16日 12:02 1 点赞 1 评论 更新于 2017-05-09 11:44

本文将深入探讨Cocos2d-x物理引擎中碰撞和接触设置的相关问题,这些设置对Box2d和Cocos2d-x 3.2自带的物理引擎均适用。

碰撞设置的三个函数

1. setGroup(int group)

  • 调用方式及作用范围:该函数可由bodyshape调用。若由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物理引擎中物体的碰撞和接触行为。

作者信息

boke

boke

共发布了 1025 篇文章