我正在做一个物理游戏,遇到了一个奇怪的错误:有时,在发射了大量子弹后,碰撞检测就开始失败。
从下面的GIF中可以看出,碰撞只在半个平台上起作用,这是非常奇怪的。此外,还启用了Box2D调试呈现程序,并且还可以看到平台是一个单一的主体。

下面是我如何让这个bug发生的原因,因为只有在发射了大量子弹之后才会发生这种情况(在开始时,一切都很好):

备注:
bullet字段设置为truebullet字段设置为true,没有什么区别DynamicBodies,平台是StaticBodiescategoryBits和maskBits是正确的(碰撞应该发生,确实会发生,但会出现故障)World的重力是(0,-25度)下面是Box2D时间步长代码,类似于来自libGDX维基的步进代码
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
}
}我试着改变:
TIME_STEP值较低,如1/60fVELOCITY_ITERATIONS稍微高一点,到8POSITION_ITERATIONS稍微高一点,到6VELOCITY_ITERATIONS和POSITION_ITERATIONS到100
两者之间没有明显的差异。关注点:
被窃听的平台似乎开始表现得像一颗子弹(它不会与其他子弹或玩家相撞),至少一半。那么,在经历了大量的categoryBits和world.destroyBody()之后,它的maskBits和world.createBody()能否在飞行中被改变,也许是因为共享?
那么,在这种情况下,我应该如何避免碰撞失败呢?
发布于 2019-05-02 18:46:15
我终于修好了。
我找到的解决方案是循环遍历每个有主体的实体,并调用refilter(),这似乎是修复了它:
engine.getEntitiesFor(Family.one(BodyComponent::class.java).get()).forEach {
it.body.body.fixtureList.first().refilter()
}将来,我只能在需要的时候才调用refilter() (如果我可以确定何时必须调用它),而不是调用每个帧,但它现在起作用了。
看起来,在更改了refilter()之外的身体的filterData (改变其categoryBits或maskBits)之后,应该调用FixtureDef,但是我似乎并没有这么做(或者我遗漏了什么东西),所以这有点奇怪。
https://stackoverflow.com/questions/55903552
复制相似问题