Пример JavaFX Animated Ball

Пример анимированного шара JavaFX

Прыгающий мяч - это «Привет, мир» анимаций в JavaFx. Его просто написать, легко понять и раскрыть потенциал JavaFx даже на этой примитивной стадии.

Мы начнем с создания движущегося мяча, который станет основой для следующего подпрыгивающего мяча.

1. Пример движущегося мяча

Помимо базовой настройки в этом коде есть только одна важная строка. Строка, в которой мы создаемTimeline. ЭтотTimeline обладает двумя важными свойствами; KeyFrame иKeyValue. То, что мы говоримTimeline на простом английском языке, это «переместите мяч с того места, где он находится, к концуPane за 3 секунды». Тогда мы также просим его - любезно - сделать это дважды и вуаля!

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();
    }
}

Выход:

javafx-animated-ball-example-1

2. Прыгающий мяч

При быстром просмотре кода вы можете заметить сходство с предыдущим. Наша установка почти такая же, за исключением того, чтоTimeline теперь имеетEventHandler. Код внутри метода handle перемещает мяч наdx иdy, если только мяч не находится на границеPane, где в зависимости от того, где он находится, изменяютсяdx и dy на отрицательный шаг (другими словами, заставляет мяч двигаться в другую сторону).

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();
    }
}

Выход:

javafx-animated-ball-example-2

3. Ваша первая игра

Экспериментируя с примером Bouncing Ball, я подумал, что если я сделаю все прозрачным и добавлюMouseEvent, закрывающее приложение при нажатии? Ну… угадайте, что… В итоге я пытался поймать прыгающий мяч на своем рабочем столе! Так я сделал свою первую игру на JavaFx! Наслаждайтесь!

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();
    }
}

Выход:

javafx-animated-ball-example-3