【问题标题】:Chipmunk collisions not happening when moving sprite using actions使用动作移动精灵时不会发生花栗鼠碰撞
【发布时间】:2016-03-09 22:13:56
【问题描述】:

确实是一个基本问题,但我正在将具有物理主体的精灵 A 移动到具有另一个物理主体的另一种精灵 B 上。我希望为这些物体调用碰撞回调 oncontact。它们使用setCategoryBitmask() 设置各自的类别位掩码,并且使用setContactTestBitmask() 分别设置彼此的类别。

只要我不移动精灵 A,碰撞就会起作用。我认为问题是我使用 cocos2d 动作移动了精灵 A,我需要做其他事情。但是使用 cocos2d 动作来编写这样的脚本对我来说看起来比我能想到的任何其他事情都要简单。

  • 使用物理调用移动精灵 A。 (看起来工作量很大,而且似乎很难达到精确的脚本完美)
  • 改为在 update() 中进行我自己的碰撞检测。 (看起来也像一堆工作,特别是如果精灵旋转等)

还有其他捷径吗?还是我错过了什么?

【问题讨论】:

    标签: cocos2d-x chipmunk


    【解决方案1】:

    我最终做了“在 update() 中做我自己的碰撞检测”。问题不大。

    update() 中的类似内容...

    const Rect RECT_A = spriteA->getBoundingBox();
    for (auto spriteB : someparent->getChildren()) {
        const Rect RECT_B = spriteB->getBoundingBox();
        if (RECT_A.intersectsRect(RECT_B)) {
             // Hit
        }
    }
    

    【讨论】:

      【解决方案2】:

      如果碰撞检测不起作用,接触检测应该没问题。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-03
        • 1970-01-01
        • 2021-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多