--什么是热更新?
游戏客户端启动时,主动请求服务端检查版本号,并更新资源到本地.
应用场景:
情况一:游戏客户端已经发布了,但突然发现有个比较严重的bug需要修复。这时需要更新游戏的代码(Lua代码)。
情况二:情人节到了,需要搞个活动,在游戏中营造一个节日氛围。这时,需要更新游戏资源或增加一些功能。
好处:不需要重新打包和提交应用到市场等待审核.
-- 热更新流程-->游戏启动-->检查版本
-->有版本更新-->初始化下载路径
-->设置搜索目录路径(优先搜索下载目录资源)
-->下载更新zip包-->解压zip包-->进入游戏
-->没有版本更新-->进入游戏
--cocos2dx 已经封装好了AssetsManager,主要用于热更新。
----------------------------------------------------------------------------------------------- 昨天没完成的东西,今天 继续补。唉,东西贵在坚持,本人是也是刚学cocos2dx,对于一个实习来说,有点时间写东西,我觉得是件很祝福的东西,也希望能通过文章来交更多的朋友,不管你来至哪个地球。(友人A:有完没完,说好的热更新呢。)好吧,废话不多说,友人A 是我内心的一个角色,大家请无视。(友人A: .......)
-- 关于AssetsManager资产管理类,主要是用来更新资源的,(友人A:..老兄说一下这个AssetsManager..都有些什么方法..),那接下来的说一下API。
virtual bool checkUpdate() |
检测是否有版本更新 |
virtual void update(); |
下载更新的资源包并解压到下载路径 |
void setDelegate(); |
设置下载回调 |
void setConnectionTimeout(unsigned int timeout); |
连接超时 |
(友人A:...喂喂,只给这些有个球用啊..)
好吧,我们来看一下实战吧。
这个例程是用的是Cocos2dx 上的helloworld修改的,定义一个updateLayer类,以下是头文件。
#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(); };
#include "UpdateLayer.h" #include "HelloWorldScene.h" #if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32) #include <dirent.h> #include <sys/stat.h> #endif bool 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",this,menu_selector(UpdateLayer::getClientVersion)); itemGetClientVersion->setPosition(ccp(visibleSize.width/2, 100)); menu->addChild(itemGetClientVersion); // 获取服务器最新版本 CCMenuItemFont* itemGetServerVersion = CCMenuItemFont::create("checkUpdate",this,menu_selector(UpdateLayer::checkUpdate)); itemGetServerVersion->setPosition(ccp(visibleSize.width/2, 150)); menu->addChild(itemGetServerVersion); // 更新版本 CCMenuItemFont* itemUpdateVersion = CCMenuItemFont::create("updateVersion",this,menu_selector(UpdateLayer::update)); itemUpdateVersion->setPosition(ccp(visibleSize.width/2, 200)); menu->addChild(itemUpdateVersion); // 进入场景 CCMenuItemFont* itemEnterScene = CCMenuItemFont::create("enterScene",this,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);//callBack 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, '\0', 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()); }
在hellowrold 跳转场景时,就跳到一个updateLayer场景。
(友人A:.....嗯,不对,好像在哪见过,时间也不过,也在不是上班,你吖的在写东西,你老板知道吗)
........我想说Duang...不过确实这东西的出处:http://blog.csdn.net/linchaolong/article/details/42321767
不过我想说的,Fuck the regulation,有时候不要过自己太大的压力,人就要活得自在点好,也不过几十年,还要有不明白的,可以给我留言。
(友人A:......)