How to make the ball bounce off the walls in JavaFX?

Gregg1989 picture Gregg1989 · Nov 16, 2013 · Viewed 12.6k times · Source

I am new to Javafx and I am creating a simple program. What I'm trying to achieve is get the ball to bounce off the walls, but I haven't figured out how to do that yet. Also, feel free to leave other suggestions about my code.

Here's the source code:

public class GamePractice extends Application {

    public static Circle circle;
    public static Pane canvas;
    private long counter = 0;

    @Override
    public void start(Stage primaryStage) {

        canvas = new Pane();
        Scene scene = new Scene(canvas, 800, 600);

        primaryStage.setTitle("Game");
        primaryStage.setScene(scene);
        primaryStage.show();

        circle = new Circle(15,Color.BLUE);
        circle.relocate(100, 100);         

        canvas.getChildren().addAll(circle);


        Timeline loop = new Timeline(new KeyFrame(Duration.millis(10), new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent t) {
                if (counter++ % 10 == 0)
                {
                    circle.setLayoutX(circle.getLayoutX() + 10);
                    circle.setLayoutY(circle.getLayoutY() + 10);


                    //This is what I currently have, am I headed the right direction?
                    //Check X and Y for collision with the ball
                    if ((circle.getTranslateX() == canvas.getWidth() - 10) || (circle.getTranslateY() == canvas.getHeight() - 10)) {
                        //How do I make the ball bounce?
                    }

                }
            }

        }));

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

I appreciate the help.

Answer

Jens Piegsa picture Jens Piegsa · Nov 16, 2013

One hint: you should avoid comparing double values for exact equality a == b.

With some small changes of your code you're already there:

package learn.javafx;

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 GamePractice extends Application {

    public static Circle circle;
    public static Pane canvas;

    @Override
    public void start(final Stage primaryStage) {

        canvas = new Pane();
        final Scene scene = new Scene(canvas, 800, 600);

        primaryStage.setTitle("Game");
        primaryStage.setScene(scene);
        primaryStage.show();

        circle = new Circle(15, Color.BLUE);
        circle.relocate(100, 100);

        canvas.getChildren().addAll(circle);

        final Timeline loop = new Timeline(new KeyFrame(Duration.millis(10), new EventHandler<ActionEvent>() {

            double deltaX = 3;
            double deltaY = 3;

            @Override
            public void handle(final ActionEvent t) {
                circle.setLayoutX(circle.getLayoutX() + deltaX);
                circle.setLayoutY(circle.getLayoutY() + deltaY);

                final Bounds bounds = canvas.getBoundsInLocal();
                final boolean atRightBorder = circle.getLayoutX() >= (bounds.getMaxX() - circle.getRadius());
                final boolean atLeftBorder = circle.getLayoutX() <= (bounds.getMinX() + circle.getRadius());
                final boolean atBottomBorder = circle.getLayoutY() >= (bounds.getMaxY() - circle.getRadius());
                final boolean atTopBorder = circle.getLayoutY() <= (bounds.getMinY() + circle.getRadius());

                if (atRightBorder || atLeftBorder) {
                    deltaX *= -1;
                }
                if (atBottomBorder || atTopBorder) {
                    deltaY *= -1;
                }
            }
        }));

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

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