我在我的iPhone遊戲中使用cocos2d和box2d。如何在碰撞後移除Box2d中的對象,但延遲?
當兩個球碰到對方時,我通過ContactListener獲得了一個通知,並且我有兩個身體的引用。
我可以摧毀他們兩個,但我想延遲這樣做。
因此,兩個球碰到對方,他們反彈,然後在第二次消失後。
我在我的iPhone遊戲中使用cocos2d和box2d。如何在碰撞後移除Box2d中的對象,但延遲?
當兩個球碰到對方時,我通過ContactListener獲得了一個通知,並且我有兩個身體的引用。
我可以摧毀他們兩個,但我想延遲這樣做。
因此,兩個球碰到對方,他們反彈,然後在第二次消失後。
然後在BeginContact或EndContact中啓動一個計時器,然後刪除Body。
我使用一個類(下)我的衝突處理過濾掉重複的衝突,並通過消息系統發送通知「實體」的對象。
注意:這是更大的代碼庫的一部分;隨時提出任何問題,如果你需要澄清,因爲代碼不在這裏。
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());
*/
}
};
一旦實體收到消息,每個人都可以啓動一個計時器,並在需要的時候自我毀滅。或者你可以讓你的消息延遲排隊,以便在遊戲的消息處理階段被破壞(如果有的話)。這很好,因爲它可以讓你明確地控制何時發生破壞,並且在物理過程中不會發生這種情況,這可能會導致引擎出現問題。
你能更多地提高嗎? – 2013-05-23 13:39:31