本站文章均爲 李華明Himi 原創,轉載務必在明顯處註明:
轉載自【黑米GameDev街區】 原文連接: http://www.himigame.com/iphone-cocos2dx/653.htmlcss
本篇跟你們分享下Cocos2dX中的存儲,其中也介紹些細節容易犯錯的問題;html
在Cocos2dX中提供了自帶存儲類:CCUserDefault ,固然了這裏Himi強調一點,若是你的數據量比較大,建議使用SQL存儲比較適合,另一點要注意的是,儘量不要在Cocos2dX中使用與平臺相關的api進行開發,例如Xcode使用Cocos2dX進行開發遊戲時不當心使用了iOS的控件/組件在項目中,那麼當移植到Android等平臺的時候就確定異常費勁,估計連正常運行都不可能,由於其餘平臺不可能正好有iOS的這些控件,即便有也確定底層實現不同!換句話而言,神馬功能都使用Cocos2dX api實現,儘可能都向X靠攏吧,因此這裏的存儲我也使用X自帶的CCUserDefault;至少使用Cocos2dX自帶的對於跨平臺這一塊確定支持的比較好啦;c++
言歸正傳,先大體介紹一下這個類的API:web
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
Public Member Functions
~CCUserDefault ()
bool
getBoolForKey (
const
char
*pKey,
bool
defaultValue=
false
)
Get
bool
value by key,
if
the key doesn't exist, a
default
value will
return
.
int
getIntegerForKey (
const
char
*pKey,
int
defaultValue=0)
Get integer value by key,
if
the key doesn't exist, a
default
value will
return
.
float
getFloatForKey (
const
char
*pKey,
float
defaultValue=0.0f)
Get
float
value by key,
if
the key doesn't exist, a
default
value will
return
.
double
getDoubleForKey (
const
char
*pKey,
double
defaultValue=0.0)
Get
double
value by key,
if
the key doesn't exist, a
default
value will
return
.
std::string getStringForKey (
const
char
*pKey,
const
std::string &defaultValue=
""
)
Get string value by key,
if
the key doesn't exist, a
default
value will
return
.
void
setBoolForKey (
const
char
*pKey,
bool
value)
Set
bool
value by key.
void
setIntegerForKey (
const
char
*pKey,
int
value)
Set integer value by key.
void
setFloatForKey (
const
char
*pKey,
float
value)
Set
float
value by key.
void
setDoubleForKey (
const
char
*pKey,
double
value)
Set
double
value by key.
void
setStringForKey (
const
char
*pKey,
const
std::string &value)
Set string value by key.
void
flush ()
Save content to xml file.
Static Public Member Functions
static
CCUserDefault * sharedUserDefault ()
static
void
purgeSharedUserDefault ()
static
const
std::string & getXMLFilePath ()
|
從以上能夠一目瞭然CCUserDefault的使用和功能,哈希表結構,Key -Value,key索引Value值;api
提供的存儲都是些基礎類型,bool,int,string,double,float,方法很容易懂:存儲使用set ,獲取使用get !app
那麼最後static方法中能夠看到CCUserDefault類留出了一個sharedUserDefault做爲接口供開發者使用,那麼大概介紹後,下面咱們來寫幾段代碼驗證下:iphone
1
2
3
4
5
6
7
8
|
//咱們這裏簡單存儲條數據
CCUserDefault::sharedUserDefault()->setStringForKey(
"key"
,
"himi"
);
CCUserDefault::sharedUserDefault()->flush();
//這裏必定要提交寫入哦,不然不會記錄到xml中,下次啓動遊戲你就獲取不到value了。
//這裏隨便定義一個string爲了驗證咱們的存儲
string str=
"wahaha"
;
//取出咱們剛存儲的himi,而後賦值給str驗證下;
str= CCUserDefault::sharedUserDefault()->getStringForKey(
"key"
);
CCLog(
"打印str=:%s"
,str.c_str());
|
這裏要注意, CCUserDefault中有個 flush()的函數,這個用來將數據寫入xml文件中,也就是說當你使用setXX的一些函數後記得提交(調用一下flush函數)ide
OK,下面是控制檯輸入的結果:函數
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Cocos2d: cocos2d: cocos2d-1.0.1-x-0.12.0
Cocos2d: cocos2d: GL_VENDOR: Imagination Technologies
Cocos2d: cocos2d: GL_RENDERER: PowerVR SGX 543
Cocos2d: cocos2d: GL_VERSION: OpenGL ES-CM 1.1 IMGSGX543-63.14.2
Cocos2d: cocos2d: GL_MAX_TEXTURE_SIZE: 4096
Cocos2d: cocos2d: GL_MAX_MODELVIEW_STACK_DEPTH: 16
Cocos2d: cocos2d: GL supports PVRTC: YES
Cocos2d: cocos2d: GL supports BGRA8888 textures: NO
Cocos2d: cocos2d: GL supports NPOT textures: YES
Cocos2d: cocos2d: GL supports discard_framebuffer: YES
Cocos2d: cocos2d: compiled with NPOT support: NO
Cocos2d: cocos2d: compiled with VBO support in TextureAtlas : NO
Cocos2d: 打印str=:himi
|
最後一句驗證了咱們的存儲沒問題,那麼咱們如今驗證是否真的存在xml中了,首先中止當前運行的項目,而後刪除剛纔代碼替換以下代碼:加密
1
|
CCLog(
"打印str=:%s"
,CCUserDefault::sharedUserDefault()->getStringForKey(
"key"
).c_str());
|
而後從新運行此項目,觀察控制檯打印以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Cocos2d: cocos2d: cocos2d-1.0.1-x-0.12.0
Cocos2d: cocos2d: GL_VENDOR: Imagination Technologies
Cocos2d: cocos2d: GL_RENDERER: PowerVR SGX 543
Cocos2d: cocos2d: GL_VERSION: OpenGL ES-CM 1.1 IMGSGX543-63.14.2
Cocos2d: cocos2d: GL_MAX_TEXTURE_SIZE: 4096
Cocos2d: cocos2d: GL_MAX_MODELVIEW_STACK_DEPTH: 16
Cocos2d: cocos2d: GL supports PVRTC: YES
Cocos2d: cocos2d: GL supports BGRA8888 textures: NO
Cocos2d: cocos2d: GL supports NPOT textures: YES
Cocos2d: cocos2d: GL supports discard_framebuffer: YES
Cocos2d: cocos2d: compiled with NPOT support: NO
Cocos2d: cocos2d: compiled with VBO support in TextureAtlas : NO
Cocos2d: 打印str=:himi
|
經過剛纔的key->」key」,正常獲取到「himi」這個字符串了,OK,監測沒問題;
那麼通常狀況下咱們會須要一個方法就是斷定當前項目是否已經有存儲數據的xml文件存在了,那麼Himi這裏說下,Cocos2dX默認源碼中有這個方法,可是並無提供給開發者使用,由於此函數被private私有了,此函數源碼以下圖所示:
那麼既然如此Himi這裏就自定義了一個檢測是否已存在數據xml的函數提供你們使用:(提醒:不少童鞋該說啦,爲何不直接修改源碼將其public呢?!其實Himi也這麼想,可是若是你後期使用了新的Cocos2dX的版本,或者同事機器的Cocos2dX並無這麼修改源碼都會產生錯誤,反過來講,既然能很容易的寫出一個判斷的方法何須去動它呢,不是麼?哈哈!)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
.h文件:
bool isHaveSaveFile
(
)
;
.cpp文件:
/
/
當前項目是否存在存儲的xml文件
bool HelloWorld
:
:
isHaveSaveFile
(
)
{
if
(
!CCUserDefault
:
:
sharedUserDefault
(
)
-
>
getBoolForKey
(
"isHaveSaveFileXml"
)
)
{
CCUserDefault
:
:
sharedUserDefault
(
)
-
>
setBoolForKey
(
"isHaveSaveFileXml"
,
true
)
;
CCUserDefault
:
:
sharedUserDefault
(
)
-
>
flush
(
)
;
/
/
提交
/
/
CCLog
(
"存儲文件不存在,頭次開始加載遊戲"
)
;
return
false
;
}
else
{
/
/
CCLog
(
"存儲文件已存在"
)
;
return
true
;
}
}
|
備註:當存儲數據的xml不存在的時候,你的第一次存儲數據的時候默認會建立,路徑在你的app下的documents,以下圖所示:
那麼這裏Himi強調一點!你們要注意setXX的函數的參數,例如如下這個函數:
setStringForKey (const char *pKey, const std::string &value)
第一個參數是const char*類型,不是string!!!!(Himi由於這個緣由浪費很多時間,悲劇阿。)
Himi當時存儲寫了以下代碼,形成錯誤,以下:
1
|
CCUserDefault::sharedUserDefault()->setStringForKey(
""
+823, sKey);
|
錯誤截圖以下:(存儲的key變成了路徑。。。。《數據是Himi加密後的》)
哎,鬱悶,這裏Himi犯錯但願童鞋們不要再範此錯誤,以前Himi一直想找 itoa 找個函數,可是怎麼都找不到!(c++ 應該存在的整形轉字符串),可是Cocos2dX中沒有,而且最後Himi使用了與Cocos2dX引擎中的實現itoa的源碼,發現以下:
Cocos2dX自帶的這個CCUserDefault並非加密的,而是明文而且是.xml格式的,因此後續Himi準備寫一篇使用base64來進行加密的文章供你們參考;
本篇源碼下載:
SaveDataForCocos2dx.zip (667 字節, 1 次)