2014-04-06 14 views
1

遇到物理體碰撞/接觸不按我期望的方式工作的問題。我可能會誤解他們應該如何工作。我的理解是,如果physicsBodyA具有0x1的類別位掩碼,並且physicsBodyB具有0x1的接觸測試位掩碼,則聯繫測試應評估爲true,我應該從事件分派器獲得回調。Cocos2d-x v3.0rc1物理接觸物聯繫人問題

但是這不起作用。我接觸評估爲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

從Box2D的手冊:

--------引用

碰撞過濾,可以防止碰撞夾具之間。例如,假設你製作一個騎着自行車的角色。你想要 自行車碰撞地形和角色與地形碰撞 ,但你不希望角色與自行車碰撞(因爲他們必須重疊)。 Box2D支持使用類別和組進行衝突 篩選。 Box2D支持16種碰撞 類別。對於每個燈具,您可以指定它屬於哪個類別 。您還可以指定該燈具可以碰撞的其他類別 。例如,您可以在多人遊戲中指定所有玩家不會彼此碰撞,並且怪物不會與對方 相撞,但是玩家和怪物應該相互碰撞。這是通過掩碼位 完成的。例如:

playerFixtureDef.filter.categoryBits = 0x0002; 
monsterFixtureDef.filter.categoryBits = 0x0004; 
playerFixtureDef.filter.maskBits = 0x0004; 
monsterFixtureDef.filter.maskBits = 0x0002; 

這裏是規則發生的碰撞:

​​

--------引用結束

所以底線是,如果你想讓兩件事情以同樣的方式與ea作出反應就碰撞而言,它們都必須具有相同的類別和掩碼位。

對於一些更好的(非常好的)深入討論,請繼續和look at this site(不,它不是我的)。

對於一些其他有趣的Box2D的東西,look here(這是我的)。

+1

請注意,Cocos2d-x v3不使用Box2d,但使用Chipmunk,並且Box2d使用的2位掩碼與Cocos2d-x中使用的3位掩碼相關的方式並不那麼明顯。 – trojanfoe