box2d,联系人显得太早了

时间:2014-01-05 12:32:49

标签: box2d

我有两个身体,每个身体直径1米,我将一个身体移向另一个身体,并且当它撞到另一个身体的边缘时想要阻止它。

为此,我在每个更新中查看移动身体的联系人列表,但是即使它仍然像0.2米一样,并且移动的身体停在远处,如屏幕截图所示,在那里显示与另一个身体的接触。

我不知道该怎么做。也许最好使用contact listener和preSolve函数而不是_body-> getContactList?

screenshot

2 个答案:

答案 0 :(得分:0)

我找到了联系人的超级精英IsTouching()属性)) 问题解决了

答案 1 :(得分:0)

对于一个/两个精灵来说,使用isTouching()可能是好的,但是当你有很多时,那该怎么办?

我有一个用于过滤联系人并采取行动的课程。我将在下面发布。您可以随意使用它。它还会过滤掉重复的联系人。您可以使用“消息管理器”接收通知,也可以根据需要对其进行修改以采取特殊行为。在物理学的每个更新循环结束时,我调用NotifyCollisions(...)让系统处理它们。

注意:这是更大代码库的一部分;如果您需要澄清,请随时提出任何问题,因为代码不在此处。

  class EntityContactListener : public ContactListener
    {
    private:
       GameWorld* _gameWorld;


  EntityContactListener() {}

   typedef struct 
   {
      Entity* entA;
      Entity* entB;
   } CONTACT_PAIR_T;

   vector<CONTACT_PAIR_T> _contactPairs;

public:
   virtual ~EntityContactListener() {}

   EntityContactListener(GameWorld* gameWorld) :
      _gameWorld(gameWorld)
   {
      _contactPairs.reserve(128);
   }

   void NotifyCollisions()
   {
      Message* msg;
      MessageManager& mm = GameManager::Instance().GetMessageMgr();

      for(uint32 idx = 0; idx < _contactPairs.size(); idx++)
      {
         Entity* entA = _contactPairs[idx].entA;
         Entity* entB = _contactPairs[idx].entB;

         //DebugLogCPP("Contact Notification %s<->%s",entA->ToString().c_str(),entB->ToString().c_str());

         msg = mm.CreateMessage();
         msg->Init(entA->GetID(), entB->GetID(), Message::MESSAGE_COLLISION);
         mm.EnqueueMessge(msg, 0);

         msg = mm.CreateMessage();
         msg->Init(entB->GetID(), entA->GetID(), Message::MESSAGE_COLLISION);
         mm.EnqueueMessge(msg, 0);         
      }
      _contactPairs.clear();
   }

   void PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
   {

   }

   // BEWARE:  You may get multiple calls for the same event.
   void BeginContact(b2Contact* contact)
   {
      Entity* entA = (Entity*)contact->GetFixtureA()->GetBody()->GetUserData();
      Entity* entB = (Entity*)contact->GetFixtureB()->GetBody()->GetUserData();
      //DebugLogCPP("Begin Contact %s->%s",entA->ToString().c_str(),entB->ToString().c_str());
      if(entA->GetGroupID() == entB->GetGroupID())
      {  // Can't collide if they are in the same group.
         return;
      }

      assert(entA != NULL);
      assert(entB != NULL);

      for(uint32 idx = 0; idx < _contactPairs.size(); idx++)
      {
         if(_contactPairs[idx].entA == entA && _contactPairs[idx].entB == entB)
            return;
         // Not sure if this is needed...
         if(_contactPairs[idx].entA == entB && _contactPairs[idx].entA == entB)
            return;
      }
      CONTACT_PAIR_T pair;
      pair.entA = entA;
      pair.entB = entB;
      _contactPairs.push_back(pair);
   }

   // BEWARE:  You may get multiple calls for the same event.
   void EndContact(b2Contact* contact)
   {
      /*
      Entity* entA = (Entity*)contact->GetFixtureA()->GetBody()->GetUserData();
      Entity* entB = (Entity*)contact->GetFixtureB()->GetBody()->GetUserData();
      DebugLogCPP("End Contact %s->%s",entA->ToString().c_str(),entB->ToString().c_str());
       */
   }
};