移动圈随机消失(javafx)

时间:2017-09-24 01:06:29

标签: java javafx

uni的分配 - 必须制作使用线程移动的弹跳球,并且可以使用向上和向下箭头键更改速度。

除了球随机消失在一些看不见的方格后面之外,我的工作得很好。它可能与左上角的速度标签有关,因为当我删除标签时,这不会再发生了。

问题的Gif:

控制类:

myFunc

球类:

public class Task3Control extends Application {

    public void start(Stage stagePrimary) {

        //create the ball
        Task3Ball ball = new Task3Ball();

        //create a label to show to ball's current speed
        Label labelSpeed = new Label("Ball Speed: "+ball.getSpeed());

        //create the root pane and place the ball and label within it
        Pane paneRoot = new Pane();
        paneRoot.getChildren().addAll(labelSpeed, ball.circle);

        //create a thread to animate the ball and start it
        Thread t = new Thread(ball);
        t.start();

        //increase and decrease the speed of the ball when the up and down arrow keys are pressed
        //also update the label to reflect the new speed
        paneRoot.setOnKeyPressed(e -> {
            if (e.getCode() == KeyCode.UP) {
                ball.increaseSpeed();
                labelSpeed.setText("Ball Speed: "+ball.getSpeed());
            } 
            else if (e.getCode() == KeyCode.DOWN) {
                ball.decreaseSpeed();
                labelSpeed.setText("Ball Speed: "+ball.getSpeed());
            }
        });

        //Create a scene containing the root pane and place it in the primary stage
        //Set the title of the window to 'Bouncing Ball Animation'
        Scene scene = new Scene(paneRoot, 400, 300);
        stagePrimary.setTitle("Bouncing Ball Animation");
        stagePrimary.setScene(scene);
        stagePrimary.show();
        paneRoot.requestFocus();
    }

1 个答案:

答案 0 :(得分:2)

此问题似乎是由于x的{​​{1}}和y属性的不当更新造成的。

请注意,鉴于您的代码,JVM不需要保证Circle的位置的任何修改对呈现线程可见,并且Circle字段的任何修改都是对动画线程可见。

BTW:您没有将动画线程标记为守护程序线程,因此它会阻止JVM关闭。

将线程设置为守护程序:

speed

正确更新圈子位置

Thread t = new Thread(ball);
t.setDaemon(true);
t.start();

然而,为此目的使用// variable never updated so there are no issues with synchronisation private final double radius = 20; ... protected void moveBall() { // do updates on the JavaFX application thread Platform.runLater(() -> { if (x - radius <= 0 || x + radius >= 400) { dx *= -1; } if (y - radius <= 0 || y + radius >= 300) { dy *= -1; } x += dx * speed; y += dy * speed; circle.setCenterX(x); circle.setCenterY(y); }); } 会更简单:

Timeline
public class Task3Ball {

    private Timeline timeline;

    ...

    protected void moveBall() {
        if (x - radius <= 0 || x + radius >= 400) {
            dx *= -1;
        }

        if (y - radius <= 0 || y + radius >= 300) {
            dy *= -1;
        }

        x += dx * speed;
        y += dy * speed;
        circle.setCenterX(x);
        circle.setCenterY(y);
    }

    public void startAnimation() {
        if (timeline == null) {
            // lazily create timeline
            timeline = new Timeline(new KeyFrame(Duration.millis(20), event -> moveBall()));
            timeline.setCycleCount(Animation.INDEFINITE);
        }

        // ensure the animation is playing
        timeline.play();
    }
}