遇到物理身体碰撞/接触不能按照我预期的方式工作的问题。我可能会误解他们应该如何工作。我的理解是,如果physicsBodyA的类别位掩码为0x1,而physicsBodyB的接触测试位掩码为0x1,则联系测试应评估为true,我应该从事件调度程序获得回调。
但是,这并不起作用。我得到联系评估为true的唯一方法是我还设置physicsBodyA的联系位掩码以匹配physicsBodyB的类别位掩码。基本上,类别和接触测试位掩码必须彼此镜像。在实践中它看起来像这样:bool TestLayer::init() {
// Call super init
if (!Layer::init()) {
return false;
}
// Get screen size
Size visibleSize = Director::getInstance()->getVisibleSize();
// Bitmasks
int BITMASK_BOUNDARY = 0x1 << 0;
int BITMASK_HERO = 0x1 << 1;
// Boundary node
Node *boundaryNode = Node::create();
boundaryNode->setAnchorPoint(Point(0.5, 0.5));
boundaryNode->setPosition(Point(visibleSize.width/2.0, visibleSize.height/2.0));
// Physics body for boundary node
PhysicsBody *boundaryBody = PhysicsBody::createEdgeBox(visibleSize);
boundaryBody->setCategoryBitmask(BITMASK_BOUNDARY);
boundaryBody->setContactTestBitmask(BITMASK_HERO);
boundaryBody->setDynamic(false);
// Set boundary body and add to scene
boundaryNode->setPhysicsBody(boundaryBody);
this->addChild(boundaryNode);
// Hero node
Sprite *hero = Sprite::create("hero_ship.png");
hero->setPosition(Point(visibleSize.width/2.0, visibleSize.height - 30.0));
// Physics body for hero node
PhysicsBody *heroBody = PhysicsBody::createBox(hero->getContentSize());
heroBody->setCategoryBitmask(BITMASK_HERO);
// Set hero body and add to scene
hero->setPhysicsBody(heroBody);
this->addChild(hero);
/*
* NOTICE: If I don't set the contact test bitmask on my hero
* body, the event listener onContactBegin callback will not
* be called.
*/
heroBody->setContactTestBitmask(BITMASK_BOUNDARY);
// Create an event listener
EventListenerPhysicsContact *listener = EventListenerPhysicsContact::create();
// Use lambda for listener callback
listener->onContactBegin = [](PhysicsContact &contact) {
CCLOG("Physics contact began.");
return true;
};
// Register listener with event dispatcher
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
// Everything worked out on init, return true
return true;
}
答案 0 :(得分:0)
来自Box2D手册:
--------引用
碰撞过滤可以防止灯具之间发生碰撞。 例如,假设您制作一个骑自行车的角色。你要 自行车与地形碰撞和角色碰撞 与地形,但你不希望角色碰撞 自行车(因为它们必须重叠)。 Box2D支持这种碰撞 使用类别和组进行过滤。 Box2D支持16次碰撞 类别。对于每个夹具,您可以指定它属于哪个类别 至。您还可以指定此夹具可能碰撞的其他类别 用。例如,您可以在多人游戏中指定所有 玩家不会相互碰撞,怪物也不会碰撞 彼此,但玩家和怪物应该相互碰撞。这是完成的 掩蔽位。例如:
playerFixtureDef.filter.categoryBits = 0x0002;
monsterFixtureDef.filter.categoryBits = 0x0004;
playerFixtureDef.filter.maskBits = 0x0004;
monsterFixtureDef.filter.maskBits = 0x0002;
以下是发生碰撞的规则:
uint16 catA = fixtureA.filter.categoryBits;
uint16 maskA = fixtureA.filter.maskBits;
uint16 catB = fixtureB.filter.categoryBits;
uint16 maskB = fixtureB.filter.maskBits;
if ((catA & maskB) != 0 && (catB & maskA) != 0)
{
// fixtures can collide
}
--------报价结束
所以最重要的是,如果你想让两件事在碰撞方面以相同的方式做出反应,那么它们必须具有相同的类别和掩码位。
对于更多(非常好的)深入讨论,请继续look at this site(不,这不是我的)。
对于其他一些有趣的Box2D内容,look here(这是我的)。