2009-04-20 24 views
0

我试图让我的游戏保持在60fps,但我从我的代码中得到奇怪的结果,如“2-8000 fps”为什么这不是在60?从帧率代码得到奇怪的结果

public static void main(String[] args) { 

     joglplat m = new joglplat(); 
     while(true){ 
      long startTime = System.nanoTime()/1000000; 
       try 
      { 
       //     123456: 6 zeros => 16ms 
       long nsToSleep = 16000000 - (System.nanoTime() - lastFrame); 
       System.out.println("ns: " + nsToSleep); 
       lastFrame = System.nanoTime(); 

       if(nsToSleep > 0) 
       { 
        System.out.println("ns2: " + (nsToSleep/1000)); 
        System.out.println("ns3: " + (nsToSleep%1000)); 
        Thread.sleep(nsToSleep/16000000, (int)(nsToSleep % 1000)); 
       } 
       else 
       { 
        Thread.yield(); // Only necessary if you want to guarantee that 
            // the thread yields the CPU between every frame 
       } 

      } 

      catch(Exception e){ 
       e.printStackTrace(); 
      } 

      m.controls(); 
      m.update(); 
      m.repaint(); 
      System.out.println("framerate: " + (System.nanoTime()/1000000 - startTime)); 
     } 
    } 

回答

1

您的输出是程序运行的秒数,不是帧率。你应该把你的帧数(你没有收集的)除以总的运行时间。

要获得帧计数,只需添加游戏循环的一个新的变量外,并通过每次加一...

public static void main(String[] args) { 
    long frames = 0; 
    joglplat m = new joglplat(); 
    while(true){ 
     frames++; 
     // other code here 
     System.out.println("framerate: " + ((System.nanoTime()/1000000 - startTime)/frames)); 
    } 
} 

但是请注意,这将在整个给你的平均帧率整个程序的执行。你有两个选项可以获得瞬时帧速率,以及过去N帧的平均帧速率。

public static void main(String[] args) { 
    long startTime = System.nanoTime(); 
    long lastFrameTime = startTime; 
    long frames = 0; 
    int framesToAverage = 10; 
    long[] frameTimes = new long[framesToAverage]; 
    joglplat m = new joglplat(); 
    while(true){ 
     // logic here 
     long currentFrameDuration = System.nanoTime() - lastFrame; 
     lastFrameTime = System.nanoTime(); 
     long instantFramerate = currentFrameDuration/1000000; 
     int currentFrameIndex = frames % frameTimes.length; 
     frameTimes[currentFrameIndex] = currentFrameDuration; 
     frames++; 
     long averageFramerate = ((lastFrameTime - startTime)/frames)/1000000; 
     long instantFramerate = currentFrameDuration/1000000; 
     if(frames > frameTimes.length) { // if it isn't, we don't have enough data yet 
      int firstFrameIndex = currentFrameIndex + 1; 
      if(firstFrameIndex > frameTimes.length) { 
       firstFrameIndex = 0; 
      } 
      long averageFrameratePerN = ((frameTimes[currentFrameIndex] - frameTimes[firstFrameindex])/frameTimes.length)/1000000; 
     } 

     // yield/sleep here 
    } 
} 
+0

从哪里收集帧计数:

在一个(未经测试/未编译的,所以可能有一些错误,但应该让你在正确的方向开始)所有样式?如何? – William 2009-04-20 19:23:07

1

我怀疑这是由Thread.sleep()方法的不准确造成的:

使当前执行的线程 休眠(暂停执行)为 指定的毫秒数加 指定的纳秒数, 受系统定时器和调度器的精度和准确度为 的限制。 线程不会丢失任何 监视器的所有权。

是否有任何理由不得不像这样持有帧率?也许你可以更全面地解释你正在努力完成什么?