我在游戏中有一个可以跳跃的角色;通过长按跳跃按钮可以影响跳跃高度。角色可以在向上的方向上达到最大速度,我试图弄清楚最长的跳跃可以将重力考虑多长时间。
我很确定这与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)
我想解决的是,如果用户最大限度地提高跳跃速度,跳跃过程的整个向上阶段需要多长时间?
答案 0 :(得分:3)
你可以在按下时让初始速度增加,角色已经移动,所以你有两个不同的阶段:
第1阶段
初始正加速度,你的角色加速,火箭或喷气背包。
初始条件(该分支的t = 0):
v0 = JumpVelocity
vmax = JumpMax
a = Gravity + jaccel
r0 = 0 (initial height)
请注意jaccel
不是JumpAccel
。鉴于您的代码JumpAccel
是deltaTime
时间内速度的变化。因此实际突发加速度为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)。两个箭头指向r1
和rmax
,使用上面获得的公式进行评估(请参阅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
如果你真的需要时间,那么只需在实际跳转发生之前在一些for循环而不是定时器中执行此操作