最近研究cocos2dx + lua 实现游戏的热更新。基本原理:比如我有一个GameScene,显示"hello world",现在热更新,更新之后显示"hello SB".如果是用c++来开发,那么只用把它作成lib库,更新时替换lib库。用lua的话,更简单,替换相关的lua就可以了。
GameScene.lua
- require "Cocos2d"
- require "Cocos2dConstants"
- local GameScene = class("GameScene",function()
- return cc.Scene:create()
- end)
- function GameScene.create()
- local scene = GameScene.new()
- scene:addChild(scene:createTitle())
- return scene
- end
- function GameScene:ctor()
- self.visibleSize = cc.Director:getInstance():getVisibleSize()
- self.origin = cc.Director:getInstance():getVisibleOrigin()
- self.schedulerID = nil
- end
- function GameScene:createTitle()
- local title = cc.Label:createWithTTF("Hello World","fonts/arial.ttf",24)
- title:setPosition(self.visibleSize.width /2,self.visibleSize.height /2)
- return title
- end
更新的 GameScene.lua
- require "Cocos2d"
- require "Cocos2dConstants"
- local GameScene = class("GameScene",function()
- return cc.Scene:create()
- end)
- function GameScene.create()
- local scene = GameScene.new()
- scene:addChild(scene:createTitle())
- return scene
- end
- function GameScene:ctor()
- self.visibleSize = cc.Director:getInstance():getVisibleSize()
- self.origin = cc.Director:getInstance():getVisibleOrigin()
- self.schedulerID = nil
- end
- function GameScene:createTitle()
- local title = cc.Label:createWithTTF("Hello SB","fonts/arial.ttf",24)
- title:setPosition(self.visibleSize.width /2,self.visibleSize.height /2)
- return title
- end
- require "Cocos2d"
- require "Cocos2dConstants"
- local MenuScene = class("MenuScene",function()
- return cc.Scene:create()
- end)
- local title
- function MenuScene.create()
- local scene = MenuScene.new()
- scene:addChild(scene:createLayer())
- --scene:addChild(scene:createLayerFarm())
- --scene:addChild(scene:createLayerMenu())
- return scene
- end
- function MenuScene:ctor()
- self.visibleSize = cc.Director:getInstance():getVisibleSize()
- self.origin = cc.Director:getInstance():getVisibleOrigin()
- self.schedulerID = nil
- end
- function MenuScene:createLayer()
- function menuCallback1(tag)
- local scene = require("GameScene")
- local gameScene = scene.create()
- cc.Director:getInstance():replaceScene(gameScene)
- end
- function menuCallback2(tag)
- MenuScene:update()
- end
- local menuLayer = cc.Layer:create()
- title = cc.Label:createWithTTF("Choose Scene","fonts/arial.ttf",24)
- title:setPosition(self.visibleSize.width /2,self.visibleSize.height /4 * 3)
- menuLayer:addChild(title)
- local menuLabel1 = cc.Label:createWithTTF("Go to Scene", "fonts/arial.ttf", 24)
- local menuItem1 = cc.MenuItemLabel:create(menuLabel1)
- menuItem1:registerScriptTapHandler(menuCallback1)
- menuItem1:setPosition(self.visibleSize.width /2,self.visibleSize.height /4 * 2)
- local menuLabel2 = cc.Label:createWithTTF("Update", "fonts/arial.ttf", 24)
- local menuItem2 = cc.MenuItemLabel:create(menuLabel2)
- menuItem2:registerScriptTapHandler(menuCallback2)
- menuItem2:setPosition(self.visibleSize.width /2,self.visibleSize.height /4 * 1)
- local MainMenu = cc.Menu:create()
- MainMenu:setPosition(0,0)
- MainMenu:addChild(menuItem1)
- MainMenu:addChild(menuItem2)
- menuLayer:addChild(MainMenu)
- return menuLayer
- end
- function MenuScene:getAssetsManager()
- local function onError(errorCode)
- if errorCode == cc.ASSETSMANAGER_NO_NEW_VERSION then
- title:setString("no new version")
- elseif errorCode == cc.ASSETSMANAGER_NETWORK then
- title:setString("network error")
- end
- end
- local function onProgress( percent )
- local progress = string.format("downloading %d%%",percent)
- title:setString(progress)
- end
- local function onSuccess()
- title:setString("downloading ok")
- end
- local pathToSave = ""
- pathToSave = createDownloadDir()
- local assetsManager = cc.AssetsManager:new("http://qd.baidupcs.com/file/1a531cc6565d95827e0ec3f9fd4af795?fid=138463011-250528-222085911919595&time=1406097600&sign=FDTAXER-DCb740ccc5511e5e8fedcff06b081203-mLvWIkhwaVZCjN%2BpTYZJZ%2BagPR4%3D&to=qb&fm=N,B,T,t&newver=1&expires=1406098200&rt=sh&r=164813188&mlogid=124796854&sh=1&vuk=138463011&vbdid=2986594979&fn=GameScene.zip",
- "https://raw.github.com/samuele3hu/AssetsManagerTest/master/version",
- pathToSave)
- 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)
- return assetsManager
- end
- function MenuScene:update()
- MenuScene:getAssetsManager():update()
- end
- return MenuScene
AssetsManager传三个参数,resource.zip路径,version路径,写文件的路径。
然后调用AssetsManager.update,进行下载更新。
注意的是,android时,它是写到Context.getCacheDir()里。所以每次进入游戏时,都会重新更新。需要修改
createDownloadDir()里创建的路径,把它写到sd卡上。