如何在每个循环后更新半径的随机值?

时间:2017-09-10 05:00:39

标签: java javafx random

以下是我的以下代码:

 public void start(Stage primaryStage) throws Exception {
        Pane root = new Pane();
        Scene scene = new Scene(root, 500, 600);
        Random rand = new Random();

       int random = rand.nextInt(100-5)+5;
       Circle circle = new Circle(0, 10, random);
       circle.setFill(Color.RED);
       root.getChildren().add(circle);

       Timeline timeline = new Timeline(
            new KeyFrame(
              Duration.seconds(2),
              new KeyValue(circle.translateXProperty(), 600)
         ));
        timeline.setCycleCount(Animation.INDEFINITE);
        timeline.setAutoReverse(false);
        timeline.play();

        primaryStage.setScene(scene);
        primaryStage.show();

    }

在此代码中,它只更新random值一次,但我希望它在每个周期后更新random值。有没有什么办法可以在每个周期后更新random值?任何帮助表示赞赏!

6 个答案:

答案 0 :(得分:1)

如果您使用的是Timeline

  

无法更改正在运行的时间轴的keyFrame。如果   对于正在运行的时间轴,keyFrames的值已更改,必须如此   停下来,再次开始拿起新值。

因此,您可以在每次要创建新的keyFrame时重新创建时间轴,在您的情况下使用new Circle(0, 10, new Random().nextInt(100-5)+5, Color.RED);

答案 1 :(得分:1)

Keyframe的构造函数需要多个KeyValue。您可以向构造函数添加一个半径为circle的新KeyValue。据我所知,您应该创建自己的Interpolator实现,以使半径的随机行为生效。 (也许有第三方解决方案)

答案 2 :(得分:1)

您应该在调用KeyValue构造函数时添加EventHandler<ActionEvent>

也就是说,向new KeyValue(circle.translateXProperty(), 600)添加一个参数,使其看起来像new KeyValue(circle.translateXProperty(), (event)->{circle.setRadius(rand.nextInt(100-5)+5);}, 600)

答案 3 :(得分:1)

默认的Interpolater(EASE_BOTH)钳位当前时间间隔的时间值,即压裂值的范围为[0.0,...,1.0]。您可以使用相同的信息并在新周期开始时更新半径。

public void start(Stage primaryStage) {
    Pane root = new Pane();
    Scene scene = new Scene(root, 500, 600);

    final Random random = new Random();
    Circle circle = new Circle(0, 0, random.nextInt(100));
    circle.setFill(Color.RED);
    root.getChildren().add(circle);

    Animation animation = new Transition() {
        {
            setCycleCount(INDEFINITE);
            setCycleDuration(Duration.seconds(2));
        }

        @Override
        protected void interpolate(double frac) {
            if (frac == 0) {
                final int newRadius = random.nextInt(100);
                System.out.println("New Radius: " + newRadius);
                circle.setRadius(newRadius + 5);
            }
            circle.setTranslateX(frac * 600);
        }
    };
    animation.play();
    primaryStage.setScene(scene);
    primaryStage.show();
}

答案 4 :(得分:0)

不确定这是否会降低您的代码速度,但您可能想尝试将循环计数设置为1而不是Animation.INDEFINITE并将整个块包装在while循环中:

public void start(Stage primaryStage) throws Exception {
    Pane root = new Pane();
    Scene scene = new Scene(root, 500, 600);
    Random rand = new Random();

    primaryStage.setScene(scene);
    primaryStage.show();

    while (true) { 
        int random = rand.nextInt(100-5)+5;
        Circle circle = new Circle(0, 10, random);
        circle.setFill(Color.RED);
        root.getChildren().add(circle);

        Timeline timeline = new Timeline(new KeyFrame(
            Duration.seconds(2),
            new KeyValue(circle.translateXProperty(), 600)
        ));
        timeline.setCycleCount(1);
        timeline.setAutoReverse(false);

        timeline.play();
    }
}

一个问题是primaryStage.show()会向上移动(因此尽管存在永久循环,它仍会运行)。如果这成为问题,请考虑将while (true)更改为其他内容。

答案 5 :(得分:0)

添加EventHandler<ActionEvent>,将radius属性更新为KeyFrame的最后Timeline

final Random rand = new Random();

int random = rand.nextInt(100-5)+5;
final Circle circle = new Circle(0, 10, random);
circle.setFill(Color.RED);
root.getChildren().add(circle);

Timeline timeline = new Timeline(
    new KeyFrame(
      Duration.seconds(2),
      event -> circle.setRadius(rand.nextInt(100-5)+5),
      new KeyValue(circle.translateXProperty(), 600)
 ));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.setAutoReverse(false);
timeline.play();