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

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

本文关键字:冲突 C++ v3 何检查 检查 cocos2d-x      更新时间:2023-10-16

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

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

碰撞筛选允许您防止形状之间的冲突。Cocos2d-x>支持使用类别和组位掩码进行冲突过滤。

Cocos2d-x 支持 32 种碰撞类别。对于每个形状,您可以指定它所属的类别。您还可以指定此形状可以与哪些其他类别发生冲突。这是通过屏蔽位完成的

问题是当我设置时:

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;
    }

这是我一直在关注的指南。

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

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