Cocos2d-x 3.2 Lua示例 AssetsManagerTest(资源管理器)
本篇博客介绍Cocos2d-x 为我们提供的一个类——AssetsManager在Lua中的使用例子,效果如下图:
Cocos2d-x 给出的例子是AssetsManagerTest,进入会发现三个菜单项:
- enter
- reset
- update
enter是进入场景,reset是删除本地版本,重新设置,update就是更新资源文件。
笔者使用LDT打开lua-tests测试项目:
在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
以下这张图截自官网:
AssetsManager这个类为我们提供了以上这些方法,下面对这些方法逐个进行简单说明:
构造函数有三个参数:一个是zip下载地址,一个是版本文件网络地址,一个是下载保存路径。
checkStoragePath:检查存储路径
checkUpdate:检查更新,返回bool值
createDirectory:根据平台创建目录
deleteVersion:删除本地版本
downLoad:下载文件
downloadAndUncompress:下载并解压缩文件
getConnectionTimeout:获得连接超时时间
getDelegate:获得委托对象
getPackageUrl:获得压缩包地址
getStoragePath:获得存储地址
getVersion:获得版本号
getVersionFileUrl:获得版本文件地址
setConnectionTimeout:设置网络连接超时
setDelegate:设置委托
setPackageUrl:设置包路径
setSearchPath:设置优先资源搜索路径
setStoragePath:设置存储路径
setVersionFileUrl:设置版本文件路径
uncompress:解压缩文件
update:更新
这里还要介绍一个委托类:AssetsManagerDelegateProtocol,我们在实现下载更新时需要回调的三个方法:
读者可以稍微研读一下以上代码,这里Cocos2d-x只是给出一个简单使用AssetsManager对程序进行热更新的例子,但没有提供完整的解决方案。后面笔者也会对Lua对Cocos2d-x客户端进行热更新这部分进行研究,有机会跟大家分享一下这方面的知识。