如何检查 cocos2d-x v3.1 中的特定冲突? C++

How to check for specific collisions in cocos2d-x v3.1? C++

我正在尝试检查精灵与物理物体之间的特定碰撞。问题是我不知道如何为每个节点物理体分配标签或为每个精灵正确设置碰撞位掩码。我成功地检查了碰撞,但它只是所有对象的真或假。

我正在遵循下面链接的 cocos2d-x 文档中的指南。其中解释了如何设置屏蔽位和屏蔽类别。

Collision filtering allows you to prevent collision between shapes. Cocos2d-x >supports collision filtering using category and groups bitmasks.

Cocos2d-x supports 32 collision categories. For each shape you can specify which category it belongs to. You also specify what other categories this shape can collide with. This is done with masking bits

问题是当我设置:

sprite1->getPhysicsBody()->setCategoryBitmask(0x02); // 0010 sprite1->getPhysicsBody()->setCollisionBitmask(0x01); // 0001

没有那些精灵的碰撞检测。但是当我设置:

invaderPhysicsBody->setContactTestBitmask(true);

碰撞检测。

有人知道如何成功设置碰撞位掩码或类别位掩码吗?

可能发生碰撞的对象:

  1. 入侵者的精灵矢量。
  2. 玩家导弹向量
  3. 入侵者导弹的矢量
  4. 玩家精灵
  5. 四个盾牌精灵

这是我的 onContactBegin 函数,一旦节点发生碰撞,它就会移除节点。这是我需要测试哪些对象发生碰撞的地方。

bool Gameplay::onContactBegin(PhysicsContact &contact) {
    std::cout << "onContactBegin -------> " << std::endl;
    player_score += 10;

    auto nodeA = contact.getShapeA()->getBody()->getNode();
    auto nodeB = contact.getShapeB()->getBody()->getNode();

    std::cout << contact.getShapeA()->getTag() << std::endl;

    if ((contact.getShapeA()->getCategoryBitmask() & contact.getShapeB()->getCollisionBitmask()) == 0
        || (contact.getShapeB()->getCategoryBitmask() & contact.getShapeA()->getCollisionBitmask()) == 0)
    {
        std::cout << "Overlap!" << std::endl;
    }
    nodeA->removeFromParent();
    nodeB->removeFromParent();

    return true;
}

这是我的碰撞侦听器:

 // Enable collision listener.
    auto contactListener = EventListenerPhysicsContact::create();
    contactListener->onContactBegin = CC_CALLBACK_1(Gameplay::onContactBegin, this);
    this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(contactListener, this);

这就是我目前为精灵创建和设置物理形体的方式:

int spacing = 0;
    // Four Player Shields
    for (int i = 0; i < 4; i++) {


        auto shield = Sprite::create("player_shield.png");

        auto shield_x = shield->getContentSize();
        auto shield_y = shield->getContentSize();
        auto shieldPhysicsBody = PhysicsBody::createBox(Size(shield_x.width,shield_y.height), PHYSICSBODY_MATERIAL_DEFAULT);

        shieldPhysicsBody->setContactTestBitmask(true);
        shieldPhysicsBody->setDynamic(true);
        shieldPhysicsBody->setTag(0);

        shield->setPosition(Vec2(200 + spacing, 150));

        shield->addComponent(shieldPhysicsBody);
        this->addChild(shield);
        spacing += 200;
    }

Here is the guide I've been following.

你的代码有很大的错误。 setContactTestBitmask 接受 int 而不是 bool。当你调用shieldPhysicsBody->setContactTestBitmask(true)时,它实际上是shieldPhysicsBody->setContactTestBitmask(0x0000001)。并且 0x000001 & 0x000010 = 0,因此不会引发任何联系事件。 spriteA 的 categoryBitmask 和 spriteB 的 ContactTestBitmask 的 & 结果决定了是否会引发接触事件。顺便说一句,一般来说,您不需要手动检查联系人,即:

if ((contact.getShapeA()->getCategoryBitmask() & contact.getShapeB()->getCollisionBitmask()) == 0
    || (contact.getShapeB()->getCategoryBitmask() & contact.getShapeA()->getCollisionBitmask()) == 0)
{
    std::cout << "Overlap!" << std::endl;
}