用于游戏循环的 Java TimerTick 事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5844794/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 13:05:07  来源:igfitidea点击:

Java TimerTick event for game loop

javaswingtimergame-loop

提问by Johnathan

I tried making a game loop in Java using the Timer from java.util.Timer. I am unable to get my game loop to execute during the timer tick. Here is an example of this issue. I am trying to move the button during the game loop, but it is not moving on the timer tick event.

我尝试使用 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();
        }
    }
}

回答by Hovercraft Full Of Eels

Since this is a Swing application, don't use a java.util.Timer but rather a javax.swing.Timer also known as a Swing Timer.

由于这是一个 Swing 应用程序,因此不要使用 java.util.Timer,而是使用 javax.swing.Timer(也称为 Swing Timer)。

e.g.,

例如,

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

in the constructor

在构造函数中

  // 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();

and

   public void gameLoop() {
      button.setLocation(button.getLocation().x + 1, button.getLocation().y);
      getContentPane().repaint(); // don't forget to repaint the container
   }

回答by JB Nizet

First of all, Timer.schedule schedules the task for one execution, not for repeated executions. So this program can only make the button move once.

首先, Timer.schedule 将任务调度为一次执行,而不是重复执行。所以这个程序只能让按钮移动一次。

And you have a second problem : all the interactions with swing components should be done in the event dispatch thread, and not in a background thread. Read http://download.oracle.com/javase/6/docs/api/javax/swing/package-summary.html#threadingfor more details. Use a javax.swing.Timer to perform swing actions at repeated intervals.

您还有第二个问题:与 Swing 组件的所有交互都应该在事件调度线程中完成,而不是在后台线程中完成。阅读http://download.oracle.com/javase/6/docs/api/javax/swing/package-summary.html#threading了解更多详情。使用 javax.swing.Timer 以重复的间隔执行摆动动作。