在关键帧方法中增加动画速率显然会禁用该功能

时间:2016-04-20 20:39:45

标签: animation javafx timeline keyframe

我搜索过,一无所获。我试图让一个简单的弹跳球连续加速。下面的代码根本不加速球(即使用鼠标点击),但getRate()属性确实按预期增加。如果我注释掉moveBall()中的increaseSpeed()方法调用,鼠标点击将加速球。

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;

public class MyApp extends Application {
  @Override
  public void start(Stage primaryStage) {
  Bounce bouncePane = new Bounce();
  bouncePane.setOnMousePressed(e -> bouncePane.increaseSpeed());

  Scene scene = new Scene(bouncePane, 250, 150);
  primaryStage.setTitle("Bouncing Ball");
  primaryStage.setScene(scene);
  primaryStage.show();
  bouncePane.requestFocus();
 }
}

public class Bounce extends Pane {
  public final double rad = 25;
  private double x = rad, y = rad;
  private double dx = 1, dy = 1;
  private Circle ball = new Circle(x, y, rad);
  private Timeline anim;

  public Bounce() {
  ball.setFill(Color.BLUE);
  getChildren().add(ball);

  anim = new Timeline(
     new KeyFrame(Duration.millis(50), e -> moveBall()));
  anim.setCycleCount(Timeline.INDEFINITE);
  anim.play();
}

public void increaseSpeed() {
  anim.setRate(anim.getRate() + 0.5);
  System.out.println(anim.getRate());
}

protected void moveBall() {

  if (x < rad || x > getWidth() - rad) {
    dx *= -1;
  }
  if (y < rad || y > getHeight() - rad) {
    dy *= -1;
  }

  x += dx;
  y += dy;
  ball.setCenterX(x);
  ball.setCenterY(y);
  increaseSpeed();
}
}

1 个答案:

答案 0 :(得分:0)

您的应用程序确实有效(有点)

如果您将KeyFrame的持续时间设置为Duration.millis(1_000)而不是Duration.millis(50),那么您将看到动画加速(最高可达1_000 / 60)。

咦?发生了什么

默认情况下,JavaFX的上限为每秒60帧。无论您将播放速率设置为什么,时间轴中的关键帧都不会被频繁调用。因为在您的示例中,您将动画的初始持续时间设置为50毫秒,然后在每帧中将速率提高50%,关键帧的动画回调很快(在人眼察觉不到的时间内)达到每秒60帧的最大帧速率,一旦这样做,你就无法更快地运行它。

你能做什么

对于这类问题,也许不依靠动画播放速度来控制对象的速度。相反,使用"game loop"实现AnimationTimer并将速度与对象关联,并根据循环将对象移动到所需位置,例如JamesD在此AnimationTimerTest中完成的。 / p>