LoginSignup
12

More than 5 years have passed since last update.

cocos2dx lua AssetsManagerEx android実験

Posted at

cocos2dx 3.5での実験

やりたいこと

  • ブラウザと同じぐらいに更新を行いやすくしたい。
  • アップデートなしでロジックの修正をできるようにしたい。

以上2点の検証をAssetsManagerExをつかってどこまでできるのか
検証してみました。(androidのみ)

クライアント側

こちらの記事をみてassetmanagerexすごい!!
luaコードもassetに含められるみたいなので実験してみました。
(iosは未確認)

src/main.lua

cc.FileUtils:getInstance():setPopupNotify(false)
cc.FileUtils:getInstance():addSearchPath("src/")
cc.FileUtils:getInstance():addSearchPath("res/")
cc.FileUtils:getInstance():addSearchPath(cc.FileUtils:getInstance():getWritablePath() .. "test/src/")
cc.FileUtils:getInstance():addSearchPath(cc.FileUtils:getInstance():getWritablePath() .. "test/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
    print(msg)
end

assetのダウンロード先をtestにしたのでそれにあわせてパスを通した

src/app/views/MainScene.lua

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

MainScene.RESOURCE_FILENAME = "MainScene.csb"


MainScene.MANIFEST = "project.manifest"
MainScene.STRAGE_PATH = "test"

function MainScene:onCreate()

    local root = self:getResourceNode()
    local progress = root:getChildByName("Loading")
    local text = root:getChildByName("LoadingLabel")

    local am = cc.AssetsManagerEx:create(MainScene.MANIFEST, cc.FileUtils:getInstance():getWritablePath() .. MainScene.STRAGE_PATH)
    am:retain()

    if not am:getLocalManifest():isLoaded() then
        printInfo("Fail to update assets, step skipped.")
        self:getApp():enterScene("HomeScene")
    else
        local function onUpdateEvent(event)
            local eventCode = event:getEventCode()
            printInfo("AssetmanagerEx:EventCode:%d:%s", eventCode, event:getMessage())
            if eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_NO_LOCAL_MANIFEST then
                print("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
                printInfo("progress:%f", percent)
                text:setString(strInfo)
                progress:setPercent(percent)
            elseif eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_DOWNLOAD_MANIFEST or 
                eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_PARSE_MANIFEST then
                print("Fail to download manifest file, update skipped.")
            elseif eventCode == cc.EventAssetsManagerEx.EventCode.NEW_VERSION_FOUND then
                print("Fail to download new version nound")
            elseif eventCode == cc.EventAssetsManagerEx.EventCode.ASSET_UPDATED then
                print("asset updated")
            elseif eventCode == cc.EventAssetsManagerEx.EventCode.UPDATE_FAILED then
                print("update failed")
            elseif eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_DECOMPRESS then
                print("error decompress")
            elseif eventCode == cc.EventAssetsManagerEx.EventCode.ALREADY_UP_TO_DATE or 
                eventCode == cc.EventAssetsManagerEx.EventCode.UPDATE_FINISHED then
                print("Update finished.")
                self:getApp():enterScene("TestScene")
            elseif eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_UPDATING then
                print("Asset ", event:getAssetId(), ", ", event:getMessage())
            end
        end

        local listener = cc.EventListenerAssetsManagerEx:create(am, onUpdateEvent)
        cc.Director:getInstance():getEventDispatcher():addEventListenerWithFixedPriority(listener, 1)
        am:update()
    end




end


return MainScene

ここで実際にTestScene.luaはサーバ側にあります。

いろいろとeventcodeの条件分岐があるけど、manifestのパースエラーとか
versionのmanifestがないとかのエラーなのでとりあえずログをはくだけに

MainScene.cbsはcocos builderで作成した適当なページです。
ローディングの実験もしたかったのでプログレスバーを含めました。

res/project.manifest
{
        "packageUrl" : "http://cocos2dx.xperia.biz/packageUrl",
        "remoteManifestUrl" : "http://cocos2dx.xperia.biz/remoteManifestUrl.manifest",
        "remoteVersionUrl" : "http://cocos2dx.xperia.biz/remoteVersionUrl.manifest",
        "version" : "1.0.0",
        "engineVersion" : "3.5",
        "assets" : {
        },
    "searchPaths" : [
    ]
}

ローカルのマニフェストファイルはこんな感じに

サーバ側

いよいよ問題のサーバ側の設定に

$ tree ./
./
├── cdn
│   ├── images
│   │   ├── Cute-Ball-Favorites-icon.png
│   │   └── ball.png
│   ├── res
│   │   └── TestScene.csb
│   ├── src
│   │   └── app
│   │       └── views
│   │           └── TestScene.lua
│   └── zip
│       └── compressed.zip
├── remoteManifestUrl.manifest
└── remoteVersionUrl.manifest

7 directories, 7 files

今回はmanifestべたで書いています。

remoteManifestUrl.manifest
{
    "packageUrl" : "http://cocos2dx.xperia.biz/cdn",
    "remoteManifestUrl" : "http://cocos2dx.xperia.biz/remoteManifestUrl.manifest",
    "remoteVersionUrl" : "http://cocos2dx.xperia.biz/remoteVersionUrl.manifest",
    "version" : "1.1.5", 
    "engineVersion" : "3.5", 
    "assets" : {
        "images/Cute-Ball-Favorites-icon.png" : { "md5" : "....." },
        "images/ball.png" : { "md5" : "..." }, 
        "zip/compressed.zip" : { "md5" : "...", "compressed" : true }, 
        "src/app/views/TestScene.lua" : { "md5" : "b84dfe61005304a7dba589896bf16c6e" },
        "res/TestScene.csb" : { "md5" : "..." }
    }, 
    "searchPaths" : [] 
}

versionの値は試行錯誤した回数ということでお察しを

remoteVersionUrl.manifest
{
    "packageUrl" : "http://cocos2dx.xperia.biz/packageUrl",
    "remoteManifestUrl" : "http://cocos2dx.xperia.biz/remoteManifestUrl.manifest",
    "remoteVersionUrl" : "http://cocos2dx.xperia.biz/remoteVersionUrl.manifest",
    "version" : "1.1.5", 
    "engineVersion" : "3.5"
}
cdn/src/app/views/TestScene.lua

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

TestScene.RESOURCE_FILENAME = "TestScene.csb"


function TestScene:onCreate()
    local root = self:getResourceNode()

    display.newSprite("images/Cute-Ball-Favorites-icon.png")
            :addTo(root)

    display.newSprite("zip/compressed/info-148099_1280.png")
            :addTo(root)
end


return TestScene

zip圧縮したものもちゃんと解凍して使えた。

そしてここで重要なのがversionをかえただけでは更新されなくて
md5の値に差があると更新してくれる作りらしい
md5の値がkeyとなっていると思ってよさそう。
TestScene.luaだけmd5ちゃんといれているのは
最初は他と同じで...として、versionだけ更新していたけど
更新されいと気づいたので

画像はいちおうgoogle検索でライセンス「改変後の再利用が許可された画像」
にして実験しました。

試していないけど、fontも音声もassetに含められそう。

androidでしか試してないけど何でも更新できるのではと感じるほど。

感想

なんでも更新できる。
luaを配信する際は難読化は必須かなと。
極論、インストール型ゲームプラットフォームアプリをつくれる気がする。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12