quick-cocos2d 之动态更新

前端之家收集整理的这篇文章主要介绍了quick-cocos2d 之动态更新前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

quick-cocos2d之动态更新

1.创建一个UpdateScene.lua 作为你的更新模块。

require("config")

require("framework.init")

require("datastore")

require("framework.cc.init")

local UpdateScene =class("UpdateScene",

function()

returndisplay.newScene(UpdateScene)

end)

local server ="http://192.168.3.2/" --192.168.3.2

local versionFile = "version/version"

local allFileList = "version/V"

local nowVersion = nil -- 当前版本号

local bigVersion = nil -- 服务器最大的版本号

function UpdateScene:ctor()

DataStore:init()

self.mIsHandover = false -- 控制noUpdateStart只回调一次

self.needRestart = false -- 是否需要重启

self.needDownload = false -- 是否需要下载

self.path =device.writablePath

self:createDownPath(self.path)

self:createDownPath(self.path.."res/")

self:createDownPath(self.path.."src/")

--把当前的版本号从本地取出来

nowVersion =self:getVersion("nowVersion")

ifnowVersion == nil or nowVersion == "" then

nowVersion = Config.gameVersion

end

self.progressLabel = display.newTTFLabel({

text = "您好,世界",

font = "Arial",

size = 35,

color = cc.c3b(255,0),-- 使用纯红色

align = cc.TEXT_ALIGNMENT_LEFT,

valign = cc.VERTICAL_TEXT_ALIGNMENT_CENTER,

dimensions = cc.size(400,200)

}):pos(display.cx,display.cy):addTo(self)

self.progressLabel:setString("更新.....")

end

--根据服务器取出来的版本文件加载要更新的资源

functionUpdateScene:downIndexedVersion()

if self.needDownload then --需要重新下载apk

--apk 下载链接

return

end

if not self.nowDownIndex then

self.nowDownIndex = 1

end

local versionUrl =server..versionFile..self.needDownVersions[self.nowDownIndex].version..

"."..self.needDownVersions[self.nowDownIndex].id

local packageUrl =self.needDownVersions[self.nowDownIndex].fileUrl

if self.nowDownIndex == 1 then

self.assetsManager =cc.AssetsManager:new(packageUrl,versionUrl,self.path) --资源包路径,版本号路径,下载好的资源存储路径

self.assetsManager:setDelegate(handler(self,self.onSuccess),cc.ASSETSMANAGER_PROTOCOL_SUCCESS )设置加载完成的回调函数

self.assetsManager:setDelegate(handler(self,self.onProgress),cc.ASSETSMANAGER_PROTOCOL_PROGRESS )设置加载进度的回调函数

self.assetsManager:setDelegate(handler(self,self.onError),cc.ASSETSMANAGER_PROTOCOL_ERROR )设置加载出现错误的回调函数

self.assetsManager:retain()

else

self.assetsManager:setVersionFileUrl(versionUrl)

self.assetsManager:setPackageUrl(packageUrl)

end

if self.assetsManager:checkUpdate() then

self.assetsManager:update()

end

end

--从服务器获取最新版本号

functionUpdateScene:getNewestVersion()

function callback(event)

local ok = (event.name == "completed")

local request = event.request

if event.name then

self.progressLabel1:setString("requestevent.name = " .. event.name)

print("request event.name = " ..event.name)

end

if not ok then

self.progressLabel1:setString("请求失败"..request:getErrorMessage())

print("请求失败"..request:getErrorMessage())

--self:pro

self:performWithDelay(

function ()

self:noUpdateStart()

end,2)

return

end

local code = request:getResponseStatusCode()

if code ~= 200 then

print("请求错误代码"..request:getResponseStatusCode())

self:performWithDelay(

function ()

self:noUpdateStart()

end,2)

return

end

if json.decode(request:getResponseString()) then

print(request:getResponseString())

local needDownVersions =json.decode(request:getResponseString())

if needDownVersions.code == 200 then

if needDownVersions.needRestart > 0 then

self.needRestart = true

end

ifneedDownVersions.needDownload > 0 then

self.needDownload = true

end

self.needDownVersions =needDownVersions.list

--版本号判断 是否已经是最新的

if needDownVersions.bigVersion == nowVersionthen

self.progressLabel:setString("已经是-----最新的版本")

self:performWithDelay(

function ()

self:noUpdateStart()

end,1)

return

end

--版本号更换,并存储到本地

nowVersion = needDownVersions.bigVersion

self:setVersion("nowVersion",nowVersion,true)

if #self.needDownVersions > 0 then

self:downIndexedVersion()

end

else

self.progressLabel:setString("当前版本已经是最新版本")

self:performWithDelay(

function ()

self:noUpdateStart()

end,2)

end

end

end

--请求得到最新的版本号数据 回调函数callback

local request = network.createHTTPRequest(callback,server..allFileList,"GET")

request:setTimeout(10)

request:start()

end

--进入场景后开始更新判断

function UpdateScene:onEnter()

self:getNewestVersion()

end

--更新成功之后,启动游戏

function UpdateScene:afterUpdateStart()

if self.needRestart then

print("提示需要重新启动游戏")

local game = require("game")

game.exit();

return

end

Config.gameVersion = nowVersion

self.progressLabel:setString("更新成功,启动游戏 ")

local game = require("game")

game.startup();

end

--不有更新(或者没有成功)直接开始

functionUpdateScene:noUpdateStart()

if self.mIsHandover == true then

return

end

self.mIsHandover = true

Config.gameVersion = nowVersion

self.progressLabel:setString("没有更新或者更新失败启动游戏")

local game = require("game")

game.startup();

end

--更新错误回调

functionUpdateScene:onError(errorCode)

if errorCode == cc.ASSETSMANAGER_NETWORK then

text = "网络出错!"

end

if errorCode == cc.ASSETSMANAGER_NO_NEW_VERSION then

text = "没有新版本"

end

if errorCode == cc.ASSETSMANAGER_UNCOMPRESS then

text = "解压出错"

end

if errorCode == cc.ASSETSMANAGER_CREATE_FILE then

text = "未知错误"

end

print("text:",text)

self:performWithDelay(function ()

self:noUpdateStart()

end

--更新进度回调

function UpdateScene:onProgress( percent)

-- 显示下载进度

localprogress = string.format("downloading %d%%",percent)

print("progress:",progress)

end

-- 更新完成回调

function UpdateScene:onSuccess()

--每次更新可能有多个zip包,做下处理

if self.nowDownIndex < #self.needDownVersions then

self.nowDownIndex = self.nowDownIndex +1

self:downIndexedVersion()

else

-- "更新成功"

self:performWithDelay(function ()

self:afterUpdateStart()

end,2)

end

end

functionUpdateScene:createDownPath( path )

if not self:checkDirOK(path) then

print("更新目录创建失败,直接开始游戏")

self:noUpdateStart()

return

else

-- print("更新目录存在或创建成功")

end

end

--改变目录

function UpdateScene:checkDirOK(path )

require "lfs"

local oldpath = lfs.currentdir()

if lfs.chdir(path) then

lfs.chdir(oldpath)

return true

end

if lfs.mkdir(path) then

return true

end

end

--

--删除目录中所有文件

functionUpdateScene:delAllFilesInDirectory( path )

for file in lfs.dir(path) do

if file ~= "." and file ~= ".."then

local f = path..'/'..file

local attr = lfs.attributes (f)

assert (type(attr) == "table")

if attr.mode == "directory" then

self:delAllFilesInDirectory(f)

else

os.remove(f)

end

end

end

end

string.startWith =function(str,strStart)

local a,_ = string.find(str,strStart)

return a==1

end

string.split = function(s,p)

local rt= {}

string.gsub(s,'[^'..p..']+',function(w)table.insert(rt,w) end )

return rt

end

--版本号的本地存储

functionUpdateScene:setVersion(__key,__value,__isSave)

DataStore:setData(__key,__isSave)

end

functionUpdateScene:getVersion(__key)

return DataStore:getData( __key )

end

return UpdateScene

main.lua

local writablePath =cc.FileUtils:getInstance():getWritablePath().."assets/"

cc.FileUtils:getInstance():addSearchPath(writablePath.."res/")

cc.FileUtils:getInstance():addSearchPath("res/")

cc.FileUtils:getInstance():addSearchPath(writablePath.."res/sound")

cc.FileUtils:getInstance():addSearchPath("res/sound")

cc.FileUtils:getInstance():addSearchPath(writablePath.."src/")

cc.FileUtils:getInstance():addSearchPath("src/")

local function main()

package.path =package.path .. ";src/"

cc.FileUtils:getInstance():setPopupNotify(false)

cc.Director:getInstance():runWithScene(require("update.updatescene").new())

end

xpcall(main,__G__TRACKBACK__)

配置文件:

1.如network.createHTTPRequest()中的第二个参数文件内容大致为(可根据需要自己配)

{"code":200,"bigVersion":"1.0.01","needRestart":0,"needDownload":0,

"list":[

{"fileUrl":"http://192.168.3.2/version/res.zip","version":"1.0","id":1},

{"fileUrl":"http://192.168.3.2/version/src.zip","id":2}

]}

2.如AssetsManager:new(constchar*packageUrl,constchar*versionFileUrl,constchar*storagePath)

中的参数2versionFileUrl版本号文件,也就是在文件里面写一个版本号,例如:1.0.01

更新的大致流程:

1. 获取当前本地存储的版本号

2. 请求更新版本的数据,并以最新版本号与当前本地存储的版本号做比较

3. 版本不一致时,就利用AssetsManager进行资源更新。否则退出让玩家开始游戏

AssetsManager的基本流程:

@H_923_2502@1. @H_923_2502@配置需要更新的zip的URL,更新版本号的URL,更新存放的相对路径

@H_923_2502@2. @H_923_2502@从Server获取该zip文件的版本号

@H_923_2502@3. @H_923_2502@对比Client中的UserDefault.xml中current-version-code键的值(当前版本号)是否过期

@H_923_2502@4. @H_923_2502@若Server的版本比Client的新,则通过http请求下载该zip

@H_923_2502@5. @H_923_2502@解压缩该zip文件

@H_923_2502@6. @H_923_2502@下载后通过CCFileUtils的fullPathForFilename方法获取文件的引用

AssetsManager内部函数:

1. 构造函数

AssetsManager::AssetsManager(constchar*packageUrl,constchar*storagePath)

_packageUrl(packageUrl)//下载.zip文件地址

_versionFileUrl(versionFileUrl)//版本核查地址 v1.0

_storagePath(storagePath)//.zip下载后存储位置

2. checkStoragePath

由1调用

检查_storagePath 存储地址不能为""并且不是以"/"结尾的,在结尾处加上"/"

3.getVersionCodelibcurl绑定的下载字符串回调函数通过checkUpdate里调用

把下载的字符串放到传过来的字符串指针里

4.checkUpdate

通过网络检查当前的版本是不是最新版本。如果是设置优先搜索资源路径setSearchPath

5.update

(1)下载地址、版本核查的网址都不能为null,存储的文件名以"。zip"后缀

(2)checkUpdate调用,是最新版本了返回,不是执行下面

(3)通过xml文件判断是不是下载完成了没有解压,是,解压,不是,调用,downLoad下载

(4)下载完成uncompress解压

(5)设置资源搜索优先级setSearchPath

(6)删除.zip源文件

6.createDirectory

创建目录

7.downLoad

执行下载资源,建立了指向本地资源的指针

关于详细讲解AssetsManager和动态更新的网站链接:

1. http://blog.sina.com.cn/s/blog_923fdd9b0101edmv.html

2. http://www.jb51.cc/article/p-rwaqitzb-tb.html

3. http://my.oschina.net/u/1785418/blog/283043

4. http://zengrong.net/post/2131.htm

出现的问题:

1. 有可能出现AssetsManager这个文件为nil的情况。那是因为他与CURL 库提供 HTTP 网络功能有关联。CURL关闭后,assetsmanager等相关功能也会被去掉。

解决:在打包时应该在android工程下的jni\Application.mk中

把 CC_USE_CURL := 1修改为1 ,设置为开启状态 ,0为关闭状态

ifeq ($(CC_USE_CURL),1)

APP_CPPFLAGS += -DCC_USE_CURL=1

以上是参考西门大官人的:基于Quick-cocos2dx 2.2.3 的动态更新实现完整篇。(打包,服务器接口,模块自更新)所写的

链接http://my.oschina.net/u/1785418/blog/283043

猜你在找的Cocos2d-x相关文章