Cocos2d x 使用动作移动精灵时不会发生花栗鼠碰撞

Cocos2d x 使用动作移动精灵时不会发生花栗鼠碰撞,cocos2d-x,chipmunk,Cocos2d X,Chipmunk,这是一个基本的问题,但我把一个有物理体的精灵a移到另一个有物理体的精灵B上。我希望对这些物体调用碰撞回调oncontact。它们分别使用setCategoryBitmask()设置各自的类别位掩码,还分别使用setContactTestBitmask()设置彼此的类别 只要我不移动精灵A,碰撞就会发生。我假设问题是我使用cocos2d动作移动精灵A,我需要做其他事情。但是在我看来,使用cocos2d操作编写类似的脚本要比我能想到的任何事情都简单得多 使用物理调用移动精灵A。(看起来需要做很多工

这是一个基本的问题,但我把一个有物理体的精灵a移到另一个有物理体的精灵B上。我希望对这些物体调用碰撞回调oncontact。它们分别使用
setCategoryBitmask()
设置各自的类别位掩码,还分别使用
setContactTestBitmask()
设置彼此的类别

只要我不移动精灵A,碰撞就会发生。我假设问题是我使用cocos2d动作移动精灵A,我需要做其他事情。但是在我看来,使用cocos2d操作编写类似的脚本要比我能想到的任何事情都简单得多

  • 使用物理调用移动精灵A。(看起来需要做很多工作,而且很难实现精确的脚本编写完美)
  • 在update()中执行我自己的碰撞检测。(看起来也是一堆工作,特别是如果精灵旋转等)
还有别的捷径吗?还是我错过了别的什么?

我最后做了“在update()中执行我自己的碰撞检测”。这不太成问题

更新()中的类似内容


当collion不工作时,接触检测应该很好

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::createWithPhysics();

    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

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

    scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
    scene->getPhysicsWorld()->setGravity(Vec2::ZERO);

    // return the scene
    return scene;
}

bool HelloWorld::init()
{
   if ( !Layer::init() )
    {
        return false;
    }

    auto createSprite = [this](const Vec2& pos) {
        auto sprite = Sprite::create();
        auto bodyA = PhysicsBody::createCircle(20);
        sprite->setPhysicsBody(bodyA);
        sprite->setPosition(pos);

        bodyA->setCollisionBitmask(0xff);
        bodyA->setCategoryBitmask(0xff);
        bodyA->setContactTestBitmask(0xff);

        return sprite;
    };

    auto spriteA = createSprite(Vec2(300, 300));
    auto moveBy = MoveBy::create(1.f, Vec2(200, 200));
    spriteA->runAction(moveBy);

    auto spriteB = createSprite(Vec2(350, 350));

    addChild(spriteA);
    addChild(spriteB);

    auto contactListener = EventListenerPhysicsContact::create();
    contactListener->onContactBegin = [=](PhysicsContact& contact) {
        auto a = contact.getShapeA()->getBody()->getNode();
        auto b = contact.getShapeB()->getBody()->getNode();

        assert((a == spriteA && b == spriteB) || (a == spriteB && b == spriteA));

        log("It is working");

        return false;
    };

    _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);

    return true;
}
Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::createWithPhysics();

    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

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

    scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
    scene->getPhysicsWorld()->setGravity(Vec2::ZERO);

    // return the scene
    return scene;
}

bool HelloWorld::init()
{
   if ( !Layer::init() )
    {
        return false;
    }

    auto createSprite = [this](const Vec2& pos) {
        auto sprite = Sprite::create();
        auto bodyA = PhysicsBody::createCircle(20);
        sprite->setPhysicsBody(bodyA);
        sprite->setPosition(pos);

        bodyA->setCollisionBitmask(0xff);
        bodyA->setCategoryBitmask(0xff);
        bodyA->setContactTestBitmask(0xff);

        return sprite;
    };

    auto spriteA = createSprite(Vec2(300, 300));
    auto moveBy = MoveBy::create(1.f, Vec2(200, 200));
    spriteA->runAction(moveBy);

    auto spriteB = createSprite(Vec2(350, 350));

    addChild(spriteA);
    addChild(spriteB);

    auto contactListener = EventListenerPhysicsContact::create();
    contactListener->onContactBegin = [=](PhysicsContact& contact) {
        auto a = contact.getShapeA()->getBody()->getNode();
        auto b = contact.getShapeB()->getBody()->getNode();

        assert((a == spriteA && b == spriteB) || (a == spriteB && b == spriteA));

        log("It is working");

        return false;
    };

    _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);

    return true;
}