如何在javafx中每5秒(5000毫秒)创建一个新球?

lf3rwulv  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(320)

我是javafx新手,我正在创建一个简单的程序。我想实现的是每5秒创建一个从墙上弹回的球,所有的球都应该每秒移动几十次(10毫秒)。另外,请随意留下关于我的代码的其他建议。
以下是源代码:
公共类主应用程序{

@Override
public void start(Stage stage) {

    //Sets the title, adds a group, and background color
    BorderPane canvas = new BorderPane();
    Scene scene = new Scene(canvas, 640, 480, Color.WHITE);
    Circle ball = new Circle(10, Color.RED);
    ball.relocate(0, 10);

    canvas.getChildren().add(ball);

    stage.setTitle("Title");
    stage.setScene(scene);
    stage.show();

    Timeline timeline = new Timeline(new KeyFrame(Duration.millis(20), new EventHandler<ActionEvent>() {
        double dx = 5;                  //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(args);
}

}

pcrecxhr

pcrecxhr1#

以下是评论中建议的一种方法:
创建保存球及其方向信息的自定义对象。
在列表中添加新创建的对象,在画布中添加球。
在所有球之间循环,并根据它们的方向信息对它们进行定位。
当你想要的时间到了,添加一个新的球。
为了简单起见,您不需要任何并发相关的东西。也许使用它们会改进实现(但我现在不涉及这一点)
下面是一个使用我提到的要点的演示。

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

import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;

public class CanvasBallCreation_Demo extends Application {
    List<Ball> balls = new ArrayList<>();
    BorderPane canvas;
    double dx = 5;                  //Step on x or velocity
    double dy = 3;                  //Step on y
    double refresh = 20;//ms
    double addBallDuration = 5000;//ms
    double temp = 0;
    SecureRandom rnd = new SecureRandom();

    @Override
    public void start(Stage stage) {
        canvas = new BorderPane();
        Scene scene = new Scene(canvas, 640, 480, Color.WHITE);
        addBall();

        stage.setTitle("Title");
        stage.setScene(scene);
        stage.show();

        Timeline timeline = new Timeline(new KeyFrame(Duration.millis(refresh), e->moveBalls()));
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.play();
    }

    private void addBall(){
        Ball ball = new Ball();
        balls.add(ball);
        canvas.getChildren().add(ball.getBall());
    }

    private void moveBalls() {
        temp = temp + refresh;
        if(temp>addBallDuration){
            temp = 0;
            addBall();
        }
        Bounds bounds = canvas.getBoundsInLocal();
        balls.forEach(obj -> {
            Circle ball = obj.getBall();
            double tx = obj.getTx();
            double ty = obj.getTy();
            ball.setLayoutX(ball.getLayoutX() + dx*tx);
            ball.setLayoutY(ball.getLayoutY() + dy*ty);

            //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())) {
                obj.setTx(-tx);
            }

            //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()))) {
                obj.setTy(-ty);
            }
        });
    }

    class Ball {
        Circle ball = new Circle(10, Color.RED);
        double tx = 1;
        double ty = 1;
        public Ball(){
            // Placing the ball at a random location between 0,0 and 10,10 to generate random paths
            ball.relocate(rnd.nextInt(10), rnd.nextInt(10));
        }

        public Circle getBall() {
            return ball;
        }

        public double getTx() {
            return tx;
        }

        public void setTx(double tx) {
            this.tx = tx;
        }

        public double getTy() {
            return ty;
        }

        public void setTy(double ty) {
            this.ty = ty;
        }
    }
}
x6yk4ghg

x6yk4ghg2#

有几个选择, java.util.concurrent.TimeUnit 或者 Thread.sleep .
你可能想看看两者,如果你需要两个操作同时进行(创建新球,球移动),我会考虑使用一个新的线程为每个球。
通过使用这些文章,您可以阅读更多关于使用线程的内容,而您的简单程序实际上似乎是学习线程的一个很好的用例。

https://www.geeksforgeeks.org/multithreading-in-java/
https://www.tutorialspoint.com/java/java_multithreading.htm
https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html

相关问题