【问题标题】:How do I change the speed of an AnimationTimer in JavaFX?如何在 JavaFX 中更改 AnimationTimer 的速度?
【发布时间】:2018-10-24 12:37:33
【问题描述】:

我正在尝试更改 AnimationTimer 的速度,因此代码运行速度较慢,这是我目前拥有的代码:

AnimationTimer timer = new AnimationTimer() {

    @Override
    public void handle(long now) {    
        if (upOrDown != 1) {
            for (int i = 0; i < 4; i++) {
                snakePositionDown[i] = snake[i].getX();
                snakePositionDownY[i] = snake[i].getY();
            }

            snake[0].setY(snake[0].getY() + 25);

            for (int i = 1; i < 4; i++) {
                snake[i].setX(snakePositionDown[i - 1]);
                snake[i].setY(snakePositionDownY[i - 1]);
            }

            leftOrRight = 2;
            upOrDown = 0;
        }
    }

};

timer.start();

如何让AnimationTimer 运行得更慢?

提前致谢!

【问题讨论】:

    标签: animation javafx timer javafx-8


    【解决方案1】:

    您可以为此使用Timeline。调整Timeline.rate 属性还可以让您更新“速度”:

    // update once every second (as long as rate remains 1)
    Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(1), event -> {
    
        if (upOrDown != 1) {
            for (int i = 0; i < 4; i++) {
                snakePositionDown[i] = snake[i].getX();
                snakePositionDownY[i] = snake[i].getY();
            }
            snake[0].setY(snake[0].getY() + 25);
            for (int i = 1; i < 4; i++) {
                snake[i].setX(snakePositionDown[i - 1]);
                snake[i].setY(snakePositionDownY[i - 1]);
            }
            leftOrRight = 2;
            upOrDown = 0;
        }    
    
    }));
    timeline.setCycleCount(Animation.INDEFINITE);
    timeline.play();
    
    ...
    
    // double speed
    timeline.setRate(2);
    

    【讨论】:

      【解决方案2】:

      AnimationTimerhandle() 方法在每个“脉冲”上调用 - 即,每次渲染帧时。默认情况下,JavaFX 工具包将尝试每秒执行 60 次,但这并不能保证。它可以通过设置系统属性来更改,JavaFX 的未来版本可能会尝试更频繁地执行脉冲。如果 FX 应用程序线程有大量工作要做,那么脉冲的发生频率可能​​低于目标频率。因此,handle() 方法中的代码需要考虑自上次更新以来的时间量。

      传递给handle(...) 方法的参数表示当前系统时间,以纳秒为单位。所以解决这个问题的典型方法是:

      AnimationTimer h = new AnimationTimer() {
      
          private long lastUpdate; // Last time in which `handle()` was called
      
          private double speed = 50 ; // The snake moves 50 pixels per second
      
          @Override
          public void start() {
              lastUpdate = System.nanoTime();
              super.start();
          }
      
          @Override
          public void handle(long now) {
              long elapsedNanoSeconds = now - lastUpdate;
      
              // 1 second = 1,000,000,000 (1 billion) nanoseconds
              double elapsedSeconds = elapsedNanoSeconds / 1_000_000_000.0;
      
              // ...
              snake[0].setY(snake[0].getY() + elapsedSeconds * speed);
              // ...
      
              lastUpdate = now;
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2015-07-20
        • 2021-12-04
        • 2021-03-12
        • 1970-01-01
        • 1970-01-01
        • 2017-05-30
        • 1970-01-01
        • 1970-01-01
        • 2012-12-02
        相关资源
        最近更新 更多