https://blog.csdn.net/wwj_748/article/details/38368061
本篇博客介绍Cocos2d-x 为我们提供的一个类——AssetsManager在Lua中的使用例子,效果如下图:
![](https://i-blog.csdnimg.cn/blog_migrate/d1b19847cd5568d404ff83e6e67a8514.png)
![](https://i-blog.csdnimg.cn/blog_migrate/dbbb2e5f02ea1b7d8b0c471e061c1948.png)
Cocos2d-x 给出的例子是AssetsManagerTest,进入会发现三个菜单项:
- enter
- reset
- update
enter是进入场景,reset是删除本地版本,重新设置,update就是更新资源文件。
笔者使用LDT打开lua-tests测试项目:
![](https://i-blog.csdnimg.cn/blog_migrate/da6c7c1c0742da23aa586dc93ff38909.png)
在src目录下找到AssetsManagerTest目录,查看以下代码(笔者对其进行了注释):
>>>AsetsManagerModule.lua
- --[[
- 资源管理器模块
- ]]--
- local AssetManagerModule = {}
- --[[
- newScene
- ]]--
- function AssetManagerModule.newScene(backfunc)
- -- 获取屏幕大小
- local winSize = cc.Director:getInstance():getWinSize()
- -- 创建新的场景
- local newScene = cc.Scene:create()
- -- 创建新的层
- local layer = cc.Layer:create()
- -- 后台更新
- local function backToUpdate()
- local scene = backfunc()
- if scene ~= nil then
- cc.Director:getInstance():replaceScene(scene)
- end
- end
- -- 创建回退菜单
- cc.MenuItemFont:setFontName("Arial")
- cc.MenuItemFont:setFontSize(24)
- local backMenuItem = cc.MenuItemFont:create("Back")
- -- 放置在右下角大致的位置
- backMenuItem:setPosition(cc.p(VisibleRect:rightBottom().x - 50, VisibleRect:rightBottom().y + 25))
- -- 注册监听方法
- backMenuItem:registerScriptTapHandler(backToUpdate)
- -- 创建菜单
- local backMenu = cc.Menu:create()
- backMenu:setPosition(0, 0)
- backMenu:addChild(backMenuItem)
- layer:addChild(backMenu,6)
- -- 创建标签
- local helloLabel = cc.Label:createWithTTF("Hello World", s_arialPath, 38)
- helloLabel:setAnchorPoint(cc.p(0.5, 0.5))-- 锚点居中
- helloLabel:setPosition(cc.p(winSize.width / 2, winSize.height - 40))
- layer:addChild(helloLabel, 5)
- -- 创建精灵,这里是一张背景图
- local sprite = cc.Sprite:create("Images/background.png")
- sprite:setAnchorPoint(cc.p(0.5, 0.5))-- 锚点居中
- sprite:setPosition(cc.p(winSize.width / 2, winSize.height / 2))
- layer:addChild(sprite, 0)
- newScene:addChild(layer)-- 添加到场景
- cc.Director:getInstance():replaceScene(newScene)-- 替换场景
- end
- -- 返回模块
- return AssetManagerModule
>>>AssetsManagerTest.lua
- -- 获取目标平台
- local targetPlatform = cc.Application:getInstance():getTargetPlatform()
- local lineSpace = 40 -- 行间距
- local itemTagBasic = 1000
- local menuItemNames =
- {
- "enter",
- "reset",
- "update",
- }
- -- 获取屏幕大小
- local winSize = cc.Director:getInstance():getWinSize()
- -- 更新层
- local function updateLayer()
- -- 首先创建一个层
- local layer = cc.Layer:create()
- local support = false
- -- 判断是否支持iphone、ipad、win32、android或者mac
- if (cc.PLATFORM_OS_IPHONE == targetPlatform) or (cc.PLATFORM_OS_IPAD == targetPlatform)
- or (cc.PLATFORM_OS_WINDOWS == targetPlatform) or (cc.PLATFORM_OS_ANDROID == targetPlatform)
- or (cc.PLATFORM_OS_MAC == targetPlatform) then
- support = true
- end
- -- 如果不支持平台
- if not support then
- print("Platform is not supported!")
- return layer
- end
- local isUpdateItemClicked = false -- 是否更新项被点击
- local assetsManager = nil -- 资源管理器对象
- local pathToSave = "" -- 保存路径
- local menu = cc.Menu:create() -- 菜单
- menu:setPosition(cc.p(0, 0)) -- 设置菜单位置
- cc.MenuItemFont:setFontName("Arial")-- 设置菜单字体样式
- cc.MenuItemFont:setFontSize(24) -- 设置字体大小
- -- 用于更新的标签
- local progressLable = cc.Label:createWithTTF("",s_arialPath,30)
- progressLable:setAnchorPoint(cc.p(0.5, 0.5))
- progressLable:setPosition(cc.p(140,50))
- layer:addChild(progressLable)
- -- 下载目录
- pathToSave = createDownloadDir()
- -- 下载错误回调
- local function onError(errorCode)
- -- 没有新版本
- if errorCode == cc.ASSETSMANAGER_NO_NEW_VERSION then
- progressLable:setString("no new version")
- elseif errorCode == cc.ASSETSMANAGER_NETWORK then
- -- 网络错误
- progressLable:setString("network error")
- end
- end
- -- 进度更新回调
- local function onProgress( percent )
- -- 显示下载进度
- local progress = string.format("downloading %d%%",percent)
- progressLable:setString(progress)
- end
- -- 下载成功方法回调
- local function onSuccess()
- progressLable:setString("downloading ok")
- end
- -- 获得资源管理器
- local function getAssetsManager()
- if nil == assetsManager then
- -- 创建一个资源管理器,第一个参数是zip包下载地址,第二个参数是版本文件,第三个参数是保存路径
- assetsManager = cc.AssetsManager:new("https://raw.github.com/samuele3hu/AssetsManagerTest/master/package.zip",
- "https://raw.github.com/samuele3hu/AssetsManagerTest/master/version",
- pathToSave)
- -- 保留所有权,该方法会增加Ref对象的引用计数
- assetsManager:retain()
- -- 设置一系列委托
- assetsManager:setDelegate(onError, cc.ASSETSMANAGER_PROTOCOL_ERROR )
- assetsManager:setDelegate(onProgress, cc.ASSETSMANAGER_PROTOCOL_PROGRESS)
- assetsManager:setDelegate(onSuccess, cc.ASSETSMANAGER_PROTOCOL_SUCCESS )
- assetsManager:setConnectionTimeout(3)-- 设置连接超时
- end
- return assetsManager
- end
- -- 更新
- local function update(sender)
- progressLable:setString("")
- -- 调用AssetsManager的update方法
- getAssetsManager():update()
- end
- -- 重设
- local function reset(sender)
- progressLable:setString("")
- -- 删除下载路径
- deleteDownloadDir(pathToSave)
- -- 删除版本
- getAssetsManager():deleteVersion()
- -- 创建下载路径
- createDownloadDir()
- end
- -- 重新加载模块
- local function reloadModule( moduleName )
- package.loaded[moduleName] = nil
- return require(moduleName)
- end
- -- 进入
- local function enter(sender)
- -- 如果更新按钮没有被点击
- if not isUpdateItemClicked then
- local realPath = pathToSave .. "/package"
- addSearchPath(realPath,true)
- end
- -- 重新加载模块
- assetsManagerModule = reloadModule("src/AssetsManagerTest/AssetsManagerModule")
- assetsManagerModule.newScene(AssetsManagerTestMain)
- end
- -- 回调方法
- local callbackFuncs =
- {
- enter,
- reset,
- update,
- }
- -- 菜单回调方法
- local function menuCallback(tag, menuItem)
- local scene = nil
- local nIdx = menuItem:getLocalZOrder() - itemTagBasic
- local ExtensionsTestScene = CreateExtensionsTestScene(nIdx)
- if nil ~= ExtensionsTestScene then
- cc.Director:getInstance():replaceScene(ExtensionsTestScene)
- end
- end
- -- 遍历添加三个菜单项
- for i = 1, table.getn(menuItemNames) do
- local item = cc.MenuItemFont:create(menuItemNames[i])
- item:registerScriptTapHandler(callbackFuncs[i])-- 注册点击回调地址
- -- 设置三个菜单的位置
- item:setPosition(winSize.width / 2, winSize.height - i * lineSpace)
- if not support then
- item:setEnabled(false)
- end
- menu:addChild(item, itemTagBasic + i)
- end
- local function onNodeEvent(msgName)
- if nil ~= assetsManager then
- -- 释放资源
- assetsManager:release()
- assetsManager = nil
- end
- end
- -- 注册层的点击回调方法
- layer:registerScriptHandler(onNodeEvent)
- layer:addChild(menu)
- return layer
- end
- -------------------------------------
- -- AssetsManager Test
- -------------------------------------
- function AssetsManagerTestMain()
- local scene = cc.Scene:create()
- scene:addChild(updateLayer())
- scene:addChild(CreateBackMenuItem())
- return scene
- end
以下这张图截自官网:
![](https://i-blog.csdnimg.cn/blog_migrate/060e0b6def17c20ffde97877fea6a07d.png)
AssetsManager这个类为我们提供了以上这些方法,下面对这些方法逐个进行简单说明:
![](https://i-blog.csdnimg.cn/blog_migrate/a22b762bdc7b6bd9652d2e58bd8b3641.png)
构造函数有三个参数:一个是zip下载地址,一个是版本文件网络地址,一个是下载保存路径。
checkStoragePath:检查存储路径
checkUpdate:检查更新,返回bool值
createDirectory:根据平台创建目录
deleteVersion:删除本地版本
downLoad:下载文件
downloadAndUncompress:下载并解压缩文件
getConnectionTimeout:获得连接超时时间
getDelegate:获得委托对象
getPackageUrl:获得压缩包地址
getStoragePath:获得存储地址
getVersion:获得版本号
getVersionFileUrl:获得版本文件地址
setConnectionTimeout:设置网络连接超时
setDelegate:设置委托
setPackageUrl:设置包路径
setSearchPath:设置优先资源搜索路径
setStoragePath:设置存储路径
setVersionFileUrl:设置版本文件路径
uncompress:解压缩文件
update:更新
这里还要介绍一个委托类:AssetsManagerDelegateProtocol,我们在实现下载更新时需要回调的三个方法:
![](https://i-blog.csdnimg.cn/blog_migrate/de00dc314472d66e9599a95441a30a1d.png)
读者可以稍微研读一下以上代码,这里Cocos2d-x只是给出一个简单使用AssetsManager对程序进行热更新的例子,但没有提供完整的解决方案。后面笔者也会对Lua对Cocos2d-x客户端进行热更新这部分进行研究,有机会跟大家分享一下这方面的知识。