1. 程式人生 > >H5遊戲開發的架構總結(一) 客戶端

H5遊戲開發的架構總結(一) 客戶端

【客戶端】
1.關於遊戲引擎
在15年3月開始準備做h5遊戲的時候,首先遇到的問題就是引擎選型的問題。
當時市面上的2d引擎主要有3個:白鷺egret,layabox和cocos2d-js。
一方面,是因為我以前用cocos2d-x(c++)做了一年多的手遊客戶端,所以,很自然就選擇了cocos2d-js。另一方面,是因為當時市面上其他兩個引擎的成功專案還不多。
cocos引擎的每一次版本更新,我們都會第一時間在我們的遊戲裡面進行測試。
如果發現遊戲在android手機上的效能有明顯提升,我們就會跟著引擎版本一起升級。站在巨人的肩膀上,我們可以事半功倍。
從15年3月的v3.5,到15年9月的v3.8,到15年11月的v3.9,直到最近16年7月的v3.12。我們一共更新了3次遊戲引擎!
PS:js-tests裡面的OpenGl Test直到v3.12才在android真機上能看到執行效果,淚流滿面!


2.關於資料加密和通訊協議
因為是強聯網遊戲,所以只能是websocket。因為我們原來的手遊客戶端和伺服器之前是tcpsocket,傳輸的內容是sha1加密過的自定義格式的二進位制資料。
所以專案的第一個難點就是怎麼用js實現json字串的二進位制編碼和解碼,以及sha1加密和解密。
TODO:其實沒有必要每一條上下行都加密和編碼解碼,這會造成客戶端和伺服器端cpu壓力過大。只需要保護一些重要的事件(如登入、充值、扣金幣等)即可!


遊戲的第一個demo做好了,上線一測試,問題來了:有些android手機的預設瀏覽器根本不支援websocket!
最開始我的解決辦法比較簡單粗暴,不支援就彈提示:"你的手機瀏覽器不支援websocket,請換chrome瀏覽器!"
市場表示接受不了:真實玩家都跑了!除了公司的測試人員,誰都不會為了玩一個h5遊戲還去專門下載一個瀏覽器!更何況除了瀏覽器,還有微信和qq,怎麼破?
最終的解決辦法,就是通訊層從websocket改成websocket+http雙協議,對外封裝成Net。業務層對websocket的呼叫都改成對Net的呼叫。
Net預設連websocket,如果不支援,就自動切換到http長輪詢。不管是websocket還是http,傳輸的內容還是之前加密過的二進位制資料。
雖然http的長輪詢在實時戰鬥的時候,會有卡頓,但是聊勝於無,至少這部分玩家能進到遊戲裡面,可以玩單機副本,和其他系統。不會因為不支援websocket而進不來!
根據我們的資料分析統計,這部分玩家居然有10%。可能不同渠道匯入的使用者,這個值會有不同!而且隨著時間的推移,這個比例應該越來越少!
PS:不支援websocket的android手機,跟IE6一樣令人討厭,都是阻礙生產力發展的,必將被歷史淘汰!

3.關於android和微信
中國的市場現狀就是,H5遊戲必須考慮android手機,必須考慮微信和qq這兩個傳播渠道。只關注用pc瀏覽器開發和蘋果手機測試沒問題,是不明智的,也是對公司的不負責任。
開發的時候可以用pc瀏覽器除錯,但是釋出之前必須在android手機的微信裡面,開啟遊戲看是否有相容性問題,同時確認流暢度。
如果pc和蘋果手機都能跑到50~60幀,但是android的微信就只有10多幀,那就必須在圖片尺寸和動畫效果等方面做取捨。
我們的標準是保證遊戲在android中端機的微信裡面開啟,最低25幀。
今年4月份微信的瀏覽器核心自動從webkit升級成Blink,這是對H5整個行業的重大利好!
竊以為,白鷺、layabox和cocos2d,包括unity,虛幻,這幾個遊戲引擎之爭,現在來看,都是在爭VR和3D,但是最終是看誰對奇葩輩出的android的全覆蓋支援最好,誰就能最終佔領中國乃至全球市場!


4.關於音樂和音效播放
cocos2d-js引擎自帶的CocosDension有bug,不能同時播放一個以上的音樂。而且在中低端的android的微信裡面,聲音品質會變差(像破鑼一樣發呲)
我們的解決方案就是引入第三方的howler.js


5.關於資源分場景載入
cocos2d-js預設的resource.js裡面,所有資源都是在一個數組裡面,所以預載入的時候必須全部都載入完了才能進遊戲!剛開始開發的時候,這樣沒有問題。
但是到了後期,隨著系統的增加,資原始檔也越來越多,對第一次玩遊戲的玩家來說,因為瀏覽器沒有緩衝,需要全部載入,在wifi環境都需要等待1分鐘以上,這會導致大量的新玩家流失!
我們的解決辦法是,分場景載入資源。在resource.js裡面,將資源按場景分成N個數組,每次載入某個場景的時候,只預載入對應數組裡面的資源。


6.關於json檔案壓縮
隨著遊戲開發的進行,場景越來越多,ccs生成的json檔案也越來越多,同時各種地圖、商品、道具、獎勵等資料的完善,對應的json檔案內容越來越多,檔案大小越來越大!
最後遊戲釋出的時候,發現居然有70個場景json檔案,合計1.3M。有27個配置json檔案,合計755K。等待這幾十個檔案載入的時間可不短!
解決辦法,引入第三方的jszip,可以將多個json檔案合併成一個zip,檔案大小隻有原來的8%。

寫了個python指令碼,把ccs和configs兩個目錄下的json檔案先轉成一個一行,再用jszip打包成2個zip檔案,遊戲一開始先用jszip載入這兩個zip,解壓的json放到全域性數組裡面。

注意這裡面有個坑,策劃的excel裡面不能出現半形逗號,否則jszip打包會報錯。強制策劃不輸入半形逗號不太合理,解決辦法是go生成json的時候替換半形逗號為全形逗號。

然後複寫了引擎的cc.loader.loadJson這個函式,對打包的json檔案特殊處理(不用額外發起http請求,直接從全域性數組裡面拿)
有了5、6這兩步的優化,現在新手在第一次Loading頁只需要等待4秒就能進入遊戲。




7.關於混淆
cocos封裝了google的混淆編譯指令碼,但是這裡面有個坑:就是加了--advance引數之後,所有變數名都會被混淆,包括object的內部函式名稱和變數。

解決辦法就是在你不想混淆的函式或者變數(object{}對外暴露的public函式和變數 以及 引用的第三方庫的函式 )前面加上一行:

/** @expose */

注意:千萬不要xxx.yyy 和 xxx['yyy'] 混著用!否則加/** @expose */也沒用,必須全部統一成其中一種寫法!


8.關於上線釋出流程和cdn快取
1)本地執行publish.sh:本地混淆編譯,本地測試publish/html5/index.html是否正常
2)本地執行oline_t1.sh:根據當前時間生成版本號,publish/html5目錄下的res和game.min.js和index.html裡面的相對路徑都改成http://cdn域名/版本號的檔案地址,
  將res和game.min.js加上版本號之後,上傳cdn伺服器。更新測試服t1的index.html,通知測試!
3)本地執行online_s1.sh:更新正式服s1上的index.html。釋出完畢。


說明:
1)客戶端和伺服器端程式設計師都是mac開發環境,每人的機子上都有一套完整的前後端遊戲環境。本地開發,本地除錯,沒有問題之後通過git提交程式碼到公司內網git伺服器。這樣可以最大限度保證多人協作的同時,互不影響開發進度!
2)因為cdn加了時間版本號,所以每一次的釋出都是馬上生效,不需要等快取過期。也不擔心多人各自發布覆蓋對方的程式碼。發步完馬上可以檢視效果,大大提高生產效率。以cdn的空間換效率,非常划算!

3)python的fab包是個好東西,可以遠端登入伺服器執行shell命令,實現本地一鍵釋出。不需要在伺服器上通過git的鉤子來實現自動釋出!

9.關於斷線重連(websocket)
1)客戶端每隔58秒有一個心跳上行,保持與伺服器的連結
2)多標籤的瀏覽器在切換tab或者瀏覽器進入後臺的時候或者斷網,都會導致心跳失效
3)每次客戶端傳送上行的時候,先判斷Net.isConnect()是否為true。如果false就先儲存上行事件和資料,然後重連,然後重新登入,然後傳送儲存的上行事件和資料。這些都是在後臺進行,如果重連失敗則彈出提示,點選確認之後重新整理頁面。

10.關於運營商的域名劫持和移動端js加彈出廣告
運營商耍流氓,中國又是一個"法制"國家,除了上https,沒有別的辦法!
我們選擇的是沃通的超安SSL,單域一年4888元 http://www.wosign.com/price.htm


11.關於客戶端AI

碰碰車只實現了簡單AI,就是在單機比賽場裡:
1)NPC碰到障礙物之後會固定角度轉向,避免卡死在角落。其他時間會隨機轉向。
2) 自動新增NPC,保證房間內NPC的最低數量
3)同一時刻只有一個NPC處於追蹤玩家狀態,有定時器觸發追蹤者的選角切換