我对游戏开发比较陌生。我现在已经开发游戏并学习游戏开发2-3个月了。我使用Java。
我一直使用 Swing 来制作图形(也就是说,整个游戏都显示在JPanel
, 用一个Graphics2D
目的)。到目前为止我没有遇到任何问题。
最近,我在最近的项目中遇到了一个问题。某些方法在以一致的时间间隔调用时存在问题(有时它应该每 15-16 毫秒运行一次,有时它开始每 3000 (!) 毫秒运行一次)。
我做了一些令人沮丧的调试和一些研究,发现发生这种情况的原因可能是因为我没有正确处理 Swing 和线程。
我的整个游戏循环都在run()
线程的方法(不是 EDT)。所以我一直在 EDT 之外修改 Swing 元素。显然,这必然会引起问题。
当我发现问题所在时,我想:
“嘿,我会简单地使用SwingUtilities.invokeLater()
为了在 EDT 内运行游戏循环!”
但后来我想起来了,就像‘禁止’一样操纵 Swing 元素outside东部夏令时间,操纵起来也有问题来自的非 Swing 对象inside the EDT (我想……这是正确的吗?).
如果是这样,那么我不知道如何使用 Swing 在 Java 中开发游戏不会遇到奇怪的问题.
我的问题是:
如何使用 Swing 安全地开发游戏?为了避免涉及 Swing 和线程的问题,我应该严格遵守哪些良好的指导方针?每个使用 Swing 的游戏开发人员都应该了解哪些说明?
理解这一点对我来说非常重要,因为我真的很想使用 Java 进行游戏开发,但如果我不理解这一点,我总是会遇到奇怪的问题并且无法取得进展。
感谢您的帮助
只要你除了面板上绘制的图形之外不修改任何东西,你就可以should大部分时间都还好。就像单个非 EDT 线程一样大多数时候。只要您不添加或删除任何 gui 元素,不调整任何内容的大小,不隐藏任何内容等,Swing 就不会对其内部细节进行足够的修改,从而导致线程和 EDT 之间的竞争条件 - 大多数的时间。
即使用户在非 EDT 代码上绘图时最小化面板也不会导致崩溃 - 面板可能会丢弃旧的图形上下文并开始使用新的图形上下文,但旧的上下文将保持有效直到你释放它(这与 C++ 不同,C++ 中delete
立即使对象无效,这会在其他线程仍然使用本地指针时导致崩溃)。
问题是,如果您使用“我还没有看到出现问题的情况,总是对我有用”的方法,那么您将依赖于未定义的行为,并且您的代码可能会在更新后立即开始崩溃你的 JVM。
你能做的最好的事情就是在 EDT 线程上设置你的 GUI,在不同的线程上运行你的游戏逻辑,调用一个计时器repaint()
每 20 毫秒在面板上显示一次(或任何您希望的帧速率)。然后,有一个类对象来保存显示当前游戏状态所需的所有内容。在一个synchronized
代码块,让面板的paint()
生成它自己的对象副本,并且有paint()
在主线程计算游戏需要的任何内容时使用副本。主线程应该使用相同的synchronized
当然要写入类对象。这样,您就可以在线程之间获得最大可能的分离。
仅在 EDT 上运行整个游戏线程可能是行不通的,因为游戏执行的任何操作可能需要一段时间才会导致 UI 冻结。任何需要大量 UI 资源的东西都会影响你的游戏逻辑。
顺便说一句,您确定您最初的问题(时不时地长时间延迟,但并非总是如此)不是垃圾收集的结果吗?我已经见过好几次了;如果您不使用并行垃圾收集器,GC 可能会运行几十秒并阻塞其他所有内容。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)