JavaFX-绑定到CenterX / CenterY,基于当前对象位置进行碰撞检测

时间:2019-03-03 00:13:04

标签: java oop javafx game-physics

我们有一个问题,就是Circle位置变为负数(假设它是相对的,因此这是有道理的),但是,我假设CenterX / Y将始终基于其在场景中的当前位置(JavaFX)。但是,每当我为此添加一个侦听器时,圆圈就会被放置在无效的位置。即使有几行设置它的位置并以相同的方式更新它,我已经听了它的X和Y属性(请注意,我已经将这些内容注释掉了)

Ball.java代码:

弹跳方法:

  /**
 * To be documented
 * @param Vector 
 * @param Vector
 */
public void bounce(Vector y, Vector x)
{
    // Get vector between two points of the side
    dest = new Vector(y.getX() - x.getX(), y.getY() - x.getY());
    Vector n1 = new Vector(-dest.getY(), dest.getX());
    n1 = n1.getUnitVector();

    Vector yCopy = new Vector(y.getX(), y.getY());

    // Vector between pall and a point
    dest = new Vector(y.getX(), y.getY());
    dest.setX(dest.getX() - this.getX());
    dest.setY(dest.getY() - this.getY());

    double distanceToLine = dest.getDotProduct(n1);
    System.out.println("Distance toline: " + distanceToLine);
    if (distanceToLine > Constants.BALL_RADIUS || distanceToLine + Constants.BALL_RADIUS < Constants.BALL_RADIUS)
    {
        System.out.println("X-X: " + x.getX() + ", Y-X: " + y.getX() + " X-Y: " + x.getY() + ", Y-Y: " + y.getY());

        Vector nextLocation = new Vector(this.getCenterY(), this.getCenterY());

        Vector speed = new Vector(this.speedX, this.speedY);
        nextLocation.add(speed);
        // Distance from next location to the side
        y.subtract(nextLocation);
        dest = new Vector(y.getX(), y.getY());
        double nextDistToLine = dest.getDotProduct(n1);
        double time = (Constants.BALL_RADIUS - distanceToLine) / (nextDistToLine - distanceToLine);
        // If the ball will be next to line within update
        System.out.println("Debug time: "+ time);
        if (time > 0 && time <= 1000)
        {
            Vector moveToLine = new Vector(this.goalSpeedX, this.goalSpeedY);
            moveToLine.multiply(time);

            moveToLine.add(new Vector(this.getCenterX(), this.getCenterY()));
            System.out.println("Time passed: X-X: " + x.getX() + ", Y-X: " + yCopy.getX() + " X-Y: " + x.getY() + ", Y-Y: " + y.getY());
            if (x.getX() == yCopy.getX())
            {
                System.out.println("XX CONFIRMED: XX : " + x.getX() + " YX: " + y.getX());
                if (moveToLine.getY() >= x.getY() - Constants.BALL_RADIUS && moveToLine.getY() <= y.getY() + Constants.BALL_RADIUS || (moveToLine.getY() >= y.getY() - Constants.BALL_RADIUS && moveToLine.getY() <= x.getY() + Constants.BALL_RADIUS))
                {
                    System.out.println("Move2Line-Y: " + moveToLine.getY() + " ");
                    this.add(moveToLine.getX(), moveToLine.getY());
                    this.goalSpeedX = -this.goalSpeedX;

                    System.out.println("Bounce: moveToLine: getY() - Y");
                }
            }
            else if (x.getY() == yCopy.getY())
            {
                System.out.println("YY CONFIRMED: XX : " + x.getX() + " YX: " + yCopy.getX());
                if (moveToLine.getX() > x.getX() - Constants.BALL_RADIUS && moveToLine.getX() < y.getX() + Constants.BALL_RADIUS || (moveToLine.getX() > y.getX() - Constants.BALL_RADIUS && moveToLine.getX() < x.getX() + Constants.BALL_RADIUS))
                {
                    this.add(moveToLine.getX(), moveToLine.getY());
                    this.goalSpeedX = -this.goalSpeedX;

                    System.out.println("Bounce: moveToLine: getX() - X");
                }
            }
        }
    }
}

/ **      *继承自超类(GameObject),将在GameLoop中调用      * @param deltaTime自上次更新以来的毫秒时间      * @TODO:如果Y坐标低于0,则用户丢了一个球      * /     @Override     公共无效更新(双deltaTime)     {         如果(是秋天)             this.speedY + = Constants.BALL_GRAVITY;

    this.speedY += approach(this.goalSpeedY, this.speedY, deltaTime * 30);
    this.speedX += approach(this.goalSpeedX, this.speedX, deltaTime * 30);

    add(Math.min(Constants.MAX_BALL_SPEED, this.speedX), Math.min(Constants.MAX_BALL_SPEED, this.speedY));
    this.centerX.set(getCenterX() + Math.min(Constants.MAX_BALL_SPEED, this.speedX));
    this.centerY.set(getCenterY() + Math.min(Constants.MAX_BALL_SPEED, this.speedY));

    System.out.println(this.toString());
    if (this.getCenterX() > Constants.VECTOR_TOP_RIGHT.getX())
    {
        bounce(Constants.VECTOR_TOP_RIGHT, Constants.VECTOR_BOT_RIGHT);
        System.out.println("Over X treshold: " + this.getX());
    }
    else if (this.getCenterX() < Constants.VECTOR_TOP_LEFT.getX())
    {
        bounce(Constants.VECTOR_BOT_LEFT, Constants.VECTOR_TOP_LEFT);
        System.out.println("Under X treshold: " + this.getX());
    }
    else if (this.getCenterY() > Constants.VECTOR_TOP_RIGHT.getY())
    {
        bounce(Constants.VECTOR_TOP_LEFT, Constants.VECTOR_TOP_RIGHT);
        System.out.println("Crossed Y treshold: " + this.getY());
    }
    else if (this.getCenterY() < Constants.VECTOR_BOT_LEFT.getY())
    {
        bounce(Constants.VECTOR_BOT_RIGHT, Constants.VECTOR_BOT_LEFT);
        System.out.println("Below Y treshold: " + this.getY());
    }
}

其他类(GameHandler,但是计时器肯定在运行,我们已经调试了几个小时)

    /**
 * Called by AnimationTimer in GameLoop
 * @param time Milliseconds since last update
 */
public void update(double deltaTime) {
    if (this.state == GameState.PLAYING) {
        //System.out.println("GameLoop: Update time: " + deltaTime + " ms");
        this.ball.update(deltaTime);
        for(Wall wall : walls)
        {
            wall.update(deltaTime);
        }
    }
}

/** This breaks the Circle class for some reason?
   *balltest.centerXProperty().bind(gameHandler.getBall().getCenterXProperty());
   *balltest.centerYProperty().bind(gameHandler.getBall().getCenterYProperty());
    */

调试结果:

  

[Ball:X = 0.0,Y = -848.2400000000009; CenterX = 0.0,CenterY = -848.2400000000009; SpeedX = 0.0SpeedY:-1.8410000000000015]   线距:52.9675209999059 X-X:0.0,Y-X:19095.45300000002   X-Y:-775.0,Y-Y:17460.445000000018调试时间:0.03929486679040967   经过的时间:X-X:0.0,Y-X:19095.45300000002 X-Y:-775.0,Y-Y:   18310.52600000002 Y阈值以下:-848.2400000000009 [Ball:X = 0.0,Y = -850.0830000000009; CenterX = 0.0,CenterY = -850.0830000000009; SpeedX = 0.0SpeedY:-1.8430000000000015]   到线的距离:54.2459571676045 X-X:0.0,Y-X:19943.69300000002   X-Y:-775.0,Y-Y:18310.52600000002调试时间:0.04134649528251092   经过的时间:X-X:0.0,Y-X:19943.69300000002 X-Y:-775.0,Y-Y:   19162.45200000002 Y阈值以下:-850.0830000000009

因此,从本质上讲,我们认为我们当前的碰撞检测问题可能是由于我们基于Ball的X / Y坐标进行检测。我认为这些是相对于Circle最初创建的位置而言的,因为它的坐标会很快变为负值,这使得碰撞处理变得如此困难。

我们认为也许使用绑定到CenterX / Y而不是X / YProperty可以解决我们的问题。但是,如果执行此操作(即使在注释先前的代码设置X / Y时也是如此),则会使圆的位置位于最左上角。即使以后手动设置位置,它仍然会出错。

有人经历过相同的事情或知道可能的解决方案吗?我们知道,我们可以重组我们的班级(例如,将更多此类内容放入主班级),以轻松解决此问题。但是,我们需要一个面向对象的结构,并且没有采取捷径。作为参考,下面是我们当前软件包设置的图片:提出建议!

Current package and class structure is appreciated! Java is not the programming language we use the most, and this is for educational purposes only.

0 个答案:

没有答案