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

        由于我要制作游戏的排行榜,在制作过程中遇到了不少的问题,一开始是不会把这个场景里面得到的数据传递到另一个页面,后来运用了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");                 //设置comment
			plistElement->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");                                                   //寻找子节点name
		if (winnameEle)
		{
			log("keyEle Text= %s", winnameEle->GetText());                                                          //获取里面的内容
			UserDefault::getInstance()->setStringForKey("mname", winnameEle->GetText());
		}

		//获取分数
		XMLElement *winscoreEle = winnameEle->NextSiblingElement("score");                                             //寻找下一个兄弟节点score
		if (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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值