我正在使用 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 上,得到了一些结果,但没有任何结论。我发现的一些修复是我已经尝试过的(例如没有正确处理输入流、没有正确处理缓冲读取器、没有处理元素等)。我找到了这些链接,但没有一个与我的问题真正相关:
(见下文)
(见下文)
(见下文)
(见下文)
(见下文)
(见下文)
我尝试的最后一次修复是重新安装 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;
}
}
我已删除 ups
和 tick()
。您应该在重新绘制后完成您的工作,并且我认为您不想做比下一帧所需的更多的工作,而下一帧至少应该达到您的最大速率。稍后,您需要添加逻辑来处理跳过帧时的跳过工作。在repaint
中增加fps
可能更有意义。
您可以将输出放入其自己的线程中,并且只有在同步增量和重置 fps
时才获取
该限制器。
关于Java 游戏运行大约 2 分钟后不断崩溃(Intellij),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39523594/