我有兩個身體,每個身體直徑1米,我將一個身體移向另一個身體,並且只是在它撞到另一個身體的邊緣時停止它。box2d,聯繫人出現得太早
爲此,我在每次更新時都會查看移動身體的聯繫人列表,但即使它仍然像0.2米一樣走動,移動身體停在遠處,您可以在截圖中看到與另一個身體的聯繫。
我不知道該怎麼做。也許它更好地使用contact listener和preSolve函數,而不是_body-> getContactList?
我有兩個身體,每個身體直徑1米,我將一個身體移向另一個身體,並且只是在它撞到另一個身體的邊緣時停止它。box2d,聯繫人出現得太早
爲此,我在每次更新時都會查看移動身體的聯繫人列表,但即使它仍然像0.2米一樣走動,移動身體停在遠處,您可以在截圖中看到與另一個身體的聯繫。
我不知道該怎麼做。也許它更好地使用contact listener和preSolve函數,而不是_body-> getContactList?
我已經找到了聯繫人的超大型精英IsTouching()屬性)) 問題解決
使用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());
*/
}
};