1
\$\begingroup\$

I am using box2D and I have two objects, one is bouncy ball and the other one is block. I'd like to find which side of the block is collided with, so I can only make the ball bounce when it hits the top.

I tried to implement many things like fixture data and by detecting position, using manifold but not get the accurate result. I also tried to calculate distance between two object but all went wrong.

\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

On the collision, simply reference the relative positions of the two objects. If the ball is above the block, it struck the top. You really only have to check the y coordinate if you're sure a collision is happening. Something like the following:

enter image description here

Simply check to ensure the y coordinate of the circle is within a tolerance of the box half-height + the radius of the ball. You see that the ball on the left passes the test (its center is within the bounds) and the ball on the right fails (its center is out of the bounds).

\$\endgroup\$
3
  • \$\begingroup\$ what is padding ??? i applied this method also but i am getting problem when ball hit the corners \$\endgroup\$ Commented Nov 24, 2013 at 7:46
  • \$\begingroup\$ The padding is a tolerance that allows the center to be within a small range. This is useful for inaccuracies in the detections and floating point calculations. Update your question with details of the corner problem if you want help with that, I can't do much for you with "getting problem", it doesn't mean anything. \$\endgroup\$
    – House
    Commented Nov 24, 2013 at 7:50
  • \$\begingroup\$ i applied the following code to detect the top and corners if (((positionBall.y-(ball->getContentSize().height/2)) > (positionBox.y+(box->getSize().height/2)))) { ball->playNormalBounceAnimation(); } else { CCLOG("No bounce animation"); ball->playNOBounceAnimation(); } } \$\endgroup\$ Commented Nov 25, 2013 at 7:59
1
\$\begingroup\$

Below is the code I came up with to register the side of a body that a collision occurred. I only have experience with Box2d in a javascript version: box2dweb. I am assuming this code doesn't work for your target platform, but I would guess that there is a similar solution using any Box2D implementation.

var listener = new b2ContactListener;

listener.BeginContact = function (contact) {

  //placeholder for contact point
  var manifold = new b2WorldManifold();

  //fill placeholder with contact "world" contact points
  contact.GetWorldManifold(manifold);

  //NOTE: m_pointCount is compared and not "m_points.length"
  //basically the b2WorldManifold starts with 2 points
  //but does not necessarily solve them
  var point_count = contact.GetManifold().m_pointCount;

  //add up midpoint intermediate values
  for (var i=0;i<point_count;i++){
    midpoint.x += manifold.m_points[i].x;
    midpoint.y += manifold.m_points[i].y;
  }

  //gets the midpoint of the contact points
  if (!(point_count <= 1)) {
    midpoint.x = midpoint.x / point_count;
    midpoint.y = midpoint.y / point_count;

  //only 1 point
  } else {
    midpoint.x = manifold.m_points[0].x;
    midpoint.y = manifold.m_points[0].y;
  }

  //use the Box2d user data field to map back to game object (ent)
  var bA = contact.GetFixtureA().GetBody().GetUserData();
  var bB = contact.GetFixtureB().GetBody().GetUserData();
  if (!bA || !bB) return;
  var A = bA.ent, B = bB.ent;

  //call each entities collision function with the midpoint of the collision
  A.onCollide(B,midpoint.x,midpoint.y);
  B.onCollide(A,midpoint.x,midpoint.y);

}

Entity.prototype.onCollide = function (other_ent,cx,cy) {

  var pos = this.body.GetPosition();

  //careful - gotcha here is that height of SetAsBox is in halves!
  var top = pos.y - this.h / 2;

  var side;

  // unless you are using "bullet" option for a fixture the
  // collision points are typically crossing into the body
  // thus .. adding minor amount of buffer to the top
  if (cy < (top + 0.01) ) {
    side = "top";
  } else {
    side = "not-top";
  }

}

//Box2d World object
world.SetContactListener(listener);

eg

enter image description here enter image description here


This question was the closest that I could find to one I asked. I really wanted to answer your question with my own findings, but I was stumped, and had to ask my own question :)

There are a couple ways to solve this problem, but if you wanted to use collision information this should be somewhat viable.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .