Exemple de balle animée JavaFX

Exemple de balle animée JavaFX

Le Bouncing Ball est le «Hello World» des animations en JavaFx. Il est simple à écrire, facile à comprendre et révèle le potentiel de JavaFx même à partir de cette étape primitive.

Nous commencerons par créer une balle en mouvement qui jettera les bases de la balle rebondissante qui suivra.

1. Exemple de balle en mouvement

Outre la configuration de base, ce code n'a qu'une seule ligne importante. La ligne où nous créons lesTimeline. CeTimeline possède deux propriétés importantes; lesKeyFrame et lesKeyValue. Ce que nous disons auxTimeline en anglais simple, c'est "déplacez la balle de là où elle est, à la fin desPane en 3 secondes". Ensuite, nous lui demandons aussi - gentiment - de le faire deux fois et voilà!

MovingBall.java

package com.techfou.javafx.animatedball;

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class MovingBall extends Application{

    @Override
    public void start(Stage stage) {
        Pane canvas = new Pane();
        Scene scene = new Scene(canvas, 300, 300);
        Circle ball = new Circle(10, Color.RED);
        ball.relocate(0, 10);

        canvas.getChildren().add(ball);

        stage.setTitle("Moving Ball");
        stage.setScene(scene);
        stage.show();

        Bounds bounds = canvas.getBoundsInLocal();
        Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(3),
                new KeyValue(ball.layoutXProperty(), bounds.getMaxX()-ball.getRadius())));
        timeline.setCycleCount(2);
        timeline.play();
    }

    public static void main(String[] args) {
        launch();
    }
}

Sortie:

javafx-animated-ball-example-1

2. Balle rebondissante

Avec un aperçu rapide du code, vous pouvez remarquer les similitudes avec le précédent. Notre configuration est à peu près la même sauf que leTimeline a maintenant unEventHandler. Le code à l'intérieur de la méthode de poignée déplace la balle dedx etdy sauf si la balle est aux limites desPane, où selon l'endroit où elle se trouve change lesdx et dy au pas négatif (en d'autres termes fait bouger la balle dans l'autre sens).

BouncingBall.java

package com.techfou.javafx.animatedball;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class BouncingBall extends Application{

    @Override
    public void start(Stage stage) {

        Pane canvas = new Pane();
        Scene scene = new Scene(canvas, 300, 300, Color.ALICEBLUE);
        Circle ball = new Circle(10, Color.CADETBLUE);
        ball.relocate(5, 5);

        canvas.getChildren().add(ball);

        stage.setTitle("Animated Ball");
        stage.setScene(scene);
        stage.show();

        Timeline timeline = new Timeline(new KeyFrame(Duration.millis(20),
                new EventHandler() {

            double dx = 7; //Step on x or velocity
            double dy = 3; //Step on y

            @Override
            public void handle(ActionEvent t) {
                //move the ball
                ball.setLayoutX(ball.getLayoutX() + dx);
                ball.setLayoutY(ball.getLayoutY() + dy);

                Bounds bounds = canvas.getBoundsInLocal();

                //If the ball reaches the left or right border make the step negative
                if(ball.getLayoutX() <= (bounds.getMinX() + ball.getRadius()) ||
                        ball.getLayoutX() >= (bounds.getMaxX() - ball.getRadius()) ){

                    dx = -dx;

                }

                //If the ball reaches the bottom or top border make the step negative
                if((ball.getLayoutY() >= (bounds.getMaxY() - ball.getRadius())) ||
                        (ball.getLayoutY() <= (bounds.getMinY() + ball.getRadius()))){

                    dy = -dy;

                }
            }
        }));
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.play();
    }

    public static void main(String[] args) {
        launch();
    }
}

Sortie:

javafx-animated-ball-example-2

3. Votre premier match

En expérimentant avec l'exemple Bouncing Ball, je me suis dit que se passerait-il si je rendais tout transparent et ajoutais unMouseEvent qui ferme l'application au clic? Eh bien… devinez quoi… J'ai fini par essayer d'attraper une balle qui rebondit sur mon bureau! Et c’est ainsi que j’ai créé mon premier jeu en JavaFx! Prendre plaisir!

MyFirstGame.java

package com.example.javafx.animatedball;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;

public class MyFirstGame extends Application{

    @Override
    public void start(Stage stage) {

        Pane canvas = new Pane();
        Scene scene = new Scene(canvas, 300, 300, Color.TRANSPARENT);
        Circle ball = new Circle(10, Color.DARKSLATEBLUE);
        ball.relocate(5, 5);

        canvas.getChildren().add(ball);

        stage.initStyle(StageStyle.TRANSPARENT);
        scene.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                Platform.exit();
                System.exit(0);
            }
        });
        stage.setTitle("Animated Ball");
        stage.setScene(scene);
        stage.show();

        Timeline timeline = new Timeline(new KeyFrame(Duration.millis(20), new EventHandler() {
            double dx = 7; //Step on x or velocity
            double dy = 3; //Step on y

            @Override
            public void handle(ActionEvent t) {
                //move the ball
                ball.setLayoutX(ball.getLayoutX() + dx);
                ball.setLayoutY(ball.getLayoutY() + dy);

                Bounds bounds = canvas.getBoundsInLocal();

                //If the ball reaches the left or right border make the step negative
                if(ball.getLayoutX() <= (bounds.getMinX() + ball.getRadius()) ||
                        ball.getLayoutX() >= (bounds.getMaxX() - ball.getRadius()) ){

                    dx = -dx;

                }

                //If the ball reaches the bottom or top border make the step negative
                if((ball.getLayoutY() >= (bounds.getMaxY() - ball.getRadius())) ||
                        (ball.getLayoutY() <= (bounds.getMinY() + ball.getRadius()))){

                    dy = -dy;

                }

            }
        }));
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.play();
    }

    public static void main(String[] args) {
        launch();
    }
}

Sortie:

javafx-animated-ball-example-3