您的位置:首页 > 移动开发 > Cocos引擎

cocos2dx-lua_热更新_AssetsManagerExTest分析

2016-07-12 17:23 351 查看
以下是在win7下的coocs2dx3.10 lua开发的

1.概述

这里要创建一个测试cocos2dx lua的AssetsManagerExTest的项目。

2.搭建ftp服务器

(1)开始菜单中输入"打开或关闭",找到"打开或关闭Window功能"

(2)在打开或关闭Window功能中到打“Internet信息服务”然后把FTP服务器和Web管理工具打上勾,然的确定

(3)开始菜单中搜索“IIS”,打开Internet信息服务(IIS)管理器

(4)进入Internet信息服务管理器,在网站上右击,点“添加FTP站点”

(5)在添加FTP站点中输入站点名称“myftp”,物理路径为"e:\\myftp",点下一步

(6)在绑定SSL设置中IP地址输入本机的IP地址,端口为21,SSL点无,然后下一步

(7)身份验证和授权信息中,选"基本","未选定",然后完成。

(8)按win+R打开运行,输入services.msc打开服务窗口,找到Microsoft FTP Service,启动服务

(9)进入Internet信息服务管理器,右击你的myftp,点击“管理FTP站点”,然后"启动"

(10)右击计算机,点管理,进入本地用户和组中,进入用户,右键新建两个用户,一个admin,一个为view,并设置密码,

admin用户管理ftp,view只能读ftp,不能写。

用户名 全名  描述          密码  

admin  admin  完全控制ftp  321321

view   view   查看ftp      321321

(11)进入IIS管理器中选中myftp-->FTP授权规则-->编辑权限-->安全-->编辑-->添加 在选择用户或组中输入

admin然后点确定,再点添加后输入view后点确定,回到myftp权限窗口中选中admin在admin的权限中勾选完

全控制,view用用户不用勾选完成控制。然后确定,确定,确定

(12)双击 FTP授权规则,后在右边点击添加允许规则,指定的用户中输入admin,权限为读取和写入然后确定,

然后再点允许规则,在指定的用户中输入view,权限为读取,然后确定。

(13)在开始菜单中输入 window然后找到windows防火墙,点“允许程序或功能通过windows防火墙”

(14)在允许程序通过windows防火墙通信中选择FTP服务器,将后面的两个框也都选中。

点击下方的“允许运行另一程序”,在弹出窗口里,点“浏览”,找到C:\Windows\System32\inetsrv\inetinfo.exe,

点添加。点确定。

因为在Win7下,FTP是IIS的一个组件,因此也必须在防火墙中将IIS设置为允许。而IIS又不在默认的列表中,

因此得手动添加。

(15)在windows防火墙中点高级设置,在入站规则中点新建规则,选中端口,点下一步

(16)协议和端口分页,在特定本地端口中输入21,点下一步

(17)操作分页,点允许连接,下一步

(18)配置文件分页,域、专用、公用都选上,下一步

(19)名称分页,名称输入21,描述输入21,完成

(20)在地址栏输入ftp://192.168.1.52 会出现登录框,出入admin用户和密码,登录成功则ftp服务器配置成功,

如果不成功,先检查admin用户能不能登录window,因为如果设置了新建用户第一次登录系统要改密码,那就必须

先改密码再登录

(21)输入
ftp://192.168.1.52
用admin用户登录后新建文件夹成功

用view用户登录后,新建文件夹出错

配置成功!

(22)IE中敲入ftp://url访问需要用户名与密码的资源
ftp://username:password@url 
另外,可以在服务器匿名登陆打上勾,就可直接进了

(23)出现“ftp文件夹错误”

自己的问题

我使用公司的电脑搭建ftp,绑定了一个动态IP,昨天搭建完时没啥问题,今天重新进入,因为IP变了,自然

就登录不进去ftp了。解决方法就是在Internet信息服务(IIS)管理器中点击myftp,右键“编辑绑定”,重新

设置为你本机IP。

3.测试部分更新

3.1.在ftp服务器创建要下载的资源的路径

(1)以下资源全是官方AssetsManagerExTest成功运行后在本地创建的,这里只是拷贝过来用

E:/myftp/test/

将cocos lua的AssetsManagerExTest的更新的资源文件放到此路径下。

test--

--app

  --views

    --MainScene.lua

--Images

  --...

--compressed.zip        //注意:这里要将AssetsManagerExTest的更新的资源文件夹compressed重新压缩,要以zip压缩

--project_dev.manifest

--version_dev.manifest

(2)修改更新的配置文件

project_dev.manifest-----------------

{
"packageUrl" : "ftp://view:321321@192.168.1.49/test/",
"remoteManifestUrl" : "ftp://view:321321@192.168.1.49/test/project_dev.manifest",
"remoteVersionUrl" : "ftp://view:321321@192.168.1.49/test/version_dev.manifest",
"version" : "1.2.0",
"engineVersion" : "3.x dev",

"assets" : {
"Images/assetMgrBackground1.jpg" : {
"md5" : "....."
},
"Images/ball.png" : {
"md5" : "..."
},
"Images/blocks.png" : {
"md5" : "..."
},
"compressed.zip" : {
"md5" : "...",
"compressed" : true
},
"Images/Bird.jpg" : {
"md5" : "..."
},
"Images/Daisy_Flower.jpg" : {
"md5" : "..."
},
"Images/Mountain_Reflections.jpg" : {
"md5" : "..."
},
"Images/Plitvice_National_Park.jpg" : {
"md5" : "..."
},
"Images/sakountala.jpg" : {
"md5" : "..."
},
"Images/Snake_River.jpg" : {
"md5" : "..."
},
"Images/Thunder.jpg" : {
"md5" : "..."
},
"Images/Tranquil_Lagoon.jpg" : {
"md5" : "..."
},
"Images/Tyrol.jpg" : {
"md5" : "..."
},
"Images/univ-lille1.jpg" : {
"md5" : "..."
},
"Images/Yellow_Garden_Flowers.jpg" : {
"md5" : "..."
},
"Images/Yellow_Lilly.jpg" : {
"md5" : "..."
},
"Images/Yellow_Tulips.jpg" : {
"md5" : "..."
},
"app/views/MainScene.lua" : {
"md5" : "..."
}
},

    

    "searchPaths" : [

    ]

}

version_dev.manifest-----------------

{
"packageUrl" : "ftp://view:321321@192.168.1.49/test/",
"remoteManifestUrl" : "ftp://view:321321@192.168.1.49/test/project_dev.manifest",
"remoteVersionUrl" : "ftp://view:321321@192.168.1.49/test/version_dev.manifest",
"version" : "1.2.0",
"engineVersion" : "3.0 dev"

}

(3)这个文件用来测试是否更新的lua会先加载

MainScene.lua-----------------

local MainScene = class("MainScene", cc.load("mvc").ViewBase)

MainScene.RESOURCE_FILENAME = "MainScene.csb"

function MainScene:onCreate()

    release_print("MainScene")

    

    local layer = cc.Layer:create()  

    --test:which image will be show? (res/Images/blocks.png, update/Images/blocks.png)

    --result:update/Images/blocks.png

    local background1 = cc.Sprite:create("Images/blocks.png")

    background1:setPosition(cc.p(100, 100))   

    layer:addChild(background1, 2)

    --result:update/Images/sakountala.jpg

    local background2 = cc.Sprite:create("Images/sakountala.jpg")

    background2:setPosition(cc.p(300, 200))   

    layer:addChild(background2, 3)

    --test the image in res:res/Images/myDaisy_Flower.jpg

    local background3 = cc.Sprite:create("Images/myDaisy_Flower.jpg")

    background3:setPosition(cc.p(900, 500))   

    layer:addChild(background3, 3)

    

    self:addChild(layer)  

end

return MainScene

3.2.创建cocos2dx lua项目

clientTest--

--res

  --fonts

    --Marker Felt.ttf

  --Images

    --blocks.png          //注意这里的图片与ftp服务器中的对应图片同名,但图片经过ps,加了一个黑框
--myDaisy_Flower.jpg  //这张图与官方AssetsManagerExTest列子中下载的Daisy_Flower.jpg相同,这里只是改了个名字
--sakountala.jpg      //注意这里的图片与ftp服务器中的对应图片同名,但图片经过ps,加了一个黑框

  --Manifests

    --project.manifest

  --updateScent.csb     //这个界面包含一个文本控件:tips

  --MainScene.csb       //cocos2dx的默认主界面

  --HelloWorld.png      //cocos2dx的默认logo

--src

  --app

    --MyApp.lua
--views
 --updateScent.lua
 --MainScene.lua

  --packages

    --mvc
 --AppBase.lua
 --init.lua
 --ViewBase.lua

  --main.lua

(1)这里提前添加更新文件夹的搜索路径

main.lua------------------

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

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

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

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

require "config"

require "cocos.init"

local function main()

    require("app.MyApp"):create():run()

end

local status, msg = xpcall(main, __G__TRACKBACK__)

if not status then

    release_print(msg)

end

  

(2)这里要修改初始界面

AppBase.lua---------------

local AppBase = class("AppBase")

function AppBase:ctor(configs)

    self.configs_ = {

        viewsRoot  = "app.views",

        modelsRoot = "app.models",

        defaultSceneName = "updateScent",  --注意这里的名字

    }
...

end

(3)更新界面脚本

updateScent.lua--------------------------

local updateScent = class("updateScent", cc.load("mvc").ViewBase)

updateScent.RESOURCE_FILENAME = "updateScent.csb"

function create()

    release_print("updateScent:0")

self.root = self:getResourceNode()

    self.tips = self.root:getChildByName("tips")

    self.tips:setText("check download")

    

    local am1 = nil

    am1 = cc.AssetsManagerEx:create("Manifests/project.manifest", cc.FileUtils:getInstance():getWritablePath() .. "update")

    am1:retain()

    

    if not am1:getLocalManifest():isLoaded() then

        self.tips:setText("Fail to update assets, step skipped.")    

    else

        release_print("updateScent:onStartDownload:1")

        local function onUpdateEvent(event)

            local eventCode = event:getEventCode()

            --release_print("updateScent:onStartDownload:eventCode=" .. eventCode)

            if eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_NO_LOCAL_MANIFEST then

                self.tips:setText("No local manifest file found, skip assets update.")

            elseif  eventCode == cc.EventAssetsManagerEx.EventCode.UPDATE_PROGRESSION then

                local assetId = event:getAssetId()

                local percent = event:getPercent()

                local strInfo = ""

    

                if assetId == cc.AssetsManagerExStatic.VERSION_ID then

                    strInfo = string.format("Version file: %d%%", percent)

                elseif assetId == cc.AssetsManagerExStatic.MANIFEST_ID then

                    strInfo = string.format("Manifest file: %d%%", percent)

                else

                    strInfo = string.format("%d%%", percent)

                end

                self.tips:setText(strInfo)

            elseif eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_DOWNLOAD_MANIFEST or 

                eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_PARSE_MANIFEST then

                self.tips:setText("Fail to download manifest file, update skipped.")

            elseif eventCode == cc.EventAssetsManagerEx.EventCode.ALREADY_UP_TO_DATE or 

                eventCode == cc.EventAssetsManagerEx.EventCode.UPDATE_FINISHED then

                release_print("updateScent:5")

                self.tips:setText("Update finished.")

    
--显示主场景界面

                self:getApp():enterScene("MainScene") 

            elseif eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_UPDATING then

                self.tips:setText("Asset " .. event:getAssetId() .. ", " .. event:getMessage() .. ". Please restart game!")

            end

        end

        local listener1 = cc.EventListenerAssetsManagerEx:create(am1,onUpdateEvent)

        cc.Director:getInstance():getEventDispatcher():addEventListenerWithFixedPriority(listener1, 1)

    

        am1:update()

    end

end

return LauncherScene

(4)客户端的版本文件

project.manifest-------------------

{
"packageUrl" : "ftp://view:321321@192.168.1.49/test/",
"remoteManifestUrl" : "ftp://view:321321@192.168.1.49/test/project_dev.manifest",
"remoteVersionUrl" : "ftp://view:321321@192.168.1.49/test/version_dev.manifest",
"version" : "1.0.0",
"engineVersion" : "3.0 beta",

"assets" : {
},

    

    "searchPaths" : [

    ]

}

(5)这里的MainScene.lua与ftp服务器上的MainScene.lua差别只在图片的位置上

MainScene.lua-----------------

local MainScene = class("MainScene", cc.load("mvc").ViewBase)

MainScene.RESOURCE_FILENAME = "MainScene.csb"

function MainScene:onCreate()

    release_print("MainScene")

    

    local layer = cc.Layer:create()  

    --test:which image will be show? (res/Images/blocks.png, update/Images/blocks.png)

    --result:update/Images/blocks.png

    local background1 = cc.Sprite:create("Images/blocks.png")

    background1:setPosition(cc.p(100, 100))   

    layer:addChild(background1, 2)

    --result:update/Images/sakountala.jpg

    local background2 = cc.Sprite:create("Images/sakountala.jpg")

    background2:setPosition(cc.p(300, 700))   

    layer:addChild(background2, 3)

    --test the image in res:res/Images/myDaisy_Flower.jpg

    local background3 = cc.Sprite:create("Images/myDaisy_Flower.jpg")

    background3:setPosition(cc.p(600, 500))   

    layer:addChild(background3, 3)

    

    self:addChild(layer)  

end

return MainScene

(6)运行

若是运行成功,应该会在界面上看到下载文件的进度百分百,下载完成后会跳转到主界面,即以cocos2dx的logo

为背景,3张图片分别在屏幕左、中、右。

另外,在项目路径下多了一个update文件夹,其中就是从ftp服务器下载的文件。

4.测试整包更新

(1)创建路径

E:/myftp/apk/

apk--

--test.apk      //此是安卓安装文件

(2)经过测试发现AssetsManagerEx不能实现大文件的传输,故这里调用Android、iOS自身的下载方法

MainActivity.java---------

public void DownloadApk (final String url) {
Thread thread = new Thread() {
public void run () {
try {
DownloadingApk(url);
}catch(Exception e) {
Log.e("download",e.getMessage());
}
}
};
thread.start();

}

void DownloadingApk (String url) throws IOException {
String[] fileNames = url.split("|");
String fileName = fileNames[1];
URL myUrl = new URL(url.replace("|","/"));
URLConnection conn = myUrl.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
int fileSize = conn.getContentLength();
if(fileSize <= 0)
System.out.println("fileSize <= 0");
if(is == null)
System.out.println("stream is null");

if(fileSize > 0 && is != null) {
FileOutputStream fos = new FileOutputStream(Environment.getExternalStorageDirectory() + "/" + fileName);
byte[] buf = new byte[1024];
int downloadFileSize = 0;
do {
int numRead = is.read(buf);
if(numRead == -1)
break;
fos.write(buf,0,numRead);
downloadFileSize += numRead;
//更新登录界面的下载进度条
float num = (float)downloadFileSize/fileSize;
...
}while(true);
InstallApk(fileName); //安装
fos.close();
}else {
...
}

try {
is.close();
}catch (Exception e) {
}

}

void InstallApk (String apkName) {
Log.d("install",apkName);
String fileName = Environment.getExternalStorageDirectory() + "/" + apkName;
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(fileName)), "application/vnd.android.package-archive");
startActivity(intent);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cocos2d-x