当前位置: 首页 > 知识库问答 >
问题:

发射大量子弹后,Box2D碰撞检测失败

燕鸿波
2023-03-14

我正在开发一个物理游戏,遇到了一个奇怪的bug:有时,在发射大量子弹后,碰撞检测开始失败。

从下面的GIF可以看出,碰撞只在半个平台上起作用,很奇怪。此外,启用了Box2D调试渲染器,还可以看到平台是一个单体。

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

注意:
- 子弹的子弹场设置为 true
- 我将玩家的子弹场设置为 true,没有区别
- 玩家是 1 米乘 1 米
- 玩家和子弹是动态体,平台是静态体
- 地图接近 (0, 0),尽管它有点在负数 (-1.5), 我怀疑这很重要
- 类别BitsmaskBits是正确的(碰撞应该发生,它确实发生了,但故障)
- 子弹消失后,身体的数量与游戏开始时相同(所以它们实际上被摧毁了)
- 世界的重力是(0,-25f)
- 游戏以60fps的速度运行

这是Box2D时间步进代码,类似于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
    }
}

我尝试更改:
- TIME_STEP到较低的值,如1/60f
- VELOCITY_ITERATIONS高一点,到8
- POSITION_ITERATIONS高一点,到6
- VELOCITY_ITERATIONSPOSITION_ITERATIONS到100
,没有(明显的)差异。

问题:<br>被窃听的平台似乎开始表现得像子弹(它不会与其他子弹或玩家碰撞),至少在中途。因此,它的<code>分类位</code>和<code>掩码位</code>可以在经过许多<code>世界之后动态更改。createBody()和世界。destroyBody(),可能是由于池?

那么在这种情况下,我应该如何努力才能使碰撞不失败呢?

共有1个答案

苏建安
2023-03-14

我终于设法修复了它。

我找到的解决方案是循环遍历每个具有主体的实体,并调用<code>refilter(),这似乎解决了这个问题:

engine.getEntitiesFor(Family.one(BodyComponent::class.java).get()).forEach {
    it.body.body.fixtureList.first().refilter()
}

将来,我可以只在需要时调用<code>refilter()

看起来您应该在更改主体的filterData(更改其分类位maskBits)之后调用refilter()Fixture Def之外,但我似乎没有这样做(或者可能我错过了一些东西),所以这有点奇怪。

 类似资料:
  • 所以我用Box2D在游戏中进行冲突检测。我有一个包含地形信息的地图:现在它只是一个有道路或草地的字符[][]。现在,在每个关卡开始时,我想创建矩形来描述不同的地形,但是我希望这些矩形得到优化,显然这需要相当多的算法。 我的第一个方法是在关卡开始时为地图上的每一个区块创建一个单独的地形。FPS降低到了5。 我的第二个想法是当玩家沿着地图移动时,简单地为地形创建不同的矩形,删除看不见的矩形。虽然它仍然

  • 问题内容: 我正在打乒乓球,发现很难编写一种算法来正确地使球从四壁弹回(我将在稍后处理得分,因为只有西+东双方会成为进球)。所以此刻,我希望球在盒子周围弹跳。 检测球是否撞到墙壁很容易,但是我在计算新角度时遇到了麻烦。 到目前为止,这是我想出的: 这仅适用于大约一半的碰撞,并且看起来非常难看。我确信这应该非常简单,并且之前已经做过很多次了。 在我的代码中,dstX / dstY是X / Y目标坐标

  • 我是Bullet新手,如果我的问题对你来说听起来微不足道,我提前道歉。 我需要从.stl文件加载一组凹三角形网格,并执行碰撞检测。用户可以移动对象。在用户手册中,我读到:“凹形三角形网格:对于静态世界环境,表示静态三角形网格的一种非常有效的方法是使用btBvhTriangleMeshShape。” 因此,我的问题是:Bullet可以检测使用BvhTriangleMeshShape建模的凹形网格对象

  • 我正在用一个简单的克隆人进行实验,以了解游戏状态,游戏循环等。 我遇到的困难之一是碰撞检测。 我有一个由Ball、Brick和Paddle扩展的类。在这个类中,我有一个方法来返回对象的边界矩形,一个碰撞(item)方法来确定2个对象是否发生了碰撞,以及用于、、和的方法来确定对象的哪一边与另一边发生了碰撞。 这些方法如下: ball类有一个名为< code > checkBallCollission

  • 碰撞检测 现在你知道了如何制造种类繁多的图形对象,但是你能用他们做什么?一个有趣的事情是利用它制作一个简单的 碰撞检测系统 。你可以用一个叫做:hitTestRectangle 的自定义的函数来检测两个矩形精灵是否接触。 hitTestRectangle(spriteOne, spriteTwo) 如果它们重叠, hitTestRectangle 会返回 true。你可以用 hitTestRect

  • 本节暂未进行完全的重写,错误可能会很多。如果可能的话,请对照原文进行阅读。如果有报告本节的错误,将会延迟至重写之后进行处理。 当试图判断两个物体之间是否有碰撞发生时,我们通常不使用物体本身的数据,因为这些物体常常会很复杂,这将导致碰撞检测变得很复杂。正因这一点,使用重叠在物体上的更简单的外形(通常有较简单明确的数学定义)来进行碰撞检测成为常用的方法。我们基于这些简单的外形来检测碰撞,这样代码会变得