溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

cocos2dx基礎(chǔ)篇(20)——數(shù)據(jù)存儲(chǔ)CCUserDefault

發(fā)布時(shí)間:2020-10-16 13:17:34 來(lái)源:網(wǎng)絡(luò) 閱讀:15234 作者:shahdza 欄目:開(kāi)發(fā)技術(shù)

【嘮叨】

    一個(gè)游戲怎么能沒(méi)有游戲存檔呢?在cocos2dx中也提供了一個(gè)數(shù)據(jù)存儲(chǔ)類(lèi)CCUserDefault,可以作為一個(gè)輕量級(jí)的數(shù)據(jù)庫(kù)來(lái)使用。

    它支持五種數(shù)據(jù)bool、int、float、double、string的存儲(chǔ)。


【致謝】

    http://gl.paea.cn/contents/252ac3e59bc18069.html


【Demo下載】

    https://github.com/shahdza/Cocos_LearningTest/tree/master/demo_%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8CCUserDefault 


【3.x】

    (1)去掉 “CC”

    (2)獲取單例:sharedUserDefault() 改為 getInstance()

    (3)增加數(shù)據(jù)值:Data

//
	void setDataForKey(const char* pKey, const Data& value);
	Data getDataForKey(const char* pKey, const Data& defaultValue = Data::Null);
//

    (4)其他變化不大。




【CCUserDefault】

    CCUserDefault類(lèi)和之前講的CCDirector、SimpleAudioEngine一樣,都是采用單例模式。

    可以通過(guò)sharedUserDefault()函數(shù)來(lái)獲取其唯一的實(shí)例對(duì)象。

    CCUserDefault采用XML存儲(chǔ)技術(shù),就是一般的鍵值對(duì),這個(gè)類(lèi)似C++中的map的映射(鍵——值)。一個(gè)關(guān)鍵字對(duì)應(yīng)一個(gè)值。其實(shí)現(xiàn)的接口也比較簡(jiǎn)單實(shí)用,通過(guò)傳統(tǒng)的set()、get()方法訪問(wèn)和修改值。

    它支持五種數(shù)據(jù):bool、intfloat、double、string。


1、原理

    (1)類(lèi)似map的映射(鍵——值)。一個(gè)關(guān)鍵字對(duì)應(yīng)一個(gè)值,并利用set()/get()進(jìn)行訪問(wèn)。

    (2)數(shù)據(jù)直接存儲(chǔ)在一個(gè)XML文件中,并且文件名為程序項(xiàng)目的名字,如“MyTest.xml”。

    (3)首次使用時(shí),XML不存在,CCUserDefault會(huì)自動(dòng)創(chuàng)建相應(yīng)的XML文件。


2、設(shè)置數(shù)據(jù)值set

    通過(guò)(鍵——值)的方式進(jìn)行設(shè)置。

//
	void setBoolForKey(   const char* pKey, bool value);               //設(shè)置一個(gè)bool值
	void setIntegerForKey(const char* pKey, int value);                //設(shè)置一個(gè)int值
	void setFloatForKey(  const char* pKey, float value);              //設(shè)置一個(gè)float值
	void setDoubleForKey( const char* pKey, double value);             //設(shè)置一個(gè)double值
	void setStringForKey( const char* pKey, const std::string& value); //設(shè)置一個(gè)string值
//


3、獲取數(shù)據(jù)值get

    通過(guò)關(guān)鍵字,來(lái)從XML文件中獲取數(shù)據(jù)值。

    若關(guān)鍵字不存在,會(huì)自動(dòng)設(shè)置(鍵——值)映射,并設(shè)置對(duì)應(yīng)的默認(rèn)值defaultValue。

//
	bool getBoolForKey(   const char* pKey, bool defaultValue = false);                   //讀取一個(gè)bool值
	int getIntegerForKey(const char* pKey, int defaultValue = 0);                         //讀取一個(gè)int值
	float getFloatForKey(  const char* pKey, float defaultValue = 0.0);                   //讀取一個(gè)float值
	double getDoubleForKey( const char* pKey, double defaultValue = 0.0);                 //讀取一個(gè)double值
	std::string getStringForKey( const char* pKey, const std::string& defaultValue = ""); //讀取一個(gè)string值
//


4、保存flush

    當(dāng)set完后,數(shù)據(jù)不會(huì)馬上保存到XML文件中。

    所以一定要記得用flush()來(lái)保存數(shù)據(jù),否則會(huì)丟失!

//
	CCUserDefault::sharedUserDefault()->flush();
//


5、其他操作

    獲取單例對(duì)象、釋放單例對(duì)象、獲取XML文件路徑、判斷XML文件是否已經(jīng)存在。

//
	static CCUserDefault* sharedUserDefault();  //獲取單例對(duì)象
	static void purgeSharedUserDefault();       //釋放單例對(duì)象
	const static std::string& getXMLFilePath(); //獲取XML路徑
	static bool isXMLFileExist();               //XML文件是否已創(chuàng)建
//


6、使用技巧

    (1)每次操作都要打長(zhǎng)長(zhǎng)的CCUserDefault::sharedUserDefault(),來(lái)獲得單例對(duì)象。是不是很麻煩呢?可以通過(guò)宏定義來(lái)縮短長(zhǎng)度。

//
	#define UserDefault CCUserDefault::sharedUserDefault()
//

    (2)在使用的時(shí)候,要特別注意:區(qū)別 const char*const std::string 是不一樣的!

    (3)當(dāng)set完后,一定要記得用flush()來(lái)保存數(shù)據(jù),否則會(huì)丟失!




【代碼實(shí)戰(zhàn)】

    代碼來(lái)源于TestCpp項(xiàng)目中。


1、需要引用以下的頭文件和命名空間

    因?yàn)橐玫紺++的string類(lèi)型。

//
	#include <string>
	using namespace std;
//


2、宏定義獲取單例對(duì)象的函數(shù)

//
	#define UserDefault CCUserDefault::sharedUserDefault()
//


3、編寫(xiě)數(shù)據(jù)存儲(chǔ)相關(guān)操作,并在控制臺(tái)輸出數(shù)據(jù)值

//
	//設(shè)置set
		UserDefault->setBoolForKey(   "bool",    true);
		UserDefault->setIntegerForKey("integer", 100);
		UserDefault->setFloatForKey(  "float",   33.33f);
		UserDefault->setDoubleForKey( "double",  44.44);
		UserDefault->setStringForKey( "string",  "1111111");


	//獲取get,并輸出到控制臺(tái)
		//通過(guò)關(guān)鍵字,獲取數(shù)據(jù)
		bool b = UserDefault->getBoolForKey("bool");
		int i = UserDefault->getIntegerForKey("integer");
		float f = UserDefault->getFloatForKey("float");
		double d = UserDefault->getDoubleForKey("double");
		string ret = UserDefault->getStringForKey("string");

		//輸出到控制臺(tái)
		CCLOG( (b == true)? "bool is true" : "bool is false" );
		CCLOG("integer is %d", i);
		CCLOG("float is %f", f);
		CCLOG("double is %f", d);
		CCLOG("string is %s", ret.c_str());


	//輸出XML文件路徑
		if( UserDefault->isXMLFileExist() ) //是否存在
		{
			string path = UserDefault->getXMLFilePath();
			CCLOG("XML file is exist!");
			CCLOG( "XML file path : %s", path.c_str() );
		}
		else
		{
			CCLOG("XML file is not exist!");
		}


	//保存數(shù)據(jù)
		UserDefault->flush();
//


4、運(yùn)行結(jié)果

cocos2dx基礎(chǔ)篇(20)——數(shù)據(jù)存儲(chǔ)CCUserDefault

    

cocos2dx基礎(chǔ)篇(20)——數(shù)據(jù)存儲(chǔ)CCUserDefault


5、分析與總結(jié)

    (1)不知道大家是否發(fā)現(xiàn)輸出的結(jié)果有問(wèn)題?float我設(shè)置的是33.33,為何輸出的是33.330002。不是應(yīng)該輸出33.330000才對(duì)嗎?

    這個(gè)就要講講C++浮點(diǎn)數(shù)的精度問(wèn)題了,float是單精度浮點(diǎn)數(shù),而double是雙精度浮點(diǎn)數(shù)。float的有效精度在6~7位,超過(guò)7位就可能會(huì)失真,就像上面的那個(gè)例子一樣。而double的有效精度在15~16位,超過(guò)16位才會(huì)失真。具體的原理,自行百度吧!

    (2)getXMLFilePath()獲取的XML文件路徑為絕對(duì)路徑。另外XML文件保存的路徑為項(xiàng)目的Debug.win32中,說(shuō)明XML文件是保存在應(yīng)用程序所在目錄下的。




向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI