Cocos2d x 碰撞检测在cocos2dx v3中无法使用物理

Cocos2d x 碰撞检测在cocos2dx v3中无法使用物理,cocos2d-x,box2d,Cocos2d X,Box2d,我想用物理引擎碰撞两个精灵。 但是我的联系人没有回应。日志或运行时没有警告/错误。 以下是我所做的: 声明 1)cocos2d::PhysicsWorld* m_world; 2)void setPhyWorld(cocos2d::PhysicsWorld* world){m_world = world;} 3)bool onContactBegin(cocos2d::PhysicsContact& contact); 实施 对于PhysicsWorld: 场景-> Scene* He

我想用物理引擎碰撞两个精灵。 但是我的联系人没有回应。日志或运行时没有警告/错误。 以下是我所做的:

声明

1)cocos2d::PhysicsWorld* m_world;
2)void setPhyWorld(cocos2d::PhysicsWorld* world){m_world = world;}
3)bool onContactBegin(cocos2d::PhysicsContact& contact);
实施 对于PhysicsWorld: 场景->

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::createWithPhysics();
    scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);

    auto layer = HelloWorld::create();
    layer->setPhyWorld(scene->getPhysicsWorld());

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}
物理世界->

void HelloWorld::createPhysicsWorld(){

    auto body = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3);
    auto edgeNode = Node::create();
    edgeNode->setPosition(Point(visibleSize.width/2,visibleSize.height/2));
    edgeNode->setPhysicsBody(body);
    this->addChild(edgeNode);
}
创建精灵->

void HelloWorld::createCar(){
    car = Sprite::create("car.png");

    auto body3 = PhysicsBody::createBox(car->getContentSize());
    body3->setDynamic(false);
    body3->setCategoryBitmask(2);
    body3->setCollisionBitmask(2);
    body3->setContactTestBitmask(true);
    car->setPhysicsBody(body3);
    // position the sprite on the center of the screen
    car->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

    // add the sprite as a child to this layer
    this->addChild(car, 1);

    car->setAnchorPoint(Vec2(0.5, 0));

    car->setFlippedX(true);
}

void HelloWorld::createRocket(){
    rocket = Sprite::create("rocket.png");

    auto body2 = PhysicsBody::createBox(rocket->getContentSize());
    body2->setDynamic(false);
    body2->setCategoryBitmask(1);
    body2->setCollisionBitmask(1);
    body2->setContactTestBitmask(true);
    rocket->setPhysicsBody(body2);

    // position the sprite on the center of the screen
    rocket->setPosition(Vec2(visibleSize.width/2 + origin.x,origin.y));

    // add the sprite as a child to this layer
    this->addChild(rocket, 1);

}
碰撞->

 auto contactListener = EventListenerPhysicsContact::create();
    contactListener->onContactBegin = CC_CALLBACK_1(HelloWorld::onContactBegin, this);
    this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(contactListener,this);
ContactListner->

bool HelloWorld::onContactBegin(cocos2d::PhysicsContact& contact)
{   
    CCLOG("onContactBegin -------> ");
    return true;
}                                                            

嗯,原来这是一个有点丑陋的错误

body3->setContactTestBitmask(true);
此方法的参数是位掩码而不是'true'/'false'字段,因此您的'true'掩码被视为1,而您的实体掩码为2。解决办法是:

body3->setCategoryBitmask(1);
body3->setCollisionBitmask(3);
body3->setContactTestBitmask(1);

body2->setCategoryBitmask(3);
body2->setCollisionBitmask(1);
body2->setContactTestBitmask(1);

嗯,原来这是一个有点丑陋的错误

body3->setContactTestBitmask(true);
此方法的参数是位掩码而不是'true'/'false'字段,因此您的'true'掩码被视为1,而您的实体掩码为2。解决办法是:

body3->setCategoryBitmask(1);
body3->setCollisionBitmask(3);
body3->setContactTestBitmask(1);

body2->setCategoryBitmask(3);
body2->setCollisionBitmask(1);
body2->setContactTestBitmask(1);

我只是注释掉
body2->setDynamic(false)内部createRocket方法和setGravityEnable(false);现在它可以工作了

void HelloWorld::createRocket(){
    rocket = Sprite::create("rocket.png");
    rocket->setPosition(Vec2(visibleSize.width/2 + origin.x,origin.y - 50));
    rocket->setTag(3);
    auto body2 = PhysicsBody::createBox(rocket->getContentSize());
    //body2->setDynamic(false);
    body2->setTag(3);
    body2->setGravityEnable(false);
    body2->setCollisionBitmask(3);
    body2->setContactTestBitmask(true);
    rocket->setPhysicsBody(body2);

    this->addChild(rocket, 1);

}

我只是注释掉
body2->setDynamic(false)内部createRocket方法和setGravityEnable(false);现在它可以工作了

void HelloWorld::createRocket(){
    rocket = Sprite::create("rocket.png");
    rocket->setPosition(Vec2(visibleSize.width/2 + origin.x,origin.y - 50));
    rocket->setTag(3);
    auto body2 = PhysicsBody::createBox(rocket->getContentSize());
    //body2->setDynamic(false);
    body2->setTag(3);
    body2->setGravityEnable(false);
    body2->setCollisionBitmask(3);
    body2->setContactTestBitmask(true);
    rocket->setPhysicsBody(body2);

    this->addChild(rocket, 1);

}

你在代码中遗漏了一件棘手的事情,一个主体应该设置为true

body->setDynamic(真)


干杯

代码中遗漏了一件棘手的事情。一个主体应该设置为dynamic为true

body->setDynamic(真)


干杯

我认为碰撞位掩码必须是相同的。根据cocos参考:通过执行逻辑“与”运算,将该主体的碰撞掩码与另一主体的类别掩码进行比较我也这样做了。但setCollisionBitmask用于检测哪个物理体与其他物理体发生碰撞以执行不同的操作。这看起来更像是Box2D,而不是花栗鼠,更改了标记。我认为碰撞位掩码必须是相同的。根据cocos参考:通过执行逻辑“与”运算,将该主体的碰撞掩码与另一主体的类别掩码进行比较我也这样做了。但setCollisionBitmask用于检测哪个物理体与其他物理体发生碰撞以执行不同的操作。这看起来更像是Box2D,而不是花栗鼠,更改的标记。最好使用十六进制数字。我该如何感谢你?我浪费了数小时设置错误的“接触测试掩码”。我阅读了API参考,发现只有当联系人测试掩码和类别掩码的逻辑and为非零值时,才会注册联系人。最好使用十六进制数字。我该如何感谢您?我浪费了数小时设置错误的“接触测试掩码”。我阅读了API参考,发现只有当contact test mask和category mask的逻辑and为非零值时,才会注册contact。