首页 > 解决方案 > 如何让时间线不再粘在一起?

问题描述

我有一个 javafx 项目,其中有一个圆圈和四个按钮(左、右、上、下)。当您按下按钮时,圆圈将开始沿按钮的方向移动。如果你按下另一个按钮,圆圈必须改变方向。如果您按下圆圈,它将变为红色,并且时间线将停止。问题是每次您再次按下按钮时,它都会更新时间线,但它会生成另一个时间线,并且圆圈会变得疯狂。

每次有人按下按钮但没有工作时,我都试图停止时间线。

Timeline animation;
btnL.setOnAction(e -> {
 if(check == false){
  animation = new Timeline(new KeyFrame(Duration.millis(50), f->  moveBall('l')));
  animation.setCycleCount(Timeline.INDEFINITE);
  animation.play();
  check = true;
 }
});
btnR.setOnAction(e -> {
 if(check == false){
  animation = new Timeline(new KeyFrame(Duration.millis(50), f-> moveBall('r')));
  animation.setCycleCount(Timeline.INDEFINITE);
  animation.play();
  check = true;
 }
});
btnU.setOnAction(e -> {
 if(check == false){
  animation = new Timeline(new KeyFrame(Duration.millis(50), f-> 
moveBall('u')));
  animation.setCycleCount(Timeline.INDEFINITE);
  animation.play();
  check = true;
 }
});
btnD.setOnAction(e -> {
 if(check == false){
  animation = new Timeline(new KeyFrame(Duration.millis(50), f-> moveBall('d')));
  animation.setCycleCount(Timeline.INDEFINITE);
  animation.play();
  check = true;
 }
});
circle.setOnMouseClicked(e -> {
 circle.setFill(Color.RED);
 animation.stop();
 check = false;
});

最后我做了一个布尔检查来检查是否有人按下了按钮并且球正在移动,任何其他按钮都不会做任何事情。但我相信还有一个更正确的解决方案。

标签: javajavafx

解决方案


在创建新时间线之前停止时间线应该可以:

btnL.setOnAction(e -> {
    if(!check) {
        if (animation != null) {
            animation.stop(); // stop old animation
        }
        animation = new Timeline(new KeyFrame(Duration.millis(50), f->  moveBall('l')));
        animation.setCycleCount(Timeline.INDEFINITE);
        animation.play();
        check = true;
    }
});

由于您要更改的唯一内容是char传递给moveBall,因此您可以简单地将这个值存储在一个字段中并仅使用一个Timeline

private char direction = 0;
private final Timeline animation = new Timeline(new KeyFrame(Duration.millis(50), f-> moveBall(direction)));

{
    animation.setCycleCount(Timeline.INDEFINITE);
}

private void setDirection(char direction) {
    if (!check) {
        this.direction = direction;
        animation.playFromStart();
        check = true;
    }
}
btnL.setOnAction(e -> setDirection('l'));
btnR.setOnAction(e -> setDirection('r'));
...

注意:我假设check设置为false您未显示的代码中的某个位置。否则,只有在圆圈上单击才能允许其他按钮按下以在初始按钮之后产生任何效果。如果没有,只需删除ifand 分配并仅保留if.


推荐阅读