Jump to content

  • Log In with Google      Sign In   
  • Create Account


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.

  • You cannot reply to this topic
6 replies to this topic

#1 B0rn2c0de   Members   -  Reputation: 104

Like
0Likes
Like

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 .



Sponsor:

#2 Strewya   Members   -  Reputation: 1337

Like
0Likes
Like

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* paddle = nullptr;
	b2Body* ball = nullptr;
	if(bA->GetUserData() == &m_ball)
	{
		ball = bA;
		paddle = bB;
	}
	else if(bB->GetUserData() == &m_ball)
	{
		ball = bB;
		paddle = bA;
	}
	else
	{
		DEBUG_INFO("No ball in collision, leaving");
		return;
	}
		
	if(paddle->GetUserData() != &m_leftPaddle && paddle->GetUserData() != &m_rightPaddle)
	{
		DEBUG_INFO("No paddle in collision, leaving");
		return;
	}
}

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


#3 Aardvajk   Crossbones+   -  Reputation: 5858

Like
0Likes
Like

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.



#4 B0rn2c0de   Members   -  Reputation: 104

Like
0Likes
Like

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 ??



#5 Aardvajk   Crossbones+   -  Reputation: 5858

Like
0Likes
Like

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.



#6 B0rn2c0de   Members   -  Reputation: 104

Like
0Likes
Like

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



#7 Strewya   Members   -  Reputation: 1337

Like
1Likes
Like

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.



PARTNERS