我尝试使用java.util.Timer中的Timer在Java中进行游戏循环。在计时器滴答声期间,我无法让我的游戏循环执行。以下是此问题的示例。我试图在游戏循环期间移动按钮,但它没有继续计时器滴答事件。
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();
}
}
}
答案 0 :(得分:9)
由于这是一个Swing应用程序,因此不要使用java.util.Timer,而应使用javax.swing.Timer,也称为Swing Timer。
如,
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
}
答案 1 :(得分:4)
首先,Timer.schedule为一次执行调度任务,而不是重复执行。所以这个程序只能让按钮移动一次。
你还有第二个问题:所有与swing组件的交互都应该在事件派发线程中完成,而不是在后台线程中完成。阅读http://download.oracle.com/javase/6/docs/api/javax/swing/package-summary.html#threading了解更多详情。使用javax.swing.Timer以重复的间隔执行swing动作。