[英]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.