您好,登錄后才能下訂單哦!
【嘮叨】
一個(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、int、float、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é)果
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)用程序所在目錄下的。
免責(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)容。