官术网_书友最值得收藏!

3.1 使用AssetsManagerEx

AssetsManagerEx的使用非常簡單,需要用到兩個類,AssetsManagerEx和EventListenerAssetsManagerEx, AssetsManagerEx用來執(zhí)行增量更新,EventListenerAssetsManagerEx用來監(jiān)聽增量更新中觸發(fā)的各種事件,如各種更新失敗的原因、進度更新以及更新成功等事件。使用的示例代碼如下。

        //傳入Manifest路徑和緩存路徑,創(chuàng)建AssetsManagerEx對象
        auto AssetsManager = AssetsManagerEx::create(manifestPath, storagePath);
        AssetsManager->retain();
        //傳入AssetsManagerEx對象和回調(diào)函數(shù),EventListenerAssetsManagerEx可以捕獲
        AssetsManagerEx觸發(fā)的各種事件
        auto listener = EventListenerAssetsManagerEx::create(AssetsManager, callback);
        //監(jiān)聽事件需要先將EventListenerAssetsManagerEx添加到EventDispatcher
        Director::getInstance()->getEventDispatcher()->addEventListenerWithFixe
        dPriority(listener , 1);
        //最后執(zhí)行AssetsManagerEx的update()方法自動更新
        AssetsManager->update();

上面的代碼簡單描述了使用AssetsManagerEx的步驟,接下來詳細介紹一下AssetsManagerEx的使用。首先是AssetsManagerEx,增量更新的核心功能都由AssetsManagerEx實現(xiàn),需要傳入Manifest文件的路徑和相對于WritablePath可寫路徑的緩存路徑來初始化AssetsManagerEx。Manifest文件是用于檢查版本更新的文件,在后面會詳細介紹,緩存路徑指的是增量更新文件下載后存儲的路徑,由于權(quán)限等問題,從服務(wù)器下載的資源并不能替換程序安裝目錄下的原始資源,所以我們會下載到一個可寫的緩存目錄下,在加載資源的時候優(yōu)先加載緩存目錄中的資源,如找不到則再去加載安裝目錄中的資源。AssetsManagerEx的常用接口如下。

        //檢查是否有更新
        void checkUpdate();
        //自動檢查是否有更新,有則自動更新
        void update();
        //下載更新失敗的部分資源
        void downloadFailedAssets();
        //獲取本地Manifest對象
        const Manifest* getLocalManifest() const;

update()方法和checkUpdate()方法的區(qū)別是,update()方法會檢查更新并自動執(zhí)行更新,而checkUpdate()方法則只是檢查是否有更新,如果希望實現(xiàn)一些非強制性的更新,或者在更新之前彈出一個對話框,由玩家來決定是否更新等,就可以使用checkUpdate()方法。

checkUpdate()方法的返回值是void,那么我們?nèi)绾沃朗欠裥枰履兀客ㄟ^消息!我們需要創(chuàng)建一個EventListenerAssetsManagerEx對象來監(jiān)聽AssetsManagerEx觸發(fā)的消息,當檢查到新版本時,AssetsManagerEx會觸發(fā)NEW_VERSION_FOUND消息,而不需要更新時,則會觸發(fā)ALREADY_UP_TO_DATE消息,AssetsManagerEx會觸發(fā)的所有消息如下。

        enum class EventCode
        {
            ERROR_NO_LOCAL_MANIFEST,    //本地Manifest錯誤
            ERROR_DOWNLOAD_MANIFEST,    //下載Manifest失敗
            ERROR_PARSE_MANIFEST,       //解析Manifest失敗
            NEW_VERSION_FOUND,          //檢查到新版本
            ALREADY_UP_TO_DATE,         //已經(jīng)是最新版本
            UPDATE_PROGRESSION,         //更新進度刷新消息
            ASSET_UPDATED,              //有資源下載成功
            ERROR_UPDATING,             //有文件下載失敗
            UPDATE_FINISHED,            //更新完成
            UPDATE_FAILED,              //更新失敗
            ERROR_DECOMPRESS            //解壓文件失敗
        };

可調(diào)用EventListenerAssetsManagerEx的create()方法傳入AssetsManagerEx對象和回調(diào)函數(shù),創(chuàng)建對象,然后將EventListenerAssetsManagerEx對象添加到EventDispatcher中,當消息觸發(fā)時會調(diào)用回調(diào)函數(shù),將事件對象傳入到回調(diào)函數(shù)中。示例教程中的TutorialUpdateAssets示例演示了如何使用AssetsManagerEx進行熱更新,示例代碼如下。

        std::string storage = FileUtils::getInstance()->getWritablePath() +
        "test1/";
        auto assetMgrEx = AssetsManagerEx::create("project.manifest", storage);
        assetMgrEx->retain();

        auto amListener = cocos2d::extension::EventListenerAssetsManagerEx::
        create(assetMgrEx, [this](EventAssetsManagerEx* event){
            switch (event->getEventCode())
            {
            case EventAssetsManagerEx::EventCode::ERROR_NO_LOCAL_MANIFEST:
            {
              //本地Manifest文件錯誤
              CCLOG("No local manifest file found, skip assets update.");
              this->onLoadEnd();
            }
              break;

            case EventAssetsManagerEx::EventCode::UPDATE_PROGRESSION:
            {
              //更新進度
              std::string assetId = event->getAssetId();
              float percent = event->getPercent();
              std::string str;
              if (assetId == AssetsManagerEx::VERSION_ID)
              {
                  str = StringUtils::format("Version file: %.2f", percent) + "%";
              }
              else if (assetId == AssetsManagerEx::MANIFEST_ID)
              {
                  str = StringUtils::format("Manifest file: %.2f", percent) + "%";
              }
              else
              {
                  str = StringUtils::format("%.2f", percent) + "%";
              }
              CCLOG("asset %s download %s Percent", assetId.c_str(), str.c_str());
            }
              break;
            case EventAssetsManagerEx::EventCode::ERROR_DOWNLOAD_MANIFEST:
            case EventAssetsManagerEx::EventCode::ERROR_PARSE_MANIFEST:
            {
              //下載或解析Manifest文件失敗
              CCLOG("Fail to download manifest file, update skipped.");
              this->onLoadEnd();
            }
              break;
            case EventAssetsManagerEx::EventCode::ALREADY_UP_TO_DATE:
            case EventAssetsManagerEx::EventCode::UPDATE_FINISHED:
            {
              //最新版本不需要更新或更新完成
              CCLOG("Update finished. %s", event->getMessage().c_str());
              this->onLoadEnd();
            }
              break;
            case EventAssetsManagerEx::EventCode::UPDATE_FAILED:
            {
              //更新失敗
              CCLOG("Update failed. %s", event->getMessage().c_str());
              event->getAssetsManagerEx()->downloadFailedAssets();
              this->onLoadEnd();
            }
              break;
            case EventAssetsManagerEx::EventCode::ERROR_UPDATING:
            {
              //更新資源失敗
              CCLOG("Asset %s : %s", event->getAssetId().c_str(), event->
              getMessage().c_str());
          }
              break;
          case EventAssetsManagerEx::EventCode::ERROR_DECOMPRESS:
          {
              //解壓失敗
              CCLOG("%s", event->getMessage().c_str());
          }
              break;
          default:
              break;
        );
        //自動檢查是否有更新,有則自動更新
        void update();
        //下載更新失敗的部分資源
        void downloadFailedAssets();
        //獲取本地Manifest對象
        const Manifest* getLocalManifest() const;
          }
        });
        //將EventListenerAssetsManagerEx添加到EventDispatcher中
        Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority
        (amListener, 1);
        assetMgrEx->update();

在回調(diào)函數(shù)中可以獲取EventAssetsManagerEx對象,從該對象中獲取消息ID、CURL錯誤碼、錯誤消息、資源ID、AssetsManagerEx、總的下載進度以及當前文件的下載進度等信息。

需要注意的是創(chuàng)建AssetsManagerEx時傳入的Manifest文件和下載路徑,我們傳入的project.manifest文件是安裝包中的一個Manifest文件,它記錄了本地的資源列表以及服務(wù)器的Manifest文件地址,后面會詳細介紹Manifest文件。下載路徑需要是一個可寫的路徑,所以需要獲取WritablePath作為前綴,注意不要和其他路徑混合在一起,這個路徑只用來存放增量更新更新下來的文件,不要將游戲的存檔等信息放到這個路徑下。

示例不論更新成功還是失敗,最終都會調(diào)用onLoadEnd()方法,在onLoadEnd()方法中創(chuàng)建一個Sprite,如果更新失敗會根據(jù)本地的圖片創(chuàng)建Sprite,如果更新成功則會根據(jù)更新下來的圖片創(chuàng)建Sprite。

        void TutorialUpdateAssets::onLoadEnd()
        {
            auto backgroundSprite = Sprite::create("Images/background1.jpg");
            addChild(backgroundSprite, 1);
            backgroundSprite->setPosition(Director::getInstance()->getWinSize()*0.5f);
        }
主站蜘蛛池模板: 新巴尔虎右旗| 青神县| 珠海市| 浠水县| 五指山市| 康平县| 巴里| 博野县| 吉首市| 缙云县| 许昌市| 临西县| 台山市| 嵊泗县| 富民县| 罗甸县| 抚宁县| 枞阳县| 富裕县| 新巴尔虎右旗| 宁都县| 横山县| 旺苍县| 平阴县| 高陵县| 伽师县| 江阴市| 明光市| 铜山县| 界首市| 牟定县| 乌兰察布市| 信宜市| 富民县| 和田县| 项城市| 枝江市| 泰州市| 新闻| 科技| 桦甸市|