【问题标题】:Make ball bounce in canvas让球在画布上弹跳
【发布时间】:2014-08-27 01:18:56
【问题描述】:

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

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

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

我没有得到的部分是ballHits() 方法。如果球击中球门,则从右侧以例如100,然后它应该以 80 度反弹。球来自右侧,所以x_traj 是负数。我们在天花板上弹跳,所以球会掉落而不是升降,因此我们将y_traj 从负(升降)更改为正(掉落)。球仍然会向右移动,所以我们保持这个方向不变。

第二种情况是当球击中左墙时。球又从右边来了,所以我们知道traj_x 是负数。我们反弹,所以球回到右边,所以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;
}

【问题讨论】:

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


【解决方案1】:

它的工作方式很棘手,因为当您的角度 > 90° 时余弦变为负数。 如果球首先击中底部或顶部,则让他以不同的初始轨迹和角度开始是行不通的。

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

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

【讨论】:

  • 嗯,我试图让它在角度 > 和
  • 我编辑了我的答案,你能告诉我这是否有效吗?
  • 是的,效果很好。有点奇怪。但是,我想知道,那么惯用的方法是什么?
  • 好吧,你可以只使用角度,并根据它们的符号来改变轨迹,但这意味着你必须重新考虑你的角度范围 [0-180] 是不够的,你需要一个范围[0-360],您还可以保留您的轨迹并将 abs() 放在余弦上。对于角度,您必须设置由球刚刚击中的一侧确定的偏移量,它可能是 90° 用于 RIGHT,180° 用于 TOP,270° 用于 LEFT,0 用于 BOTTOM,您不必费心不再使用 x_traj 和 y_traj。
猜你喜欢
  • 2020-02-22
  • 1970-01-01
  • 2013-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多