2013-04-02 68 views
3

嗯,我已經爲此找了很多東西,但我能找到的所有人都是這麼說的,就像做pi *方向一樣,方向就是我假設球進入的角度。但是我的問題是,我不知道如何獲得球首先進入的角度,所以我不能做到這一點。 如果任何人都可以解釋我將如何計算球擊中球拍帽的角度,反彈後球的速度大小以及應該增加的角度,那樣會很棒。Pong Paddle碰撞速度和反彈角度

謝謝任何​​和所有的答覆!

我的代碼工作如下(這樣你就可以得到我想要做的是怎麼一個想法):

/* 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); 
+1

這是一個數學問題,與編程無關。 –

+2

我會說,因爲我正在編程計算價值,但我不是在這裏爭論。對不起,如果它實際上只是數學。 – user1763295

+0

難道你不知道球被釋放的第一個角度嗎?從那裏你可以計算出球將撞擊槳葉的角度和之後的角度。儘管我同意米奇的觀點,但這比編程更重要。不錯的拼圖雖然 –

回答

0

在最簡單的意義上(忽略球旋轉,摩擦,槳移動等)是相對於入射角制定出對於表面法線和倒轉。在簡單物理碰撞的情況下,入射角是球在碰撞點處相對於槳表面法線的移動角度。在任意座標空間中的計算是這樣的:

angleReflect = angleNormal - (angleBallMovement - angleNormal) 

對於真正矩形的槳正常的一個非常簡單的情況下將是垂直於運動的槳的軸。這讓你很少控制球,因爲反射角總是純粹是球移動方向的函數。

您可以通過根據球撞擊槳葉中心的距離改變槳葉表面的法向矢量來模擬彎曲的槳葉表面。這允許玩家通過在球拍中心上截斷球來改變球的移動角度,以獲得更陡峭或更淺的反射角。

真正的樂趣是當你開始向混合中添加摩擦,旋轉和槳運動計算。獲取一個有點吃不消對於大多數玩家跟蹤,但允許一些有趣的把戲射擊:)

-

至於如何計算的角度,三角函數Math.atan2(x, y)會給你給定[x,y]速度矢量的角度(以弧度表示),並給出運動矢量的長度。這給了你一條線,你可以與槳的表面相交(考慮到球的半徑,如果你的準確性),以獲得影響的點。運動「線」的其餘部分通過入射角以及您添加的任何其他計算來反映,從而給出球的最終位置和新的速度向量。

激光筆和鏡子是很好的可視化工具,這個:)

+0

你能否看看我的代碼的工作方式,雖然你的建議很好,但我不確定它是否符合我ballY運動的方式。它基本上是通過增量完成的,每次渲染幀時,ballY被設置爲ballY +增量。那麼,角度反射會實際應用於什麼呢?還是有一種不同的方式可以做到這一點? – user1763295

+0

@ user1763295您的代碼使用直角座標('BallSpeedX'和'BallSpeedY')來描述速度矢量。將其轉換爲極座標('angle'和'magnitude')爲您提供了一種計算反射的簡單方法。然後你可以轉換回直角座標進行更新。它們是可以互換的,只是表示相同信息的兩種方式,所以請使用適用於特定問題的方法。 – Corey

+0

對不起,但你,但我已經完成了你所說的話,然後將這個角度的數學與我在其他文章中發現的想法結合起來,現在當一個槳擊中球時它就會飛走,而那個沒有擊中的人球得分很高,因爲它速度很快,剛剛超出界限。我已更新原始帖子以顯示我現在擁有的代碼。 – user1763295

1

爲了計算的角度,你必須知道什麼方向,球在移動,你必須在你BallSpeedXBallSpeedY信息值。假設你的原始位置是(0,0),BallSpeedX是2,而BallSpeedY是3.所以你有一個直角三角形,一邊是2,另一邊是3,你可以使用簡單的三角來計算出角度。

現在,槳可能與X軸平行,因此您必須計算相對於該軸的角度。但這不應該太難。一旦你知道了球撞擊槳的角度,你只需從180度(或pi弧度)減去該值,那就是新的角度。所以如果球在60度時碰到槳,它會在120度反彈。這是假設沒有旋轉,完美的彈性,沒有槳運動等。

當球離開槳時球的速度取決於你。你可以假設沒有能量損失,並且使得球從槳上離開的速度相同。或者你可以說彈跳吸收了球的10%的能量,在這種情況下,你想把球的速度降低10%(但是不要僅僅從X和Y速度值中減去10%,或者你「會改變角度)。

現在清如泥濘?