循环中的 PathTransition
PathTransition in loop
我有 8x8 板,其中 SIZE = 8,moveHistory 是 javafx.geometry.Point2D 的 ArrayList。这是代码:
private class ChessBoard extends Pane {
ImageView knightImageView = new ImageView("image/knight.jpg");
ChessBoard() {
this.setOnMouseClicked(e -> {
startX = (int)(e.getX() / (getWidth() / SIZE));
startY = (int)(e.getY() / (getHeight() / SIZE));
resetMoveHistory();
paint();
});
}
protected void paint() {
this.getChildren().clear();
this.getChildren().add(knightImageView);
knightImageView.setX(startX * getWidth() / SIZE);
knightImageView.setY(startY * getHeight() / SIZE);
knightImageView.setFitWidth(getWidth() / SIZE);
knightImageView.setFitHeight(getHeight() / SIZE);
for (int i = 1; i <= SIZE; i++) {
this.getChildren().add(new Line(0, i * getHeight() / SIZE,
getWidth(), i * getHeight() / SIZE));
this.getChildren().add(new Line(i * getWidth() / SIZE, 0,
i * getWidth() / SIZE, getHeight()));
}
if (moveHistory != null) {
for (int i = 1; i < moveHistory.size(); i++) {
Point2D p1 = moveHistory.get(i - 1);
Point2D p2 = moveHistory.get(i);
PathTransition ptMove = new PathTransition();
Line line = (new Line(
p1.getX() * (getWidth() / SIZE) + getWidth() / SIZE / 2,
p1.getY() * (getHeight() / SIZE) + (getHeight() / SIZE / 2),
p2.getX() * (getWidth() / SIZE) + getWidth() / SIZE / 2,
p2.getY() * (getHeight() / SIZE) + getHeight() / SIZE / 2));
ptMove.setPath(line);
ptMove.setNode(knightImageView);
ptMove.setCycleCount(1);
ptMove.setDuration(Duration.seconds(2));
ptMove.play();
}
}
}
}
我想做的是显示最后一个循环的动作,但它只显示 1 个不正确的动作并且一遍又一遍地播放它。 我哪里错了? 任何帮助都将不胜感激!
play()
方法开始动画播放并立即退出。因此,您实际上几乎同时启动了所有动画,并让它们同时播放。每个动画设置 knightImageView
的 translateX
和 translateY
属性,这些值将在动画持续期间由每个渲染帧上的每个动画设置。无论哪个动画碰巧最后设置了值,都会在该帧上设置 "win",这就是将要渲染的值。所以整体效果将是高度不可预测的。
你想要的(我认为)是一个接一个地播放动画。你可以用 SequentialTransition
来做到这一点。你的代码应该看起来像这样:
if (moveHistory != null) {
SequentialTransition sequentialTransition = new SequentialTranstiion();
for (int i = 1; i < moveHistory.size(); i++) {
Point2D p1 = moveHistory.get(i - 1);
Point2D p2 = moveHistory.get(i);
PathTransition ptMove = new PathTransition();
Line line = (new Line(
p1.getX() * (getWidth() / SIZE) + getWidth() / SIZE / 2,
p1.getY() * (getHeight() / SIZE) + (getHeight() / SIZE / 2),
p2.getX() * (getWidth() / SIZE) + getWidth() / SIZE / 2,
p2.getY() * (getHeight() / SIZE) + getHeight() / SIZE / 2));
ptMove.setPath(line);
ptMove.setNode(knightImageView);
ptMove.setCycleCount(1);
ptMove.setDuration(Duration.seconds(2));
sequentialTransition.getChildren().add(ptMove);
}
sequentialTransition.play();
}
这里要注意的另一件事是,过渡通过操纵 translateX
和 translateY
坐标来移动图像视图。您调用的 ImageView
的 setX
和 setY
方法可能不会按照您的想法进行:请参阅 Javadocs.
我有 8x8 板,其中 SIZE = 8,moveHistory 是 javafx.geometry.Point2D 的 ArrayList。这是代码:
private class ChessBoard extends Pane {
ImageView knightImageView = new ImageView("image/knight.jpg");
ChessBoard() {
this.setOnMouseClicked(e -> {
startX = (int)(e.getX() / (getWidth() / SIZE));
startY = (int)(e.getY() / (getHeight() / SIZE));
resetMoveHistory();
paint();
});
}
protected void paint() {
this.getChildren().clear();
this.getChildren().add(knightImageView);
knightImageView.setX(startX * getWidth() / SIZE);
knightImageView.setY(startY * getHeight() / SIZE);
knightImageView.setFitWidth(getWidth() / SIZE);
knightImageView.setFitHeight(getHeight() / SIZE);
for (int i = 1; i <= SIZE; i++) {
this.getChildren().add(new Line(0, i * getHeight() / SIZE,
getWidth(), i * getHeight() / SIZE));
this.getChildren().add(new Line(i * getWidth() / SIZE, 0,
i * getWidth() / SIZE, getHeight()));
}
if (moveHistory != null) {
for (int i = 1; i < moveHistory.size(); i++) {
Point2D p1 = moveHistory.get(i - 1);
Point2D p2 = moveHistory.get(i);
PathTransition ptMove = new PathTransition();
Line line = (new Line(
p1.getX() * (getWidth() / SIZE) + getWidth() / SIZE / 2,
p1.getY() * (getHeight() / SIZE) + (getHeight() / SIZE / 2),
p2.getX() * (getWidth() / SIZE) + getWidth() / SIZE / 2,
p2.getY() * (getHeight() / SIZE) + getHeight() / SIZE / 2));
ptMove.setPath(line);
ptMove.setNode(knightImageView);
ptMove.setCycleCount(1);
ptMove.setDuration(Duration.seconds(2));
ptMove.play();
}
}
}
}
我想做的是显示最后一个循环的动作,但它只显示 1 个不正确的动作并且一遍又一遍地播放它。 我哪里错了? 任何帮助都将不胜感激!
play()
方法开始动画播放并立即退出。因此,您实际上几乎同时启动了所有动画,并让它们同时播放。每个动画设置 knightImageView
的 translateX
和 translateY
属性,这些值将在动画持续期间由每个渲染帧上的每个动画设置。无论哪个动画碰巧最后设置了值,都会在该帧上设置 "win",这就是将要渲染的值。所以整体效果将是高度不可预测的。
你想要的(我认为)是一个接一个地播放动画。你可以用 SequentialTransition
来做到这一点。你的代码应该看起来像这样:
if (moveHistory != null) {
SequentialTransition sequentialTransition = new SequentialTranstiion();
for (int i = 1; i < moveHistory.size(); i++) {
Point2D p1 = moveHistory.get(i - 1);
Point2D p2 = moveHistory.get(i);
PathTransition ptMove = new PathTransition();
Line line = (new Line(
p1.getX() * (getWidth() / SIZE) + getWidth() / SIZE / 2,
p1.getY() * (getHeight() / SIZE) + (getHeight() / SIZE / 2),
p2.getX() * (getWidth() / SIZE) + getWidth() / SIZE / 2,
p2.getY() * (getHeight() / SIZE) + getHeight() / SIZE / 2));
ptMove.setPath(line);
ptMove.setNode(knightImageView);
ptMove.setCycleCount(1);
ptMove.setDuration(Duration.seconds(2));
sequentialTransition.getChildren().add(ptMove);
}
sequentialTransition.play();
}
这里要注意的另一件事是,过渡通过操纵 translateX
和 translateY
坐标来移动图像视图。您调用的 ImageView
的 setX
和 setY
方法可能不会按照您的想法进行:请参阅 Javadocs.