cocos2dx 3.6 关于场景间传值(UserDefault)、本地存储的基本方法(tinyxml2)

来源:互联网 发布:淘宝国际转运店铺 编辑:程序博客网 时间:2024/05/17 23:14

        由于我要制作游戏的排行榜,在制作过程中遇到了不少的问题,一开始是不会把这个场景里面得到的数据传递到另一个页面,后来运用了UserDefault传值成功之后存入数组之中成功实现了排行榜以及排序的功能。然而却发现一个致命的bug,每一次关闭游戏打开之后排行榜里面的数据就被清空了,具体原因在下面再阐述。然后我就搜索了很多资料,查找了很多方法,发现不是版本不适合,就是没有办法实现我的功能。最后通过了tinyxml2 这个已经被集成在cocos2dx 3.6版本中的这个功能实现了排行榜以及数据存储了功能。接下来分享给大家,希望对有相关问题的人有所帮助。

        先说一下UserDefault的用法,

主要方法:

        设置一个键值和存放的数据   如果没有文件存在它会自动生成一个的

void    setBoolForKey(const char* pKey, bool value);void    setIntegerForKey(const char* pKey, int value);void    setFloatForKey(const char* pKey, float value);void    setDoubleForKey(const char* pKey, double value);void    setStringForKey(const char* pKey, const std::string & value);

        通过键读取数据,如果键不存在,可以设置一个defaultValue返回自己想要的值。

bool    getBoolForKey(const char* pKey);int    getIntegerForKey(const char* pKey);float    getFloatForKey(const char* pKey);double    getDoubleForKey(const char* pKey);std::string    getStringForKey(const char* pKey);
        还有几个比较重要的

        void flush ()   将内容保存到xml文件

        static const std::string & getXMLFilePath ()   获取文件地址

        static bool isXMLFileExist ()   是否存在该文件


        你用 set的语句设置了不少的值,然后用了flush()把他们存储起来了,但是发现你想要追加数据的时候只能再次使用flush()方法,这个时候如果你没有把原来的那些set语句重新设置一遍,他就会覆盖掉原来的数据。所以没有办法每一次获取一个,存储一个。达不到追加的效果(至少我找了真的很久都没有方法,最后我总结了一下,这个类应该是用于存储最高分,或者是系统设置的时候使用的!(个人感觉应该是这样的)

这个地址可以去看看 : http://www.cocos.com/doc/cocos2d-x-3.0/db/d94/classcocos2d_1_1_user_default.html


        这样以后我实在是没有办法,所以去查了很多资料,发现好像可以用数据库,可以用FileUnit,可以用tinyxml地方法来实现本地存储。我没有学过这里的任何东西,如果有人学过数据库,就还是用数据库来写可能很方便。我最后选择了tinyxml2,发现cocos2dx 3.6 已经把它集成在自己的类库里面了,所以不用再去网上下载了。


        下面贴上我的代码

void  GameScenePop::getPageXML(const char *fileName){//记录姓名并且传递到英雄榜auto pastname = (TextFieldTTF *)this->getChildByTag(TAG_MENU_TXTFILED);pastname->detachWithIME();//关闭输入框std::string winName = pastname->getString();//存放名字char * charwinName = new char[30];charwinName = (char*)winName.data();//记录分数并且传递到英雄榜auto pastscore = (Label *)this->getChildByTag(TAG_MENU_SCORE);std::string winScore = pastscore->getString();//转换格式char * charwinScore = new char[30];charwinScore = (char*)winScore.data();/* sprintf(charwinScore, "%s", winScore);*/int pastwinScore = atoi(charwinScore);//存放分数std::string filePath = FileUtils::getInstance()->getWritablePath() + fileName;<span></span>                          <span></span>//路径加名字tinyxml2::XMLDocument *pDoc = new tinyxml2::XMLDocument();XMLError errorId = pDoc->LoadFile(filePath.c_str());if (errorId != 0) {//xml格式错误return;}XMLElement *rootEle = pDoc->RootElement();                                                    //新建指针指向根节点if (rootEle == nullptr)      //如果没有根节点{        //添加plist节点        XMLElement *plistElement = pDoc->NewElement("plist");                                 //新建节点plistElement->SetAttribute("version", "1.0");                                         //设置里面的属性pDoc->LinkEndChild(plistElement);XMLComment *commentElement = pDoc->NewComment("this is xml comment");                 //设置commentplistElement->LinkEndChild(commentElement);//添加dic节点XMLElement *dicElement = pDoc->NewElement("dic");                                      //新建节点plistElement->LinkEndChild(dicElement);                                                //把节点添加在<span></span>plistElement节点下//添加key节点XMLElement *keyElement = pDoc->NewElement("data");/*keyElement->LinkEndChild(pDoc->NewText("key"));*/dicElement->LinkEndChild(keyElement);                                                  //把节点添加在<span></span>dicElement节点下//添加key节点下 姓名XMLElement *name = pDoc->NewElement("name");name->LinkEndChild(pDoc->NewText(charwinName));                                        //给节点添加文本内容keyElement->LinkEndChild(name);//添加key节点下 分数XMLElement *score = pDoc->NewElement("score");<span></span>                                         //给节点添加文本内容score->LinkEndChild(pDoc->NewText(charwinScore));keyElement->LinkEndChild(score);}else{XMLElement *dicEle = rootEle->FirstChildElement();                                    //设置一个指针指向根结点的第一个子孩子if (dicEle == nullptr)      //如果没有dic节点{//添加dic节点XMLElement *dicElement = pDoc->NewElement("dic");rootEle->LinkEndChild(dicElement);//添加key节点XMLElement *keyElement = pDoc->NewElement("data");/*keyElement->LinkEndChild(pDoc->NewText("key"));*/dicEle->LinkEndChild(keyElement);//添加key节点下 姓名XMLElement *name = pDoc->NewElement("name");name->LinkEndChild(pDoc->NewText(charwinName));keyElement->LinkEndChild(name);//添加key节点下 分数XMLElement *score = pDoc->NewElement("score");score->LinkEndChild(pDoc->NewText(charwinScore));keyElement->LinkEndChild(score);}else{XMLElement *keyEle = dicEle->FirstChildElement();                               //设置一个指针指向dicELe的第一个子孩子int ii = 1;for (int i = 0; i < ii; i++)//继续添加key节点{int can = 0;if (keyEle == nullptr){//添加key节点XMLElement *keyElement = pDoc->NewElement("data");/*keyElement->LinkEndChild(pDoc->NewText("key"));*/dicEle->LinkEndChild(keyElement);//添加key节点下 姓名XMLElement *name = pDoc->NewElement("name");name->LinkEndChild(pDoc->NewText(charwinName));keyElement->LinkEndChild(name);//添加key节点下 分数XMLElement *score = pDoc->NewElement("score");score->LinkEndChild(pDoc->NewText(charwinScore));keyElement->LinkEndChild(score);can = 1;}if (can==0){keyEle = keyEle->NextSiblingElement();                           //指针指向下一个兄弟节点ii++;                                                            //用来记录一共存在的节点}can = 0;}input = ii;                                                                      //把节点数统计起来}}//CCLOG("chenggonglema");pDoc->SaveFile(filePath.c_str());                                                                       //把操作变化存储起来在xml文件里面pDoc->Print();delete pDoc;}

        里面有一些是我自己的其他参数,大家不用看。 我想分享的是它的基本语法,注释里面我特意写详细了,大家看看每句代码是什么意思就好。


        新建出来的xml文件是这样的:


<plist version="1.0">    <!--this is xml comment-->    <dic>        <data>            <name>LuChaoyu</name>            <score>99966</score>        </data>    </dic></plist>
        其中LuChaoyu和99966 是我在文本框输入的姓名以及游戏得分。

        然后每一次都添加data节点就好了。


以下是获取的代码,我写在另一个场景中:


void Poplayer::getPageXML(const char *fileName){outPut=UserDefault::getInstance()->getIntegerForKey("input");clean = true;std::string filePath = FileUtils::getInstance()->getWritablePath() + fileName;tinyxml2::XMLDocument *pDoc = new tinyxml2::XMLDocument();XMLError errorId = pDoc->LoadFile(filePath.c_str());if (errorId != 0) {//xml格式错误return;}XMLElement *rootEle = pDoc->RootElement();XMLElement *dicEle = rootEle->FirstChildElement();XMLElement *datatEle = dicEle->FirstChildElement();for (int i = 0; i < outPut; i++){//获取姓名XMLElement *winnameEle = datatEle->FirstChildElement("name");                                                   //寻找子节点nameif (winnameEle){log("keyEle Text= %s", winnameEle->GetText());                                                          //获取里面的内容UserDefault::getInstance()->setStringForKey("mname", winnameEle->GetText());}//获取分数XMLElement *winscoreEle = winnameEle->NextSiblingElement("score");                                             //寻找下一个兄弟节点scoreif (winscoreEle){log("childEle Text= %s", winscoreEle->GetText());std::string winScore = winscoreEle->GetText();//转换格式char * charwinScore = new char[30];charwinScore = (char*)winScore.data();/* sprintf(charwinScore, "%s", winScore);*/int pastwinScore = atoi(charwinScore);//存放分数UserDefault::getInstance()->setIntegerForKey("mscore", pastwinScore);}getnamescore();                                                                                                 datatEle = datatEle->NextSiblingElement();                                                                      //指向下一个兄弟节点}//CCLOG("chenggonglema");delete pDoc;}

        总体就是这些,这里没有涉及到删除节点等方法,等日后研究好再来发,完善一下。最近在写AI五子棋功能,没啥时间研究这个了......

        希望这些可以帮到大家,谢谢~~




2 0
原创粉丝点击