Getting the world's contactListener in Box2D

前端 未结 2 1771
梦毁少年i
梦毁少年i 2021-01-28 21:09

I\'m writing a game for Mac OS using cocos2D and Box2D. I\'ve added a b2ContactListener subclass to my world as follows:

contactListener = new Cont         


        
相关标签:
2条回答
  • 2021-01-28 21:43

    A contact listener just serves as an entry point for the four functions BeginContact, EndContact, PreSolve and PostSolve. Typically it has no member variables, so there is no reason to get it, because there is nothing to get from it.

    When one of these functions is called during a world Step, you can make a note of which two things touched/stopped touching etc, but you should not change anything in the world right away, until the time step is complete.

    I think the crux of this question is the method used to 'make a note' of which things touched, but that's really up to you and depends on what kind of information you need. For example if you're only interested in BeginContact, then the absolute simplest way might be to just store which two fixtures touched as a list of pairs:

    std::vector< std::pair<b2Fixture*, b2Fixture*> > thingsThatTouched;
    
    //in BeginContact
    thingsThatTouched.push_back( make_pair(contact->GetFixtureA(), contact->GetFixtureB()) );
    
    //after the time step
    for (int i = 0; i < thingsThatTouched.size(); i++) {
        b2Fixture* fixtureA = thingsThatTouched[i].first;
        b2Fixture* fixtureB = thingsThatTouched[i].second;
        // ... do something clever ...
    }
    thingsThatTouched.clear(); //important!!
    

    For this to work you'll need to make the thingsThatTouched list visible from the contact listener function, so it could either be a global variable, or you could set a pointer to it in the contact listener class, or maybe have a global function that returns a pointer to the list.

    If you need to keep track of more information such as what things stopped touching, or do something after the time step based on how hard things impacted when they touched etc, it will take a bit more work and becomes more specific. You might find these tutorials useful:

    This one uses BeginContact/EndContact to update a list of which other things a body is touching, and uses it to decide if a player can jump at any given time: http://www.iforce2d.net/b2dtut/jumpability

    This one uses a similar method to look at what type of surfaces are currently under a car tire, to decide how much friction the surface has: http://www.iforce2d.net/b2dtut/top-down-car

    This one uses PreSolve to decide whether two bodies (arrow and target) should stick together when they collide, based on the speed of the impact. The actual 'sticking together' processing is done after the time step finishes: http://www.iforce2d.net/b2dtut/sticky-projectiles

    0 讨论(0)
  • 2021-01-28 21:56

    I think you simply can call GetContactList and then process all the contacts using iterator if you need to do it in some other place

    0 讨论(0)
提交回复
热议问题