cocos2dx lua 热更新

cocos2dx lua 热更新
最近研究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
最关键的更新模块,MenuScene.lua
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
关键看cc.AssertsMananger。cpp在extensions\assets-manager。
AssetsManager传三个参数,resource.zip路径,version路径,写文件的路径。
然后调用AssetsManager.update,进行下载更新。

注意的是,android时,它是写到Context.getCacheDir()里。所以每次进入游戏时,都会重新更新。需要修改 createDownloadDir()里创建的路径,把它写到sd卡上。



你可能感兴趣的:(cocos2dx lua 热更新)