ContactListener for Collision Event - SWTube/Darkest-Cave GitHub Wiki
-
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(); } } }