多次废除PathTransition

时间:2018-09-20 18:51:22

标签: java javafx

我正在尝试创建一个程序,该程序可以在边框上随机移动多个圆圈。我创建了一个方法,使我的圈子在窗格上遵循随机的“直线”路径。我通过PathTransition做到这一点。他们确实沿线前进,因此继续前进。但是当它们到达转换的结尾时,它们就会停止...我希望它们移动到另一个随机位置,以便它们在窗格中随机移动。

在这里,我在边框的任意位置创建并添加具有随机颜色的圆圈:

public void MoveCircles(BorderPane borderPane,Circle circles[]){
    for (int i = 0; i < 20; i++) {
        Random random = new Random();
        int endPosX = random.nextInt((int) borderPane.getWidth() - 30);
        int endPosY = random.nextInt((int) borderPane.getHeight() - 30);

        Line line2 = new Line(circles[i].getCenterX(), circles[i].getCenterY(), endPosX, endPosY);
        PathTransition pathTransition2 = new PathTransition();
        pathTransition2.setNode(circles[i]);
        pathTransition2.setDuration(Duration.seconds(2));
        pathTransition2.setPath(line2);
        pathTransition2.play();
    }
}

以下是使它们移动的方法:

MoveCircles(borderPane,circles);

我在这里调用方法:

pad('12ab\n121\n51', 5)
> '12ab \n121  \n51   '

我试图在循环中重复该方法,但这不起作用。他们只移动一次就停下来。我如何才能使该方法一遍又一遍地重复,以使圆圈不断移动。提前输入:)

2 个答案:

答案 0 :(得分:0)

调用动画的play()方法时,动画开始在后台播放。因此,如果您创建并启动几个影响同一个节点的动画,它们都几乎同时开始,并且会相互干扰。

您想要的是让多个动画依次播放。您可以使用SequentialTransition

public void moveCircles(BorderPane borderPane, Circle circles[]) {

    // Better to create one Random and keep using it to generate random values.
    Random random = new Random();

    int repeatCount = 5;

    for (int i = 0; i < circles.length; i++) {

        SequentialTransition sequence = new SequentialTransition();

        for (int r = 0; r < repeatCount; r++) {
            int endPosX = random.nextInt((int) borderPane.getWidth() - 30);
            int endPosY = random.nextInt((int) borderPane.getHeight() - 30);

            Line line2 = new Line(circles[i].getCenterX(), circles[i].getCenterY(), endPosX, endPosY);
            PathTransition pathTransition2 = new PathTransition();
            pathTransition2.setNode(circles[i]);
            pathTransition2.setDuration(Duration.seconds(2));
            pathTransition2.setPath(line2);
            sequence.getChildren().add(pathTransition2);
        }

        sequence.play();
    }
}

答案 1 :(得分:0)

作为SequentialTransition的替代方法,可以使用PathTransition类的setOnFinished方法。动画完成后将调用此方法。在这里,您可以设置新路径并重新开始动画。

使用setOnFinished方法,MoveCircles方法变为:

public void MoveCircles(BorderPane borderPane,Circle circles[]){
    for (int i = 0; i < 20; i++) {
        PathTransition pathTransition2 = new PathTransition();
        pathTransition2.setNode(circles[i]);
        pathTransition2.setDuration(Duration.seconds(2));
        pathTransition2.setPath(createPath(borderPane, pathTransition2));       
        pathTransition2.play();
        pathTransition2.setInterpolator(Interpolator.LINEAR);               
        pathTransition2.setOnFinished(e -> {                        
            pathTransition2.setPath(createPath(borderPane, pathTransition2));   
            pathTransition2.play();                         
        });                                     
    }
}

由于路径的创建被使用了两次,因此有必要使用一种单独的方法来移动功能,例如

private Line createPath(BorderPane borderPane, PathTransition pathTransition) {
    Circle circle = (Circle)pathTransition.getNode();
    Line line = (Line)pathTransition.getPath();
    Random random = new Random();
    int endPosX = random.nextInt((int) borderPane.getWidth() - 30);
    int endPosY = random.nextInt((int) borderPane.getHeight() - 30);
    return new Line(line == null ? circle.getCenterX() : line.getEndX(), line == null ? circle.getCenterY() : line.getEndY(), endPosX, endPosY); // without discontinuities
    // return new Line(circle.getCenterX(), circle.getCenterY(), endPosX, endPosY); // with discontinuities
}

由于createPath方法的第二个参数是pathTransition本身,因此很容易将上一条路径的终点用作起点 避免连续运动序列不连续的下一条路径。但这当然是可选的。