简体   繁体   English

使球在画布上弹跳

[英]Make ball bounce in canvas

I have written code that should form the basis for a simple Pong game. 我编写的代码应构成简单的Pong游戏的基础。 It works, but I don't understand why. 它有效,但是我不明白为什么。 It should not work. 应该工作。 I'm hoping somebody can give me the insight I'm missing as to why it does work. 我希望有人能给我关于它为什么起作用的缺失见解。

I have the following concept in my canvas (which has (0,0) on the top left): 我的画布上有以下概念(该画布的左上角为(0,0)):

A ball always bounces in an angle between 0 and 180 degrees. 球总是以0到180度之间的角度弹跳。 I have taken the bottom of my canvas as the basis. 我以画布的底部为基础。 Left is 0 degrees, right is 180 degrees. 左为0度,右为180度。 If it bounces on a wall the ball's angle ( ball_angle ) changes to 180 - ball_angle degrees. 如果它在墙上弹跳,则球的角度( ball_angle )更改为180 - ball_angle度。 A ball's trajectory is defined by 2 more variables ( x_traj and y_traj ) indicating the direction on each axis. 球的轨迹由另外两个变量( x_trajy_traj )定义,这些变量指示每个轴上的方向。

The part I don't get is the ballHits() method. 我没有得到的部分是ballHits()方法。 If the ball is hitting the cealing, coming from the right with a degree of eg 100, then it should bounce off at a degree of 80. The ball is coming from the right so the x_traj is negative. 如果球从右侧以例如100的高度击中遮挡,那么它应该以80度弹起。球从右侧进入,因此x_traj为负。 We are bouncing on the cealing so the ball drops instead of lifts, ergo we change the y_traj from negative (lifting) to positive (dropping). 我们在遮挡中弹跳,因此球掉落而不是举起,因此,我们将y_traj从负(举起)更改为正(掉落)。 The ball will still be going to the right, so we leave that direction in tact. 球仍将向右移动,因此我们将方向保持不变。

Second scenario is when the ball hits the left wall. 第二种情况是球击中左墙。 The ball is coming from the right again, so we know that traj_x is negative. 球再次从右边traj_x ,因此我们知道traj_x为负。 We bounce off so the ball goes back to the right, ergo traj_x should be multiplied by -1 to make it positive again (move to the right). 我们弹起球,使球回到右方,因此ergo traj_x应乘以-1 ,使其再次变为正(向右移动)。 Wether we hit the wall coming from above or below, we are still going that same direction after bouncing of the wall. 如果我们从上方或下方撞击墙,则墙反弹后仍沿相同的方向前进。 We don't change the traj_y variable. 我们不更改traj_y变量。

However, below is the working code. 但是,下面是工作代码。 I do not have to change any variable when I hit the left or right wall. 当我打左或右墙时,我不必更改任何变量。 Could somebody explain to me why? 有人可以向我解释为什么吗?

If needed, the full compiling project can be found on GitHub . 如果需要,可以在GitHub上找到完整的编译项目。

Code to move the ball to new coordinates: 将球移动到新坐标的代码:

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);
}

Code that determines if we have hit a wall: 确定我们是否碰壁的代码:

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;
}

Well it's working in a tricky way because cosine goes negative when your angle is > 90°. 好吧,它以一种棘手的方式工作,因为当您的角度> 90°时,余弦会变为负值。 Making him start with a different initial trajectory and angle should not work if the ball hits the bottom or top first. 如果球先击中底部或顶部,则使他从不同的初始轨迹和角度开始应该不起作用。

Edit : I thought it would do that but doing it on paper proves me wrong, well it's a weird way to do it but it's working as intended. 编辑 :我认为可以这样做,但是在纸上进行证明了我错了,嗯,这是一种奇怪的方法,但是它可以按预期工作。 I'll investigate to find if there's a way it doesn't work. 我将调查是否有某种方法不起作用。

Edit 2 : Does a start angle in range of [88-92] work ? 编辑2 :起始角度在[88-92]范围内有效吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM