一直想寫一個多人在線遊戲,也一直在研究相關的技術。從目前瞭解到的信息來看,網絡遊戲的同步方案大部分狀況下是:幀同步或狀態同步。下面就介紹一下,我對幀同步的一些瞭解。git
什麼是幀同步?簡化的流程以下圖。 github
紅色箭頭:客戶端向服務端發送玩家的操做指令。(A-A: 玩家A按下A鍵)服務器
藍色箭頭:服務器每隔一段時間T
,向全部客戶端發送當前收集到的客戶端指令。網絡
幀同步原理就是這麼簡單:同步玩家的全部操做而非狀態(HP、攻擊力、位置)。當客戶端收到服務端的消息時,進行遊戲狀態更新,即圖中藍色箭頭位置。因此理想狀態下,全部客戶端的更新都是同步的。由於繪製時間點是統一的,指令也是一致的,那麼就是完美的同步了。socket
那麼問題來了,若是出現網絡延遲怎麼辦?性能
實際渲染時,玩家A
將比玩家B
更早收到消息,意味着玩家A
的設備裏角色已經開始動了而玩家B
的設備裏遊戲角色仍是沒有反應,即不一樣步。若是不做處理,隨着網絡波動,將會致使遊戲進行到必定程度後,玩家A
和玩家B
是兩個不一樣的遊戲畫面。優化
其實,影響不一樣步的因素有不少,網絡延時多是最直觀的。下面我列舉一下,別人和我本身實踐中用到的優化方案。ui
爲了研究幀同步,寫了一個TANK.IO。項目後續會更新,如今這個實現並不完美。socket.io
主要的優化操做:spa
避免浮點數運算
對小數進行有效位數限定。
export function toFixed(i, precision=3) {
return +i.toFixed(precision)
}
複製代碼
利用msgpack
壓縮數據,socket.io
有對應插件
const
parser = require('socket.io-msgpack-parser'),
io = require('socket.io')(3000, {parser})
複製代碼
PS: 不一樣步的優化感受不是很好,就不發出來了。能夠本地運行一下代碼,在局域網下運行,遊戲總體還過得去。