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);
}