ContactListener for Collision Event - SWTube/Darkest-Cave GitHub Wiki

๊ฐœ์š”

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