1
votes

I'm developing a cocos2d-x game (version 3.8). My game uses chipmunk physics and it has a static body that works like an interruptor. This interruptor is enabled when another body is over it. The interruptor is disabled when bodies separate each other.

I want to:

  • Moving body don't collision with interruptor. It has to cross interruptor with no bounce
  • I want to detect when moving body separates the interruptor

My first approach was implementing onContactBegin method. I return false when those two bodies get in touch. This way the body crosses the interruptor and does not bounce.

The problem is onContactSeparate method is not called, because contact did not happen.

If I return true in onContactBegin method, onContactSeparate is called and I can detect it. The problem is the body does not cross the interruptor, it bounces.

[EDIT] More info

This is the scenario where two sprites are separated. The ball can move and interruptor is a static body. Ball could be over the interruptor.

Interruptor disabled

This is the scenario where two sprites are in contact and object1 (the ball) is over the interruptor. I want to detect where two sprites separate each other.

Interruptor enabled

Any help would be appreciated!

1

1 Answers

1
votes

It seems to me like you are using Box2D within cocos, so I'll answer with that as my base assumption.

This is what i would do.

  1. My interrupter would be a b2Body* with no BodyDef dimensions defined or just a 0x0 dimension def.
  2. I would set the user data for the bodyDef to a rectangle that describes my interruption area. This way you can always have your interruption area represented, but will not collide with anything.
  3. (Optional) If you want the interruption area to move around based on the fake body you assigned to it, you can updated it just after the step function using something like below.

    world->Step(delta, 10, 10);   
    for (auto physicsBody = _world->GetBodyList(); physicsBody; physicsBody = physicsBody->GetNext())
    { 
     auto userData = static_cast<Node*>(physicsBody->GetUserData());
     if(userData != NULL)
     {
       // Set interruptor area rectangle = physicsBody->GetPosition();
     }
    }
    
  4. To let the rest of the system know when I have left the interrupter I would store a function pointer to the function I want to call when this happens, When a object enters the interruption area I would flag it saying "I'm in the area" after that, the first update step you get when it's not in the area anymore I would fire the callback and reset the flags I used to get to that point.

I hope this helps. You are not giving a lot of context for what you want to do, an image would be helpful. Especially when it comes to looking for help with code that has a visual representation as well.

[EDIT] Based on the behaviour you want this is the way I did this. The first thing to know is that you don't need physics collisions for the behaviour you want. You can do this by using bounding box intersection tests and use flags and callbacks to figure out the rest.

I have an object that knows about both the ball and my interrupter nodes. In the update loop of this object I check if the two intersects. I set a flag indicating "I am in the interrupter", the next frame that I am not in the interrupter and my flag is still true I call the function that I assigned with my "leaving logic" in it, and set then flag back to false.