Java 游戏运行大约 2 分钟后不断崩溃(Intellij)

标签 java intellij-idea

我正在使用 Intellij 进行 Java 编程。

我目前正在尝试制作一款自上而下的基于瓷砖的射击游戏。

我的问题是,我的游戏在大约 2 分钟后崩溃,并弹出一个消息“Java(TM) Platform SE Binary 已停止工作”。我记录了它崩溃 3 次所需的时间:1m57s、1m59s、1m58s .

游戏现在处于非常简单的状态,我不确定是什么导致了崩溃。所有相关代码都位于两个类中:GameFrame.java(扩展 JFrame)和 GamePanel.java(扩展 JPanel)。

GameFrame.java:

    package net.magnusfrater.tds.game;

    import javax.swing.*;

    public class GameFrame extends JFrame {

        public static final int width = 1000;
        public static final int height = width / 16 * 10;

        private GamePanel gp;

        public GameFrame () {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setSize(width,height);
            setResizable(false);
            setLocationRelativeTo(null);

            setTitle("Time Based Fast Paced Top Down Shooter Demo");

            gp = new GamePanel();
            add(gp);

            setVisible(true);
        }

        public static void main (String[] args) {
            GameFrame gf = new GameFrame();
        }
    }

GamePanel.java

    package net.magnusfrater.tds.game;

    import net.magnusfrater.tds.input.Keyboard;

    import javax.swing.*;
    import java.awt.*;

    public class GamePanel extends JPanel implements Runnable {

        //panel
        private Thread thread;
        private static boolean running;
        private boolean fpsLock;

        //input
        private Keyboard kb;

        //game
        private Game game;

        public GamePanel () {
            //panel
            thread = new Thread(this, "Time Based Fast Paced Top Down Shooter Demo");
            running = true;
            fpsLock = true;

            //input
            //kb = new Keyboard();
            //addKeyListener(kb);

            //game
            //game = new Game(1);

            thread.start();
        }

        public void run () {
            long iTimeNS = System.nanoTime();
            int tickRate = 60;
            long ns = 1000000000 / tickRate;

            int ups = 0;
            int fps = 0;

            long iTimeS = System.nanoTime();
            long s = 1000000000;

            while (running) {

                long fTimeNS = System.nanoTime();
                if (fTimeNS - iTimeNS >= ns){
                    iTimeNS = System.nanoTime();

                    tick();
                    ups++;

                    if (fpsLock){
                        repaint();
                        fps++;
                    }
                }

                if (!fpsLock){
                    repaint();
                    fps++;
                }

                long fTimeS = System.nanoTime();
                if (fTimeS - iTimeS >= s){
                    iTimeS = System.nanoTime();

                    System.out.println("ups: " + ups + "\tfps: " + fps);

                    ups = 0;
                    fps = 0;
                }

            }

            System.exit(0);
        }

        public void tick () {
            if (kb != null)
                kb.tick();

            if (game != null)
                game.tick();
        }

        @Override
        public void update (Graphics g) {
            paint(g);
        }

        @Override
        public void paint (Graphics g) {

            g.setColor(Color.WHITE);
            g.fillRect(0,0,GameFrame.width, GameFrame.height);

            //if (game != null)
                //game.paint(g);
        }

        public static void quitGame () {
            running = false;
        }
    }

我最初认为问题是由于我加载 Sprite 表图像的方式或者可能是我加载关卡设计文本文件的方式引起的,但在重新处理这两个问题后,问题仍然存在。

这让我感到好奇和有点厌倦,所以我尝试找出更多有关崩溃的解释。首先,我从弹出窗口中阅读了更多内容,但它没有说任何有用的内容:(见下文)

其次我查看了 Intellij 给出的退出代码:(见下文)

我查了一下退出代码 255 是什么,但没有任何有用的信息。我能找到的最好的解释是退出代码 255 意味着真正的退出代码超出范围:(见下文)

此时我已经没有想法了,所以我开始简单地用谷歌搜索我能想到的一切。谷歌搜索“Java(TM)平台 SE 二进制文件已停止工作”的问题在于,几乎每个建议的链接都是有关 Minecraft 的问题。将我的搜索限制在 Stack Overflow 上,得到了一些结果,但没有任何结论。我发现的一些修复是我已经尝试过的(例如没有正确处理输入流、没有正确处理缓冲读取器、没有处理元素等)。我找到了这些链接,但没有一个与我的问题真正相关:

  1. (见下文)

  2. (见下文)

  3. (见下文)

  4. (见下文)

  5. (见下文)

  6. (见下文)

我尝试的最后一次修复是重新安装 Java SE 开发工具包 8u101 和 Java SE 开发工具包 8u102。然后我重新启动了 Intellij。然后我重新启动了计算机。

没有任何作用。

现在我觉得我就是个傻子。我忽略了一些我可以轻易看出的事情。我错过了什么?

(ps~ 这可能是一个相关的问题。因此,如果我运行游戏时几乎没有任何内容,且 fps 未锁定为 60,那么我会得到非常荒谬的每秒帧数。我不认为 fps高达 7,000,000 是可能的。我想。我不知道。我也编程错误了吗?这是我的 ups/fps 输出的相关图片:[见下文])

(参见此处) 因此,Stack Overflow 不允许分数在特定阈值内的成员(member)发布超过 2 个链接,并且绝对不允许发布图像。所以这里是一个谷歌文档的链接,其中包含我上面提到的所有链接和图像: https://docs.google.com/document/d/1XrBuVio19GmkFz0EfRzXVp5AJmM5zPfVO6vK3oS3Eaw/edit?usp=sharing

最佳答案

尝试将 -Xmx 设置为 2G 之类的值,看看它是否运行时间更长。如果是这样,则说明某些内容正在分配内存,并且可能您设置了其他设置,由于某种原因退出而不是垃圾收集。

此外,尝试更改代码以使用 Guava's RateLimiter 来限制事物.

…
// class level
final RateLimiter frameLimiter = RateLimiter.create(60.0);
final RateLimiter outputLimiter = RateLimiter.create(1.0);
…
// in run method
while (running) {
  frameLimiter.acquire();
  repaint();
  fps++;
  if (outputLimiter.tryAcquire()){
    System.out.println("fps: " + fps);
    fps = 0;
  }
}

我已删除 upstick()。您应该在重新绘制后完成您的工作,并且我认为您不想做比下一帧所需的更多的工作,而下一帧至少应该达到您的最大速率。稍后,您需要添加逻辑来处理跳过帧时的跳过工作。在repaint 中增加fps 可能更有意义。 您可以将输出放入其自己的线程中,并且只有在同步增量和重置 fps 时才获取该限制器。

关于Java 游戏运行大约 2 分钟后不断崩溃(Intellij),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39523594/

相关文章:

Java - 如何处理动态 JSON 类别名称?

java - 线程 “main”中的异常java.lang.NoClassDefFoundError : javapasswords in Linux [closed]

java - 使用atom导入包

java - Maven:打包和模块依赖

Java 注释 - 如何创建数组?

java - Java 中的迭代数组

intellij-idea - 正确更新 IntelliJ IDEA 社区版

intellij-idea - 如果不是Android项目,我可以将Gradle的--stacktrace放入哪些选项中?

java - 将 GWT 项目导入 IntelliJ 失败

android-studio - Intellij IDEA (Android Studio) Kotlin 插件的用途是什么?