Search code examples
animationtimejavafxwaitpause

JavaFX animating simon says, cant figure out timing


Im writing a simon says game in javaFX and i've come across the problem of animating the sequence. I can't figure out how to queue the animation of the buttons(which are arcs that get highlighted)

if (mootor.isArvutiKäik()){
                mootor.genereeriuus(); 
                for(int i = 0; i < mootor.getJärjend().size(); i++){
                    if(mootor.getJärjend().get(i)==0){
                        punane.setFill(Color.RED);
                        Timeline timeline = new Timeline(new KeyFrame(
                                Duration.millis(500),
                                ae -> punane.setFill(Color.RED.darker())));
                        timeline.play();
                    } else if (mootor.getJärjend().get(i)==1) {
                        roheline.setFill(Color.GREEN.brighter());
                        Timeline timeline = new Timeline(new KeyFrame(
                                Duration.millis(500),
                                ae -> roheline.setFill(Color.GREEN)));
                        timeline.play();
                    } else if (mootor.getJärjend().get(i)==2) {
                        sinine.setFill(Color.BLUE);
                        Timeline timeline = new Timeline(new KeyFrame(
                                Duration.millis(500),
                                ae -> sinine.setFill(Color.BLUE.darker())));
                        timeline.play();
                    } else {
                        kollane.setFill(Color.YELLOW);
                        Timeline timeline = new Timeline(new KeyFrame(
                                Duration.millis(500),
                                ae -> kollane.setFill(Color.YELLOW.darker())));
                        timeline.play();
                    }
                    PauseTransition test = new PauseTransition(Duration.millis(500));
                    test.play();
                }
                //mootor.setArvutiKäik(false);
            }

The code generates an integer from 0 to 3 and depending on the integer highlights an arc corresponding to the number. Right now, however, all the generated integers and thus arcs are highlighted at once. I saw mentions of platform.runlater (or something similar) but I couldnt figure it out, how to use it.

Thank you for your time!


Solution

  • An Animation will start as soon as you call the play method. Since the loop runs in short time compared to the time the animation should wait, all events happen (almost) simultaneously.

    You can use a SequentialTransition to play the Animations sequentially.

    The following code demonstrates one way to repeatedly change the color of a Rectangle:

    @Override
    public void start(Stage primaryStage) {
        Rectangle rect = new Rectangle(50, 50);
    
        Button btn = new Button("start");
        btn.setOnAction((ActionEvent event) -> {
            SequentialTransition sequence = new SequentialTransition();
    
            List<Color> colors = Arrays.asList(Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW);
    
            for (Color color : colors) {
                PauseTransition transition = new PauseTransition(Duration.millis(500));
                transition.setOnFinished(evt -> rect.setFill(color));
                sequence.getChildren().add(transition);
            }
    
            sequence.play();
        });
    
    
        Scene scene = new Scene(new VBox(rect, btn));
    
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    

    In your case however you could simply add all KeyFrames to the same Timeline animation using different values for the in all KeyFrames. You could simply use Duration.millis(1000*i + 500) as the times for the color changes.