</pre><span style="font-size:18px;">一直一来都是用c++来写游戏,最近学lua主要是因为lua更新比较方便,cocos提供了AssetsManager类可以进行一些资源包的更新,但是不够灵活,AssetsManagerEx 是AssetsManager的增强版本,提供了比AssetsManager更加灵活的更新方式<strong>使用AssetsManagerEx的方法:</strong></span><p><span style="font-size:18px;color:#cc0000;"><strong>添加必要的头文件</strong></span></p><p><span style="font-size:18px;"></span><pre name="code" class="cpp">#include "extensions/cocos-ext.h" USING_NS_CC_EXT;@H_404_5@ 创建AssetsManagerEx对象@H_404_5@
AssetsManagerEx* HelloWorld::getAssetsManagerEx() { static AssetsManagerEx *amEx = nullptr; if (!amEx) { amEx = AssetsManagerEx::create("project.manifest",m_pathToSaveEx); amEx->retain(); if (amEx->getLocalManifest()->isLoaded()) { log("Fail to update assets,step skipped."); } auto listener = EventListenerAssetsManagerEx::create(amEx,CC_CALLBACK_1(HelloWorld::onAssetsEvent,this)); Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(listener,1); } return amEx; }@H_404_5@ AssetsManagerEx在创建的时候需要传入两个参数: 清单文件 和 更新目录 @H_404_5@
清单文件project.manifest
下面一个清单文件的一些具体内容@H_404_5@{ "packageUrl" : "<a target=_blank href="http://tools.itharbors.com/assets_manager/AMTestScene1/">http://tools.itharbors.com/assets_manager/AMTestScene1/</a>","remoteManifestUrl" : "<a target=_blank href="http://tools.itharbors.com/assets_manager/AMTestScene1/project_dev.manifest">http://tools.itharbors.com/assets_manager/AMTestScene1/project_dev.manifest</a>","remoteVersionUrl" : "<a target=_blank href="http://tools.itharbors.com/assets_manager/AMTestScene1/version_dev.manifest">http://tools.itharbors.com/assets_manager/AMTestScene1/version_dev.manifest</a>","version" : "1.2.0","engineVersion" : "3.x dev",</p><p> "assets" : { "Images/assetMgrBackground1.jpg" : { "md5" : "....." },"Images/ball.png" : { "md5" : "..." },"Images/blocks.png" : { "md5" : "..." },"compressed.zip" : { "md5" : "...","compressed" : true } },"searchPaths" : [ ] }packageUrl是资源下载的地址@H_404_5@ remoteManifestUrl是获取远程清单文件的url@H_404_5@ remoteVersionUrl是获取远程版本清单文件的url@H_404_5@
assets 里面包含的则是文件的清单
@H_404_5@
另一个是资源的更新目录,下载好的资源就在该目录下
单独创建一个函数来获取更新目录
void HelloWorld::InitDownLoadDirEx() { m_pathToSaveEx = FileUtils::getInstance()->getWritablePath(); #if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32) DIR *pDir = NULL; pDir = opendir(m_pathToSaveEx.c_str()); if (!pDir) { mkdir(m_pathToSaveEx.c_str(),S_IRWXU | S_IRWXG | S_IRWXO); } #else if ((GetFileAttributesA(m_pathToSaveEx.c_str())) == INVALID_FILE_ATTRIBUTES) { CreateDirectoryA(m_pathToSaveEx.c_str(),0); } #endif CCLOG("InitDownLoadDirEx end"); }不同平台的目录创建方式有点不同 @H_404_5@ @H_404_5@ 处理更新事件@H_404_5@ AssetsManagerEx的监听处理比AssetsManager更简单,只需要注册一个监听,上面代码里面已经有了@H_404_5@ 下面是监听函数的内容@H_404_5@
@H_404_5@
void HelloWorld::onAssetsEvent(EventAssetsManagerEx* pEvent) { switch (pEvent->getEventCode()) { case EventAssetsManagerEx::EventCode::ERROR_NO_LOCAL_MANIFEST: { log("没有本地清单文件"); } break; case EventAssetsManagerEx::EventCode::ERROR_DOWNLOAD_MANIFEST: { log("下载远程清单文件失败"); } break; case EventAssetsManagerEx::EventCode::ERROR_PARSE_MANIFEST: { log("解析清单文件失败"); } break; case EventAssetsManagerEx::EventCode::NEW_VERSION_FOUND: { log("找到新版本"); } break; case EventAssetsManagerEx::EventCode::ALREADY_UP_TO_DATE: { log("更新完成"); } break; case EventAssetsManagerEx::EventCode::UPDATE_PROGRESSION: { log("更新中"); char szBuf[256] = ""; sprintf(szBuf,"%s,%0.2f,%0.2f",pEvent->getAssetId().c_str(),pEvent->getPercentByFile(),pEvent->getPercent()); m_pProcessLabel->setString(szBuf); } break; case EventAssetsManagerEx::EventCode::ASSET_UPDATED: { log("检测更新"); } break; case EventAssetsManagerEx::EventCode::ERROR_UPDATING: { log("更新出错"); } break; case EventAssetsManagerEx::EventCode::UPDATE_FINISHED: { log("更新完成"); } break; case EventAssetsManagerEx::EventCode::UPDATE_Failed: { log("更新失败"); } break; case EventAssetsManagerEx::EventCode::ERROR_DECOMPRESS: { log("解压出错"); } break; default: break; } }注意:@H_404_5@ pEvent->getPercentByFile()是获取的整个更新进度@H_404_5@
pEvent->getPercent()是获取的当前文件的下载进度
@H_404_5@
启动更新@H_404_5@ 很简单
InitDownLoadDirEx(); getAssetsManagerEx()->update();@H_404_5@ AssetsManagerEx在更新文件的时候首先会访问本地的清单文件,获取其中的remoteManifestUrl和remoteVersionUrl,并且通过它们得到最新的清单文件和版本信息,将远程的清单内容与本地的清单做比较,如果远程的版本号大于本地版本号则比对assets项,将与本地清单不同的文件项都下载下来,然后覆盖本地的清单文件