正在作項目中有不少遊戲數據要保存,常見的玩家數據這些比較簡單的能夠用CCUserDefault。它是cocos2d-x用來存取基本數據類型用的。保存爲XML文件格式。css
主要方法:(和java的map很像,鍵值對)html
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返回本身想要的值。java
bool getBoolForKey(const char* pKey, bool defaultValue = false); int getIntegerForKey(const char* pKey, int defaultValue = 0); float getFloatForKey(const char* pKey, float defaultValue=0.0f); double getDoubleForKey(const char* pKey, double defaultValue=0.0); string getStringForKey(const char* pKey, const std::string & defaultValue = "");
首次運行程序時能夠生成xml文件CCUserDefault::sharedUserDefault()->setIntegerForKey("MyGold", 0);編程
這樣就能夠生成一個xml文件。不過這種硬代碼我不是很喜歡。函數
每次調用的時候要寫很長的代碼。能夠建議搞幾個宏,畢竟CCUserDefault的get,set實在太長了。lua
#define SaveStringToXML CCUserDefault::sharedUserDefault()->setStringForKey #define SaveIntegerToXML CCUserDefault::sharedUserDefault()->setIntegerForKey #define SaveBooleanToXML CCUserDefault::sharedUserDefault()->setBoolForKey #define LoadStringFromXML CCUserDefault::sharedUserDefault()->getStringForKey #define LoadIntegerFromXML CCUserDefault::sharedUserDefault()->getIntegerForKey #define LoadBooleanFromXML CCUserDefault::sharedUserDefault()->getBoolForKey
如何首次生成判斷文件是否存在呢spa
其實能夠利用get方法去獲取。 code
if ( !LoadBooleanFromXML("_IS_EXISTED")) { initUserData(); SaveBooleanToXML("_IS_EXISTED", true); }
對了,ccUserDefault在0.9.1版本會在安卓平臺下crash掉,更新源代碼就OK了。xml
注意事項:htm
一、在win32下運行的時候,發現用CCUserDefault生成的xml文件不是在Resources文件夾,而是在遊戲.exe的目錄下。Public函數就上面幾個,想設置存取路徑在資源內估計是不行了。若是在Android下,想經過CCUserDefault讀取apk裏面的xml文件,我想不太可行。由於不能指定路徑。
因爲不能設置路徑讀取資源內的xml文件,那麼,CCUserDefault的xml文件只好在遊戲首次運行時生成,生成後在進行修改等各類操做。要生成xml文件,通常要在代碼裏寫死一些硬代碼,如:
CCUserDefault::sharedUserDefault()->setIntegerForKey("HighScore", 0);
這樣就能夠生成一個xml文件。固然硬代碼太多,代碼看起來就不怎麼優雅了,我的感受用CCUserDefault保存一些配置數據便可,如音樂開關,最高分紅績等。固然也能夠用lua存取,不過只爲了幾個默認配置就把lua引擎加進來的話,感受有點蛋疼。
PS:個人蛋疼小遊戲由於所有數據都拿CCUserDefault保存,如今代碼裏只是設置默認數據的硬代碼就有好多行…
遊戲代碼裏通常都是首次調CCUserDefault生成xml數據文件,生成後再讀取修改。若是每次遊戲運行時都setBoolForKey("IsMusicOpened", true);一次。那麼,用戶怎麼關閉音效都是多餘的,由於每次遊戲運行音效開關的默認值都是true,因此,咱們應該保證生成默認配置的方法只調用一次。最多見的邏輯固然就是判斷當xml文件不存在時,建立配置數據,存在的話,修改配置數據。
那麼怎麼判斷這個xml文件已經生成了呢?CCUserDefault提供的public函數只有上面幾個,並無判斷xml文件是否已生成的函數。判斷xml文件是否存在的方法實際是有的,不過在private裏面
這裏,重溫一下get方法。
bool getBoolForKey(const char* pKey, bool defaultValue = false);
若是獲取的鍵不存在,則返回false。因此,咱們就能夠在這裏作點文章。
if ( !LoadBooleanFromXML("PARAM_IS_FILE_EXISTED")){
CreateGameData();
SaveBooleanToXML("PARAM_IS_FILE_EXISTED", true);
}
Xml文件不存在時,用get方法取值明顯會是false,這樣就會進到if內,在這裏咱們就能夠生成xml文件,建立默認數據。再將鍵值設爲true,下次取鍵值就是true,代碼固然不會跑到if裏面去了。這樣的話,之後遊戲運行時也不會由於重複調用CreateGameData()而將已經修改的配置屬性值給刷掉。
在0.9.1版本,ccUserDefault會在安卓平臺下crash掉,解決方法是更新cocos2d-x的源代碼。連接:
http://bbs.9ria.com/thread-220485-1-1.html
如下是CCUserDefault的小應用:
#define SaveStringToXML CCUserDefault::sharedUserDefault()->setStringForKey #define SaveIntegerToXML CCUserDefault::sharedUserDefault()->setIntegerForKey #define SaveBooleanToXML CCUserDefault::sharedUserDefault()->setBoolForKey #define SaveFloatToXML CCUserDefault::sharedUserDefault()->setFloatForKey #define SaveDoubleToXML CCUserDefault::sharedUserDefault()->setDoubleForKey #define LoadStringFromXML CCUserDefault::sharedUserDefault()->getStringForKey #define LoadIntegerFromXML CCUserDefault::sharedUserDefault()->getIntegerForKey #define LoadBooleanFromXML CCUserDefault::sharedUserDefault()->getBoolForKey #define LoadFloatToXML CCUserDefault::sharedUserDefault()->getFloatForKey #define LoadDoubleToXML CCUserDefault::sharedUserDefault()->getDoubleForKey
if ( !LoadBooleanFromXML("bool")){//PARAM_IS_FILE_EXISTED // 建立CCUserDefault單例並建立相應的數據類型鍵,設置其鍵值。; SaveStringToXML("string", "value1"); SaveIntegerToXML("integer", 10); SaveFloatToXML("float", 2.3f); SaveDoubleToXML("double", 2.4); SaveBooleanToXML("bool", true); // 設置完後,打印各種型鍵取出的值。; string ret =LoadStringFromXML("string"); CCLOG("string is %s", ret.c_str()); double d =LoadDoubleToXML("double"); CCLOG("double is %f", d); int i = LoadIntegerFromXML("integer"); CCLOG("integer is %d", i); float f =LoadIntegerFromXML("float"); CCLOG("float is %f", f); bool b =LoadBooleanFromXML("bool"); if (b) { CCLOG("bool is true"); } else { CCLOG("bool is false"); } CCUserDefault::sharedUserDefault()->flush(); CCLog("init with ccuserdefault"); }else{ CCLog("load with ccuserdefault"); }