在我們的游戲開發中,在線升級是必須要解決的需求,你不可能每出一個版本,就讓用戶去官網下載吧。 特別是資源的更新。
假設我們的游戲由兩個東西組成 game.exe res.zip
見名知意,game.exe是游戲主程序,res.zip是資源包
那,我們如何面對更新呢。
首先想到的就是,當我們的game.exe啟動后,我們會去下載PATCH服務器取得更新列表,比如game.exe是否有更新,res_patch.zip包大小等信息。
拿到后,我們就進行下載,下載后的文件可以保存到 patches/目錄下 (名字自己定) 比如
patches/game_v001.exe
patches/res_v001.zip
有了這個以后,首先,我們要解決的是game.exe自更新問題。由于game.exe在運行過程中,是不能進行自修改的。所以,當我們發現有game_xxx.exe等字樣的時候,我們需要喚起另一個進程,這個進程可以是SHELL,也可以是寫的一個 _patch.exe什么的東西。 它的作用,就是將game_v001.exe覆蓋原來的game.exe,并啟動game.exe
大概過程如下
game.exe檢查更新
game.exe下載文件
game.exe發現自己有新版本,啟動_patch.exe進程,并結束自己
_patch.exe使用game_v001.exe覆蓋game.exe,并刪掉game_v001.exe
_patch.exe啟動game.exe,并結束自己
這樣game.exe就完成了。
由于整個過程比較繞,許多游戲都是做了一個launcher.exe來專門負責這個事情。
下面來說說資源的更新
資源的更新也較為簡單
直接根據新版本,強制修改res.zip內容就可以了,這個過程由launcher來負責。
上面是一個端游粗略的更新過程……。
同樣的方案,我們用到手游上如何呢? 這就要求我們對手游的局限要了解
手機中,安裝目錄是沒有寫權限的,不管是IOS還是ANDROID。 其它系統不知道
因此,我們無法做到應用程序代碼的自更新,也無法直接修改安裝包中的資源
動態庫的方案也無法做到代碼自更新,因為IOS審核不過。 我們就沒有必要為一個游戲搞兩套方案了。
因此,如果代碼出現了更新,就只能讓用戶去APPSTORE上重新下載了。
但是,我們依然要面臨資源的更新,邏輯的更新問題。 如果小改一個BUG,或者小修一個圖片,都要讓用戶重新下載。 這流失率估計就能上100%了。
面對邏輯更新問題,大部分團隊選擇了腳本作為純邏輯開發,普通的C++,JAVA,OC代碼,僅是做一些層底支持。這樣一來,所有的問題,都折射到了資源更新上。
剛剛說了,我們無法修改安裝包中的數據。 那,我們自己新開一個擁有可寫權限的目錄不就可以了么。
在IOS和ANDROID下面,都可以取得writablePath,或者cachePath來使用。
隨之而來的問題,就是資源加載。比如,在安裝包中,有一個 res/logo.jpg 現在,我在更新目錄下也有res/logo.jpg文件。
如何加載呢。最直接的方法,就是記錄一下,哪個資源,在哪個路徑下。但這個功能,如果做在上層的話,那每一次取資源,都要用 getRealPath等字樣來包裝。 如果做到底層去的話,又覺得這個功能確實不太適合放到底層。
像cocos2dx這個引擎,你就得手工修改資源加載處的代碼了。
對于這樣的方案,我們可以使用引擎中較為常見的一個功能,就是引擎的路徑系統。
路徑系統允許用戶設置多個路徑,當加載一個資源時,它會按對應路徑逐個匹配,直到找到它為止。 因此,如果你加載 一個圖片 1.jpg 如果多個目錄下有,且這些目錄都被添加到路徑系統中了的話,那處于最前面的路徑會優先匹配,后面的文件夾永遠沒有機會被訪問到。除非之前的路徑被刪除……
基于這一特性,我們可以制定出手游上的資源更新方案
在引擎中,我們可以規劃兩個路徑,一個是UPDATE的存放路徑,一個是安裝目錄的路徑
每次加載資源,優先搜索UPDATE
像cocos2dx,irrlicht等引擎,都有這樣的路徑搜索機制,只需添加好就可以了。
至于具體的資源更新,就是下載一個列表,然后根據列表進行文件下載和替換就可以了。
對于手機游戲的資源要不要ZIP,這個根據個人需求。
值得一說的是,目前手機存儲卡均采用閃存或者SSD,讀寫速度比PC硬盤快多了。文件分離,做累加更新,是非常方便的。 當然,如果你堅持使用端游的逐版本更新機制,也是沒有任何問題的。
文章列表