How to make two way platform box2d body?

2019-07-18 06:12发布

I have created platform using box2d. I want box2d body detect and not detect dynamically.

Box2d shapes will do the followings

  1. Detect collision on some condition
  2. Not detect collision on some condition

Both condition will work on different condition in same box2d object.

Any idea would help a lot. Thanks in advance.

1条回答
何必那么认真
2楼-- · 2019-07-18 07:08

There are several ways to control what happens when a collision occurs in Box2d. The first thing to do is read this article and decide on what way you want to control it.

That gives you several options. Here is what I did for the last game I worked on where this mattered:

  1. Each actor in the game (space ships, bullets, etc.) has a specific C++ class associated with it (call it the "Controller") This allowed me to combine the logic and container for the Box2d body together.
  2. When I create the Box2d body, I use the usertag to hold a pointer to the Controller for it.
  3. When a collision occurs, I can look at the two colliding objects and make a decision what to do on the spot.

To determine "when the collision occurs", use contact filtering:

/// Implement this class to provide collision filtering. In other words, you can implement
/// this class if you want finer control over contact creation.
class b2ContactFilter
{
public:
    virtual ~b2ContactFilter() {}

    /// Return true if contact calculations should be performed between these two shapes.
    /// @warning for performance reasons this is only called when the AABBs begin to overlap.
    virtual bool ShouldCollide(b2Fixture* fixtureA, b2Fixture* fixtureB);
};

Use the class above as a base class for your own contact class and override the ShouldCollide(...) method with something like this:

virtual bool ShouldCollide(b2Fixture* fixtureA, b2Fixture* fixtureB)
{
bool result = true;
Controller* controllerA = fixtureA->->GetBody()->GetUserData();
Controller* controllerB = fixtureA->->GetBody()->GetUserData();

**Either write code here directly or invoke other function to use controllerA and controllerB to decide if a collision should occur.  This can be as simple or complicated as needed.  You need to set the value of "result".

return result;

}

When you create the body, call

fixture->SetFilterData(filter);

on each fixture attached to the bodies you want to "filter". The filter must "exist" somewhere other than on the stack (maybe as a static member in your Controller itself, so you can customize it).

Was this helpful?

查看更多
登录 后发表回答