I am working on a physics game and encountered a strange bug: sometimes, after firing a lot of bullets, collision detection starts to fail.
As can be seen in the following GIF, the collision works only on half the platform, which is very strange. Also, the Box2D debug renderer is enabled and it can also be seen that the platform is a single body.
Here is how I get this bug to happen, as it only happens only after firing lots of bullets (in the beginning everything works fine):
Notes:
- the bullet has the bullet
field set to true
- I set the player's bullet
field to true
, did not make a difference
- the player is 1 meter by 1 meter
- the player and the bullets are DynamicBodies
and the platforms are StaticBodies
- the map is near to (0, 0), though it goes a bit in the negatives (-1.5), I doubt it matters
- the categoryBits
and maskBits
are correct (the collision should happen, and it does happen, but glitches)
- after the bullets disappear, the number of bodies is the same as when the game starts (so they are actually destroyed)
- the World
's gravity is (0, -25f)
- the game runs at 60fps
Here is the Box2D timestep code, similar to the stepping code from the libGDX wiki:
companion object {
private const val TIME_STEP = 1f / 300f
private const val VELOCITY_ITERATIONS = 6
private const val POSITION_ITERATIONS = 2
}
private var accumulator = 0f
override fun update(deltaTime: Float) {
accumulator += Math.min(deltaTime, 0.25f)
while (accumulator >= TIME_STEP) {
world.step(TIME_STEP, VELOCITY_ITERATIONS, POSITION_ITERATIONS)
accumulator -= TIME_STEP
}
}
I tried changing:
- TIME_STEP
to a lower value, like 1/60f
- VELOCITY_ITERATIONS
a bit higher, to 8
- POSITION_ITERATIONS
a bit higher, to 6
- VELOCITY_ITERATIONS
and POSITION_ITERATIONS
to 100
and there was no (obvious) difference.
Concern:
The bugged platform seems to start behaving like a bullet (it doesn't collide with other bullets or with the player), at least halfway. So could its categoryBits
and maskBits
be changed on-the-fly, after a lot of world.createBody()
and world.destroyBody()
, maybe due to pooling?
So what should I try for the collision not to fail in this case?