歡迎你們前往雲+社區,獲取更多騰訊海量技術實踐乾貨哦~javascript
做者:木桶java
《歡樂坦克大戰》是一款支持3V3實時對戰並首批參與上線的微信小遊戲中的做品。由於該遊戲爲微信小遊戲中的重度之做,項目開發週期很是短,因此遊戲複雜度、開發難度、性能挑戰也是挺大的;項目組在一個月內就完成了單機、網絡對戰玩法的開發。node
同時,由於客戶端開發團隊的核心成員有多年的cocos2dx引擎開發經驗,因此項目組決定使用CocosCreator V1.6.1版本的引擎進行開發。而對於微信小遊戲平臺採用的javascript語言,開發團隊基本上是從0開始作,邊學邊作,對自身挑戰很大。android
網絡通訊方面項目採用了WebSocket協議進行通訊,而通訊格式是json。爲了迎合tdr的xml協議,項目組本身開發了tdr->json的轉換工具。算法
爲了方便策劃同窗使用excel表格進行數據配置,項目組又開發了將excel轉換成json文件的工具,以便供客戶端讀取配置文件。chrome
地圖方面咱們沒有使用cocos引擎自帶的TileMap,而是本身實現了一個類TileMap機制。策劃同窗能夠在excel中配置地圖信息,使用工具將excil轉換成json格式的地圖文件供客戶端加載。json
因爲開發進度緊張,須要同時開發單機和PVP玩法。因此咱們封裝了一個命令層(CMD層)來進行戰鬥邏輯驅動。好比使用搖桿控制坦克運動,是由表現層發送CMD命令給邏輯層進行處理,在單機模式下CMD會存儲於客戶端本地列表,而後由命令管理器CMDMgr在Update時讀取本地命令列表驅動邏輯層進行處理。而在對戰模式中,CMD命令會被髮往服務器,由服務器廣播給全部玩家,玩家客戶端的命令管理器CMDMgr在Update時驅動邏輯層進行處理。引入命令層(CMD層)以後,戰鬥邏輯層是抽象獨立的,開發不須要關心當前的玩法模式,能夠方便的複用,減小了開發成本。小程序
咱們PVP實時對戰採用的是c/s模式的同步架構,客戶端作碰撞檢測,將碰撞檢測結果通知服務器,服務器進行校驗並作傷害計算,而後廣播給其餘玩家。遊戲支持斷線重連、客戶端crash重連機制,服務器擁有戰鬥中的全部狀態數據,重連時將全部數據發送給客戶端,客戶端進行戰鬥場景還原。微信小程序
玩家位置同步採用了基於時間戳的位置點同步算法。這個算法原先應用於《全民飛機大戰》的雙打模式、對抗模式中。《全民飛機大戰》中實時對戰採用的是UDP通訊。而在《歡樂坦克大戰的》WebSocketTCP環境下也取得了不錯的效果。算法原理以下:瀏覽器
在開發過程當中,咱們也遇到了很多挑戰,可是咱們都一一解決了,具體遇到的問題以下:
微信小遊戲平臺增長了動態執行代碼的限制,好比:eval('console.log(1)')、new Function(‘console.log(1)')、setTimeout('console.log(1)’) 等調用方式沒法調用。而在CocosCreatorV1.6.1源碼中大量使用了Function,爲了解決這個問題,咱們和cocos引擎開發商的溝通了下,又參考cocos在1.7版本(當時還沒有發佈)中的修改,修改了一些源碼,解決了此問題。
正如標題所示,微信小程序嚴格要求了大小,爲了解決這個問題,咱們又想了很多辦法。
使用png圖片壓縮工具pngquant,能夠有效的減少png圖片的文件大小(一般能壓縮60%-70%)左右。
經過以上2個措施,資源仍然會超標,只能採用資源動態下載的方案了。
咱們在遊戲中增長了一個資源更新場景。遊戲啓動時,場景進行資源更新時遊戲業務模塊都沒有建立,等到遊戲場景中再進行業務模塊的建立和初始化工做,而後再進行場景切換。具體方案以下:
1.先下載一個資源更新配置文件,此文件中有待資源下載列表、資源校驗MD5信息。
2.根據資源下載列表,將校驗MD5和本地文件進行對比,若是相同則不下載,若是不一樣則下載。
3.下載完畢後,進行MD5校驗,若是校驗不經過則刪除本地文件,從新走下載流程。這裏的MD5校驗,不只能夠校驗資源下載是否正確;對於防止資源被惡意修改,資源反做弊也有必定做用。
4.修改cocos引擎源碼, 在load-pipeline中,將資源讀取替換成讀取本地的下載文件。
因爲遊戲運營中可能會有Bug發生,須要下發客戶端補丁。資源更新配置文件可能會被屢次修改,而CDN更新會有延遲問題,致使部分玩家下載的配置文件多是較舊的版本。並且有部分中小運營商,爲了成本考慮,會緩存舊的文件。以往的項目在發生這種狀況時,通常是聯繫玩家進行定位,發現是運營商問題再反饋給運維同窗,由網絡部門的同事推進運營商進行修改,效率不高。爲了減小這種狀況發生的可能性,咱們使用了雙CDN策略。
具體的作法是,對於同名文件增長版本號機制,更新文件時將文件內部存儲版本號+1,並在2個不一樣的CDN進行更新。客戶端下載時,下載2份文件,取版本號大的爲準。這樣當更新配置文件時,2個不一樣CDN只要有一個同步到便可,既能減小了CDN更新延遲,又下降了運營商緩存問題出現的機率。
和通常的遊戲不一樣的是,微信小遊戲平臺自己的js腳本執行效率較弱,iOS環境小遊戲javascript引擎目前使用的是JavaScriptCore,默認沒開jit優化,js執行速度會比手機safari慢,從簡單測試結果來看,速度會慢兩倍左右。從Profiler來看,js腳本執行時間會佔到80%左右。所以減小腳本的計算量也是性能優化一個重要的方面。
小米6 |
android小遊戲 |
android 微信瀏覽器 |
android chrome |
---|---|---|---|
57.55 |
53 |
58 |
|
iphone6 |
IOS小遊戲 |
IOS 微信瀏覽器 |
IOS safari |
20 |
48 |
50 |
幀率測試對比
DrawCall
渲染批次合併和大多遊戲項目相似,須要合理的規劃圖集的使用,將同一個層次的GameObj使用的圖片資源進行拼圖。
能夠分爲地圖背景層、地表、地圖物件、坦克、子彈、特效、UI等拼圖,儘可能確保同一個層次的遊戲對象使用相同的圖集,相鄰的精靈使用的材質相同。
mask
遊戲中會顯示玩家的圓形頭像,而微信平臺下載的頭像是矩形。原先頭像顯示使用的是cocos的mask組件進行渲染,效率較低。咱們本身實現了一個基於mesh的控件,將一個圓等分爲n個三角形,給這些三角形頂點賦予相應的UV,從而畫出一個圓形頭像。減小了頭像渲染時的批次開銷。
碰撞檢測
cocos creator自帶的碰撞系統效率不高,沒有作空間劃分,不適合大量單位的碰撞檢測。而且每幀都須要更新碰撞體的碰撞盒。咱們遊戲地圖中存在大量的靜態物件(如地圖中的磚塊、主基地、鋼板等),而玩家在場景中移動時,是經過移動攝像機達到地圖視野的變化,因此大量的地圖靜態物件的世界座標是不變的,他們的碰撞盒只須要計算一次便可。
爲了解決這個問題,咱們給cocos的node增長了一個屬性static,static節點的計算結果能夠緩存起來,避免重複計算。
對象池
遊戲中的坦克、子彈、磚塊等採用對象池,進入戰鬥場景時有足夠數量的預加載,戰鬥過程當中進行復用,避免實時的對象建立與銷燬。
避免場景、節點更新
分析cocoscreator的源碼發現,當有節點發生active,會觸發遞歸遍歷場景,開銷較大。
爲了不這類開銷,遊戲中的物體死亡時,不會將其從場景中移除或禁用,而是設置死亡狀態,經過移動座標到很遠的地方,代碼中不執行相應的邏輯處理。儘可能保持幀率平穩,避免性能曲線的毛刺
裁剪
當物體不在主角視野範圍內而且不是持久播放的特效和聲音能夠進行裁剪不播放。
機型適配
對於美術資源進行了高、中、低3檔分級,由策劃在資源表格中配置不一樣分級下的資源名稱。遊戲過程當中,根據機型和實際性能表現,選擇一種檔次進行表現。
圖中橫座標是時間(單位秒),縱座標是FPS,能夠看出FPS有了明顯提高。經過一系列的優化措施,最終保證了低端機iphone5S基本能知足遊戲須要。
以上就是《歡樂坦克大戰》微信小遊戲開發總結,有興趣的小夥伴能夠一塊兒來交流哦~