2014-01-05 86 views
0

我有兩個身體,每個身體直徑1米,我將一個身體移向另一個身體,並且只是在它撞到另一個身體的邊緣時停止它。box2d,聯繫人出現得太早

爲此,我在每次更新時都會查看移動身體的聯繫人列表,但即使它仍然像0.2米一樣走動,移動身體停在遠處,您可以在截圖中看到與另一個身體的聯繫。

我不知道該怎麼做。也許它更好地使用contact listener和preSolve函數,而不是_body-> getContactList?

screenshot

回答

0

我已經找到了聯繫人的超大型精英IsTouching()屬性)) 問題解決

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()); 
     */ 
    } 
};