一、引言
數據存儲和網絡功能可以說是一款游戲中必不可少的功能,如果一款游戲不能保存進度那么它的可玩性必然大打折扣(試想一下,玩家辛辛苦苦玩了一整天的游戲,結果退出時告訴人家不能保存關卡信息,你明天還得從頭來再玩一遍。那玩家一定會掏出准備已久的西瓜刀~)
其實Cocos2d-x引擎早已為我們開發者封裝好了多種數據存儲的類或者方法,包括簡單信息的存儲,文件的讀寫,SQLite數據庫和RAR格式的壓縮文件的讀取等等。(用心良苦啊!)其中大部分的存儲功能被封裝到了UserDefault類中。
二、數據存儲
1.UserDefault類
UserDefault 是一個小型的數據管理類。你可以通過這個類保存並獲得基本類型值的數據。 例如:setBoolForKey("played", true)
將在數據庫中添加一個值為 true 的布爾型數據。 它的 key 是 "player"。可以通過 getBoolForKey("player")
獲取這個數據。
UserDefault類提供了一些常用的方法用於讀取和存儲數據信息,如下表:
方法名 | 說 明 |
getBoolForKey | 獲取bool類型的鍵值對的值 |
getIntegerForKey | 獲取int類型的鍵值對的值 |
getFloatForKey | 獲取float類型的鍵值對的值 |
getDoubleForKey | 獲取double類型的鍵值對的值 |
getStringForKey | 獲取String類型的鍵值對的值 |
getDataForKey | 獲取二進制的鍵值對的值 |
setBoolForKey | 存入bool類型的數據 |
setIntegerForKey | 存入int類型的數據 |
setFloatForKey | 存入float類型的數據 |
setDoubleForKey | 存入double類型的數據 |
setStringForKey | 存入String類型的數據 |
setDataForKey | 存入二進制數據 |
flush | 將內容保存到XML文件 |
getXMLFilePath | 獲取XML文件的保存路徑 |
isXMLFileExist | 判斷一個XML文件是否存在 |
具體的參數及詳細的說明可以在Cocos2d-x的UserDefaultAPI文檔中查詢(吐槽一句Cocos2d-x的文檔真夠差勁的,相比之下Egret的文檔好很多。)
OK,下面我們寫一個小例子,來看一下UserDefault這個類具體是怎么使用的,先上代碼:
1 bool HelloWorld::init() 2 { 3 if ( !Layer::init() ) 4 { 5 return false; 6 } 7 auto* background = LayerColor::create(Color4B(255, 255, 255, 255)); 8 addChild(background);
//創建一個菜單按鈕 9 auto* readLabel = Label::create("read", "Arial", 56); 10 readLabel->setColor(Color3B(0, 0, 0)); 11 auto* pReadLabel = MenuItemLabel::create(readLabel, this, menu_selector(HelloWorld::readCallback)); 12 auto* buttonReadLabel = Menu::create(pReadLabel, NULL); 13 buttonReadLabel->setPosition(320, 260); 14 addChild(buttonReadLabel); 15 auto* saveLabel = Label::create("save", "Arial", 56); 16 saveLabel->setColor(Color3B(0, 0, 0)); 17 auto* pSaveLabel = MenuItemLabel::create(saveLabel, this, menu_selector(HelloWorld::saveCallback)); 18 auto* buttonSaveLabel = Menu::create(pSaveLabel, NULL); 19 buttonSaveLabel->setPosition(320, 100); 20 addChild(buttonSaveLabel); 21 UserDefault::sharedUserDefault()->setBoolForKey("isExisted",false); 22 return true; 23 } 24 void HelloWorld::readCallback(Ref* pSender) 25 { 26 CCLOG("============================================================"); 27 CCLOG("reading begin!");
//根據isExisted的值來判斷,是否數據被寫入 28 if (UserDefault::sharedUserDefault()->getBoolForKey("isExisted")) 29 {
//讀取鍵值為Int的內容並輸出 30 int intVar = UserDefault::sharedUserDefault()->getIntegerForKey("int"); 31 CCLOG("the int is:%d", intVar);
//讀取鍵值為float的內容並輸出 32 float floatVar = UserDefault::sharedUserDefault()->getFloatForKey("float"); 33 CCLOG("the float is:%f", floatVar);
//讀取鍵值為string的內容並輸出 34 std::string str = UserDefault::sharedUserDefault()->getStringForKey("string"); 35 CCLOG("the string is:%s", str); 36 }
//如果isExisted的鍵值為false的話,說明信息沒有被保存,不可用 37 else 38 { 39 CCLOG("not exist!"); 40 } 41 CCLOG("============================================================"); 42 } 43 void HelloWorld::saveCallback(Ref* pSender) 44 { 45 CCLOG("============================================================"); 46 CCLOG("save begin!"); 47 UserDefault::sharedUserDefault()->setIntegerForKey("int", 999); 48 UserDefault::sharedUserDefault()->setFloatForKey("float", 3.1415926); 49 UserDefault::sharedUserDefault()->setStringForKey("string", "this is a string!"); 50 UserDefault::sharedUserDefault()->setBoolForKey("isExisted", true); 51 CCLOG("saved file path is %s", UserDefault::sharedUserDefault()->getXMLFilePath()); 52 CCLOG("============================================================"); 53 }
程序運行起來以后可以看到read和save兩個按鈕,點擊他們可以看到在控制台打印出來的信息,如下圖:
可以看到,數據信息已經被成功的寫入並且讀取出來了,而且還打印了文件的存放路徑。這種方式特別適合保存游戲進度和最高分、排行榜等內容比較少的數據。但是如果數據量比較大的時候就需要采取別的方式了,比如文件讀寫的方式。
二、Cocos2dx中的文件讀寫
1 bool HelloWorld::init() 2 { 3 if ( !Layer::init() ) 4 { 5 return false; 6 } 7 // 創建一個菜單按鈕,用於讀取文件中的內容 8 auto* background = LayerColor::create(Color4B(255, 255, 255, 255)); 9 addChild(background); 10 auto* readLabel = Label::create("read", "Arial", 56); 11 readLabel->setColor(Color3B(0, 0, 0)); 12 auto* pReadLabel = MenuItemLabel::create(readLabel, this, menu_selector(HelloWorld::readCallback)); 13 auto* buttonReadLabel = Menu::create(pReadLabel, NULL); 14 buttonReadLabel->setPosition(320, 260); 15 addChild(buttonReadLabel); 16 auto* saveLabel = Label::create("save", "Arial", 56); 17 saveLabel->setColor(Color3B(0, 0, 0)); 18 auto* pSaveLabel = MenuItemLabel::create(saveLabel, this, menu_selector(HelloWorld::saveCallback)); 19 auto* buttonSaveLabel = Menu::create(pSaveLabel, NULL); 20 buttonSaveLabel->setPosition(320, 100); 21 addChild(buttonSaveLabel); 22 return true; 23 } 24 void HelloWorld::readCallback(Ref* pSender) 25 { 26 CCLOG("============================================================"); 27 std::string path = FileUtils::sharedFileUtils()->getWritablePath()+"test.txt"; 28 // 輸出文件路徑 29 CCLOG("path = %s", path.c_str()); 30 // 創建一個文件指針 31 FILE* file = fopen(path.c_str(), "r"); 32 if (file) { 33 char* buf; //要獲取的字符串 34 int len; //獲取的長度 35 // 獲取文件長度長度 36 fseek(file, 0, SEEK_END); //移到尾部 37 len = ftell(file); //提取長度 38 rewind(file); //回歸原位 39 CCLOG("count the file content len = %d", len); 40 //分配buf空間 41 buf = (char*)malloc(sizeof(char) * len + 1); 42 if (!buf) 43 { 44 CCLOG("malloc space is not enough."); 45 } 46 //讀取進的buf,單位大小,長度,文件指針 47 int rLen = fread(buf, sizeof(char), len, file); 48 buf[rLen] = '\0'; 49 CCLOG("has read Length = %d", rLen); 50 CCLOG("has read content = %s", buf); 51 fclose(file); 52 free(buf); 53 } 54 else 55 { 56 CCLOG("open file error."); 57 } 58 CCLOG("============================================================"); 59 } 60 void HelloWorld::saveCallback(Ref* pSender) 61 { 62 CCLOG("============================================================"); 63 std::string path = CCFileUtils::sharedFileUtils()->getWritablePath() + "test.txt"; 64 FILE* file = fopen(path.c_str(), "w"); 65 if (file) 66 { 67 char* pContent = "this is a word"; 68 fputs(pContent, file); 69 CCLOG("save file succeed."); 70 fclose(file); 71 } 72 else 73 { 74 CCLOG("save file error."); 75 } 76 CCLOG("============================================================"); 77 }
程序運行調試圖:
Cocos2d-x中文件讀寫的方式和C++對文件的操作是一樣的,先創建一個文件指針指向一個文件,然后打開這個文件,接着寫入數據,最后關閉文件。以下是詳細說明:
File對象:文件對象,用於創建文件,操作文件。
fopen:打開一個文件,可以根據參數的不同來決定文件的打開方式(比如 r,w,a等等)。
fseek:移動文件指針,可以將指針指向文件中特定位置的字符。
ftell:獲取文件指針相對於文件開頭的距離。
malloc:為指針分配內存。
fread:讀取一個文件,需要輸入緩沖區的地址,單位大小,長度和文件指針。
更多詳細的文件操作內容可以移步此篇博文。
其實在Cocos2d-x中還有利用比如csv,json等保存數據的方法,但由於篇幅限制,本篇博客中我們就不再探討了,以后的博客中會詳細的介紹json和csv的操作。
本篇博客所有代碼已經同步到Github:
UserDefault類使用:https://github.com/XINCGer/Cocos2d-X_Tools/tree/master/Cocos2d-x_Demo/LocalDataSave
文件讀寫操作:https://github.com/XINCGer/Cocos2d-X_Tools/tree/master/Cocos2d-x_Demo/FileSystemInCocos2dx
下一篇博客,我們將學習Cocos2d-X中的弱聯網技術。
作者:馬三小伙兒
出處:http://www.cnblogs.com/msxh/p/5744177.html
請尊重別人的勞動成果,讓分享成為一種美德,歡迎轉載。另外,文章在表述和代碼方面如有不妥之處,歡迎批評指正。留下你的腳印,歡迎評論!