游戏循环半固定时间步骤理解

时间:2018-04-03 16:41:31

标签: java

我有一个游戏循环,除了分析更新和渲染帧所花费的时间之外什么都不做。这是主要的课程

public static void main(String args[])throws Exception
{
  Clock clock=new Clock(Math.pow(10,9),80);

  double delta=0;
  int updates=0;
  long timer1=System.currentTimeMillis();

  while(true)
  {
   long frameTime=clock.getDelta(); 

   delta+=clock.getDeltaUpdate(frameTime);
   while(delta>=1)
   {   
    updates++;  
    delta--;   
   }

   if(System.currentTimeMillis()-timer1>=1000)
   {   
    updates=0;
    timer1+=1000;
   }        
  }
 }

这是类Clock.java

public class Clock
{
  private long
  previous=0,
  current=0;

  private final double updateCount;

  Clock(double timing,double updates)
  {
   current=System.nanoTime();
   previous=current;

   updateCount=timing/updates;
  }

  long getDelta()
  {
   current=System.nanoTime();
   long delta=current-previous;
   previous=current;

   return delta;
  }

  double getDeltaUpdate(long delta){return delta/updateCount;}
}

以下是我使用简单线性代数

的理解方法

让我们说

In  1000000000ns(1 second)   ->    60 Frames to be rendered(This is our target)

 Therefore  In (X)ns          ->    1 Frame to be rendered

通过简单的交叉乘法

        60X=1000000000ns

        X=1000000000/60

这意味着我们希望主循环采用1000000000/60(ns)来渲染帧 这是我们的目标

但是我们的系统需要花费自己的时间来渲染帧。让我们说一个特定的 帧渲染帧需要135ns。因此通过使用线性代数

设y =(1000000000/60)是我们希望系统渲染1帧的时间。因此

Our Goal     In   y(ns)      ->  1 Frame Should be rendered



But System   In   135(ns)    ->  k(No of subframes to be rendered to make same 

                                   amount of progress as in y(ns) of time) 

因此通过交叉乘法

k*y=135ns      ->       k=135ns/y  ->   i.e  ->  135ns/(1000000000)/60

or k  =   (135ns*60)/1000000000

所以k告诉我们没有更新/步骤采取单帧,以便在1000毫秒内模拟大约60个物理步骤,即使系统需要不同的时间来渲染帧

因此在主类中我们有代码行

delta+=clock.getDeltaUpdate(frameTime);

其中clock.getDeltaUpdate(long)返回'k' 和变量“frametime”是时间 系统需要渲染一帧(在我们的例子中为135ns)

我不明白的一个概念是我们为什么要做

delta+= 

而不仅仅是

delta=

我认为是未经模仿的(k的小数值)来自我们之前帧的更新会被添加到我们的下一帧中,这会导致对于连续帧的更新错误,但事实并非如此并且它不起作用

任何人都可以解释为什么delta + = work's和delta = dosen't?

很抱歉浪费任何人在这里的时间,但在数学方面,我真的很喜欢

同样在LWJGL 2.9.3中,我们有一个名为Display.sync(int)的函数,它封装了我们的

帧。

是否可以在此游戏循环中实现该功能?

感谢你。

1 个答案:

答案 0 :(得分:0)

我意识到我误解了delta的概念。它没有给出每帧需要执行的子更新的数量,而是给出已经完成的帧的百分比系统产生时间[以纳秒为单位]并且我的游戏循环消耗它[以毫秒为单位]。

在我的Clock.getDeltaUpdate()方法中,delta给出了渲染帧所花费的时间,而updateCount是一个误导性的名称,而是包含我们的系统渲染帧所需的时间。 所以,如果我们划分

Time Taken By system per frame(delta)/Time we want per frame(update count)

我们得到一个百分比值,包含系统渲染的帧数。之后我们只需迭代那么多帧并继续我们的动画。

增量+需要向前推进时间(通过delta纳秒),这样我们的累加器可以完成一帧时间,否则delta =会分配一个绝对时间(以纳秒计),因此我们的游戏时钟永远不会到达一个帧除非我们的系统很慢