我一直在寻找实现此目的的方法,但是我似乎无法找到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。 请帮我。 预先感谢!
答案 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
,但是只有在动画尚未运行时,它才会播放。