cocos2dx-lua中有assetmanagerex的c++实现类,也有绑定到lua。不过在3.10之前有缺陷,问题是当有文件下载失败时会陷入死循环,导致业务链断裂。不过网上有解决办法,可简单修改源码解决。不过个人还是建议可以把高于3.10版本以后的assetmanagerex代码移植到旧的3.x版本,也可以选择新项目使用3.10以后版本。
以下是lua版本使用热更新的方法
local AutoUpdateScene = class("AutoUpdateScene", cc.load("mvc").ViewBase)
local manifestPath = "project.manifest"
local storagePath = "update"
function AutoUpdateScene:onCreate()
self._update_failed_count = 0
local layer = cc.Layer:create()
local am = nil
local function onEnter()
local ttfConfig = {}
ttfConfig.fontFilePath = "fonts/arial.ttf"
ttfConfig.fontSize = 80
local progress = cc.Label:createWithTTF(ttfConfig, "0%", cc.VERTICAL_TEXT_ALIGNMENT_CENTER)
progress:setPosition(cc.p(display.center.x, display.center.y + 50))
layer:addChild(progress)
am = cc.AssetsManagerEx:create(manifestPath, cc.FileUtils:getInstance():getWritablePath() .. storagePath)
am:retain()
if not am:getLocalManifest():isLoaded() then
print("Fail to update assets, step skipped.")
self:onFail("本地资源错误,请重新下载游戏。")
else
local function onUpdateEvent(event)
local eventCode = event:getEventCode()
print("====== assetsmanagerex error code:", eventCode)
--[[ cc.EventAssetsManagerEx.EventCode = {
ERROR_NO_LOCAL_MANIFEST = 0,
ERROR_DOWNLOAD_MANIFEST = 1,
ERROR_PARSE_MANIFEST = 2,
NEW_VERSION_FOUND = 3,
ALREADY_UP_TO_DATE = 4,
UPDATE_PROGRESSION = 5,
ASSET_UPDATED = 6,
ERROR_UPDATING = 7,
UPDATE_FINISHED = 8,
UPDATE_FAILED = 9,
ERROR_DECOMPRESS = 10
} ]]
if eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_NO_LOCAL_MANIFEST then
print("No local manifest file found, skip assets update.")
self:onFail(string.format("本地资源错误,请重新下载游戏。(错误码:%d)", eventCode))
elseif eventCode == cc.EventAssetsManagerEx.EventCode.UPDATE_PROGRESSION then
local assetId = event:getAssetId()
local percent = event:getPercent()
local strInfo = ""
if assetId == cc.AssetsManagerExStatic.VERSION_ID then
strInfo = string.format("Version file: %d%%", percent)
elseif assetId == cc.AssetsManagerExStatic.MANIFEST_ID then
strInfo = string.format("Manifest file: %d%%", percent)
else
strInfo = string.format("%d%%", percent)
end
progress:setString(strInfo)
self:setLoadingProgress(event:getPercentByFile())
elseif eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_DOWNLOAD_MANIFEST or
eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_PARSE_MANIFEST then
print("Fail to download manifest file, update skipped.")
self:onFail(string.format("更新失败,请检查网络配置。(错误码:%d)", eventCode))
elseif eventCode == cc.EventAssetsManagerEx.EventCode.ALREADY_UP_TO_DATE or
eventCode == cc.EventAssetsManagerEx.EventCode.UPDATE_FINISHED then
print("Update finished.")
self:onSuccess()
elseif eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_UPDATING then
print("Asset ", event:getAssetId(), ", ", event:getMessage())
-- self:onFail(string.format("更新资源失败,请检查网络后重试。(%d)", eventCode))
elseif eventCode == cc.EventAssetsManagerEx.EventCode.UPDATE_FAILED then
print("Fail to download resource files.")
self._update_failed_count = self._update_failed_count + 1
if self._update_failed_count <= 3 then
print("try again")
am:downloadFailedAssets()
else
self:onFail(string.format("更新失败,请检查网络配置。(错误码:%d)", eventCode))
end
elseif eventCode == cc.EventAssetsManagerEx.EventCode.NEW_VERSION_FOUND then
print("new version found.")
--am:update()
elseif eventCode == cc.EventAssetsManagerEx.EventCode.ASSET_UPDATED then
print("assets updated.")
elseif eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_DECOMPRESS then
print("decompress error.")
end
end
local listener = cc.EventListenerAssetsManagerEx:create(am, onUpdateEvent)
cc.Director:getInstance():getEventDispatcher():addEventListenerWithFixedPriority(listener, 1)
am:update()
--am:checkUpdate()
end
end
local function onExit()
am:release()
end
local function onNodeEvent(event)
if "enter" == event then
onEnter()
elseif "exit" == event then
onExit()
end
end
layer:registerScriptHandler(onNodeEvent)
self:addChild(layer)
end
function AutoUpdateScene:onFail(msg)
print("====== update fail ======", msg)
-- 热更新失败处理
end
function AutoUpdateScene:onSuccess()
print("====== update success ======")
local writablePath = cc.FileUtils:getInstance():getWritablePath()
package.path = writablePath .. "update/src/?.lua;./?.lua;"
-- 启动热更新后的场景
end
return AutoUpdateScene
最后给自己写的小游戏打下广告,一个释放你压力的小游戏,一个你敢叫它敢动的小游戏。敢不敢来试下?
点击下载,或在 Google Play Store 搜索 Make a Noise