首页 > 解决方案 > Java FX 弹跳球开箱即用

问题描述

我是 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() 似乎是我的问题所在。非常感谢任何帮助,谢谢!很抱歉,如果这是对已经回答的内容的重新发布,我似乎找不到任何对我的具体情况有帮助的东西。如果需要,我还可以提供程序实际外观和球在哪里转的屏幕截图。谢谢!

标签: javafxborderbounce

解决方案


如果您尝试在 moveBall() 方法中打印半径的值,您会注意到它的值始终为 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);
}

推荐阅读