--什麼是熱更新? git
遊戲客戶端啓動時,主動請求服務端檢查版本號,並更新資源到本地. 服務器
應用場景: 函數
狀況一:遊戲客戶端已經發布了,但忽然發現有個比較嚴重的bug須要修復。這時須要更新遊戲的代碼(Lua代碼)。 this
狀況二:情人節到了,須要搞個活動,在遊戲中營造一個節日氛圍。這時,須要更新遊戲資源或增長一些功能。 url
好處:不須要從新打包和提交應用到市場等待審覈. spa
-- 熱更新流程-->遊戲啓動-->檢查版本 .net
-->有版本更新-->初始化下載路徑 代理
-->設置搜索目錄路徑(優先搜索下載目錄資源) code
-->下載更新zip包-->解壓zip包-->進入遊戲 orm
-->沒有版本更新-->進入遊戲
--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:......)