[英]Create a parabolic trajectory with fixed angle
我正在嘗試在XNA游戲中投箭,但是我很難嘗試實現一個好的拋物線。
我需要的:
這是我已經擁有的:
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
)以制作出完美的拋物線時,我該怎么做才能使其箭頭走到底?
注意:到目前為止,我從未聽說過XNA,但我確實使用C#。 讓我知道這是否行得通,盡管它的要旨應該在那里。
在您的最后一個if語句中,松開Enter鍵后,您希望每次調用Update時都將向下速度增加一定的(小常數)(我假設增加y坐標會使事物在屏幕上“向下”移動) 。 為此,請在釋放Enter后立即進行操作,而不是每次都調用double vy = timeHeld * Math.Sin(alpha)
,將結果保存到以后可以引用的變量中,然后使用bool值來跟蹤何時計算該值,只有在釋放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;
}
}
希望這可以奏效,盡管可能會有更有效的方法來做到這一點。 雖然這不是一個物理站點,請參見本參考;-)
上面討論的解決方案依賴於您在每次迭代中計算新的速度,然后計算前一位置的增量(變化)以確定當前位置。
這符合游戲循環的正常邏輯。 但是,它在計算上比需要的更為復雜,並且可能由於舍入誤差而變得不穩定。
更簡單,更穩定的解決方案是確定拋物線方程,並用其直接計算發射后時刻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)= 2at + b = b
通過微分速度獲得加速度,我們得到t = 0時的初始加速度為2a。 但是唯一的加速度是由於重力引起的,所以2a = -g,其中g是您的重力常數。
在時間t將這兩個方程放在一起
x(t)= v / sqrt(2); y(t)=-(g / 2)t ^ 2 + vt / sqrt(2)
您知道v和t,定義了g,因此可以直接從該方程式計算出在時間t處的x和y坐標。
這是一種更直接,更可靠的方法(舍入誤差不會累積)。 這就是我個人的方式。 我的手榴彈始終遵循完美的拋物線弧,並且以計算有效的方式進行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.