在运行动画时使新动画无法播放(在动画过程中禁用setOnMouseClicked)

时间:2018-09-04 22:33:08

标签: java javafx

我一直在寻找实现此目的的方法,但是我似乎无法找到javafx的解决方案(我只能在jQuery和javascript中找到它)。 我有一个游戏,您可以在Mouseclick上旋转磁贴(ImageViews),并使用

setOnMouseClicked(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            update();
        }
    };

更新有这个:

public void update() {
    Animation animation = new RotateTransition(Duration.millis(100), this);
    animation.setByAngle(90);
    animation.play();
    tile.rotate();
}

问题是,当我在瓷砖上单击得太快时(尽管它仍在旋转),它被拧紧并卡在例如60度的位置。 我只想制作它,因此在动画运行时无法单击imageView。 请帮我。 预先感谢!

2 个答案:

答案 0 :(得分:0)

您可以添加一个布尔值,用于存储该函数当前是否正在运行,并相应地禁用/启用它。

boolean currentlyPlaying = false;
node.setOnMouseClicked(event -> {
    if (!currentlyPlaying)
        update();
});
public void update() {
    Animation animation = new RotateTransition(Duration.millis(100), this);
    animation.setByAngle(90);
    animation.play();
    currentlyPlaying = true;
    animation.setOnFinished(event -> currentlyPlaying = false;);
    tile.rotate();
}

答案 1 :(得分:0)

另一种方法是使用boolean中的status property,而不是创建单独的Animation变量。您还可以为每个图块重复使用相同的Animation

import javafx.animation.Animation.Status;
import javafx.animation.RotateTransition;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Main extends Application {

  private RotateTransition transition;

  @Override
  public void start(Stage primaryStage) throws Exception {
    GridPane root = new GridPane();
    root.setPadding(new Insets(20));
    root.setHgap(15);
    root.setVgap(15);

    EventHandler<MouseEvent> onClick = this::handleClick;
    for (int i = 0; i < 10; i++) {
      for (int j = 0; j < 10; j++) {
        Rectangle rect = new Rectangle(50, 50);
        rect.setOnMouseClicked(onClick);
        root.add(rect, i, j);
      }
    }

    Scene scene = new Scene(root);
    primaryStage.setScene(scene);
    primaryStage.setTitle("Animation Example");
    primaryStage.setResizable(false);
    primaryStage.show();
  }

  private void handleClick(MouseEvent event) {
    if (transition == null) {
      transition = new RotateTransition(Duration.seconds(100));
      transition.setByAngle(90);
    } else if (transition.getStatus() == Status.RUNNING) {
      return;
    }

    transition.setNode((Rectangle) event.getSource());
    transition.playFromStart();
    event.consume();
  }

}

此代码仅在当前未运行时才开始新的过渡。但是请注意,此设置仅允许一个瓷砖在任何给定时间旋转。如果您希望每个图块都有动画,则需要进行一些小的调整。

import java.util.HashMap;
import java.util.Map;
import javafx.animation.Animation.Status;
import javafx.animation.RotateTransition;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Main extends Application {

  private final Map<Rectangle, RotateTransition> animations = new HashMap<>();

  @Override
  public void start(Stage primaryStage) throws Exception {
    GridPane root = new GridPane();
    root.setPadding(new Insets(20));
    root.setHgap(15);
    root.setVgap(15);

    EventHandler<MouseEvent> onClick = this::handleClick;
    for (int i = 0; i < 10; i++) {
      for (int j = 0; j < 10; j++) {
        Rectangle rect = new Rectangle(50, 50);
        rect.setOnMouseClicked(onClick);
        root.add(rect, i, j);
      }
    }

    Scene scene = new Scene(root);
    primaryStage.setScene(scene);
    primaryStage.setTitle("Animation Example");
    primaryStage.setResizable(false);
    primaryStage.show();
  }

  private void handleClick(MouseEvent event) {
    RotateTransition animation = animations.computeIfAbsent((Rectangle) event.getSource(), rect -> {
      RotateTransition rt = new RotateTransition(Duration.millis(100), rect);
      rt.setByAngle(90);
      return rt;
    });

    if (animation.getStatus() != Status.RUNNING) {
      animation.playFromStart();
      event.consume();
    }
  }

}

现在,每个图块都有自己的RotateTransition,但是只有在动画尚未运行时,它才会播放。