让球在画布上反弹

时间:2014-08-27 01:18:57

标签: java swing collision-detection java-2d

我编写的代码应该构成一个简单的Pong游戏的基础。它有效,但我不明白为什么。它应该工作。我希望有人可以给我一些我不知道为什么它能起作用的见解。

我的画布中有以下概念(左上角有(0,0)):

球始终以0到180度之间的角度反弹。我把画布的底部作为基础。左边是0度,右边是180度。如果它在墙上反弹,则球的角度(ball_angle)会变为180 - ball_angle度。球的轨迹由另外两个变量(x_trajy_traj)定义,表示每个轴上的方向。

我没有得到的部分是ballHits()方法。如果球击中了软管,则从右侧进入,例如: 100,然后它应该在80度反弹。球从右边来,所以x_traj是负的。我们在cealing上反弹,所以球落下而不是举起,我们将y_traj从负(提升)改为正(下降)。球仍然会向右移动,所以我们将保持这个方向。

第二种情况是球击中左墙。球又来自右边,所以我们知道traj_x是负面的。我们反弹,所以球回到右边,ergo traj_x应该乘以-1以使其再次为正(向右移动)。当我们从上方或下方撞到墙壁时,我们仍然在墙壁弹跳后朝着同一方向前进。我们不会更改traj_y变量。

但是,下面是工作代码。当我击中左壁或右壁时,我不必更改任何变量。有人可以向我解释原因吗?

如果需要,可以在GitHub上找到完整的编译项目。

将球移动到新坐标的代码:

private void updateBall()
{
    // http://gamedev.stackexchange.com/questions/73593/calculating-ball-trajectory-in-pong
    // If the ball is not hitting anything, we simply move it.
    // http://en.wikipedia.org/wiki/Polar_coordinate_system
    if (ballHits())
    {
        // Bounce the ball off the wall.
        ball_angle = 180 - ball_angle;
    }
    // http://en.wikipedia.org/wiki/Polar_coordinate_system
    // Convert the angle to radians.
    double angle = (ball_angle * Math.PI) / 180;

    // Calculate the next point using polar coordinates.
    ball_x = ball_x + (int) (x_traj * BALL_STEPSIZE * Math.cos(angle));
    ball_y = ball_y + (int) (y_traj * BALL_STEPSIZE * Math.sin(angle));
    System.out.printf("Ball: (%d,%d) @ %d\n", ball_x, ball_y, ball_angle);
}

确定我们是否遇到障碍的代码:

private boolean ballHits()
{
    // If we came out of bounds just reset it.
    ball_y = Math.max(0,  ball_y);
    ball_x = Math.max(0,  ball_x);
    // Check to see if it hits any walls.
    // Top
    if(ball_y <= 0)
    {
        System.out.println("Collision on top");
        y_traj *= -1;
        x_traj *= -1;
        return true;
    }
    // Left
    if(ball_x <= 0)
    {
        System.out.println("Collision on left");
        //y_traj *= -1;
        //x_traj *= -1;
        return true;
    }
    // Right
    if(ball_x >= B_WIDTH)
    {
        System.out.println("Collision on right");
        //y_traj *= -1;
        //x_traj *= -1;
        return true;
    }
    // Bottom
    if(ball_y >= B_HEIGHT)
    {
        System.out.println("Collision on bottom");
        y_traj *= -1;
        x_traj *= -1;
        return true;
    }
    return false;
}

1 个答案:

答案 0 :(得分:2)

嗯,它的工作方式很棘手,因为当你的角度> 1时,余弦变为负值。 90°。 如果球首先击中底部或顶部,那么让他以不同的初始轨迹和角度开始应该不起作用。

编辑:我认为它可以做到这一点,但在纸上做这些证明我错了,这是一种奇怪的方式,但它按预期工作。我会调查一下它是否有一种不起作用的方式。

编辑2 :[88-92]范围内的起始角度是否有效?