2013-06-26 24 views
0

我想在我的XNA遊戲中拋出一個箭頭,但我很難嘗試實現一個良好的拋物線。創建固定角度的拋物線軌跡

我需要什麼:

  • 你越握輸入更強的箭頭去。
  • 箭頭角度將始終相同,45度

這是我已經有:

private float velocityHeld = 1f; 
protected override void Update(GameTime gameTime) 
{ 

    if (Keyboard.GetState().IsKeyDown(Keys.Enter) && !released) 
    { 
     timeHeld += velocityHeld; 
     holding = true; 
    } 
    else 
    { 
     if (holding) 
     { 
      released = true; 
      holding = false; 
      lastTimeHeld = timeHeld; 
     } 
    } 


    if (released && timeHeld > 0) 
    { 
     float alpha = MathHelper.ToRadians(45f); 
     double vy = timeHeld * Math.Sin(alpha); 
     double vx = timeHeld * Math.Cos(alpha); 

     ShadowPosition.Y -= (int)vy; 
     ShadowPosition.X += (int)vx; 
     timeHeld -= velocityHeld; 
    } 
    else 
    { 
     released = false; 
    } 
} 

我的問題是,我需要什麼做的,使箭頭走底,因爲它失去了速度(timeHeld),以一個完美的拋物線?

+0

提示:在地球上,拋出的物體傾向於拋出拋物線,因爲由於重力引起的加速度不斷地改變物體的速度。 – Kevin

+0

我明白了,所以你告訴我我需要實施重力法嗎? – Moondustt

+0

當試圖創建逼真的運動時,通常有一個好主意。 – mcmonkey4eva

回答

0

注意:我從來沒有聽說過XNA,但我確實使用C#。讓我知道這完全不是那麼回事,但是它的精神應該在那裏。

在最後一個if語句中,釋放Enter鍵後,每次調用Update時我都希望將向下速度增加一定的(小常量)量(我假設增加y座標使事物向下移動「 在屏幕上)。爲此,只要Enter被釋放,而不是每次調用double vy = timeHeld * Math.Sin(alpha),將結果保存到稍後可以引用的變量中,然後使用布爾值來跟蹤何時計算該值,這僅在Enter之後發行了。

換句話說,它是這樣的:

// extra variables 
bool justReleased = false; 
double vy, vx; 
... 
protected override void Update(GameTime gameTime) 
{ 
    // ... 
     if (holding) 
     { 
      released = true; 
      holding = false; 
      lastTimeHeld = timeHeld; 
      justReleased = true; // add this here 
     } 
    // ... 

    if (released && timeHeld > 0) 
    { 
     float alpha = MathHelper.ToRadians(45f); 

     // not local variables anymore. Also I flipped the sign - my intention is that initial vertical velocity is "upwards" 
     if(justReleased) 
     { 
      vy = -1 * timeHeld * Math.Sin(alpha); 
      vx = timeHeld * Math.Cos(alpha); 
      justReleased = false; 
     } 

     ShadowPosition.Y += (int)vy; // Note: I flipped this operator 
     ShadowPosition.X += (int)vx; 
     timeHeld -= velocityHeld; 

     // increase the downward velocity 
     vy += 2; // or some constant. I can't test this. :\ 
    } 
    else 
    { 
     released = false; 
    } 
} 

希望這個作品,雖然有可能是更有效的方法來做到這一點。雖然這不是一個物理場所,請參閱this以供參考;-)

0

上面討論的解決方案依賴於您計算每次迭代的新速度,然後計算前一個位置的增量(變化)以確定當前位置。

這符合遊戲循環的正常邏輯。然而,這是計算複雜得多,它需要的,並且可能是不穩定的,由於舍入誤差。

更簡單和更穩定的解決方案是確定拋物線的方程,並使用它在發射後直接計算出時間t的位置。

讓箭頭從x = 0開始,y = 0。設發射速度爲v。在發射後的時間t,箭頭的座標爲x = kt,其中k = v * cos(45)= v/sqrt(2)。

y位置是一個二次方程y = at^2 + bt + c,我們不知道a,b,c。

但是,當T = 0,Y = 0,因此C = 0

當t = 0時,初始向下的速度爲v * SIN(45)= V/SQRT(2)

使用演算點點(微分位置以獲得速度),在t = 0

v/SQRT(2)= 2原子+ b =

鑑別速度獲得加速度,我們得到在t初始加速= 0是2a。但唯一的加速度是由重力引起的,所以2a = -g其中g是你的引力常數。

把這兩個方程一起,在時間t

X(t)= V/SQRT(2);你知道v和t,你定義g,所以你可以計算出x和y座標在時間上直接從這個方程。

這是一個更直接的方法,更強大(舍入誤差不會累積)。這是我親自做的。我的手榴彈總是遵循完美的拋物線弧線,並以計算有效的方式進行。