Событие Java TimerTick для игрового цикла

Я попытался создать игровой цикл на Java, используя таймер из java.util.Timer. Я не могу заставить свой игровой цикл выполняться во время тика таймера. Вот пример этой проблемы. Я пытаюсь переместить кнопку во время игрового цикла, но она не движется по событию таймера.

import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JButton;

public class Window extends JFrame {

    private static final long serialVersionUID = -2545695383117923190L;
    private static Timer timer;
    private static JButton button;

    public Window(int x, int y, int width, int height, String title) {

        this.setSize(width, height);
        this.setLocation(x, y);
        this.setTitle(title);
        this.setLayout(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

        timer = new Timer();
        timer.schedule(new TimerTick(), 35);

        button = new JButton("Button");
        button.setVisible(true);
        button.setLocation(50, 50);
        button.setSize(120, 35);
        this.add(button);
    }

    public void gameLoop() {

        // Button does not move on timer tick.
        button.setLocation( button.getLocation().x + 1, button.getLocation().y );

    }

    public class TimerTick extends TimerTask {

        @Override
        public void run() {
            gameLoop();
        }
    }
}

person Johnathan    schedule 30.04.2011    source источник


Ответы (2)


Поскольку это приложение Swing, используйте не java.util.Timer, а javax.swing.Timer, также известный как Swing Timer.

e.g.,

private static final long serialVersionUID = 0L;
private static final int TIMER_DELAY = 35;

в конструкторе

  // the timer variable must be a javax.swing.Timer
  // TIMER_DELAY is a constant int and = 35;
  new javax.swing.Timer(TIMER_DELAY, new ActionListener() {
     public void actionPerformed(ActionEvent e) {
        gameLoop();
     }
  }).start();

и

   public void gameLoop() {
      button.setLocation(button.getLocation().x + 1, button.getLocation().y);
      getContentPane().repaint(); // don't forget to repaint the container
   }
person Hovercraft Full Of Eels    schedule 30.04.2011
comment
Вот соответствующий пример. - person trashgod; 01.05.2011
comment
@trashgod: я бы не назвал код Жанетт связанным, так как мой код не входит и никогда не будет в той же лиге. - person Hovercraft Full Of Eels; 01.05.2011
comment
@Bala: она Клеопатра, божество кодирования Swing и один из авторов утилит SwingX. - person Hovercraft Full Of Eels; 01.05.2011
comment
@Hovercraft Full Of Eels Я только что «пополнил» свои очки ... хорошо для вас +1 хороший ответ. :) - person Boro; 01.05.2011

Во-первых, Timer.schedule планирует выполнение задачи на одно выполнение, а не на многократное выполнение. Таким образом, эта программа может заставить кнопку двигаться только один раз.

И у вас есть вторая проблема: все взаимодействия с компонентами Swing должны выполняться в потоке диспетчеризации событий, а не в фоновом потоке. Прочитайте http://download.oracle.com/javase/6/docs/api/javax/swing/package-summary.html#threading для получения дополнительных сведений. Используйте javax.swing.Timer для выполнения действий качания через повторяющиеся интервалы.

person JB Nizet    schedule 30.04.2011