cocos2dx 2.2.* 内更新资源

来源:互联网 发布:别哭了宝贝网络歌手 编辑:程序博客网 时间:2024/06/06 00:03

提示:

覆盖路径cocos2d-x-2.2.2\extensions\AssetsManager下的AssetsManager.h AssetsManager.cpp。。

刚刚接触cocos2dx,需要内更新游戏资源,找了一下发现这个项目cocos2d-x-2.2.2\samples\Cpp\AssetsManagerTest  发现这个DEMO写的很不错,不但可以更新资源还可以更新代码,但是只能更新js/lua这种脚本语言的代码,c++代码是不可以的  不过我只需要更新游戏资源就可以了.

    于是,我就新建了一个项目TestUpdata(一激动单词都拼错了). 由于我win电脑暂时没配置cygwin,所以打包android不方便,当然也不可以打包ios,所以我就在MAC上开始写这个DEMO了,与其说是写不如说是copy. 就是单纯的把AssetsManagerTest这个DEMO里更新js的代码给删除了,只要更新资源的就好了.为了测试方便我把DEMO里获取资源的路径改成了自己的,在Github里申请了一个账号,然后把测试资源传上去.

    写完以后,我用了一台5c测试的,更新是正常的,但是更新到本地的资源删除不了,然后在xcode里用模拟器发现是可以删除的,各种郁闷各种纠结啊 后来突然想到了是不是没越狱的原因,然后换了一台越狱的4s果然好了. 额,好悲剧! 打包成apk也是一切正常的.

    简单的流程跑通以后,想加入一些提示以及支持断点下载资源. 想了一下之前做unity3d内更新的时候,我的version列表里面有所有assetbundle文件名和最后修改的时间,这样只需要在游戏本地维护一份相同的version文件就好了. 不过这个DEMO里资源是扔到一个zip文件里的,所以断点更新肯定不好弄,我也不想改太多代码[人太懒了],所以这个就算了. 不过我可以在version文件里写入资源的大小,这样每次更新之前可以提示玩家是否更新资源.

    简单的改了一下AssetsManager.h和AssetsManager.cpp其实就是加了一个函数'getPackageSize',以前version文件里只有一个版本号,现在在版本号之后用#符号隔开了一个资源zip包大小的int字段. version.txt文件改成了类似 1.0.2#20480 ,解析的时候getPackageSize返回后面一个字段就好了.

说一下AssetsManager.h中添加public函数int getPackageSize(); private变量int _packageSize; 在AssetsManager.cpp中checkUpdate函数中需要把以前一个版本字段给解析成一个版本一个资源大小资源,如果是c#或者java直接split赋值就好了,可是c++还要自己写. 然后我就在checkUpdate函数里修改:

curl_easy_setopt(_curl, CURLOPT_WRITEDATA, &_version);改成

 ////////////////////////////
    string temp;
    //....
    curl_easy_setopt(_curl, CURLOPT_WRITEDATA, &temp);    //&_version

    //....

    //modify by xudd , to resolve package size
    string str[20];
    int index=temp.find('#');
    int i=0;
    while (index!=-1) {
        str[i++]=temp.substr(0,index);
        temp=temp.substr(index+1);
        index=temp.find('.');
    }
    str[i++]=temp;

    _version=str[0];
    _packageSize=atoi(str[1].c_str());

    //CCLOG("version-%s",_version.c_str());
    //CCLOG("packageSize-%d",_packageSize);

    ////////////////////////////////

然后完成函数

    int AssetsManager::getPackageSize()
    {
        return _packageSize;
    }

    到此我的TestUpdata已经可以正常跑了,当然了还有些提示以及更新的流程跟正式游戏不一样[正常的游戏肯定不是摁完按钮才检测版本的]

    在MAC上打包apk ipa都完成后,我在win32上直接运行,又报错了,error C1083: 无法打开包括文件:“pthread.h”: No such file or directory    e:\cocos2dx\cocos2d-x-2.2.2\cocos2d-x-2.2.2\extensions\assetsmanager\assetsmanager.h 就是找不到pthread.h  google第一条消息告诉我如果使用pthread.h需要右击工程-->属性-->配置属性-->链接器-->输入-->附加依赖项中添加pthreadVCE2.lib 看了一下是添加过的 接着添加附加包含目录,右击项目-->属性-->配置属性-->C/C++-->常规-->附加包含目录加入pthread头文件所在的目录,这个没有,把$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32\pthread这个路径添加进去以后就正常了

    写这篇废话的目的就是想记录一下 1-ios未越狱机器删除不了资源 2-pthread.h找不到

    如果你不慎看到了这篇文章,可能觉着满篇废话不知所云,无代码无真相.. 一会我会把整个工程上传了,地址http://download.csdn.net/detail/xd0718/7124233

///////////////////////////////////////////////////代码如下:

#ifndef __HELLOWORLD_SCENE_H__#define __HELLOWORLD_SCENE_H__#include "CCApplication.h"#include "cocos2d.h"#include "AssetsManager/AssetsManager.h"class HelloWorld : public cocos2d::CCLayer, public cocos2d::extension::AssetsManagerDelegateProtocol{public:    HelloWorld();    ~HelloWorld();        // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone    virtual bool init();        // there's no 'id' in cpp, so we recommend returning the class instance pointer    static cocos2d::CCScene* scene();        // a selector callback    void menuCloseCallback(CCObject* pSender);        // implement the "static node()" method manually    CREATE_FUNC(HelloWorld);        void enter(cocos2d::CCObject *pSender);    void reset(cocos2d::CCObject *pSender);    void update(cocos2d::CCObject *pSender);        virtual void onError(cocos2d::extension::AssetsManager::ErrorCode errorCode);    virtual void onProgress(int percent);    virtual void onSuccess();    private:    cocos2d::extension::AssetsManager* getAssetsManager();    void createDownloadedDir();        void checkUpdate();        cocos2d::CCMenuItemFont *pItemEnter;    cocos2d::CCMenuItemFont *pItemReset;    cocos2d::CCMenuItemFont *pItemUpdate;    cocos2d::CCLabelTTF *pProgressLabel;    std::string pathToSave;    bool isUpdateItemClicked;};#endif // __HELLOWORLD_SCENE_H__

=========================.ccp

#include "HelloWorldScene.h"#include "MenuScene.h"#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)#include <dirent.h>#include <sys/stat.h>#endifUSING_NS_CC;USING_NS_CC_EXT;using namespace std;HelloWorld::HelloWorld(): pItemEnter(NULL), pItemReset(NULL), pItemUpdate(NULL), pProgressLabel(NULL), isUpdateItemClicked(false){}HelloWorld::~HelloWorld(){    AssetsManager *pAssetsManager = getAssetsManager();    CC_SAFE_DELETE(pAssetsManager);}CCScene* HelloWorld::scene(){    // 'scene' is an autorelease object    CCScene *scene = CCScene::create();        // 'layer' is an autorelease object    HelloWorld *layer = HelloWorld::create();        // add layer as a child to scene    scene->addChild(layer);        // return the scene    return scene;}// on "init" you need to initialize your instancebool HelloWorld::init(){    CCLayer::init();        createDownloadedDir();        CCSize size = CCDirector::sharedDirector()->getWinSize();        pItemReset = CCMenuItemFont::create("reset", this, menu_selector(HelloWorld::reset));    pItemEnter = CCMenuItemFont::create("enter", this, menu_selector(HelloWorld::enter));    pItemUpdate = CCMenuItemFont::create("update", this, menu_selector(HelloWorld::update));        pItemEnter->setPosition(ccp(size.width/2, size.height/2 + 100));    pItemReset->setPosition(ccp(size.width/2, size.height/2));    pItemUpdate->setPosition(ccp(size.width/2, size.height/2 - 100));        CCMenu *menu = CCMenu::create(pItemUpdate, pItemEnter, pItemReset, NULL);    menu->setPosition(ccp(0,0));    addChild(menu);        pProgressLabel = CCLabelTTF::create("", "Arial", 40);    pProgressLabel->setPosition(ccp(200, 250));    addChild(pProgressLabel);        checkUpdate();        return true;}void HelloWorld::menuCloseCallback(CCObject* pSender){#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");#else    CCDirector::sharedDirector()->end();#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)    exit(0);#endif#endif}void HelloWorld::checkUpdate(){    bool flag=getAssetsManager()->checkUpdate();    CCLOG("flag:%d size:%d",flag,getAssetsManager()->getPackageSize());    if(flag)    {        char packSize[50];        sprintf(packSize, "%dKB", getAssetsManager()->getPackageSize()>>10);        pProgressLabel->setString(packSize);    }}void HelloWorld::update(cocos2d::CCObject *pSender){    pProgressLabel->setString("");        // update resources    getAssetsManager()->update();        isUpdateItemClicked = true;}void HelloWorld::reset(cocos2d::CCObject *pSender){    pProgressLabel->setString(" ");        // Remove downloaded files#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)    string command = "rm -r ";    // Path may include space.    command += "\"" + pathToSave + "\"";    system(command.c_str());#else    string command = "rd /s /q ";    // Path may include space.    command += "\"" + pathToSave + "\"";    system(command.c_str());#endif    // Delete recorded version codes.    getAssetsManager()->deleteVersion();        createDownloadedDir();}void HelloWorld::enter(cocos2d::CCObject *pSender){    // Should set search resource path before running script if "update" is not clicked.    // Because AssetsManager will set    if (! isUpdateItemClicked)    {        vector<string> searchPaths = CCFileUtils::sharedFileUtils()->getSearchPaths();        searchPaths.insert(searchPaths.begin(), pathToSave);        CCFileUtils::sharedFileUtils()->setSearchPaths(searchPaths);    }        //CCScriptEngineProtocol *pEngine = ScriptingCore::getInstance();    //CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);    //ScriptingCore::getInstance()->runScript("main.js");        CCScene *ss = MenuLayer::scene();    CCDirector::sharedDirector()->replaceScene(ss);}AssetsManager* HelloWorld::getAssetsManager(){    static AssetsManager *pAssetsManager = NULL;        if (! pAssetsManager)    {        pAssetsManager = new AssetsManager("https://raw.github.com/ddir/TestUpdate/master/TestUpdate.zip",                                           "https://raw.github.com/ddir/TestUpdate/master/version.txt",                                           pathToSave.c_str());        pAssetsManager->setDelegate(this);        pAssetsManager->setConnectionTimeout(3);    }        return pAssetsManager;}void HelloWorld::createDownloadedDir(){    pathToSave = CCFileUtils::sharedFileUtils()->getWritablePath();    pathToSave += "tmpdir";        // Create the folder if it doesn't exist#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)    DIR *pDir = NULL;        pDir = opendir (pathToSave.c_str());    if (! pDir)    {        mkdir(pathToSave.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);    }#elseif ((GetFileAttributesA(pathToSave.c_str())) == INVALID_FILE_ATTRIBUTES){CreateDirectoryA(pathToSave.c_str(), 0);}#endif}void HelloWorld::onError(AssetsManager::ErrorCode errorCode){    if (errorCode == AssetsManager::kNoNewVersion)    {        pProgressLabel->setString("no new version");    }        if (errorCode == AssetsManager::kNetwork)    {        pProgressLabel->setString("network error");    }}void HelloWorld::onProgress(int percent){    char progress[20];    snprintf(progress, 20, "downloading %d%%", percent);    pProgressLabel->setString(progress);}void HelloWorld::onSuccess(){    pProgressLabel->setString("download ok");}


0 0