JavaFX Animated Ball Example
The Bouncing Ball is the “Hello World” of animations in JavaFx. It’s simple to write, easy to understand and reveals the potential of JavaFx even from this primitive stage.
We will start by creating a moving ball that will set the basis for the bouncing ball that will follow.
1. Moving Ball Example
Apart from the basic set up this code has only one important line. The line where we create the Timeline. This Timeline holds two important properties; the KeyFrame and the KeyValue. What we say to the Timeline in simple English is “move the ball from where it is, to the end of the Pane in 3 seconds”. Then we also ask it -kindly- to do it twice and voilà!
package com.mkyong.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();
Output:
2. Bouncing Ball
With a quick view on the code you can notice the similarities to the previous one. Our set up is pretty much the same except that the Timeline now has an EventHandler. The code inside the handle method moves the ball by dx and dy unless the ball is at the bounds of the Pane, where depending on where it is changes the dx and dy to negative step (in other words makes the ball move the other way).
package com.mkyong.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<ActionEvent>() { 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();
Output:
3. Your first game
While experimenting with the Bouncing Ball example, I thought to myself what if I make it all transparent and add a MouseEvent that closes the application on click? Well… guess what… I ended up trying to catch a bouncing ball on my desktop! And that’s how I made my first game in JavaFx! Enjoy!
package com.mkyong.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<MouseEvent>() { @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<ActionEvent>() { 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();
Output:
References
From:一号门
Previous:jsoup Basic web crawler example
COMMENTS