在線更新是用腳本編寫游戲邏輯的特有功能,由於腳本語言是邊解釋邊編譯的特性,使得游戲在運行的時候可以通過下載最新的腳本來執行游戲邏輯。在不修改Native接口的情況下,在線更新每次更新只需要下載一個(500k-1M)的zip腳本壓縮包即可。相比較而言,傳統的apk打包或者ios的ipa打包且不說打包花費的時間,用戶每次更新必須重新下載整個程序包(一般在30M以上,甚至到幾百M),更要命的是ios上傳發布必須通過蘋果審核,一個審核周期就是至少一周,還有幾率被蘋果打回,其實有的時候只是修改了一個比較重要的bug而已。
cocos2d-x的CCFileUtil有一個比較重要的功能,就是設定資源的搜索路徑,具體的js調用方法為:
// 設定資源搜索路徑,優先級為傳入數組的順序 cc.FileUtils.getInstance().setSearchPath([cachePath]); // 添加一個資源搜索路徑,優先級排在最后 cc.FileUtils.getInstance().addSearchPath(cachePath);
資源是指:腳本代碼,圖片紋理,聲音,plist,配置文件等。。
同時,資源又細分為打包資源和緩存資源。
打包資源:顧名思義,導入ipa或者apk中的資源,玩家下載程序包后就包含了這些資源數據。這些資源可以在游戲程序包的中找到
緩存資源:當進入游戲后,在游戲過程中聯網下載了一個資源,該資源會被存入一個緩存目錄,下次讀取相同的資源后,玩家就不用再次聯網下載了,轉而讀取緩存目錄的資源。
游戲是如何判斷緩存目錄中的資源文件呢?這里就要用到上面提到的資源搜索路徑。
正常情況下,我在游戲中創建一個sprite。
var sprite = cc.Sprite.create('res/images/test.png');
這個時候系統會去在打包資源目錄下搜索'res/images/test.png',如果沒有這個圖片的話,就會拋出異常,當使用了FileUtil的資源搜索路徑后,系統會根據配置的資源路徑來找資源
cc.FileUtils.getInstance().setSearchPath([cachePath]);
當設定了資源搜索路徑后系統先在cachePath/res/images/test.png 尋找資源,如果沒有找到,再到打包資源目錄下的res/images/test.png尋找
cc.FileUtils.getInstance().addSearchPath(cachePath);
追加資源搜索路徑后,系統也會在cache目錄下尋找資源,只是優先級比打包資源目錄要低,是先搜索打包資源目錄,如果沒有的話再搜索設定的資源路徑。
在實際的游戲中,我們一般會使用setSearchPath方法,優先尋找緩存資源目錄,再搜索打包資源目錄,這樣如果我們有新的資源改動,我們只要將新的資源下載到對應的緩存目錄,游戲就會讀到最新的資源,從而實現在線更新。
上面寫了一些更新資源的方法,下面來聊一聊如何去設計這些更新步驟。
一般我們要更新的資源為:腳本js文件,配置文件,緩存圖片等。js和配置文件大家都很清楚,為什么要更新緩存圖片呢?因為在玩家游戲的過程中會下載很多額外的圖片,這些圖片都沒有打到程序包里面,如果全部打進去,這樣整個包就會無比龐大,玩家一般能夠接受的程序包大小只有30M-100M左右,當然這個根據游戲而定。但是實際整個游戲資源是在300M以上甚至更多,所以大部分的圖片資源還是要進游戲下載的。這就出現了一個問題,某個版本升級以后我修改了某張圖片,但是這張圖片已經被玩家緩存,這個時候按照資源下載判斷的邏輯,發現有該圖片在玩家的緩存目錄就不會去下載,但這樣就會造成和最新的版本不一致,所以我們要想辦法將這張舊的緩存圖片移除,這樣的話等用到這張圖片,系統會從網絡上下載最新的圖,這個是和最新版本符合的,從而保證了版本的一致性。
為了能夠迭代更新資源,我設定了一個資源更新配置大致結構如下
version.js
game.version = '1.0.114'; game.versionInfo = { '1.0.66':{res:['res/images/ui/ui1.png']}, '1.0.86':{cfg:['cfg1.js']}, '1.0.93':{cfg:['cfg2.js']} };
game.version 是整體的游戲版本號,game.versionInfo是需要更新的配置表,前面的key表示在該版本號下面需要更新的內容。
整個更新流程如下:
1.啟動游戲下載version.js 比較當前版本號(存放在localstorge中)與game.version,如果一致,則直接進入游戲。否則下載最新的js壓縮包繼續往下執行
2.循環game.versionInfo 中的版本號與當前版本號,如果當前版本號比game.versionInfo的版本好要小,則記錄cfg和res信息。
3.根據上述循環獲得的res記錄,表示新版本更新了緩存圖片,則循環res數組刪除緩存目錄下的圖片,以便讀取該圖片時下載最新的圖片
4.根據上述循環獲得的cfg記錄,表示新版本更新了配置文件,則循環cdg數組下載指定的cdg存放在緩存目錄下,以便讀取該cfg時,獲得的是最新的配置。
小技巧:如何用js判斷某個文件是否在緩存目錄中,或者在打包目錄中
resInfo.src == fileUtils.fullPathForFilename(path)
fullPathForFilename傳入一個相對地址,如果可以在設定的緩存目錄或者打包資源中找到該文件,則會返回一個全路徑,這個路徑必然和相對路徑不相同,如果相同,則說明系統在相應的緩存路徑和打包資源中不能找到該文件。