Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Physics Body Collision and Contact Issues #8399

minggo opened this issue Sep 30, 2014 · 4 comments

Physics Body Collision and Contact Issues #8399

minggo opened this issue Sep 30, 2014 · 4 comments


Copy link

minggo commented Sep 30, 2014


This issue is migrated from here. It was created at 2014/04/06 18:34:49 +0000


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

// Set BOTH contact test bitmasks (expected to only have to set one)

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!

  • Thruxton added comment:
    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);

// Set boundary body and add to scene

// 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());

// Set hero body and add to scene


  • NOTICE: If I don't set the contact test bitmask on my hero
  • body, the event listener's onContactBegin callback will not
  • be called.


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

@minggo minggo added the type:bug label May 7, 2015
@minggo minggo added this to the unconfirmed milestone May 7, 2015
Copy link

I have meet this issue too.
the document says that in CCPhysicsBody.h,either comparison results is non-zero, the event will be dispatched:

     * 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)  

I guess this is the bug,the code should be write like this:

    if ((shapeA->getCategoryBitmask() & shapeB->getContactTestBitmask()) == 0  
        && (shapeA->getContactTestBitmask() & shapeB->getCategoryBitmask()) == 0)  

change || to &&

Copy link

jgcoded commented Dec 28, 2015

@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.

Copy link

@minggo - I was just baffling around this. Any idea when this bug will be smashed?

Copy link

shauket commented Mar 18, 2016

one body should be setDynamic true


@minggo minggo removed this from the unconfirmed milestone Aug 19, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet

No branches or pull requests

5 participants