2009-04-20 60 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()方法的不準確造成的:

使當前執行的線程 休眠(暫停執行)爲 指定的毫秒數加 指定的納秒數, 受系統定時器和調度器的精度和準確度爲 的限制。 線程不會丟失任何 監視器的所有權。

是否有任何理由不得不像這樣持有幀率?也許你可以更全面地解釋你正在努力完成什麼?