Pong Paddle碰撞速度和回弹角

时间:2013-04-02 00:03:30

标签: c# pong

我为此搜索了很多但是我能找到的就是人们说像pi *方向,方向是球在我假设的角度。但我的问题是,我不知道我是如何得到球首先进入的角度所以我不能这样做。 如果有人能够解释我将如何计算球击中桨帽的角度,那么球在反弹后应该给出的速度和它应该增加的角度那将是真棒。

谢谢您的任何回复!

我的代码如下工作(所以你可以知道我想怎么做):

/* General Paddle Properties */
double PaddleLength = 80;  //Down-wards length of the paddle
double PaddleWidth = 8;  //How thick the paddle is

/* Positioning of user control paddle */
double UserPaddleTop = 0;  //How far away from the top of the screen the paddle is
double UserPaddleLeft = 10;  //How far left from the side of the client rectangle it is

/* Positioning of ai controled paddle */
double AIPaddleTop = 0;
double AIPaddleLeft = 10;

/* Ball properties and position */
double BallSize = 5;
double BallTop = 0; 
double BallLeft = 0;
double BallSpeedY = -0.01, BallSpeedX = -0.03;

方法:

private void UpdateBall()
        {
            if (((int)(UserPaddleLeft + PaddleWidth) == (int)BallLeft) && !((int)UserPaddleTop > (int)BallTop) && !((int)(UserPaddleTop + PaddleLength) < BallTop) 
                || ((int)(AIPaddleLeft - PaddleWidth) == (int)BallLeft) && !((int)AIPaddleTop > (int)BallTop) && !((int)(AIPaddleTop + PaddleLength) < BallTop)) //Collided
            {
                BallSpeedX = -BallSpeedX; //The height is 800 the balltop is 300
                BallSpeedY = Math.Cos(BallSpeedX
            }

            if ((int)BallTop == 0 || (int)BallTop == ClientRectangle.Height) //Hit the top 
            {
                BallSpeedY = -BallSpeedY;
            }

            if ((int)BallLeft == 0)
            {
                System.Diagnostics.Debug.WriteLine("AI gets one point!");
                BallSpeedX = -0.03; //Goes towards the user AI has scored
                Scores[0]++;
                this.Title = "Pong Testing - Scores: " + Scores[0] + "|" + Scores[1];
                ResetAll();
            }
            else if ((int)BallLeft == ClientRectangle.Width)
            {
                System.Diagnostics.Debug.WriteLine("User gets one point!");
                BallSpeedX = 0.03; //Goes towards the AI user has scored
                Scores[1]++;
                this.Title = "Pong Testing - Scores: " + Scores[0] + "|" + Scores[1];
                ResetAll();
            }

            BallLeft = (BallLeft + BallSpeedX);
            BallTop = (BallTop + BallSpeedY);
        }

        private void UpdateAI()
        {
            if(!((int)(BallTop + PaddleLength) == 0) && !( (int)(BallTop + PaddleLength) >= ClientRectangle.Height ) ) //Make sure updating it pos won't make it go out of bounds
                AIPaddleTop = BallTop; //Change to real ai by using offset
        }

        protected override void OnUpdateFrame(FrameEventArgs e)
        {
            base.OnUpdateFrame(e);

            if ( (int)UserPaddleTop != 0 && Keyboard[Key.Up])
            {
                UserPaddleTop = UserPaddleTop - MoveSpeed;
            }
            else if (Keyboard[Key.Down] && (int)(UserPaddleTop + PaddleLength) != ClientRectangle.Height)
            {
                UserPaddleTop = UserPaddleTop + MoveSpeed;
            }
        }

更新1:

感谢所有人的帮助,我已经能够为它提出一些基本代码,但现在这段代码只是让球飞得太快,以至于无法获得它。有人可以帮忙吗?

代码:

        double AngleNormal = Math.Atan2(BallSpeedX,BallSpeedY);
        double AngleBallMovement = Math.Sqrt((BallSpeedX * BallSpeedX) + (BallSpeedY * BallSpeedY));
        double ReflectionAngle = AngleNormal - (AngleBallMovement - AngleNormal);
        BallSpeedY = Math.Sin(ReflectionAngle);
        BallSpeedX = Math.Cos(ReflectionAngle);

2 个答案:

答案 0 :(得分:1)

在最简单的意义上(忽略球旋转,摩擦,桨叶运动等)是计算出相对于表面法线的入射角并将其反转。在简单物理碰撞的背景下,入射角是球在碰撞点处相对于桨叶表面法线的运动角度。在任意坐标空间中,计算类似于:

angleReflect = angleNormal - (angleBallMovement - angleNormal)

对于真正矩形桨的非常简单的情况,法线将垂直于桨的运动轴。这使得你几乎无法控制球,因为反射角总是纯粹是球移动方向的函数。

您可以通过根据球撞击球拍中心的距离改变球拍表面的法线向量来模拟弯曲的桨板表面。这允许玩家通过拦截球拍中心的球来改变球的移动角度,以获得更陡峭或更浅的反射角。

真正有趣的是当你开始为混合添加摩擦,旋转和桨运动计算时。对于大多数玩家来说,获得一点点跟踪,但允许一些有趣的技巧镜头:)

-

至于 如何 来计算角度,trig函数Math.atan2(x, y)会给出一个给定[x,y]的角度(以弧度表示)速度矢量,Math.sqrt(x*x + y*y)为您提供运动矢量的长度。这为您提供了一条线,您可以将其与桨的表面相交(如果您准确的话,可以考虑球的半径)以获得冲击点。运动“线”的剩余部分使用入射角和您添加的任何其他计算反映,给出球的最终位置和新的速度矢量。

激光指示器和镜子是很好的可视化工具:)

答案 1 :(得分:1)

为了计算角度,您必须知道球的移动方向。您的BallSpeedXBallSpeedY值中包含该信息。假设你的原始位置是(0,0),BallSpeedX是2,BallSpeedY是3.所以你有一个直角三角形,一边是2,另一边是3,你可以使用简单用三角法计算出角度。

现在,桨叶可能与X轴平行,因此您必须计算相对于该轴的角度。但这不应该太难。

一旦你知道球击中球拍的角度,你只需从180度(或pi弧度)中减去该值,这就是新的角度。因此,如果球以60度撞击球拍,它将以120度反弹。这是假设没有旋转,完美的弹性,没有桨运动等。

球从桨上掉下来的速度取决于你。你可以假设没有能量损失,并且让球从球拍开始时的速度相同。或者你可以说弹跳吸收球的10%的能量,在这种情况下你想要将球的速度降低10%(但不要只从X和Y速度值减去10%,或者你' ll改变角度)。

现在清除泥土了吗?