从2.1.2版本开始,2dx在libExtensions下添加了一个AssetsManager类用于资源的在线更新和简单的版本管理,同时添加了AssetsManagerTest项目示范了AssetsManager类的用法。

运行AssetsManagerTest,可以看到菜单界面

点击enter,看到下面的画面

重新运行程序,点击update,可以看到后台的log

然后再点击enter,发现画面已经发生改变

重新运行程序,画面一直都是新的。
重新运行程序,点击reset,再点击enter,发现画面回到了旧画面


代码分析
程序创建了一个UpdateLayer,上面有三个menuitem,这个不用多说
当点击update时,程序调用getAssetsManager() 获取AssetsManager的实例,在getAssetsManager() 中应用了单例的模式,如果没有创建pAssetsManager则new一个,第一个参数是更新包地址,第二个参数是版本文件地址,第三个参数是本地存储路径

  1. void UpdateLayer::update(cocos2d::CCObject *pSender)
  2. {
  3. // update resources
  4. getAssetsManager()->update();
  5. isUpdateItemClicked = true;
  6. }
  7. AssetsManager* UpdateLayer::getAssetsManager()
  8. {
  9. static AssetsManager *pAssetsManager = NULL;
  10. if (! pAssetsManager)
  11. {
  12. pAssetsManager = new AssetsManager("https://raw.github.com/minggo/AssetsManagerTest/master/package.zip",//资源更新包地址
  13. "https://raw.github.com/minggo/AssetsManagerTest/master/version",//版本文件地址
  14. pathToSave.c_str()); //本地存储地址,见 createDownloadedDir()
  15. }
  16. return pAssetsManager;
  17. }
复制代码

获得实例后,调用 update() 方法

  1. void AssetsManager::update()
  2. {
  3. // 1. Urls of package and version should be valid;
  4. // 2. Package should be a zip file.
  5. if (_versionFileUrl.size() == 0 ||
  6. _packageUrl.size() == 0 ||
  7. std::string::npos == _packageUrl.find(".zip"))
  8. {
  9. cclOG("no version file url,or no package url,or the package is not a zip file");
  10. return;
  11. }
  12. // Check if there is a new version.
  13. if (! checkUpdate()) return; //检查是否需要更新
  14. // Is package already downloaded?
  15. string downloadedVersion = CCUserDefault::sharedUserDefault()->getStringForKey(KEY_OF_DOWNLOADED_VERSION);
  16. if (downloadedVersion != _version)
  17. {
  18. if (! downLoad()) return; //下载
  19. // Record downloaded version.
  20. CCUserDefault::sharedUserDefault()->setStringForKey(KEY_OF_DOWNLOADED_VERSION,_version.c_str());
  21. CCUserDefault::sharedUserDefault()->flush();
  22. }
  23. // Uncompress zip file.
  24. if (! uncompress()) return; //解压缩
  25. // Record new version code.
  26. CCUserDefault::sharedUserDefault()->setStringForKey(KEY_OF_VERSION,_version.c_str()); //更新本地版本号
  27. // Unrecord downloaded version code.
  28. CCUserDefault::sharedUserDefault()->setStringForKey(KEY_OF_DOWNLOADED_VERSION,"");
  29. CCUserDefault::sharedUserDefault()->flush();
  30. // Set resource search path.
  31. setSearchPath(); //更新资源搜索路径列表
  32. // Delete unloaded zip file.
  33. string zipfileName = _storagePath + TEMP_PACKAGE_FILE_NAME;
  34. if (remove(zipfileName.c_str()) != 0)
  35. {
  36. cclOG("can not remove downloaded zip file");
  37. }
  38. }
复制代码

update() 方法执行过程中,调用checkUpdate() 方法检查是否需要下载更新包

  1. bool AssetsManager::checkUpdate()
  2. {
  3. if (_versionFileUrl.size() == 0) return false;
  4. _curl = curl_easy_init();
  5. if (! _curl)
  6. {
  7. cclOG("can not init curl");
  8. return false;
  9. }
  10. // Clear _version before assign new value.
  11. _version.clear();
  12. CURLcode res;
  13. curl_easy_setopt(_curl,CURLOPT_URL,_versionFileUrl.c_str());
  14. curl_easy_setopt(_curl,CURLOPT_SSL_VERIFYPEER,0L);
  15. curl_easy_setopt(_curl,CURLOPT_WRITEFUNCTION,getVersionCode);
  16. curl_easy_setopt(_curl,CURLOPT_WRITEDATA,&_version);
  17. res = curl_easy_perform(_curl);
  18. if (res != 0)
  19. {
  20. cclOG("can not get version file content,error code is %d",res);
  21. curl_easy_cleanup(_curl);
  22. return false;
  23. }
  24. string recordedVersion = CCUserDefault::sharedUserDefault()->getStringForKey(KEY_OF_VERSION);
  25. if (recordedVersion == _version) //判断版本是否与本地版本相同,如果相同则更新搜索路径列表,并返回不需要更新
  26. {
  27. cclOG("there is not new version");
  28. // Set resource search path.
  29. setSearchPath(); //更新列表
  30. return false;
  31. }
  32. cclOG("there is a new version: %s",_version.c_str());
  33. return true;
  34. }
复制代码

检查的方法就是以指定的路径向服务器请求版本文件,然后比较内容是否与本地记录的版本(CCUserDefault::sharedUserDefault()->getStringForKey(KEY_OF_VERSION);)一致,一致则结束,不一致则返回需要更新,然后调用downLoad() 来下载,下载的过程中会回调progressFunc 来反馈进度,下载的过程应该是同步的阻塞模式(我没仔细跟进去分析,从代码的写法上猜测的),也就是下载过程中不能做其他操作。下载完成后,调用 uncompress() 解压缩到指定的路径。然后更新本地版本号为新版本号,并写文件(CCUserDefault::sharedUserDefault()->flush();)。最后调用setSearchPath() 将存储路径添加到搜索路径列表中去。

  1. void AssetsManager::setSearchPath()
  2. {
  3. vector<string> searchPaths = CCFileUtils::sharedFileUtils()->getSearchPaths(); //获得当前列表
  4. vector<string>::iterator iter = searchPaths.begin(); //获取列表的头
  5. searchPaths.insert(iter,_storagePath); //添加,添加后,新添加的路径在前
  6. CCFileUtils::sharedFileUtils()->setSearchPaths(searchPaths); //回写
  7. }
复制代码

2.1.2版本引擎对CCFileUtils 进行了重构,所谓的资源搜索路径列表就是指一个存有多个路径的序列,在搜索某个文件时,按照列表的顺序遍历(使用迭代器),依次测试文件是否存在,直到发现文件。如果列表以某种顺序组织,比如按版本号的降序排列,即先搜索新版本,后搜索旧版本,从而可以实现新版本资源替换旧版本资源的功能。

点击reset,删除已下载的文件

  1. void UpdateLayer::reset(cocos2d::CCObject *pSender)
  2. {
  3. // Remove downloaded files
  4. #if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
  5. string command = "rm -r ";
  6. // Path may include space.
  7. command += "\"" + pathToSave + "\"";
  8. system(command.c_str());
  9. #else
  10. string command = "rd /s /q ";
  11. // Path may include space.
  12. command += "\"" + pathToSave + "\"";
  13. system(command.c_str());
  14. #endif
  15. // Delete recorded version codes.
  16. getAssetsManager()->deleteVersion();
  17. createDownloadedDir();
  18. }
复制代码

点击enter,需要注意有一个判断是否点击过的update的判断,如果没有点击过则需要将新的路径手工添加到搜索列表中去,如果点击过则路径已经自动添加过了

  1. void UpdateLayer::enter(cocos2d::CCObject *pSender)
  2. {
  3. // Should set search resource path before running script if "update" is not clicked.
  4. // Because AssetsManager will set
  5. if (! isUpdateItemClicked) //判断是否需要手工添加搜索路径
  6. {
  7. vector<string> searchPaths = CCFileUtils::sharedFileUtils()->getSearchPaths();
  8. searchPaths.insert(searchPaths.begin(),pathToSave);
  9. CCFileUtils::sharedFileUtils()->setSearchPaths(searchPaths);
  10. }
  11. ccScriptEngineProtocol *pEngine = Scriptingcore::getInstance();
  12. ccScriptEngineManager::sharedManager()->setScriptEngine(pEngine);
  13. Scriptingcore::getInstance()->runScript("main.js");
  14. }
复制代码

总结 1、AssetsManager类 提供了一个很方便的更新资源的官方途径,这对手游特别是手机网游来说是一个很利好的消息,毕竟能够更新资源而不需要更新应用本身是可以减少用户流失的 2、版本管理的功能还较弱,目前的功能只能记录一个版本,即最新版本,如果能够多版本(更新历史) 管理的话,会更方便 3、应用启动后,搜索路径还需要手工添加,应该做成与版本关联的方式,根据本地的版本记录来自动的添加

cocos2d-x使用AssetsManager类实现资源的在线更新的更多相关文章

  1. ios – 如何处理退款/取消应用内购买

    我正在尝试处理iOS的退款应用内购买.但我找不到明确的指导方针来做到这一点.所以我有一个会员类型的应用程序内购买功能,其中用户凭据不一定与itunes帐户绑定.当有人进行购买时,我可以参考哪种标识符,并且当他们通过苹果申请退款时具有相同的标识符?我需要立即取消会员资格.谢谢!解决方法我最终存储了收据字符串并运行cron来完成事务并查找取消字段.

  2. ios – 当pod的新版本可用时,“pod update”是否会覆盖我的代码更改?

    我的更改会被覆盖吗?你能描述为什么是或为什么不?关于如何做到这一点.

  3. ios – 什么是Sprite Kit中的SKSpinLockSync以及如何解决它

    我收到一个带有以下堆栈跟踪的错误报告,我不知道问题是什么.我已经看到这样的建议,这可能是由于在纹理图集中有一个发射器的图像,或者是在添加的同一个运行循环中移除了一个发射器,但我认为这些都不会发生.这是一个零星的问题,我无法再创造它.我只在bug报告中看到它.我很乐意帮忙.编辑:我现在意识到我在几种不同的情况下得到SKSpinLockSync问题,并不总是与发射器有关.我认为,我经常使用发射器看到它

  4. 简析Swift和C的交互

    之前好像简单说过Swift和Objective-C的交互问题。其实我们也可以用Swift调用纯C代码或者基于C的第三方库。)Swift官方文档中,以及那本已经被迅速翻译为中文的ibooks书中,都提到了Swift调用Objective-C和C是有很好支持的。本内容包括Swift调用C和相应的C调用Swift,项目混编。对于C来说,最头疼的莫过于指针,而Swift是一门没有指针的语言。这些标准库函数表示为Darwin.C.HEADER.name。实际上由于Swift模块结构是平坦的,他们均位于Darwin中

  5. Carthage使用解决部分Swift运行时的问题

    1、首先,简单的利用Carthagehttps://github.com/Carthage/Carthage要求进行简单测试使用,建立一个demo测试2、可能由于xcode版本原因在:类似我执行时出现的错误:Argo.framework是用旧的编译器编译的(估计下载的那个包是用Xcode7编译因此在工程文件目录下需要执行将所有需要的包下载下来(原本执行update操作会直接将运行好的framewo

  6. swift接口的使用

    swiftAPI的使用最近楼主要使用swift的API接口,楼主有一个习惯,不管开发需要用到什么知识,都喜欢看官方文档,虽然大部分是英文,但是用起来还是感觉可靠,不过对于openstack给的swiftAPI接口,可叫我吃了不少苦,所以写下这篇文章希望给有同样困惑的朋友帮助。获得的结果如下:%Total%Received%XferdAverageSpeedTimeTimeTimeCurrentDloadUploadTotalSpentLeftSpeed10013771001282100959382695-

  7. pod install 与 pod update的区别

    podinstall是安装Podfile中指定版本的第三方库。podupdate是安装最新的版本,如果之前已经安装了,但是有新版本,会更新版本。

  8. 早期Swift中Cocos2D初始化代码的重构

    但是遗憾的是Swift2.2中还是不支持Type的class属性关键字,只能用static,我们期待Swift3的改进吧!

  9. 手把手教你swift项目添加cocos2dx-lua

    去倒杯水吧,这个过程会很久。。。至此,工程已经全部配置完毕,你已经解决一个大Boss了;今天就到这里吧,之后我们再续如何用swift调用lua手把手教你swift项目添加cocos2dx-lua

  10. 手把手教你swift项目集成cocos2dx-js模块

    前几天在swift项目中集成了Lua模块,使得在swift工程中用Lua写游戏逻辑成为了可能,具体工程及配置见手把手教你swift项目添加cocos2dx-lua,由于公司最近要把js做的小游戏集成到iOS原生应用中,于是我们将解锁另外一个场景,好了,下面开始;同样的,首先你得有一个swift项目我们从头开始,建立一个swift项目;我们默认你已经可以自己创建一个全新的swift项目了,这很简单,不是么?

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部