对于大学项目,我的任务是用Java制作冒险游戏。我已经使用过线程和swing库等,但现在我遇到了一个问题。
// The following is in the constructor of a subclass of JPanel
gameViewThread = new Thread(() -> {
double previous = System.currentTimeMillis();
double lag = 0.0;
double current;
double elapsed;
while(true){
current = System.currentTimeMillis();
elapsed = current - previous;
previous = current;
lag += elapsed;
System.out.println("Checking up on stuff...");
while(OverworldMap.initialised && lag >= 17) {
generateBackground();
lag -= 17;
}
}
});
在上面粘贴的代码的第11行,我有一个打印声明,我想删除。 (我不想用不需要的信息充斥控制台) 但是,当我删除该语句时,视觉效果不会更新。 我已经一次又一次地测试过,我确保OverworldMap.initialised返回true。在调试模式下运行代码时,我确保generateBackground()运行。所以对我来说,看起来视觉效果只是没有更新,除非你醒来'系统。
注意:generateBackground()在BufferedImage变量中生成并保存图像,而repaint()确保将图像绘制在正确的位置。 (repaint()在主线程中每秒调用30次)这两种方法都有效。在我尝试将背景生成(从Pokemon Fire Red o / e中思考平铺动画)转移到另一个线程之前,他们工作了。 (我不希望逻辑和动画相互干扰。(我的帧速率很低))
答案 0 :(得分:1)
因为您正在尝试从主线程更新UI。它不会那样工作。尝试在程序中使用SwingUtilities.invokeLater()方法。
以下代码段可能很有用:
public void init() {
gameViewThread = new Thread(() -> {
double previous = System.currentTimeMillis();
double lag = 0.0;
double current;
double elapsed;
while (true) {
current = System.currentTimeMillis();
elapsed = current - previous;
previous = current;
lag += elapsed;
//System.out.println("Checking up on stuff...");
while (OverworldMap.initialised && lag >= 17) {
updateUI();
//generateBackground();
lag -= 17;
}
}
});
}
public void updateUI() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// All swing UI update code here
generateBackground();
}
});
}
PS:另外,请记住,不要为你的线程使用run()方法。您应该调用start()方法使其运行。首先,在构造函数中调用我提供的init()方法以及代码中的某个地方(也可能在你的构造函数中)使用gameViewThread.start()来启动你的线程。