本站文章均为 李华明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 次)