2016-09-28 16 views
0

我們應該如何在Java中設置固定時間步?我認爲有2種方法:如何在Java中設置固定時間步

  1. 同步遊戲循環使用while
  2. 使用Thread的異步遊戲循環。

最重要的事情是性能準確性。那麼最好的方法是什麼?

這是同步的遊戲循環:

double timeStep = world.getSettings().getStepFrequency(); 
    long lastTime = System.nanoTime(); 

    while (true) { 
     long currentTime = System.nanoTime(); 
     double elapsedTime = (currentTime - lastTime)/1000000000.0; 

     if (elapsedTime >= timeStep) { 
      lastTime = currentTime; 
      world.update(elapsedTime); 
     } 
    } 

這asynchronised遊戲循環:

double timeStep = world.getSettings().getStepFrequency(); 
    long lastTime = System.nanoTime(); 

    Thread loop = new Thread() { 
     public void run() { 
      while (true) { 
       long currentTime = System.nanoTime(); 
       double elapsedTime = (currentTime - lastTime)/1000000000.0; 
       lastTime = currentTime; 

       world.update(elapsedTime); 

       try { 
        Thread.sleep((long) Math.floor(timeStep * 1000)); 
       } catch (InterruptedException e) {} 
      } 
     } 
    }; 
    loop.start(); 

同步的遊戲循環使用大量CPU的(我認爲1個核心那〜我25%? )。

異步遊戲循環的CPU使用率幾乎爲0%。

注:我想要做的遊戲是基於WebSocket的遊戲。服務器用於物理,HTML5的畫布用於渲染。

你喜歡什麼方式?爲什麼?有沒有更好的方法?

+0

如果你想精確,你需要這兩者之間的前一種選擇。如果沒有異常,Thread.sleep會在線程未運行時設置一個*最小值*。調度可能仍會延遲一段任意時間。 –

+0

@DiegoMartinoia是的,但畫布呈現在60FPS,我可以設置線程以120Hz完成其工作。 –

+1

計時器似乎最好。如果updateWorld花費太長時間,它應該能夠「丟幀」。 –

回答

4

Java API中有類可以定期執行任務。最好不要嘗試重新發明輪子並使用Java API。 A ScheduledExecutorService似乎是你需要的。

這個例子執行Runnable週期性:

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); 
executor.scheduleAtFixedRate(myRunnable, initialDelay, period, TimeUnit.MILLISECONDS); 

在你的第一個例子,你的線程在檢查巨大的倍量,如果elapsedTime >= timeStep是真實的。它會一直執行檢查,直到它是真實的,而不是一次又一次地檢查這個檢查,直到它終於成真,線程可能正在等待,處理器可能被用於其他事情。

第二個選項比第一個選項更好,因爲線程等待下一次執行的時間。

相關問題