2017-11-11 186 views
1

我正在使用HTML5 websockets和Java作爲後端的網頁遊戲。目前,爲每個玩家創建一個遊戲類的新實例,同時創建一個帶有計時器任務的計時器,以運行遊戲循環並以60fps的速度向前端發送更新。由於這些計時器在很多玩家玩的服務器資源上會非常繁重,所以我想在遊戲類中應用Singleton模式並保留一組匹配。我沒有爲每個玩家創建一個計時器,而是創建1個單獨的計時器,用數組中的每個匹配的for循環更新遊戲循環。對遊戲類使用單例模式

我不知道是否有更好的方法,因爲我聽說有很多缺點與單體模式,特別是單元測試。

回答

1

假設我明白你的問題吧,你想用1個定時器所有的比賽,併爲每場比賽使用for-loop來更新比賽。

這是一個可怕的想法。任何沿着那條線的任何形式的渲染都會影響整個服務器。如果第一場比賽的人向服務器發送大量數據,則會阻止該線程並減慢每場比賽的的FPS。

是的,定時器在服務器上很重。但是,如果一次有太多的活動匹配,則對所有匹配使用一個計時器會導致線程阻塞,因爲單線程無法處理該高負載並以60 FPS運行。

設計任何給定遊戲服務器的最佳方法是使用線程。

您可以使用Thread.sleep創建延遲並維護給定的FPS,並使用線程而不是定時器來減輕負載。 IT仍然很重,但使用線程比定時器要輕。

至於實際的線,這是它的一部分:

public void run(){ 


long lastLoopTime = System.nanoTime(); 
    final int TARGET_FPS = 60;//The FPS. Can be reduced or increased. 
    final long OPTIMAL_TIME = 1000000000/TARGET_FPS;//1 second = 10^9 nanoseconds 
    long lastFpsTime = 0;//Used to calculate delta 
    while(running){ 
     long now = System.nanoTime();//Get the current time 
     long updateLength = now - lastLoopTime;//get the time it took to update 
     lastLoopTime = now;//set the last time the loop started to the current time 
     double delta = updateLength/((double)OPTIMAL_TIME);//Calculate delta 

     lastFpsTime += updateLength; 
     if(lastFpsTime >= 1000000000){ 
      lastFpsTime = 0; 
     } 

     //Right here you place your code. Update the servers, push and read data, whatever you need 

     try{ 
      long gt = (lastLoopTime - System.nanoTime() + OPTIMAL_TIME)/1000000;//calculate the time to sleep, and convert to milliseconds 
      Thread.sleep(gt);//And finally, sleep to maintain FPS 
     }catch(InterruptedException e){ 
     } 
    } 
} 

類擴展條條都有一個名爲running布爾值。布爾值允許線程停止而不必拋出異常。

您爲每個比賽創建一個線程(這是一個重要的點,對每個玩家都這樣做,並且你會殺死資源,爲所有比賽做一個,除非你有一臺超級計算機,否則你不可能維持60個FPS在匹配的數量上)),並且具有用於管理連接和匹配線程的主線程

0

爲singelton設計模式最簡單的規則是 -

  1. 創建一個私有構造
  2. 這個地方里面創建靜態嵌段 - >要在整個項目僅實例化一個時刻的代碼
  3. 創建一個靜態方法,然後返回該對象
  4. 要完成步驟3,請聲明一個私有靜態實例變量。

考慮例如休眠的配置和buildSessionFactory方法,使本作singelton我的建議是

public class Singelton { 

    private static SessionFactory sessionFactory=null; 
    static { 
     Configuration configuration = new Configuration(); 
     configuration.configure(); 
     sessionFactory = configuration.buildSessionFactory(); 
    } 

    public static SessionFactory getSessionFactory() { 
     return sessionFactory; 
     } 

    private Singelton() { 
    } 
}