寫在前面
又是12點半了,對于一個程序員來說,這是一個黃金時間,精力旺盛,我想,是最適合整理和分享一些思路的時候了。
自從上次寫了 基于Quick-cocos2d-x的資源更新方案
同樣可見quick-cocos2d-x官方論壇貼子:http://www.cocoachina.com/bbs/read.php?tid=209421&fpage=2
一直覺得有些什么地方不對。思考了許久之后,發現對于framework和update自身模塊的更新,是有一定的問題的。
對于update自身模塊的更新來說,檢查是否有更新,若有更新,則使用require "main"重新來過。 是非常合理。
而對于framework的更新,就不是那么容易了。 前一篇文章中,我提到若檢查到framework有更新,則提示用戶重啟客戶端,看似很不經意的操作,卻給了用戶思考要不要再次打開此游戲的機會。
對于這種思考機會,我們是不能給用戶的。 因此,無縫更新才是硬道理。
BTW:目前我使用的是 quick-cocos2d-x 2.2.3rc 版本
改進后的熱更新流程
在思索良久后,我發現對于update模塊的實現,是完全可以脫離quick框架的。update模塊所需要的scene,writablePath,md5file等功能,都不是quick提供的,僅僅是quick提供了一層封裝。因此,我們可以使用純cocos2d-lua的API來實現update模塊。這樣一來,framework.init就可以不在update模塊里調用,那當我們在update中更新了framework模塊時,我們完全不需要擔心require重入問題。 因為在真正進入游戲前,我們的framework中的任何模塊,都還沒有被require過。
由于每天晚上只有1多小時的編程時間,所以,這事兒我又花了好幾天。其間也遇上了不少問題。
我先來說說新版的更新流程
在前一文章的基礎上,我們修改前三個步驟
1、從服務器取得update模塊,與本地進行比較
2、檢查update的md5值,看是否有更新,如果有更新,則下載update.bin,重新載入,并退到main(退出之前,注意清除對某些的引用),再次重新進入
3、如果本地update的值與服務器相同,表示update模塊沒有更新,則去下載文件列表 flist
.....后面的步驟不變
這樣修改完畢后,我們就可以完全實現update模塊的自更新,以及framework的自更新了。 整個過程不需要重新啟動。
主要問題與解決辦法
下面來說說這幾天遇上的問題
1、在ANDROID上讀取APK內文件的MD5值
由于CCCrypto::md5file是用fopen讀取文件內容,再交給MD5計算器得出MD5值。 所以,在APK里是不可以的,后來,我把fopen改成了CCFileUtils::getFileData得到解決
2、flist是一個LUA文件,如果處于APK中,則無法使用dofile,如果是從網上下載,也無法使用dofile
為了保持兼容,在讀取APK和執行網上下載來的flist時,我使用了loadstring(str)() 這樣就解決了所有問題
3、遞歸創建文件和清空文件夾
一開始使用了os.execute來執行mkdir,rm等命令,但一但執行命令時控制臺有輸出,那整個LUA的LOG就亂了。 后來改為了lfs手工創建和遍歷刪除來解決。工作良好
4、compile_scripts.bat打包
我需要將update打一個包,main.lua不打包,其余的app和config.lua打一個包
由于compile_script.bat是按文件夾進行模塊剔除的,所以,我只好調整以下結構
scripts +--launcher_src +--launcher.lua app +---MyApp +---config.lua +---scenes --main.lua
可以看出,我將更新模塊單獨放入了一個文件夾,將config.lua移到了app下面。 差點忘了說,我的update模塊,也是沒有依賴config.lua的。
這樣,我就可以打出app和luancher兩個包了,陽光七月的打包后綴是*.bin,我用了png,總之,這個后綴是無關緊要的,打包我寫了兩個腳本
build_app.bat
內容:%QUICK_COCOS2DX_ROOT%/bin/compile_scripts.bat -i scripts/app_src -p app -o res/app.png
build_lchr.bat
內容:%QUICK_COCOS2DX_ROOT%/bin/compile_scripts.bat -i scripts/lchr_src -p lchr -o res/lchr.png
這樣當我們想要運行程序的時候,只需要打包一下就可以了。
F5實時刷新
考慮到很多時候,我們改了代碼就想直接按F5,不想去打包……。 這里有兩個方案。
一是處理一下PLAYER的F5事件,自動執行上面兩個腳本。
二是處理一下main.lua,使它支持打包和非打包模式,目前,我是通過修改main.lua來做的
LOAD_FROM_BIN = true APP_NAME = "dota" APP_PACKAGE_ROOT = "" if LOAD_FROM_BIN then APP_PACKAGE_ROOT = "app" CCLuaLoadChunksFromZIP("res/lchr.png") package.loaded["lchr.launcher"] = nil require("lchr.launcher") else APP_PACKAGE_ROOT = "app_src" package.loaded["lchr_src.launcher"] = nil require("lchr_src.launcher") end
讓一切消散在風里
寫到這里,已經不知道自己還要說些什么了。雖然目前功能不夠完善,但已經可以發碼了。希望能夠給大家一個參考。
文章列表