Java FX 弹跳球弹出盒子
Java FX bounce ball bounces out of box
我是 JavaFX 的新手,我(希望)有一个简单的问题,也许有人可以帮助我解决。我试过在网上寻找答案,但似乎没有什么适合我的。
所以基本上我想要做的是让一个球(在我的例子中是一张脸)在玻璃周围弹跳,只要它撞到墙上就改变方向 - 很简单。我似乎无法弄清楚为什么墙壁只触发脸部的左侧和顶部。 (换句话说,左墙和顶墙正确触发反弹,但底墙和右墙允许窗格穿过它们,使对象在以下情况下反弹:1. 脸的左侧接触右墙或 2. 顶侧脸接触底壁。脸本身在 BorderPane 中弹跳,如果这对这一切有影响的话。这可能是我所拥有的代码背后的逻辑,我实际上是从教科书中得到的。
这里是这件事的相关代码:
public class BoxPane extends Pane {
private double radius;
private double x, y;
private double dx = 1;
private double dy = 1;
private Pane thisPane;
private Timeline animation;
public BoxPane(Pane pane)
{
getChildren().add(pane);
thisPane = pane;
radius = thisPane.getWidth()/2;
x = radius;
y = radius;
animation = new Timeline(new KeyFrame(Duration.millis(50), e -> moveBall()));
animation.setCycleCount(Timeline.INDEFINITE);
animation.play();
}
public void increaseSpeed()
{
animation.setRate(animation.getRate() + 0.1);
}
public void decreaseSpeed()
{
animation.setRate(animation.getRate()>0?animation.getRate() - 0.1 : 0);
}
protected void moveBall()
{
if((x < radius || x > getWidth() - radius))
{
dx *= -1;
}
if(y < radius || y > getHeight() - radius) {
dy *= -1;
}
x += dx;
y += dy;
thisPane.setTranslateX(x);
thisPane.setTranslateY(y);
}
}
如果我的代码中有不清楚的地方,我可以尝试解释。但基本上,我采用了我传入的对象的半径,并以此创建了一个动画。当按下一个键时,我有一些方法可以提高和降低速度(函数调用来自不同的 java 文件),而 moveBall() 似乎是我的问题所在。
非常感谢任何帮助,谢谢!
很抱歉,如果这是对已经回答过的内容的重新发布,我似乎找不到任何对我的具体情况有帮助的内容。如果需要,我还可以提供程序的实际外观以及球在何处转动的屏幕截图。谢谢!
如果您尝试在 moveBall() 方法中打印 radius 的值,您会注意到它的值始终为 0。因为您在场景图形中渲染窗格之前获取窗格的宽度。要解决此问题,您可以将 radius 更改为 DoubleProperty 并将其值绑定到窗格宽度 属性.
您的 moveBall() 逻辑也需要进行小的修正。请检查以下更正。
private DoubleProperty radius = new SimpleDoubleProperty();
public BoxPane(Pane pane) {
getChildren().add(pane);
thisPane = pane;
radius.bind(thisPane.widthProperty().divide(2));
x = radius.get();
y = radius.get();
animation = new Timeline(new KeyFrame(Duration.millis(5), e -> moveBall()));
animation.setCycleCount(Timeline.INDEFINITE);
animation.play();
}
protected void moveBall() {
double faceWidth = radius.get() * 2;
if ((x < 0 || x > getWidth() - faceWidth)) {
dx *= -1;
if (x < 0) {
x = 0;
} else if (x > getWidth() - faceWidth) {
x = getWidth() - faceWidth;
}
}
if (y < 0 || y > getHeight() - faceWidth) {
dy *= -1;
if (y < 0) {
y = 0;
} else if (y > getHeight() - faceWidth) {
y = getHeight() - faceWidth;
}
}
x += dx;
y += dy;
thisPane.setTranslateX(x);
thisPane.setTranslateY(y);
}
我是 JavaFX 的新手,我(希望)有一个简单的问题,也许有人可以帮助我解决。我试过在网上寻找答案,但似乎没有什么适合我的。
所以基本上我想要做的是让一个球(在我的例子中是一张脸)在玻璃周围弹跳,只要它撞到墙上就改变方向 - 很简单。我似乎无法弄清楚为什么墙壁只触发脸部的左侧和顶部。 (换句话说,左墙和顶墙正确触发反弹,但底墙和右墙允许窗格穿过它们,使对象在以下情况下反弹:1. 脸的左侧接触右墙或 2. 顶侧脸接触底壁。脸本身在 BorderPane 中弹跳,如果这对这一切有影响的话。这可能是我所拥有的代码背后的逻辑,我实际上是从教科书中得到的。
这里是这件事的相关代码:
public class BoxPane extends Pane {
private double radius;
private double x, y;
private double dx = 1;
private double dy = 1;
private Pane thisPane;
private Timeline animation;
public BoxPane(Pane pane)
{
getChildren().add(pane);
thisPane = pane;
radius = thisPane.getWidth()/2;
x = radius;
y = radius;
animation = new Timeline(new KeyFrame(Duration.millis(50), e -> moveBall()));
animation.setCycleCount(Timeline.INDEFINITE);
animation.play();
}
public void increaseSpeed()
{
animation.setRate(animation.getRate() + 0.1);
}
public void decreaseSpeed()
{
animation.setRate(animation.getRate()>0?animation.getRate() - 0.1 : 0);
}
protected void moveBall()
{
if((x < radius || x > getWidth() - radius))
{
dx *= -1;
}
if(y < radius || y > getHeight() - radius) {
dy *= -1;
}
x += dx;
y += dy;
thisPane.setTranslateX(x);
thisPane.setTranslateY(y);
}
}
如果我的代码中有不清楚的地方,我可以尝试解释。但基本上,我采用了我传入的对象的半径,并以此创建了一个动画。当按下一个键时,我有一些方法可以提高和降低速度(函数调用来自不同的 java 文件),而 moveBall() 似乎是我的问题所在。 非常感谢任何帮助,谢谢! 很抱歉,如果这是对已经回答过的内容的重新发布,我似乎找不到任何对我的具体情况有帮助的内容。如果需要,我还可以提供程序的实际外观以及球在何处转动的屏幕截图。谢谢!
如果您尝试在 moveBall() 方法中打印 radius 的值,您会注意到它的值始终为 0。因为您在场景图形中渲染窗格之前获取窗格的宽度。要解决此问题,您可以将 radius 更改为 DoubleProperty 并将其值绑定到窗格宽度 属性.
您的 moveBall() 逻辑也需要进行小的修正。请检查以下更正。
private DoubleProperty radius = new SimpleDoubleProperty();
public BoxPane(Pane pane) {
getChildren().add(pane);
thisPane = pane;
radius.bind(thisPane.widthProperty().divide(2));
x = radius.get();
y = radius.get();
animation = new Timeline(new KeyFrame(Duration.millis(5), e -> moveBall()));
animation.setCycleCount(Timeline.INDEFINITE);
animation.play();
}
protected void moveBall() {
double faceWidth = radius.get() * 2;
if ((x < 0 || x > getWidth() - faceWidth)) {
dx *= -1;
if (x < 0) {
x = 0;
} else if (x > getWidth() - faceWidth) {
x = getWidth() - faceWidth;
}
}
if (y < 0 || y > getHeight() - faceWidth) {
dy *= -1;
if (y < 0) {
y = 0;
} else if (y > getHeight() - faceWidth) {
y = getHeight() - faceWidth;
}
}
x += dx;
y += dy;
thisPane.setTranslateX(x);
thisPane.setTranslateY(y);
}