当我通过主菜单开始游戏(蛇游戏)时,它不起作用 - 它基本上冻结,也可能是因为我在那里有无限循环。但是当我删除这个循环时,它确实起作用,并且我可以关闭应用程序 - 从菜单启动游戏时我无法做到,但没有该循环,我的蛇就无法移动。当我通过main开始游戏时 - 只需调用“View”类,它就可以正常工作。Java - 由于无限循环无法关闭窗口
我知道我应该使用线程而不是循环,但我不知道如何正确使用它们。
部分代码不起作用:
public void Draw() throws InterruptedException, IOException{
addKeyListener(this);
bf = this.getBufferStrategy();
while(true){
tmp = System.currentTimeMillis()/1000;
sec = tmp - start;
if (sec % 5 == 0) {
Obstacles(30);
}
g = bf.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.LIGHT_GRAY);
for (int i = 0; i < obs.size(); i++) {
g.fillRect(obs.get(i).x*SCALE, obs.get(i).y*SCALE, SCALE, SCALE);
}
for (Point point : snakeParts) {
g.setColor(Color.BLUE);
g.fillRect(point.x * SCALE, point.y * SCALE, SCALE, SCALE);
}
g.fillRect(head.x * SCALE, head.y * SCALE, SCALE, SCALE);
switch(kind){
case 0:
g.setColor(Color.RED);
break;
case 1:
g.setColor(Color.YELLOW);
break;
case 2:
g.setColor(Color.GREEN);
break;
}
g.fillRect(bonus.x * SCALE, bonus.y * SCALE, SCALE, SCALE);
string = "Score: " + score + ", Length: " + tailLength + ", Time: " + time/20;
g.setColor(Color.WHITE);
g.drawString(string, this.getWidth()/2-80, 45);
Move();
bf.show();
Thread.sleep(speed);
}
}
并开始游戏从主菜单按钮:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
try
{
if (cfg.nick())
{
this.setVisible(false);
new View().setVisible(true);
new View().startGame();
}
} catch (InterruptedException ex)
{
Logger.getLogger(HerniMenu.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex)
{
Logger.getLogger(HerniMenu.class.getName()).log(Level.SEVERE, null, ex);
}
}
感谢您的帮助!
废钢所有这一切 - 只使用一个[摇摆定时器](https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html )。当你想停止定时器时,只需调用'stop()'就可以了。它比你所做的更容易,也是线程安全的(你的代码绝对不是)。 –
我建议也看着'SwingWorker'。 – Logan
@LoganKulinski:如果他所做的只是一个简单的动画,那就完蛋了。一个摆动计时器更简单,更笨蛋的证明。如果我不得不运行长时间运行的任务(如数据库访问或文件上载或下载),但使用动画,则需要使用SwingWorker,长时间运行的部分就是延迟本身,这是Timer的基础。 –