解决物体加速向上的时间,将重力考虑在内

时间:2014-04-23 09:21:04

标签: math gravity

我在游戏中有一个可以跳跃的角色;通过长按跳跃按钮可以影响跳跃高度。角色可以在向上的方向上达到最大速度,我试图弄清楚最长的跳跃可以将重力考虑多长时间。

我很确定这与SUVAT方程式有关,因为物体正在加速,但我似乎无法将重力引入等式中。以下是我正在使用的变量......

JumpVelocity = 2.0,
JumpAccel = 0.5,
JumpMax = 7.5,
Gravity = -14.0,

一旦按下跳跃,就会设置初始速度......

yVelocity = JumpVelocity;

然后保持跳跃按钮的每一帧,速度增加,直到达到上限

if (!jumpFinished)
{
    yVelocity += JumpAccel; 
    yVelocity += Gravity * deltaTime;
    if (yVelocity >= JumpMax) 
    {
        yVelocity = JumpMax;
        jumpFinished = true;
    }
}
yVelocity *= deltaTime;

我检查跳转是否已完成:

if (yVelocity <= 0.0)

我想解决的是,如果用户最大限度地提高跳跃速度,跳跃过程的整个向上阶段需要多长时间?

3 个答案:

答案 0 :(得分:3)

你可以在按下时让初始速度增加,角色已经移动,所以你有两个不同的阶段:

第1阶段

初始正加速度,你的角色加速,火箭或喷气背包。

初始条件(该分支的t = 0):

v0   = JumpVelocity
vmax = JumpMax
a    = Gravity + jaccel 
r0   = 0 (initial height)

请注意jaccel不是JumpAccel。鉴于您的代码JumpAcceldeltaTime时间内速度的变化。因此实际突发加速度为jaccel = JumpAccel/deltaTime。 (有用:完整性 - 提供deltaTime)。

您的代码中的这一行对我没有意义:请解释。

yVelocity *= deltaTime;

现在你想知道何时 v,速度达到vmax。给出:

v = v0 + a*t

您希望t找到v=vmax的值。所以你替换并解决了t:

vmax = v0 + a*t
t = (vmax - v0)/a

或使用您的符号:

t = (JumpMax - JumpVelocity)/(Gravity + jaccel)

t,你现在可以评估你达到最大速度时所达到的高度。获取此kinematic equation

r = r0 + v0*t + 0.5*a*t*t

并将所有变量替换为r1,即thurst末尾的位置。

r1 = 0 + JumpVelocity*t + 0.5*(Gravity + jaccel)*t*t

第2阶段

角色继续减速直到达到最大高度,这就是你想知道的。

在第二个问题中,我们在这里“移动”时间原点,第一阶段刚刚完成,所以我们再次处于t = 0(这不能应用于图形 - 坐标系只有一个...因为在下面的gnuplot命令中这样做了更多的减法。忘记之前评估的t - 它现在超出了范围。我们目前的初始条件是:

v0   = JumpMax
a    = Gravity
r0   = r1, r evaluated at the previous stage

现在,您希望在t时找到v=0的值。所以,再次使用:

v = v0 + a*t

替换v = 0并解决t

0 = v0 + a*t
t = -v0/a

使用您的变量(之前没有符号替换 - 更容易理解,您可以实际评估它):

t = -JumpMax/Gravity

替换kinematic equation with constant acceleration中的t,以便找到当时的位置(最大高度的时间!):

r = r0 + v0*t + 0.5*a*t*t

使用您的变量是:

rmax = r1 + JumpMax*t + 0.5*Gravity*t*t.

就是这样:rmax是你的角色达到的最大高度。

总而言之,我很高兴使用gnuplot绘制这两个函数 - 它可以免费用于linux和windows,因此你可以使用它。

在图表中,您可以在不同的时间步长获得位置(每个点在随后的时间步长,绘制高度,r,相对于时间,t)。两个箭头指向r1rmax,使用上面获得的公式进行评估(请参阅gnuplot命令)

plotted with gnuplot

这里有gnuplot命令来生成图表 - 祝你好运!

unset key

JumpVelocity = 2.0
JumpMax = 7.5
Gravity = -14
jaccel = 30

const_acc(t,r0,v0,a) = r0 + v0*t + 0.5*a*t**2

t1 = (JumpMax - JumpVelocity)/(Gravity + jaccel)
r1 = const_acc(t1, 0, JumpVelocity,Gravity+jaccel)
t2 = -JumpMax/Gravity + t1
rmax = const_acc(t2-t1, r1, JumpMax, Gravity)

set arrow from t1,0 to t1,r1
set arrow from t2,0 to t2,rmax

set xlabel "t" 
set ylabel "r" 
set xrange [ 0 : 2 ]
set yrange [ 0 : ]

plot x <= t1 ? const_acc(x,0,JumpVelocity,Gravity + jaccel) : 1/0 w p, x >= t1 ? const_acc(x-t1, r1, JumpMax, Gravity) : 1/0 w p
pause -1

答案 1 :(得分:1)

你需要的基本方程是v = u + at,其中u是初始速度,v是时间t之后的速度,加速度。你似乎有两个加速度,即角色和重力加速度。这些组合使得一个加速度为-14 + 0.5 = -13.5

当v = 0时

t = -u / a

答案 2 :(得分:1)

我假设2D世界(3D几乎相同)

跳跃时没有向上加速(除非你有火箭......)

  • 相反,你加速了一段时间脚仍然在地上(按键时有限的时间)
  • 从地面抬起后,只有摩擦力和重力加速度
  • 跳跃高度取决于逃逸速度(当你抬离地面时)

我会这样做:

// globals
struct pnt { float x,y; };
int jump=0; // jump flag
pnt acc; // acceleration [m/s^2]
pnt vel; // velocity [m/s]
pnt pos; // position [m]
float M=75.0; // player mass [kg]
float F=1000.0; // player jump force [N]
float a;
float dt; // time of your timer interval [s]
float tjump;

// init jump on some key hit ... 
jump=1;
acc.x+= F*cos(a)/m; // F/m is the jump strength force / mass
acc.y+= F*sin(a)/m; // a is angle of the jump force
pos.y-= crouch to jump lift off offset; // bigger offset means bigger jump 0.4[m] for example
tjump=0.0;

// integration timer with dt interval
vel+=acc*dt
pos+=vel*dt
if ((jump==1)&&(pos.y>=ground(x).y)) // lift off test
 {
 acc.x= 0.00;
 acc.y=-9.81; // just gravity no movement or jump ...
 jump++;
 }
if ((jump==2)&&(pos.y<=ground(x).y)) // hit the ground test
 {
 acc.y= 0.00;
 vel.y= 0.00;
 pos.y=ground(x).y; // stop on ground
 jump=0; // end of jump
 }
// now for your question add this
if ((jump==2)&&(vel.y>=0)) tjump+=dt; // and at the end tjump will contain the time you want
  • 功能:pnt ground(float x);返回x轴
  • 的地面上的点
  • 如果你的地板多于你需要的地面(pnt p);
  • 从p
  • 向下返回最近的楼层地面点

如果你真的需要时间,那么只需在实际跳转发生之前在一些for循环而不是定时器中执行此操作