移动圆随机消失(javafx)
uni的分配-必须制作一个用线移动的弹跳球,您可以使用向上和向下箭头键更改速度 除了球随机消失在一些看不见的方块后面之外,我所做的一切都很好。它可能与左上角的速度标签有关,因为当我移除标签时,这种情况不再发生 问题所在: 控制类:移动圆随机消失(javafx),java,javafx,Java,Javafx,uni的分配-必须制作一个用线移动的弹跳球,您可以使用向上和向下箭头键更改速度 除了球随机消失在一些看不见的方块后面之外,我所做的一切都很好。它可能与左上角的速度标签有关,因为当我移除标签时,这种情况不再发生 问题所在: 控制类: public class Task3Control extends Application { public void start(Stage stagePrimary) { //create the ball Task3
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();
}
球类:
public class Task3Ball implements Runnable {
private double radius = 20;
private double x = radius*2, y = radius*2;
private double dx = 1, dy = 1;
private double speed = 3.0;
public Circle circle = new Circle(radius,Color.GREEN);
/** Returns the current speed of the ball.
* @return (String) the speed as a string, formatted to two decimal places
*/
public String getSpeed() {
return String.format("%.2f", speed);
}
/** Increases the speed of the ball by 0.1 to a maximum of 5.
*/
public void increaseSpeed() {
speed += 0.1;
if (speed > 5)
speed = 5;
}
/** Decreases the speed of the ball by 0.1 to a minimum of 1.
*/
public void decreaseSpeed() {
speed -= 0.1;
if (speed < 1)
speed = 1;
}
/** Moves the ball based on its current speed and direction.
* Reverses the direction of the ball when it collides with the edge of the window.
* Updates the circle object to reflect its current position.
*/
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);
}
/** Uses a thread to move the ball every 20 milliseconds.
*/
public void run() {
while(true) {
try {
moveBall();
Thread.sleep(20);
}
catch(InterruptedException e) {
System.out.println("interrupt");
}
}
}
}
public类Task3Ball实现可运行{
私人双半径=20;
专用双x=半径*2,y=半径*2;
专用双dx=1,dy=1;
私人双速=3.0;
公共圆圈=新圆圈(半径、颜色、绿色);
/**返回球的当前速度。
*@return(String)将速度设置为字符串,格式设置为小数点后两位
*/
公共字符串getSpeed(){
返回字符串.format(“%.2f”,速度);
}
/**将球的速度增加0.1,最大值为5。
*/
public void increaseSpeed(){
速度+=0.1;
如果(速度>5)
速度=5;
}
/**将球的速度降低0.1,最小值为1。
*/
公共空间减少速度(){
速度-=0.1;
如果(速度<1)
速度=1;
}
/**根据球的当前速度和方向移动球。
*当球与窗口边缘碰撞时反转球的方向。
*更新圆对象以反映其当前位置。
*/
受保护的void moveBall(){
如果(x半径=400)
dx*=-1;
如果(y半径=300)
dy*=-1;
x+=dx*速度;
y+=dy*速度;
圆。设置中心x(x);
圆。设置中心(y);
}
/**使用线程每20毫秒移动一次球。
*/
公开募捐{
while(true){
试一试{
移动球();
睡眠(20);
}
捕捉(中断异常e){
系统输出打印项次(“中断”);
}
}
}
}
此问题似乎是由于圆的x
和y
属性更新不当造成的
请注意,给定您的代码,JVM不需要保证圆的位置的任何修改对渲染线程可见,并且速度
字段的任何修改对动画线程可见
顺便说一句:您没有将动画线程标记为守护进程线程,因此它将阻止JVM关闭
将线程设置为守护进程:
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);
});
}
此问题似乎是由于圆的x
和y
属性更新不当造成的
请注意,给定您的代码,JVM不需要保证圆的位置的任何修改对渲染线程可见,并且速度
字段的任何修改对动画线程可见
顺便说一句:您没有将动画线程标记为守护进程线程,因此它将阻止JVM关闭
将线程设置为守护进程:
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);
});
}
完美的非常感谢你,费边!:)完美的非常感谢你,费边!:)