Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使球在画布上反弹_Java_Swing_Collision Detection_Java 2d - Fatal编程技术网

Java 使球在画布上反弹

Java 使球在画布上反弹,java,swing,collision-detection,java-2d,Java,Swing,Collision Detection,Java 2d,我已经写了一些代码,这些代码应该是一个简单的乒乓球游戏的基础。这很有效,但我不明白为什么。它不应该起作用。我希望有人能给我一些我所缺少的关于它为什么起作用的见解 我的画布中有以下概念(左上角有(0,0)): 球总是以0到180度的角度反弹。我以画布的底部为基础。左边是0度,右边是180度。如果球在墙上反弹,球的角度(ball\u angle)将变为180-ball\u angle度。球的轨迹由另外两个变量(x_-traj和y_-traj)定义,指示每个轴上的方向 我没有得到的部分是ballHit

我已经写了一些代码,这些代码应该是一个简单的乒乓球游戏的基础。这很有效,但我不明白为什么。它不应该起作用。我希望有人能给我一些我所缺少的关于它为什么起作用的见解

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

球总是以0到180度的角度反弹。我以画布的底部为基础。左边是0度,右边是180度。如果球在墙上反弹,球的角度(
ball\u angle
)将变为
180-ball\u angle
度。球的轨迹由另外两个变量(
x_-traj
y_-traj
)定义,指示每个轴上的方向

我没有得到的部分是
ballHits()
方法。如果球从右侧以度数(例如100度)撞击赛琳,则应以度数80反弹。球是从右边来的,所以x轨迹是负数。我们在球拍上弹跳,因此球会下降而不是上升,因此我们将
y_traj
从负(上升)改为正(下降)。球仍然会向右移动,所以我们要巧妙地保持这个方向

第二种情况是当球击中左墙时。球又从右边来了,所以我们知道
traj_x
是负数。我们弹起使球回到右边,因此
traj_x
应乘以
-1
,使其再次为正(向右移动)。无论我们是从上面还是从下面撞到墙,在墙反弹后,我们仍然沿着同一方向前进。我们不更改
traj_y
变量

但是,下面是工作代码。当我碰到左边或右边的墙时,我不需要改变任何变量。谁能给我解释一下原因吗

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

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

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;
}
private boolean ballHits()
{
//如果我们出界,就重新设置它。
ball_y=Math.max(0,ball_y);
ball_x=Math.max(0,ball_x);
//检查它是否碰到任何墙壁。
//顶
如果(球y=B高度)
{
System.out.println(“底部碰撞”);
y_traj*=-1;
x_traj*=-1;
返回true;
}
返回false;
}

它的工作方式很复杂,因为当角度>90°时,余弦为负。 如果球先击中底部或顶部,那么让他从不同的初始轨迹和角度出发是行不通的

编辑:我原以为这样做可以,但在纸上做证明我错了,这是一种奇怪的方式,但它按预期工作。我会调查一下,看看有没有办法


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

若要更快获得更好的帮助,请发布一个(最小的、完整的、可验证的示例)。另请参见。嗯,我已尝试使其在角度>内反弹,并在顶部和底部分别反弹<90°,但似乎效果不错。但我知道它来自余弦。不过,我会在纸上复制一些场景。我编辑了我的答案,你能告诉我这是否有效吗?是的,这非常有效。有点奇怪。但是,我想知道,那么惯用的方法是什么呢?你可以只使用角度,然后用它们的符号得到轨迹的变化,但这意味着你必须重新考虑你的角度范围[0-180]是不够的,你需要[0-360]的范围,你也可以保持你的轨迹,在余弦上加一个abs()。对于你必须放置一个由球刚刚击中的一侧确定的偏移角度,它可能是,右侧90°,顶部180°,左侧270°,底部0,你不必再为x_traj和y_traj费心了。