View more

View more

View more

Image of the Day Submit

IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

box2d checking for multiple collisions simultaneously

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

6 replies to this topic

#1B0rn2c0de  Members

Posted 02 March 2014 - 03:27 PM

i am currently working on a 2d endless runner using sfml and box 2d in which my player body comprises of 2 fixtures one for the main body and one sensor for checking if it is grounded . also the game consisits of obstacles on which the player can stand and jump ..what want to do is to kill the player if the main body fixture touches the obstacle but not the other ground fixture because that happens when the player is standing on the obstacle .. is there a way to implement such a condition or is there any workaround on how to kill the player when he collides with an obstacle ?? all the fixtures have seperate int tags as the user data ex- every obstacle has int tag of 5 and the player ground sensor has the int tag of 4 .

#2Strewya  Members

Posted 03 March 2014 - 02:59 AM

Yes, you can give the world a contact listener with which you check if the bodies of the collided fixtures are the player and an obstacle.

There are basically two ways about this, either you set up the contact listener, or you manually iterate over all contact after every step and manually check if the player and an obstacle are colliding. The contact listener is the superior way, because you don't have to do any kind of iteration, Box2D will provide you with the two fixtures that are colliding.

Some sample code from my Pong clone:

void PongGame::speedUpBall(b2Contact* contact)
{
auto fA = contact->GetFixtureA();
auto fB = contact->GetFixtureB();

auto bA = fA->GetBody();
auto bB = fB->GetBody();
b2Body* ball = nullptr;
if(bA->GetUserData() == &m_ball)
{
ball = bA;
}
else if(bB->GetUserData() == &m_ball)
{
ball = bB;
}
else
{
DEBUG_INFO("No ball in collision, leaving");
return;
}

{
return;
}
}


devstropo.blogspot.com - Random stuff about my gamedev hobby

#3Aardvajk  Members

Posted 03 March 2014 - 12:26 PM

Just remember to never modify any of your physics bodies in response directly to one of these callbacks. Box2D doesn't like that at all. You need to cache the contacts in some kind of structure and process them after the update() call if you want to do that.

#4B0rn2c0de  Members

Posted 04 March 2014 - 05:06 AM

i have done something like that the problem is the contact callback is called even when the player is standing on top of an obstacle . i want to to tackle that problem like i want to check if the player is colliding with the obstacle but not standing on it  so thta i can kll my player when he collides with an obstacle from the sides and not when he is standing on it.. any ideas on how i can do that ??

#5Aardvajk  Members

Posted 04 March 2014 - 05:47 AM

Can you not check if a) the player intersects the object and b) the ground sensor doesn't intersect the object?

Stuff like this can be tricky. The other approach is to consider the player velocity when the collision occurs - if within a certain tolerance of straight down, consider him standing, if not, consider it a side collision.

#6B0rn2c0de  Members

Posted 04 March 2014 - 07:31 AM

thats the thing i cant figure out that how do i check both a) and b) conditions simultaneously because the begin contact returns only one pair of fixtures at at a time .. any ideas about that ? .. i will try with the other approach .. but the first one will be more precise

#7Strewya  Members

Posted 04 March 2014 - 08:00 AM

Don't do that inside your contact listener, instead, when the contact listener is called mark that the player is colliding with the obstacle inside your Player struct/class. Same thing with the ground sensor.

Then, after world.step() returns, check your boolean(s) to determine if you have to kill the player or not.

Example (pseudo code for the most part):

void killCheck(b2Contact* contact)
{
auto fa = contact->getFixtureA();
auto fb = contact->getFixtureB();

auto ba = fa->getBody();
auto bb = fb->getBody();

if(ba->getUserData() == ENUM_PLAYER_TYPE && bb->getUserData() == ENUM_OBSTACLE_TYPE)
{
//the vice versa should also be checked, if bb is player and ba is obstacle
m_player.isPlayerColliding = true;
}

if(ba->getUserData() == ENUM_GROUND_SENSOR_TYPE && bb->getUserData() == ENUM_OBSTACLE_TYPE)
{
//the vice versa should also be checked, if bb is sensor and ba is obstacle
m_player.isSensorColliding = true;
}
}

///after world.step() returns

if(m_player.isPlayerColliding == true && m_player.isSensorColliding == false)
{
//kill player
}
...


devstropo.blogspot.com - Random stuff about my gamedev hobby

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.