Когда я запускаю игру (змеиную игру) через главное меню, она не работает - она практически замораживается, и это также, вероятно, потому, что бесконечный цикл, который у меня есть , Но когда я удаляю этот цикл, он работает так же хорошо, как я могу закрыть приложение - я не могу это сделать, когда игра запускается из меню, но без этого цикла моя змея не может двигаться. И когда я начинаю игру через главное - просто вызывая класс «Вид», он работает правильно.Java - не удается закрыть Окно из-за бесконечного цикла
Я знаю, что я должен использовать Threads вместо цикла, но я понятия не имею, как их правильно использовать.
Часть кода, который не работает:
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: это конец, если все, что он делает, это простая анимация. Таймер Swing намного проще и увереннее. Я бы использовал SwingWorker, если мне пришлось запускать долговременную задачу, например, доступ к базе данных или загрузку или загрузку файлов, но с анимацией длительная часть - это сама задержка, для которой создан таймер. –