您好,登錄后才能下訂單哦!
【嘮叨】
一個游戲怎么能沒有游戲存檔呢?在cocos2dx中也提供了一個數據存儲類CCUserDefault,可以作為一個輕量級的數據庫來使用。
它支持五種數據bool、int、float、double、string的存儲。
【致謝】
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)增加數據值:Data
// void setDataForKey(const char* pKey, const Data& value); Data getDataForKey(const char* pKey, const Data& defaultValue = Data::Null); //
(4)其他變化不大。
【CCUserDefault】
CCUserDefault類和之前講的CCDirector、SimpleAudioEngine一樣,都是采用單例模式。
可以通過sharedUserDefault()函數來獲取其唯一的實例對象。
CCUserDefault采用XML存儲技術,就是一般的鍵值對,這個類似C++中的map的映射(鍵——值)。一個關鍵字對應一個值。其實現的接口也比較簡單實用,通過傳統的set()、get()方法訪問和修改值。
它支持五種數據:bool、int、float、double、string。
1、原理
(1)類似map的映射(鍵——值)。一個關鍵字對應一個值,并利用set()/get()進行訪問。
(2)數據直接存儲在一個XML文件中,并且文件名為程序項目的名字,如“MyTest.xml”。
(3)首次使用時,XML不存在,CCUserDefault會自動創建相應的XML文件。
2、設置數據值set
通過(鍵——值)的方式進行設置。
// void setBoolForKey( const char* pKey, bool value); //設置一個bool值 void setIntegerForKey(const char* pKey, int value); //設置一個int值 void setFloatForKey( const char* pKey, float value); //設置一個float值 void setDoubleForKey( const char* pKey, double value); //設置一個double值 void setStringForKey( const char* pKey, const std::string& value); //設置一個string值 //
3、獲取數據值get
通過關鍵字,來從XML文件中獲取數據值。
若關鍵字不存在,會自動設置(鍵——值)映射,并設置對應的默認值defaultValue。
// bool getBoolForKey( const char* pKey, bool defaultValue = false); //讀取一個bool值 int getIntegerForKey(const char* pKey, int defaultValue = 0); //讀取一個int值 float getFloatForKey( const char* pKey, float defaultValue = 0.0); //讀取一個float值 double getDoubleForKey( const char* pKey, double defaultValue = 0.0); //讀取一個double值 std::string getStringForKey( const char* pKey, const std::string& defaultValue = ""); //讀取一個string值 //
4、保存flush
當set完后,數據不會馬上保存到XML文件中。
所以一定要記得用flush()來保存數據,否則會丟失!
// CCUserDefault::sharedUserDefault()->flush(); //
5、其他操作
獲取單例對象、釋放單例對象、獲取XML文件路徑、判斷XML文件是否已經存在。
// static CCUserDefault* sharedUserDefault(); //獲取單例對象 static void purgeSharedUserDefault(); //釋放單例對象 const static std::string& getXMLFilePath(); //獲取XML路徑 static bool isXMLFileExist(); //XML文件是否已創建 //
6、使用技巧
(1)每次操作都要打長長的CCUserDefault::sharedUserDefault(),來獲得單例對象。是不是很麻煩呢?可以通過宏定義來縮短長度。
// #define UserDefault CCUserDefault::sharedUserDefault() //
(2)在使用的時候,要特別注意:區別 const char* 和 const std::string 是不一樣的!
(3)當set完后,一定要記得用flush()來保存數據,否則會丟失!
【代碼實戰】
代碼來源于TestCpp項目中。
1、需要引用以下的頭文件和命名空間
因為要用到C++的string類型。
// #include <string> using namespace std; //
2、宏定義獲取單例對象的函數
// #define UserDefault CCUserDefault::sharedUserDefault() //
3、編寫數據存儲相關操作,并在控制臺輸出數據值
// //設置set UserDefault->setBoolForKey( "bool", true); UserDefault->setIntegerForKey("integer", 100); UserDefault->setFloatForKey( "float", 33.33f); UserDefault->setDoubleForKey( "double", 44.44); UserDefault->setStringForKey( "string", "1111111"); //獲取get,并輸出到控制臺 //通過關鍵字,獲取數據 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"); //輸出到控制臺 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!"); } //保存數據 UserDefault->flush(); //
4、運行結果
5、分析與總結
(1)不知道大家是否發現輸出的結果有問題?float我設置的是33.33,為何輸出的是33.330002。不是應該輸出33.330000才對嗎?
這個就要講講C++浮點數的精度問題了,float是單精度浮點數,而double是雙精度浮點數。float的有效精度在6~7位,超過7位就可能會失真,就像上面的那個例子一樣。而double的有效精度在15~16位,超過16位才會失真。具體的原理,自行百度吧!
(2)getXMLFilePath()獲取的XML文件路徑為絕對路徑。另外XML文件保存的路徑為項目的Debug.win32中,說明XML文件是保存在應用程序所在目錄下的。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。