首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Libgdx、物理、加速和FPS

Libgdx、物理、加速和FPS
EN

Stack Overflow用户
提问于 2013-01-11 11:33:32
回答 1查看 2.9K关注 0票数 2

我正在用Libgdx框架做一个平台游戏。我想为我的角色实现跳跃的能力。我使用简单的公式:

代码语言:javascript
复制
speed += acceleration * delta_time
r += speed * delta_time

它工作得很好,但仅限于每秒恒定的帧数。FPS越低,我的角色跳跃越低。我不知道这种行为的原因是什么,跳跃的高度应该是相同的:/有我的代码片段:

代码语言:javascript
复制
delta_time=Gdx.graphics.getDeltaTime();
if(input.getUpArrow()){
     if(is_in_air==false){
        is_in_air=true;
        speed_y=speed_y_0;
     }
  }

  if(is_in_air==true){
     speed_y-=acceleration*delta_time;
  }
  else{
     speed_y=0;
  }
  
  x+=speed_x*delta_time;
  y+=speed_y*delta_time;

下面是一个插图(黑点是字符位置):http://i.imgur.com/tfSTM.jpg

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-01-11 22:03:54

对于您使用的非常简单且高度不准确的积分器,这是非常正常的行为。做数学运算并证明这一点是相当容易的。

让我们取一个1/30秒的时间跨度。当游戏以30fps的速度运行时,speed_yy只有一次更新,所以在1/30秒后,新的位置y'将是:

代码语言:javascript
复制
speed_y' = speed_y - a*dt
y' = y + speed_y'*dt = y + speed_y*dt - a*dt^2

这里dt是1/30秒的时间增量。

当游戏以60fps的速度运行时,在相同的1/30秒内会发生两次更新,时间增量是dt/2的两倍

代码语言:javascript
复制
// First update
speed_y' = speed_y - a*(dt/2)
y' = y + speed_y'*(dt/2) = y + speed_y*(dt/2) - a*(dt/2)^2
// Second update
speed_y'' = speed_y' - a*(dt/2) = speed_y - a*dt
y'' = y' + speed_y''*(dt/2) = y + speed_y*dt - 3*a*(dt/2)^2

现在比较两个更新后的y位置:

30 FPS的

  • is is: 60 FPS it is:y + speed_y*dt - a*(3/4)*dt^2

显然,在60FPS时,y的新位置将高于30FPS时的新位置,因为减去的值更低。

这只会影响垂直运动。水平速度是恒定的,如果你用两倍的短时间增量更新x一次或两次都无关紧要,因此当你的角色跳跃时,它总是以相同的水平距离到达落地的地方,无论FPS是什么。

要解决这个问题,你必须仔细研究恒定加速度下的运动方程:

代码语言:javascript
复制
y(t) = y(t=0) + v(t=0)*t - (1/2)*a*t^2

t=0的选择是任意的,因为物理定律在时移下是不变的,所以可以将t=0作为更新间隔的开始,然后t=delta_time将在当前更新之后给出位置。正确的更新算法如下:

代码语言:javascript
复制
x += speed_x*delta_time;
if (is_in_air) {
   y += (speed_y - 0.5*acceleration*delta_time)*delta_time;
   speed_y -= acceleration*delta_time;
}

请注意,根据在运动方程中找到的值,应该在垂直位置之后更新speed_y

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14271232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档