libGDX - Box2D 世界步骤中的无限循环
libGDX - endless loop in Box2D world step
我正在开发一款使用 libGDX, that uses Box2D 进行碰撞检测的小游戏。这工作正常,直到我在游戏中添加了一个 arrow,所以玩家可以 shoot。自从我添加了这个功能后,我就面临着游戏时不时卡住,没有反应的问题。
我认为这种行为的原因是无限循环 Box2D 世界步骤 中的某处。当我使用调试器停止执行时,停止点总是在 World.step(float, int, int)
方法中。不幸的是,这是一个 native 方法,所以我找不到问题的确切位置:
// from com.badlogic.gdx.physics.box2d.World
public void step (float timeStep, int velocityIterations, int positionIterations) {
jniStep(addr, timeStep, velocityIterations, positionIterations);
}
private native void jniStep (long addr, float timeStep, int velocityIterations, int positionIterations);
问题:
有时在使用新的 “射箭” 功能时,执行似乎停止并且游戏只是冻结。真的很难重现,所以我真的不知道真正的根本原因是什么。只有在Box2D世界添加新的arrow时才会出现,但不会一直出现。
到目前为止我尝试过的:
- 为了验证问题出在 Box2D 代码中,我尝试将 arrow 的 夹具的 mask 更改为
0x0000
,所以它不会与任何其他物体发生碰撞。这实际上解决了问题(或者至少我不能再重现它了)。但这并没有太大帮助,因为没有射中任何东西的箭在游戏中不是很有用...
- 更改夹具的 mask,使其不与特定类别(称为
CATEGORY_OBSTACLE
)冲突似乎也解决了问题,但我有不知道为什么,这仍然不是真正的解决方案...
代码:
由于我什至无法可靠地重现该问题,我也无法创建一个最小可重现示例。我只能指向 GitHub repo of the game. Sorry for this :( The current code is placed in the branch projectile_bug.
稍微解释一下代码:
- class
GameScreen
有一个render
方法,从中调用了World.step
方法(导致死循环的方法)。
- class
Dwarf
有一个executeSpecialAction
方法,它通过一些工厂方法开始创建箭头。
- 最后,class
ProjectileFactory
有一个 createProjectile
方法,它创建 arrow 并将其添加到世界。
- Box2D fixture 使用的 categories 和 masks 放在
PhysicsBodyCategories
class . arrow 的 fixture 使用遮罩MASK_PLAYER_ATTACK
重现步骤:
由于我真的不知道问题的根本原因,这个错误只能通过在地图上射一些箭来重现:
- 在
desktop
子项目DesktopLauncher
中使用main方法开始游戏。
- 移动到世界各地并使用space键
发射一些箭
- 希望 bug 出现...通常需要在世界上放置相当多的箭头才能出现 bug(我提高了 projectile_bug 分支中的射速以加快速度)
题目:
我不确定是什么导致了这个错误,我对 Box2D 还是很陌生。如果有人知道如何解决这个问题或知道这个问题的解决方法,那真的会对我有很大帮助。此外,如果您知道一些相关的、报告的错误或类似的事情,它也会有所帮助。
提前致谢。
好吧,我咬一口。根据我的经验,box2d 崩溃或挂起的大部分时间是在 body 或 fixtures 没有被正确销毁时,或者当有一些对被销毁 body 的悬空引用时。因此,我只是尝试在 step 函数之后从您的代码 PhysicsWorld.getInstance().removeBodiesAndFixtures();
中删除此语句,瞧,它起作用了。顺便说一句,不错的游戏。这当然不是解决方案,但它可能会提示您在哪里搜索根本原因。
我正在开发一款使用 libGDX, that uses Box2D 进行碰撞检测的小游戏。这工作正常,直到我在游戏中添加了一个 arrow,所以玩家可以 shoot。自从我添加了这个功能后,我就面临着游戏时不时卡住,没有反应的问题。
我认为这种行为的原因是无限循环 Box2D 世界步骤 中的某处。当我使用调试器停止执行时,停止点总是在 World.step(float, int, int)
方法中。不幸的是,这是一个 native 方法,所以我找不到问题的确切位置:
// from com.badlogic.gdx.physics.box2d.World
public void step (float timeStep, int velocityIterations, int positionIterations) {
jniStep(addr, timeStep, velocityIterations, positionIterations);
}
private native void jniStep (long addr, float timeStep, int velocityIterations, int positionIterations);
问题:
有时在使用新的 “射箭” 功能时,执行似乎停止并且游戏只是冻结。真的很难重现,所以我真的不知道真正的根本原因是什么。只有在Box2D世界添加新的arrow时才会出现,但不会一直出现。
到目前为止我尝试过的:
- 为了验证问题出在 Box2D 代码中,我尝试将 arrow 的 夹具的 mask 更改为
0x0000
,所以它不会与任何其他物体发生碰撞。这实际上解决了问题(或者至少我不能再重现它了)。但这并没有太大帮助,因为没有射中任何东西的箭在游戏中不是很有用... - 更改夹具的 mask,使其不与特定类别(称为
CATEGORY_OBSTACLE
)冲突似乎也解决了问题,但我有不知道为什么,这仍然不是真正的解决方案...
代码:
由于我什至无法可靠地重现该问题,我也无法创建一个最小可重现示例。我只能指向 GitHub repo of the game. Sorry for this :( The current code is placed in the branch projectile_bug.
稍微解释一下代码:
- class
GameScreen
有一个render
方法,从中调用了World.step
方法(导致死循环的方法)。 - class
Dwarf
有一个executeSpecialAction
方法,它通过一些工厂方法开始创建箭头。 - 最后,class
ProjectileFactory
有一个createProjectile
方法,它创建 arrow 并将其添加到世界。 - Box2D fixture 使用的 categories 和 masks 放在
PhysicsBodyCategories
class . arrow 的 fixture 使用遮罩MASK_PLAYER_ATTACK
重现步骤:
由于我真的不知道问题的根本原因,这个错误只能通过在地图上射一些箭来重现:
- 在
desktop
子项目DesktopLauncher
中使用main方法开始游戏。 - 移动到世界各地并使用space键 发射一些箭
- 希望 bug 出现...通常需要在世界上放置相当多的箭头才能出现 bug(我提高了 projectile_bug 分支中的射速以加快速度)
题目:
我不确定是什么导致了这个错误,我对 Box2D 还是很陌生。如果有人知道如何解决这个问题或知道这个问题的解决方法,那真的会对我有很大帮助。此外,如果您知道一些相关的、报告的错误或类似的事情,它也会有所帮助。
提前致谢。
好吧,我咬一口。根据我的经验,box2d 崩溃或挂起的大部分时间是在 body 或 fixtures 没有被正确销毁时,或者当有一些对被销毁 body 的悬空引用时。因此,我只是尝试在 step 函数之后从您的代码 PhysicsWorld.getInstance().removeBodiesAndFixtures();
中删除此语句,瞧,它起作用了。顺便说一句,不错的游戏。这当然不是解决方案,但它可能会提示您在哪里搜索根本原因。