android - Cocos2d-x v3.0rc1 PhysicsBody 接触问题

标签 android c++ ios cocos2d-x

遇到物理体碰撞/接触未按我预期的方式工作的问题。我可能误解了它们应该如何工作。我的理解是,如果 physicsBodyA 的类别位掩码为 0x1,而 physicsBodyB 的接触测试位掩码为 0x1,则接触测试应该评估为真,我应该从事件调度程序获得回调。

然而,这是行不通的。使接触评估为真的唯一方法是我还设置 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;
}

最佳答案

来自 Box2D 手册:

-------- 引用

Collision filtering allows you to prevent collision between fixtures. For example, say you make a character that rides a bicycle. You want the bicycle to collide with the terrain and the character to collide with the terrain, but you don't want the character to collide with the bicycle (because they must overlap). Box2D supports such collision filtering using categories and groups. Box2D supports 16 collision categories. For each fixture you can specify which category it belongs to. You also specify what other categories this fixture can collide with. For example, you could specify in a multiplayer game that all players don't collide with each other and monsters don't collide with each other, but players and monsters should collide. This is done with masking bits. For example:

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

Here is the rule for a collision to occur:

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
}

-------- 引用结束

所以最重要的是,如果您希望两个事物在碰撞方面以相同的方式相互 react ,那么它们都必须具有相同的类别和掩码位。

要对此进行更多(非常好的)深入讨论,请继续 look at this site (不,这不是我的)。

对于其他一些有趣的 Box2D 内容,look here (这是我的)。

关于android - Cocos2d-x v3.0rc1 PhysicsBody 接触问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22900147/

相关文章:

android - Cocos2dx Android I'm broken phenomenon 启动后是一个图像 Sprite onResume Activity

android - 效率、资源——将所有数据存储在一个或多个ArrayList中

c# - C++ 从另一个程序集继承 WPF 窗口并处理事件

c++ - SDL_PollEvent 有时在屏幕重新连接后不捕获触摸事件

ios - 为什么我的 tableView 没有被填充?

ios - 使用 detox 测试 e2e 无法启动 iPhone 模拟器,而是启动 Apple TV

java - 预定的执行者服务。如何在两个单独的服务中经过一段时间后运行两个任务

android - 智能转换为 (Int) 是不可能的,因为 <variable> 是一个局部变量,由变化的闭包捕获

C++ 编译时错误

ios - GCD : does thread only has two types? 主线程和后台线程