JavaFX:碰撞

时间:2017-08-30 08:11:01

标签: java javafx

我正在开发类似Pong的游戏,并实现了移动球拍(通过用户输入)和球的代码。我目前正在研究球和桨之间碰撞的代码。

除非我将球拍直接移到球上,否则一切似乎都能正常工作。这意味着球与桨的底部或顶部碰撞,而不是与桨的侧面碰撞,这导致球卡在桨内并且快速地卡住。

我知道运动是由每帧的球变速度引起的。我仍然无法弄清楚如何解决它。

我已经尝试实现一个布尔变量来确定球在帧期间是否已经与球拍相撞。但是,我在将这个逻辑实现到我的代码中时遇到了一些麻烦。在我的主类中,你会看到一些注释指出这个布尔变量以及我打算用它做什么。

以下是与我的问题有关的一些主要代码段。

MainApp:

// ...
new AnimationTimer() {

        @Override
        public void handle(long currentTime) {
            ballInfo.setText("Ball (" + ball.getX() + ", " + ball.getY() + ")");
            leftPaddleInfo.setText("Left Paddle (" + leftPaddle.getX() + ", " + leftPaddle.getY() + ")");
            rightPaddleInfo.setText("Right Paddle (" + rightPaddle.getX() + ", " + rightPaddle.getY() + ")");

            // Give point and reset ball.
            if (ball.didCollideWithLeftWall(canvas)) {
                givePoint(rightPaddle);
                rightPaddleScore = rightPaddle.getPoints();
                rightPaddleScoreLabel.setText("Player 2 Score: " + rightPaddleScore);
                reset();
            }

            if (ball.didCollideWithRightWall(canvas)) {
                givePoint(leftPaddle);
                leftPaddleScore = leftPaddle.getPoints();
                leftPaddleScoreLabel.setText("Player 1 Score: " + leftPaddleScore);
                reset();
            }

            // Handle bouncing off of top and bottom walls
            ball.didCollideWithWalls(canvas);

            // Keep paddle in screen bounds
            if (leftPaddle.getY() <= canvasBounds.getMinY() + 5)
                leftPaddle.setY(canvasBounds.getMinY() + 5);
            if (leftPaddle.getY() >= canvasBounds.getMaxY() - 105)
                leftPaddle.setY(canvasBounds.getMaxY() - 105);

            if (rightPaddle.getY() <= canvasBounds.getMinY() + 5)
                rightPaddle.setY(canvasBounds.getMinY() + 5);
            if (rightPaddle.getY() >= canvasBounds.getMaxY() - 105)
                rightPaddle.setY(canvasBounds.getMaxY() - 105);

            if (leftPaddle.didCollideWith(ball)) {
                ball.setvX(-ball.getvX());
                ball.setX(ball.getX() + ball.getvX());
            }

            if (rightPaddle.didCollideWith(ball)) {
                ball.setvX(-ball.getvX());
                ball.setX(ball.getX() + ball.getvX());
            }

            // Update and render
            ball.update(ELAPSED_TIME_SPEED);
            leftPaddle.update(ELAPSED_TIME_SPEED);
            rightPaddle.update(ELAPSED_TIME_SPEED);

            gc.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);

            gc.setFill(BALL_COLOR);
            ball.render(gc);

            gc.setFill(LEFT_PADDLE_COLOR);
            leftPaddle.render(gc);

            gc.setFill(RIGHT_PADDLE_COLOR);
            rightPaddle.render(gc);


        }

    }.start();

桨:

@Override
public boolean didCollideWith(Sprite other) {
    Ball ball = (Ball) other;
    double ballCenterX = ball.getCenterX();
    double ballRadius = ball.getRadius();
    double ballCenterY = ball.getCenterY();

    double halfWidth = this.getHalfWidth();
    double halfHeight = this.getHalfHeight();
    double centerX = this.getCenterX();
    double centerY = this.getCenterY();

    if (getName().toLowerCase().equals("left")) {
        boolean hitXBounds = ballCenterX - ballRadius <= centerX + halfWidth
                && ballCenterX - ballRadius >= centerX - halfWidth;
        boolean hitTopPartOfBall = ballCenterY - ballRadius <= centerY + halfHeight
                && ballCenterY - ballRadius >= centerY - halfHeight;
        boolean hitBotPartOfBall = ballCenterY + ballRadius <= centerY + halfHeight
                && ballCenterY + ballRadius >= centerY - halfHeight;

        return hitXBounds && (hitTopPartOfBall || hitBotPartOfBall);
    }

    if (getName().toLowerCase().equals("right")) {
        boolean hitXBounds = ballCenterX + ballRadius >= centerX - halfWidth
                && ballCenterX + ballRadius <= centerX + halfWidth;

        boolean hitTopPartOfBall = ballCenterY - ballRadius <= centerY + halfHeight
                && ballCenterY - ballRadius >= centerY - halfHeight;
        boolean hitBotPartOfBall = ballCenterY + ballRadius <= centerY + halfHeight
                && ballCenterY + ballRadius >= centerY - halfHeight;

        return hitXBounds && (hitTopPartOfBall || hitBotPartOfBall);
    }
    return false;
}

谢谢!

修改 我已经修复了Paddle类中的碰撞代码,因此现在执行上述错误要困难得多。但是,如果例如球的最左边的点与左桨的最右边的点接触,我仍然会得到口吃的错误。如果我的时间恰到好处,我仍然可以像以前一样将球卡在桨内(通过直接在它的顶部/底部移动它),但它只会产生这个错误仍然在桨的前面。 我也改变了上面的代码。

0 个答案:

没有答案