Cocos2d-x 3.2 Lua示例 AssetsManagerTest(资源管理器)

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客户端进行热更新这部分进行研究,有机会跟大家分享一下这方面的知识。

你可能感兴趣的:(Cocos2d-x 3.2 Lua示例 AssetsManagerTest(资源管理器))