Physics Body Collision and Contact Issues #8399
Open
Labels
Comments
I have meet this issue too. /**
* A mask that defines which categories of bodies cause intersection notifications with this physics body.
*
* When two bodies share the same space, each body's category mask is tested against the other body's contact mask by performing a logical AND operation. If either comparison results in a non-zero value, an PhysicsContact object is created and passed to the physics world’s delegate. For best performance, only set bits in the contacts mask for interactions you are interested in.
* @param bitmask An integer number, the default value is 0x00000000 (all bits cleared).
*/
void setContactTestBitmask(int bitmask); But the implement code in CCPhysicsWorld.cp, either the comparison results is zero, the event will be disabled: int PhysicsWorld::collisionBeginCallback(PhysicsContact& contact) {
...
// bitmask check
if ((shapeA->getCategoryBitmask() & shapeB->getContactTestBitmask()) == 0
|| (shapeA->getContactTestBitmask() & shapeB->getCategoryBitmask()) == 0)
{
contact.setNotificationEnable(false);
} I guess this is the bug,the code should be write like this: if ((shapeA->getCategoryBitmask() & shapeB->getContactTestBitmask()) == 0
&& (shapeA->getContactTestBitmask() & shapeB->getCategoryBitmask()) == 0)
{
contact.setNotificationEnable(false);
} change |
@youlanhai, I just faced the exact same problem and your solution worked. I can't believe this bug has been there for the past two years. It makes you wonder what else is wrong with cocos2d-x. I'm going to switch over to Box2D to avoid any more of these headaches. |
@minggo - I was just baffling around this. Any idea when this bug will be smashed? |
one body should be setDynamic true body->setDynamic(true); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note
This issue is migrated from here. It was created at 2014/04/06 18:34:49 +0000
Description
Having an issue where physics body collisions/contacts aren't working the way I anticipate. I may be misinterpreting how they're supposed to work. My understanding is that if physicsBodyA has a category bitmask of 0x1, and physicsBodyB has a contact test bitmask of 0x1, contact tests should evaluate to true and I should be getting a callback from the event dispatcher.
This isn't working, however. The only way that I get a contact evaluating to true is of I also set physicsBodyA's contact bitmask to match the category bitmask of physicsBodyB. Basically, the category and contact test bitmasks must mirror one another. In practice it looks something like this:
// Bitmasks
int BITMASK_A = 0x1 << 0;
int BITMASK_B = 0x1 << 1;
// Set category bitmasks
bodyA->setCategoryBitmask(BITMASK_A);
bodyB->setCategoryBitmask(BITMASK_B);
// Set BOTH contact test bitmasks (expected to only have to set one)
bodyA->setContactTestBitmask(BITMASK_B);
bodyB->setContactTestBitmask(BITMASK_A);
Based on the docs and other engines that I've used, this seems wrong, but maybe I'm confused. Any help would be greatly appreciated. Thanks!
Update: wanted to specify that I'm using Cocos2d v3.0rc1, and also attach a small code sample of an init() method to better illustrate my point:
// 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);
/*
*/
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;
The text was updated successfully, but these errors were encountered: