【iOS-cocos2d-X 游戏开发之五】游戏存储之Cocos2dX自带CCUserDefault

本站文章均为
http://www.himigame.com/about-himi原创,转载务必在明显处注明:
转载自
http://www.himigame.com/ 原文链接: http://www.himigame.com/iphone-cocos2dx/653.html

http://list.qq.com/cgi-bin/qf_invite?id=acfc24e272cc4a26debf3b3866edb626a9ea3fc80fd8893c 本博客最新动态!及时将最新博文通知您!本篇跟大家分享下Cocos2dX中的存储,其中也介绍些细节容易犯错的问题;在Cocos2dX中提供了自带存储类:CCUserDefault ,当然了这里Himi强调一点,如果你的数据量比较大,建议使用SQL存储比较适合,另外一点要注意的是,尽可能不要在Cocos2dX中使用与平台相关的api进行开发,例如Xcode使用Cocos2dX进行开发游戏时不小心使用了iOS的控件/组件在项目中,那么当移植到Android等平台的时候就肯定异常费劲,估计连正常运行都不可能,因为其他平台不可能正好有iOS的这些控件,即使有也肯定底层实现不一样!换句话而言,神马功能都使用Cocos2dX api实现,尽量都向X靠拢吧,所以这里的存储我也使用X自带的CCUserDefault;至少使用Cocos2dX自带的对于跨平台这一块肯定支持的比较好啦;言归正传,先大致介绍一下这个类的API:
从以上可以一目了然CCUserDefault的使用和功能,哈希表结构,Key -Value,key索引Value值;提供的存储都是些基础类型,bool,int,string,double,float,方法很容易懂:存储使用set ,获取使用get !那么最后static方法中可以看到CCUserDefault类留出了一个sharedUserDefault作为接口供开发者使用,那么大概介绍后,下面我们来写几段代码验证下:

//我们这里简单存储条数据
    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函数)OK,下面是控制台输入的结果:

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中了,首先停止当前运行的项目,然后删除刚才代码替换如下代码

CCLog("打印str=:%s",CCUserDefault::sharedUserDefault()->getStringForKey("key").c_str());

然后重新运行此项目,观察控制台打印如下:


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私有了,此函数源码如下图所示:

.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;
    }
}

http://www.himigame.com/wp-content/uploads/2012/03/1111.png

那么既然如此Himi这里就自定义了一个检测是否已存在数据xml的函数提供大家使用:(提醒:很多童鞋该说啦,为什么不直接修改源码将其public呢?!其实Himi也这么想,但是如果你后期使用了新的Cocos2dX的版本,或者同事机器的Cocos2dX并没有这么修改源码都会产生错误,反过来说,既然能很容易的写出一个判断的方法何必去动它呢,不是么?哈哈!)http://www.himigame.com/wp-content/uploads/2012/03/22221.png

那么这里Himi强调一点!大家要注意setXX的函数的参数,例如以下这个函数:setStringForKey (const char *pKey, const std::string &value)第一个参数是const char*类型,不是string!!!!(Himi因为这个原因浪费不少时间,悲剧阿。)Himi当时存储写了如下代码,造成错误,如下:

CCUserDefault::sharedUserDefault()->setStringForKey(""+823, sKey);

错误截图如下:(存储的key变成了路径。。。。《数据是Himi加密后的》)http://www.himigame.com/wp-content/uploads/2012/03/error.png

哎,郁闷,这里Himi犯错希望童鞋们不要再范此错误,之前Himi一直想找 itoa 找个函数,但是怎么都找不到!(c++ 应该存在的整形转字符串),但是Cocos2dX中没有,并且最后Himi使用了与Cocos2dX引擎中的实现itoa的源码,发现如下:http://www.himigame.com/wp-content/uploads/2012/03/33333.png

Cocos2dX自带的这个CCUserDefault并不是加密的,而是明文并且是.xml格式的,所以后续Himi准备写一篇使用base64来进行加密的文章供大家参考;本篇源码下载:

SaveDataForCocos2dx.zip (667 字节, 11 次)
http://www.himigame.com/login
登录
后即可免费下载本站所有资源。

  • 本帖最后由 romejiang 于 2012-4-18 11:54 编辑 *

http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=308&extra=page%3D1
http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=310&extra=page%3D1
http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=312&extra=page%3D1
http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=314&extra=page%3D1
http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=316&extra=page%3D1
http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=318&extra=page%3D1
http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=320&extra=page%3D1
http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=322&extra=page%3D1
http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=324&extra=page%3D1
http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=326&extra=page%3D1
http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=328&extra=page%3D1
http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=330&extra=page%3D1
http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=332&extra=page%3D1
http://cocos2d.cocoachina.com/bbs/forum.php?mod=viewthread&tid=334&extra=page%3D1

{:soso_e179:}楼主很强悍。
顺便MARK

好像CCUserDefault的key_value键值对的key不能是整数,有人验件没?

不断学习中。…