java - libGDX - Box2D 世界步骤中的无限循环
问题描述
我正在开发一个带有libGDX的小游戏,它使用Box2D进行碰撞检测。这工作得很好,直到我在游戏中添加了一个箭头,这样玩家就可以射击了。自从我添加了这个功能后,我面临着游戏时不时卡住并且不再反应的问题。
我认为这种行为的原因是Box2D 世界步骤中某处的无限循环。当我使用调试器停止执行时,停止点始终在方法中。不幸的是,这是一种本机方法,所以我找不到问题的确切位置:World.step(float, int, int)
// 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 世界添加新箭头时出现,但问题并非一直出现。
到目前为止我已经尝试过:
- 为了验证问题出在 Box2D 代码中,我尝试将箭头固定装置的掩码更改为,因此它不会与任何其他对象发生碰撞。这实际上解决了问题(或者至少我不能再重现它了)。但这并没有太大帮助,因为一个不击中任何东西的箭在游戏中并不是很有用......
0x0000
- 更改夹具的掩码,使其不与特定类别(称为
CATEGORY_OBSTACLE
)冲突似乎也解决了问题,但我不知道为什么,但这仍然不是真正的解决方案......
编码:
由于我似乎无法可靠地重现该问题,因此我也无法创建一个最小的可重现示例。我只能指向游戏的GitHub 存储库。对此感到抱歉:(当前代码放在分支projectile_bug中。
稍微解释一下代码:
- 该类
GameScreen
有一个render
方法,从中World.step
调用该方法(导致无限循环的方法)。 - 该类
Dwarf
有一个方法,它通过一些工厂方法executeSpecialAction
开始创建箭头。 - 最后,该类
ProjectileFactory
有一个createProjectile
方法,该方法创建箭头并将其添加到世界中。 - Box2D 设备使用的类别和掩码放置在
PhysicsBodyCategories
类中。箭头的夹具使用遮罩MASK_PLAYER_ATTACK
重现步骤:
由于我并不真正知道问题的根本原因,因此只能通过在地图上射击一些箭头来重现该错误:
- 使用-subproject中类中的main 方法启动游戏。
DesktopLauncher
desktop
- 移动世界并使用空格键发射一些箭头
- 希望出现错误...通常需要在世界上使用相当多的箭头才能出现错误(我增加了projectile_bug分支中的射速以加快速度)
问题:
我不确定是什么导致了这个错误,而且我对 Box2D 还是很陌生。如果有人对如何解决此问题有任何想法或知道解决此问题的方法,那真的会对我有很大帮助。此外,如果您知道一些相关的、报告的错误或类似的东西,它也会有所帮助。
提前致谢。
解决方案
好吧,我咬它。以我的经验,box2d 在大多数情况下会崩溃或挂起,因为身体或固定装置没有被正确销毁,或者当有一些对被破坏的身体的悬空引用时。所以我只是试图PhysicsWorld.getInstance().removeBodiesAndFixtures();
在 step 函数之后从你的代码中删除这个语句,瞧,它有效。不错的游戏顺便说一句。这当然不是解决方案,但它可能会提示您在哪里搜索根本原因。
推荐阅读
- python-2.7 - 从 wine 运行 pyglet 时出现空白屏幕
- php - PHP 递归地将函数应用于某些数组成员,从给定索引开始并遍历数组成员直到给定值
- django - django ManyToMany 显示相关对象
- barcode - 键盘楔形扫描仪的扫描字符结束?
- c# - 在加载图像之前关闭活动指示器
- angular - 以角度录制客户端音频
- r - 如何在重复状态行中以最短时间保持状态
- python - Slack Bot [Python/Flask]:等待来自指定用户的直接消息并保存响应
- c# - Json.Net 属性忽略所有属性
- javascript - 不能使用状态变量作为函数参数?反应