2010-10-20 31 views
0

我在我的iPhone遊戲中使用cocos2d和box2d。如何在碰撞後移除Box2d中的對象,但延遲?

當兩個球碰到對方時,我通過ContactListener獲得了一個通知,並且我有兩個身體的引用。

我可以摧毀他們兩個,但我想延遲這樣做。

因此,兩個球碰到對方,他們反彈,然後在第二次消失後。

回答

0

然後在BeginContact或EndContact中啓動一個計時器,然後刪除Body。

+0

你能更多地提高嗎? – 2013-05-23 13:39:31

0

我使用一個類(下)我的衝突處理過濾掉重複的衝突,並通過消息系統發送通知「實體」的對象。

注意:這是更大的代碼庫的一部分;隨時提出任何問題,如果你需要澄清,因爲代碼不在這裏。

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

一旦實體收到消息,每個人都可以啓動一個計時器,並在需要的時候自我毀滅。或者你可以讓你的消息延遲排隊,以便在遊戲的消息處理階段被破壞(如果有的話)。這很好,因爲它可以讓你明確地控制何時發生破壞,並且在物理過程中不會發生這種情況,這可能會導致引擎出現問題。