2
votes

I have several circles on the screen, placed on different locations (all dynamic box2d bodies).

I want to add another circle, with an initial velocity of say x, y. I want this body to move freely, as if there's no gravity. Make all it's collisions 100% elastic.

I tried setting elasticity to 1, but if I drop it from the top, it doesn't touch the ceiling again. I want it to just keep moving in the direction it was set to, unless a collision changes its direction.

To explain this further, a simple implementation of what I want would be this, in a square container, with a circular body.

when collides ->
  set body.velocityX to -body.velocityX
  set body.velocityY to -body.velocityY

Of course this doesn't work if I have bodies in between.

Suggestions in any language with box2d framework or pseudocode would be appreciated.

2
You can check the velocity in BeginContact, and then in EndContact you can adjust it to preserve the same original velocity. Only works if there are only two things touching each other at the same time though.iforce2d

2 Answers

3
votes

In addition to setting the elasticity, you need to set the damping of the body to 0 to eliminate the velocity reduction effect that you're seeing now.

From the Box2d manual:

Damping is used to reduce the world velocity of bodies. Damping is different than friction because friction only occurs with contact. Damping is not a replacement for friction and the two effects should be used together.

Damping parameters should be between 0 and infinity, with 0 meaning no damping, and infinity meaning full damping.

...

bodyDef.linearDamping = 0.0f;

bodyDef.angularDamping = 0.01f;

Damping is approximated for stability and performance. At small damping values the damping effect is mostly independent of the time step. At larger damping values, the damping effect will vary with the time step. This is not an issue if you use a fixed time step (recommended).

Additionally, as mentioned in the manual, damping is not the same as friction... so you'll probably want to set the friction of the body to 0 as well.

0
votes

Set b2BodyDef::type = b2_kinematicBody.

Box2D manual says:

A kinematic body moves under simulation according to its velocity. Kinematic bodies do not respond to forces. They can be moved manually by the user, but normally a kinematic body is moved by setting its velocity. A kinematic body behaves as if it has infinite mass, however, Box2D stores zero for the mass and the inverse mass. Kinematic bodies do not collide with other static or kinematic bodies.