原始问题
我目前正在开发一个简单的应用程序,该应用程序显示 map ,稍后将实现单位的寻路逻辑。到目前为止,我已经实现了 map 和 View ,在实现游戏循环之前一切都运行得很好。
启用游戏循环后,程序就会卡住。我无法再关闭窗口,并且 map 也不会显示,即使游戏循环执行得很好。我过去已经使用过这个游戏循环两次,直到现在才遇到任何问题。
编辑:游戏循环继续正常执行,而其他一切都卡住。
这里涉及到两个函数:
public GameController() {
paused = true;
frame = new GameFrame(this);
map = new Map(500, 500);
mvm = new MapViewModel(map.getMap(), map.getWidth(), map.getHeight());
//TODO: gameLoop() currently breaks the game.
gameLoop();
}
public void gameLoop() {
double tickTime, lastTick;
for (;;) {
tickTime = System.nanoTime();
lastTick = tickTime;
//Repaints the frame
update();
while (tickTime - lastTick < NANOSECONDS_PER_UPDATE) {
try {
Thread.sleep(1);
} catch (InterruptedException ignored) {}
tickTime = System.nanoTime();
}
}
}
edit2:我正在使用 Swing。实际的绘画发生在我的 GamePanel (JPanel) 的 PaintComponent 方法中:
@Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
//Paints the map
painter.paintMap(g2, controller.getMvm());
}
显然,如果您有任何其他问题,请随时提问。提前致谢。
解决方案
这是我现在使用的代码,GameController 和更新没有改变。
public void gameLoop() {
timer = new Timer(MILLISECONDS_PER_UPDATE, updater);
timer.start();
}
updater 是一个 ActionListener,我已将其作为私有(private)变量添加到类中。
private ActionListener updater = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("test2");
update();
}
};
您可以在本地添加更新程序,但我更喜欢这种方式。
最佳答案
您没有告诉我们您可能使用的 GUI 库,但假设它可能是 Swing,看起来您正在 Swing 事件线程(负责执行所有 Swing 操作的主线程)上运行一些长时间运行的代码图形以及与用户交互。如果是这样,那么代码将阻止 Swing 重绘 GUI,从而卡住您的应用程序。
我的建议是:
- 不要这样做。不要在主事件线程上运行任何长时间运行的代码。
- 请考虑使用 Swing Timer进行“游戏循环”。
- 或者,如果您必须使用 while 循环和线程 sleep ,请在事件线程之外执行此操作,但随后请确保所有改变 Swing 对象状态的 Swing 调用都在事件上完成线程。
- 有关 Swing 线程的更多信息,请阅读 Concurrency in Swing .
关于java - 游戏循环完全卡住了我的程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24342387/