-
Notifications
You must be signed in to change notification settings - Fork 6
ContactListener for Collision Event
CleftObsidian edited this page Oct 11, 2021
·
10 revisions
-
Box2D Collision Processing Flowchart
ContactListener는 PhysicsBody 간의 충돌 시에 호출되는 메소드*를 포함하는 클래스이다.
각 메소드는 조건에 따라 충돌 발생 시 자동으로 호출된다.
Client는 ContactListener를 상속하는 클래스를 만들어 PhysicsWorld에 새로운 Contact Listener로 설정할 수 있다.
메소드를 수정하여 충돌 시 원하는 기능을 수행하게 만들 수 있다.
*BeginContact, EndContact, PreSolve, PostSolve
class ContactListener : public b2ContactListener
{
public:
void BeginContact(b2Contact* contact)
{ /* handle begin event */ }
void EndContact(b2Contact* contact)
{ /* handle end event */ }
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
{ /* handle pre-solve event */ }
void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)
{ /* handle post-solve event */ }
};
-
BeginContact: PhysicsBody들의 Fixture가 겹치는 순간에 호출되는 메소드
void BeginContact(b2Contact* contact) { /* handle begin event */ }
-
EndContact: PhysicsBody들의 Fixture가 겹치는 것을 멈추는 순간에 호출되는 메소드
void EndContact(b2Contact* contact) { /* handle end event */ }
-
PreSolve: 충돌을 감지한 후, 충돌을 처리하기 전에 호출되는 메소드
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold) { /* handle pre-solve event */ }
-
PostSolve: 충돌 처리 이후에 호출되는 메소드
void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) { /* handle post-solve event */ }
-
올라갈 때만 통과 가능한 일방적 플랫폼 구현 시
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold) override { ContactListener::PreSolve(contact, oldManifold); b2Fixture* fixtureA = contact->GetFixtureA(); b2Fixture* fixtureB = contact->GetFixtureB(); if (fixtureA != m_platform && fixtureA != m_character) { return; } if (fixtureB != m_platform && fixtureB != m_character) { return; } b2Vec2 position = m_character->GetBody()->GetPosition(); if (position.y < m_top + m_radius - 3.0f * b2_linearSlop) { contact->SetEnabled(false); } }
-
충돌 속도 감지와 이벤트 구현 시
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold) { b2WorldManifold worldManifold; contact->GetWorldManifold(&worldManifold); b2PointState state1[2], state2[2]; b2GetPointStates(state1, state2, oldManifold, contact->GetManifold()); if (state2[0] == b2_addState) { const b2Body* bodyA = contact->GetFixtureA()->GetBody(); const b2Body* bodyB = contact->GetFixtureB()->GetBody(); b2Vec2 point = worldManifold.points[0]; b2Vec2 vA = bodyA->GetLinearVelocityFromWorldPoint(point); b2Vec2 vB = bodyB->GetLinearVelocityFromWorldPoint(point); float approachVelocity = b2Dot(vB -- vA, worldManifold.normal); if (approachVelocity > 1.0f) { MyPlayCollisionSound(); } } }