本站文章均为[ 李华明Himi ](http://www.himigame.com/about-himi)原创,转载务必在明显处注明:
转载自[【黑米GameDev街区】](http://www.himigame.com/) 原文链接: [http://www.himigame.com/iphone-cocos2dx/653.html](http://www.himigame.com/iphone-cocos2dx/653.html "【iOS-cocos2d-X")
本篇跟大家分享下Cocos2dX中的存储,其中也介绍些细节容易犯错的问题;
在Cocos2dX中提供了自带存储类:CCUserDefault ,当然了这里Himi强调一点,如果你的数据量比较大,建议使用SQL存储比较适合,另外一点要注意的是,尽可能不要在Cocos2dX中使用与平台相关的api进行开发,例如Xcode使用Cocos2dX进行开发游戏时不小心使用了iOS的控件/组件在项目中,那么当移植到Android等平台的时候就肯定异常费劲,估计连正常运行都不可能,因为其他平台不可能正好有iOS的这些控件,即使有也肯定底层实现不一样!换句话而言,神马功能都使用Cocos2dX api实现,尽量都向X靠拢吧,所以这里的存储我也使用X自带的CCUserDefault;至少使用Cocos2dX自带的对于跨平台这一块肯定支持的比较好啦;
言归正传,先大致介绍一下这个类的API:
~~~
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值;
提供的存储都是些基础类型,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私有了,此函数源码如下图所示:
[![](https://box.kancloud.cn/2016-03-31_56fcd020f09a3.png "111")](http://www.himigame.com/wp-content/uploads/2012/03/1111.png) 那么既然如此Himi这里就自定义了一个检测是否已存在数据xml的函数提供大家使用:(提醒:很多童鞋该说啦,为什么不直接修改源码将其public呢?!其实Himi也这么想,但是如果你后期使用了新的Cocos2dX的版本,或者同事机器的Cocos2dX并没有这么修改源码都会产生错误,反过来说,既然能很容易的写出一个判断的方法何必去动它呢,不是么?哈哈!)
~~~
.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,如下图所示:
[![](https://box.kancloud.cn/2016-03-31_56fcd021136d5.png "2222")](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加密后的》)
[![](https://box.kancloud.cn/2016-03-31_56fcd0212cae1.png "error")](http://www.himigame.com/wp-content/uploads/2012/03/error.png)
哎,郁闷,这里Himi犯错希望童鞋们不要再范此错误,之前Himi一直想找 itoa 找个函数,但是怎么都找不到!(c++ 应该存在的整形转字符串),但是Cocos2dX中没有,并且最后Himi使用了与Cocos2dX引擎中的实现itoa的源码,发现如下:
[![](https://box.kancloud.cn/2016-03-31_56fcd0214653e.png "33333")](http://www.himigame.com/wp-content/uploads/2012/03/33333.png)
Cocos2dX自带的这个CCUserDefault并不是加密的,而是明文并且是.xml格式的,所以后续Himi准备写一篇使用base64来进行加密的文章供大家参考;
本篇源码下载:
[SaveDataForCocos2dx.zip](http://www.himigame.com/?dl_id=62) (667 字节, 1 次)
- 前言
- 【Iphone 游戏开发】游戏引擎剖析
- [Object-C语言随笔之一]Mac os 下搭建iOS开发环境
- [Object-C语言随笔之二] 《NSLog》常用的打印调试语句与自动排版
- [Object-C语言随笔之三] 类的创建和实例化以及函数的添加和调用!
- [Object-C语言随笔之四]创建视图并绘制简单图形
- 【iOS-Cocos2d游戏开发之一】搭建cocos2d游戏引擎环境HelloWorld!
- 【iOS-Cocos2d游戏开发之二】Cocos2D 游戏开发资源贴(教程以及源码)
- 【iOS-Cocos2d游戏开发之三】CCScene切换的所有特效(28种)以及设置屏幕横竖屏!
- 【iOS-Cocos2d游戏开发之四】独自收集Cocos2d提供的字体!共57种(有对照的字体图)
- 【iOS-Cocos2d游戏开发之五】多触点与触屏事件详解(单一监听、事件分发)【11月28日更新】
- 【iOS-Cocos2d游戏开发之六】对触屏事件追加讲解,解决无法触发ccTouchMoved事件[重要!]
- 【iOS-Cocos2d游戏开发之七】在cocos2d中添加/删除系统组件,并解决View设置透明会影响View中的其他组件的问题!【11月28日更新解决添加组件Cocos2d动画停止播放的BUG】
- 【iOS-Cocos2d游戏开发之八】开启高清(960*640)模式问题与解答、图片适配以及设置iphone横竖屏
- 【iOS-Cocos2d游戏开发之九】讲解CCSpriteBatchNode与TP工具的".pvr.ccz",".plist"共用的终极精灵优化及注意事项!
- 【iOS-Cocos2d游戏开发之十】添加粒子系统特效并解决粒子特效与Layer之间的坐标问题;
- 【iOS-Cocos2d游戏开发之十一】使用Box2d物理系统以及在cocos2d框架添加Box2d物理系统lib包的方法
- 【iOS-Cocos2d游戏开发之十二】浅析使用C++/C/OC进行iOS游戏混编出现“failed with exit”问题与小结;
- 【iOS-Cocos2d游戏开发之十三】CCSprite利用Bezier(贝塞尔)做抛物线动作并让CCSprite同时播放两个Action动作!
- 【iOS-Cocos2d游戏开发之十四】音频/音效/视频播放(利用Cocos2D-iPhone-Extensions嵌入Cocos2d进行视频播放!)
- 【iOS-Cocos2d游戏开发之十五】详解CCProgressTimer 进度条并修改cocos2d源码实现“理想”游戏进度条!
- 【iOS-Cocos2d游戏开发之十六】添加本地通知(UILocalNotification)以及添加系统组件滚动视图(UIScrollView)!【2011年11月15日更新】
- 【iOS-Cocos2d游戏开发之十七】灵活使用精灵可视区域(TextureRect)与锚点(anchorPoint),并结合可视区域与锚点制作进度条!
- 【iOS开发必备指南合集】申请企业级IDP、真机调试、游戏接入GameCenter 指南(实现仿官方的成就提示)、游戏接入OpenFeint指南;
- 【iOS-Cocos2d游戏开发之十八】解决滚屏背景/拼接地图有黑边(缝隙)/动画播放出现毛边以及禁止游戏中自动锁屏问题!【2011年12月18日补充】
- 【iOS开发必收藏】详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程!【2012-12-11日更新获取"产品付费数量等于0的问题"】
- 【iOS-cocos2d-X 游戏开发之一】在Mac下结合Xcode搭建Cocos2d-X开发环境!
- 【iOS-cocos2d-X 游戏开发之二】【必看篇】总结阐述Cocos2d-X与Cocos2d-iphone区别;
- 【iOS-Cocos2d游戏开发之十九】游戏数据存储的四种常用方式NSKeyedArchiver/NSUserDefaults/Write写入/SQLite3
- 【iOS-Cocos2d游戏开发之二十】精灵的基础知识点总汇(位图操作/贴图更换/重排z轴等)以及利用CCSprite与CCLayerColor制作简单遮盖层!
- 【iOS-Cocos2d游戏开发之二十一 】自定义精灵类并为你的精灵设置攻击帧(指定开始帧)以及扩展Cocos2d源码的CCAnimation简化动画创建!
- 【iOS-Cocos2d游戏开发之二十二 】CCSpeed实现CCAnimate动画进行时设置慢动作以及设置游戏加减速进行(塔防游戏必备)!
- 【iOS-cocos2d-X 游戏开发之三】Mac下配置Android NDK环境并搭建Cocos2d-x环境并Eclipse正常编译运行Cocos2dX自带TestsDemo项目!
- 【iOS-cocos2d-X 游戏开发之四】Cocos2dX创建Android NDK新项目并编译导入Eclipse中正常运行!
- 【iOS-cocos2d-X 游戏开发之五】游戏存储之Cocos2dX自带CCUserDefault类详解;
- 【iOS-cocos2d-X 游戏开发之六】使用Base64算法对Cocos2dX自带CCUserDefault游戏存储数据编码!
- 【iOS-cocos2d-X 游戏开发之七】整合Cocos2dX的Android项目到Xcode项目中,Xcode编写&编译代码,Android导入打包运行即可!
- 【iOS-iap防护】验证用户付费收据!拒绝iap Cracker!拒绝iap Free!让iphone越狱用户无从下手!【2012年5月2日更新防护iap Free的方法】
- 【COCOS2DX-LUA 脚本开发之一】在Cocos2dX游戏中使用Lua脚本进行游戏开发(基础篇)并介绍脚本在游戏中详细用途!
- 【iOS-cocos2d-X 游戏开发之九】Cocos2dx利用CCSAXParser解析xml数据&CCMutableDictionary使用与注意!
- 【iOS-cocos2d-X 游戏开发之十】自定义CCSprite/Layer/CCNode及静态类模版&自定义类细节说明&Cocos2dx触屏事件讲解
- 【iOS-cocos2d-X 游戏开发之十一】New CCSprite()带来的错误&使用CCUserDefault及pvr.ccz在Cocos2dx中要注意!
- 【iOS-cocos2d-X 游戏开发之十二】自定义Cocos2dx摇杆(增强Joystick),增加摇杆跟随用户触点作为摇杆坐标,让摇杆不再死板!
- 【iOS-cocos2d-X 游戏开发之十三】详细讲解在Xcode中利用预编译并通过Jni调用Android的Java层代码(cocos2dx里访问调用Android函数)!
- 【iOS-cocos2d-X 游戏开发之十四】Xcode中c++&Object-C混编,详细介绍如何在cocos2dx中访问object函数以及Apple Api
- 【iOS-cocos2d-X 游戏开发之十五】Cocos2dx中响应Android的Back(返回)与Menu(小房子)事件&&Cocos2dx自动释放粒子内存函数!
- 【iOS-cocos2d-X 游戏开发之十六】配置你的Cocos2dx项目编译后的Android自动使用(-hd)高清图&设置Android自适应屏幕、缩放比例方法!
- 【Cocoa(mac) Application 开发系列之四】动作编辑器(Cocos2dx)制作流程详解及附上响应鼠标滚轴事件、反转坐标系、导入/创建资源目录等知识点代码!
- 【Cocos2d-X(2.x) 游戏开发系列之一】cocos2dx(v2.x)与(v1.x)的一些常用函数区别讲解!在2.x版CCFileData类被去除等
- 【Cocos2d-X(2.x) 游戏开发系列之二】cocos2dx最新2.0.1版本跨平台整合NDK+Xcode,Xcode编写&编译代码,Android导入打包运行即可!
- 【Cocos2dX(2.x)_Lua开发之三】★重要必看篇★在Lua中使用自定义精灵(Lua脚本与自创建类之间的访问)及Lua基础讲解
- 【Cocos2d-X(2.x) 游戏开发系列之三】最新版本cocos2d­2.0­x­2.0.2使用新资源加载策略!不再沿用-hd、-ipad、-ipadhd添加后缀方式
- 【Cocos2d-X(1.x 2.x) 修复篇】iOS6 中 libcurl.a 无法通过armv7s编译以及iOS6中无法正常游戏横屏的解决方法
- 【Cocos2d-X(1.x 2.x) 】iOS6与iphone5适相关设置随笔(解决第三方类库无法通过armv7s编译的方法、添加Default-568h@2x.png)