Java FX弹跳球开箱即弹

时间:2018-12-04 04:31:02

标签: javafx border bounce

我是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()似乎是我的问题所在。 任何帮助,不胜感激,谢谢! 很抱歉,如果这是已经回答的问题的转贴,我似乎找不到在我的特定情况下对我有帮助的任何内容。如果需要,我还可以提供该程序实际外观以及球旋转方向的屏幕截图。谢谢!

1 个答案:

答案 0 :(得分:2)

如果尝试在moveBall()方法中打印radius的值,您会注意到它的值始终为0。因为在窗格中将其宽度显示在场景图形中之前,您需要先确定其宽度。要解决此问题,可以将radius更改为DoubleProperty并将其值绑定到窗格的width属性。

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