4

私はこれについてたくさん検索しましたが、見つけることができるのは、 do 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);
4

2 に答える 2

2

最も単純な意味では (ボールのスピン、摩擦、パドルの動きなどを無視して)、表面法線に対する入射角を計算し、それを反転することです。単純な物理衝突のコンテキストでは、入射角は、衝突点でのパドルの表面の法線に対するボールの移動角度です。任意の座標空間では、計算は次のようになります。

angleReflect = angleNormal - (angleBallMovement - angleNormal)

真の長方形のパドルの非常に単純なケースでは、法線はパドルの運動軸に対して垂直になります。反射角は常に純粋にボールが動く方向の関数になるため、これではボールをほとんど制御できません。

ボールが衝突するパドルの中心からの距離に基づいてパドルの表面の法線ベクトルを変化させることにより、湾曲したパドルの表面をシミュレートできます。これにより、プレーヤーは、ボールをパドルの中心から外してインターセプトすることにより、ボールの移動角度を変更して、反射角度を急または浅くすることができます。

本当の楽しみは、ミックスに摩擦、スピン、パドル モーションの計算を追加し始めるときです。ほとんどのプレイヤーが追跡するのは少し大変ですが、いくつかの興味深いトリックショットを可能にします:)

--

角度の計算方法については、trig 関数Math.atan2(x, y)を使用すると、指定された [x,y] 速度ベクトルの角度 (ラジアン単位) が得られMath.sqrt(x*x + y*y)、移動ベクトルの長さが得られます。これにより、パドルの表面と交差できる線が得られます (精度を重視する場合は、ボールの半径を考慮して) インパクトのポイントを取得します。動きの「線」の残りの部分は、入射角と追加するその他の計算を使用して反映され、ボールの最終的な位置と新しい速度ベクトルが得られます。

レーザーポインターとミラーは、これを視覚化するための優れたツールです:)

于 2013-04-02T00:32:12.597 に答える