什么是热更新?
游戏客户端启动时,主动请求服务端检查版本号,并更新资源到本地。
应用场景:
情况一:游戏客户端已经发布了,但突然发现有个比较严重的BUG需要修复。这时需要更新游戏的代码(Lua代码)。
情况二:情人节到了,需要搞个活动,在游戏中营造一个节日氛围。这时,需要更新游戏资源或增加一些功能。
好处:不需要重新打包和提交应用到市场等待审核。
AssetsManager
在Cocos2d-x中已经封装了用于实现热更新功能的类,就是AssetsManager。
API说明:
// 检测是否有版本更新
virtual bool checkUpdate();
// 下载更新的资源包并解压到下载路径
virtual voID update();
// 获取当前客户端版本号
std::string getVersion();
// 删除客户端版本号
voID deleteVersion();
// 设置下载回调(AssetsManagerDelegateProtocol)
voID setDelegate(AssetsManagerDelegateProtocol *delegate);
// 设置连接超时时间(单位:秒)
voID setConnectionTimeout(unsigned int timeout);
// 设置从服务端下载资源包的url
voID setPackageUrl(const char* packageUrl);
// 设置服务端获取版本号的url
voID setVersionfileUrl(const char* versionfileUrl);
// 设置资源保存路径
voID setStoragePath(const char* storagePath);
因为AssetsManager使用了pthread库,所以需要在win32工程中需要包含pthread库所在目录。
VS在工程属性——C/C++——常规——附加包含目录中添加:$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32\pthread
示例工程
该工程使用Cocos2d-x2.1.6和VS2012。【点击下载源码】
把工程放到引擎projects目录下即可。
#include "UpdateLayer.h"#include "HelloWorldScene.h"#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)#include <dirent.h>#include <sys/stat.h>#endifbool UpdateLayer::init(){ if (cclayer::init()) { // 设置资源包下载目录 m_downloadDir = CCfileUtils::sharedfileUtils()->getWritablePath(); m_downloadDir += "download"; // 设置代理 getAssetsManager()->setDelegate(this); // 添加资源包下载路径到搜索路径,优先搜索更新的资源 std::vector<std::string> searchPaths = CCfileUtils::sharedfileUtils()->getSearchPaths(); searchPaths.insert(searchPaths.begin(),m_downloadDir); CCfileUtils::sharedfileUtils()->setSearchPaths(searchPaths); // 提示 m_label = cclabelTTF::create("","Arial",18); m_label->setAnchorPoint(ccp(1,0.5)); m_label->setposition(ccp(465,20)); addChild(m_label); // 菜单 Ccmenu* menu = Ccmenu::create(); menu->setposition(CCPointZero); addChild(menu); CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); // 重置 CcmenuItemFont* itemreset = CcmenuItemFont::create("reset",this,menu_selector(UpdateLayer::reset)); itemreset->setposition(ccp(visibleSize.wIDth/2,50)); menu->addChild(itemreset); // 获取当前版本号 CcmenuItemFont* itemGetClIEntVersion = CcmenuItemFont::create("getClIEntVersion",menu_selector(UpdateLayer::getClIEntVersion)); itemGetClIEntVersion->setposition(ccp(visibleSize.wIDth/2,100)); menu->addChild(itemGetClIEntVersion); // 获取服务器最新版本 CcmenuItemFont* itemGetServerVersion = CcmenuItemFont::create("checkUpdate",menu_selector(UpdateLayer::checkUpdate)); itemGetServerVersion->setposition(ccp(visibleSize.wIDth/2,150)); menu->addChild(itemGetServerVersion); // 更新版本 CcmenuItemFont* itemUpdateVersion = CcmenuItemFont::create("updateVersion",menu_selector(UpdateLayer::update)); itemUpdateVersion->setposition(ccp(visibleSize.wIDth/2,200)); menu->addChild(itemUpdateVersion); // 进入场景 CcmenuItemFont* itemEnterScene = CcmenuItemFont::create("enterScene",menu_selector(UpdateLayer::enterScene)); itemEnterScene->setposition(ccp(visibleSize.wIDth/2,250)); menu->addChild(itemEnterScene); return true; } return false;}AssetsManager* UpdateLayer::getAssetsManager(){ static AssetsManager* s_assetsManager = NulL; if (s_assetsManager ==NulL) { s_assetsManager = new AssetsManager("https://Coding.net/u/linchaolong/p/Cocos2d-x_HotUpdate/git/raw/master/test.zip",//下载资源包的url "https://Coding.net/u/linchaolong/p/Cocos2d-x_HotUpdate/git/raw/master/version",// 获取服务端版本号的url m_downloadDir.c_str()); // 资源保存路径 s_assetsManager->setDelegate(this); s_assetsManager->setConnectionTimeout(3); } cclOG("save path : %s",s_assetsManager->getStoragePath()); return s_assetsManager;}voID UpdateLayer::initDownloadDir(){ // 如果下载目录不存在,则创建下载目录#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32) DIR *pDir = NulL; pDir = opendir (m_downloadDir.c_str()); if (! pDir) { mkdir(m_downloadDir.c_str(),S_IRWXU | S_IRWXG | S_IRWXO); }#else if ((GetfileAttributesA(m_downloadDir.c_str())) == INVALID_file_ATTRIBUTES) { CreateDirectoryA(m_downloadDir.c_str(),0); }#endif}voID UpdateLayer::deleteDir(std::string dir){ // Remove downloaded files#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32) std::string command = "rm -r "; // Path may include space. command += "\"" + dir + "\""; system(command.c_str());#else std::string command = "rd /s /q "; // Path may include space. command += "\"" + dir + "\""; system(command.c_str());#endif}voID UpdateLayer::onError(cocos2d::extension::AssetsManager::ErrorCode errorCode){ switch (errorCode) { case cocos2d::extension::AssetsManager::kCreatefile: cclOG("error : create file failure"); m_label->setString("error : create file failure"); break; case cocos2d::extension::AssetsManager::kNetwork: cclOG("error : no network"); m_label->setString("error : no network"); break; case cocos2d::extension::AssetsManager::kNoNewVersion: cclOG("error : no new version"); m_label->setString("error : no new version"); break; case cocos2d::extension::AssetsManager::kUncompress: cclOG("error : uncompress file error"); m_label->setString("error : uncompress file error"); break; default: break; }}voID UpdateLayer::onProgress(int percent){ char progress[80]; memset( progress,'#ifndef __HOTUPDATER_H__#define __HOTUPDATER_H__#include "cocos2d.h"USING_NS_CC;#include "cocos-ext.h"USING_NS_CC_EXT;#include "AssetsManager/AssetsManager.h"// 热更新实现示例class UpdateLayer:public cclayer,public AssetsManagerDelegateProtocol{public: static CCScene* scene(){ CCScene* scene = CCScene::create(); scene->addChild(UpdateLayer::create()); return scene; }; static UpdateLayer* create(){ UpdateLayer* pLayer = new UpdateLayer; if (pLayer && pLayer->init()) { pLayer->autorelease(); return pLayer; } delete pLayer; return NulL; }; // 初始化 bool init(); // 下载回调函数 virtual voID onError(cocos2d::extension::AssetsManager::ErrorCode errorCode); virtual voID onProgress(int percent); virtual voID onSuccess(); // 菜单回调函数 voID reset(CCObject* pSender); // 重置版本 voID getClIEntVersion(CCObject* pSender); // 获取当前客户端版本号 voID checkUpdate(CCObject* pSender); // 检查是否有版本更新 voID update(CCObject* pSender); // 更新版本 voID enterScene(CCObject* pSender); // 进入场景,如果未更新屏幕中间会显示叹号的图片,更新后会显示另一张图片protected: // 初始化下载目录 voID initDownloadDir(); // 删除目录 voID deleteDir(std::string dir);private: cclabelTTF* m_label; std::string m_downloadDir; AssetsManager* getAssetsManager(); };#endif',sizeof(progress) ); snprintf(progress,sizeof(progress),"hotupdate downloading %d%%",percent); cclOG("percent=%d %s",percent,progress); m_label->setString(progress);}voID UpdateLayer::onSuccess(){ cclOG("download success."); m_label->setString("download success.");}voID UpdateLayer::update(CCObject* pSender){ // 初始化下载目录 initDownloadDir(); // 下载更新包 getAssetsManager()->update();}voID UpdateLayer::reset(CCObject* pSender){ if ("" != m_downloadDir) { // 删除下载目录 deleteDir(m_downloadDir); } // 删除版本号 getAssetsManager()->deleteVersion();}voID UpdateLayer::getClIEntVersion(CCObject* pSender){ CCString* msg = CCString::createWithFormat("current clIEnt version : %s",getAssetsManager()->getVersion().c_str()); cclOG("%s",msg->getCString()); m_label->setString(msg->getCString());}voID UpdateLayer::checkUpdate(CCObject* pSender){ if (getAssetsManager()->checkUpdate()) { cclOG("has new version"); m_label->setString("has new version"); }else{ cclOG("has not new version"); m_label->setString("has not new version"); }}voID UpdateLayer::enterScene(CCObject* pSender){ CCDirector::sharedDirector()->replaceScene(HelloWorld::scene());}
项目地址:
https://coding.net/u/linchaolong/p/Cocos2d-x_HotUpdate/git
转自:http://blog.csdn.net/linchaolong/article/details/42321767
总结以上是内存溢出为你收集整理的【Cocos2d-x】实现资源热更新全部内容,希望文章能够帮你解决【Cocos2d-x】实现资源热更新所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)