【Cocos2d-x游戏开发】Cocos2d-x中的数据存储技术
一、引言
数据存储和网络功能可以说是一款游戏中必不可少的功能,如果一款游戏不能保存进度那么它的可玩性必然大打折扣(试想一下,玩家辛辛苦苦玩了一整天的游戏,结果退出时告诉人家不能保存关卡信息,你明天还得从头来再玩一遍。那玩家一定会掏出准备已久的西瓜刀~)
其实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这个类具体是怎么使用的,先上代码:
bool HelloWorld::init()
{
if ( !Layer::init() )
{
return false;
}
auto* background = LayerColor::create(Color4B(, , , ));
addChild(background);
//创建一个菜单按钮
auto* readLabel = Label::create("read", "Arial", );
readLabel->setColor(Color3B(, , ));
auto* pReadLabel = MenuItemLabel::create(readLabel, this, menu_selector(HelloWorld::readCallback));
auto* buttonReadLabel = Menu::create(pReadLabel, NULL);
buttonReadLabel->setPosition(, );
addChild(buttonReadLabel);
auto* saveLabel = Label::create("save", "Arial", );
saveLabel->setColor(Color3B(, , ));
auto* pSaveLabel = MenuItemLabel::create(saveLabel, this, menu_selector(HelloWorld::saveCallback));
auto* buttonSaveLabel = Menu::create(pSaveLabel, NULL);
buttonSaveLabel->setPosition(, );
addChild(buttonSaveLabel);
UserDefault::sharedUserDefault()->setBoolForKey("isExisted",false);
return true;
}
void HelloWorld::readCallback(Ref* pSender)
{
CCLOG("============================================================");
CCLOG("reading begin!");
//根据isExisted的值来判断,是否数据被写入
if (UserDefault::sharedUserDefault()->getBoolForKey("isExisted"))
{
//读取键值为Int的内容并输出
int intVar = UserDefault::sharedUserDefault()->getIntegerForKey("int");
CCLOG("the int is:%d", intVar);
//读取键值为float的内容并输出
float floatVar = UserDefault::sharedUserDefault()->getFloatForKey("float");
CCLOG("the float is:%f", floatVar);
//读取键值为string的内容并输出
std::string str = UserDefault::sharedUserDefault()->getStringForKey("string");
CCLOG("the string is:%s", str);
}
//如果isExisted的键值为false的话,说明信息没有被保存,不可用
else
{
CCLOG("not exist!");
}
CCLOG("============================================================");
}
void HelloWorld::saveCallback(Ref* pSender)
{
CCLOG("============================================================");
CCLOG("save begin!");
UserDefault::sharedUserDefault()->setIntegerForKey("int", );
UserDefault::sharedUserDefault()->setFloatForKey("float", 3.1415926);
UserDefault::sharedUserDefault()->setStringForKey("string", "this is a string!");
UserDefault::sharedUserDefault()->setBoolForKey("isExisted", true);
CCLOG("saved file path is %s", UserDefault::sharedUserDefault()->getXMLFilePath());
CCLOG("============================================================");
}
程序运行起来以后可以看到read和save两个按钮,点击他们可以看到在控制台打印出来的信息,如下图:


可以看到,数据信息已经被成功的写入并且读取出来了,而且还打印了文件的存放路径。这种方式特别适合保存游戏进度和最高分、排行榜等内容比较少的数据。但是如果数据量比较大的时候就需要采取别的方式了,比如文件读写的方式。
二、Cocos2dx中的文件读写
bool HelloWorld::init()
{
if ( !Layer::init() )
{
return false;
}
// 创建一个菜单按钮,用于读取文件中的内容
auto* background = LayerColor::create(Color4B(, , , ));
addChild(background);
auto* readLabel = Label::create("read", "Arial", );
readLabel->setColor(Color3B(, , ));
auto* pReadLabel = MenuItemLabel::create(readLabel, this, menu_selector(HelloWorld::readCallback));
auto* buttonReadLabel = Menu::create(pReadLabel, NULL);
buttonReadLabel->setPosition(, );
addChild(buttonReadLabel);
auto* saveLabel = Label::create("save", "Arial", );
saveLabel->setColor(Color3B(, , ));
auto* pSaveLabel = MenuItemLabel::create(saveLabel, this, menu_selector(HelloWorld::saveCallback));
auto* buttonSaveLabel = Menu::create(pSaveLabel, NULL);
buttonSaveLabel->setPosition(, );
addChild(buttonSaveLabel);
return true;
}
void HelloWorld::readCallback(Ref* pSender)
{
CCLOG("============================================================");
std::string path = FileUtils::sharedFileUtils()->getWritablePath()+"test.txt";
// 输出文件路径
CCLOG("path = %s", path.c_str());
// 创建一个文件指针
FILE* file = fopen(path.c_str(), "r");
if (file) {
char* buf; //要获取的字符串
int len; //获取的长度
// 获取文件长度长度
fseek(file, , SEEK_END); //移到尾部
len = ftell(file); //提取长度
rewind(file); //回归原位
CCLOG("count the file content len = %d", len);
//分配buf空间
buf = (char*)malloc(sizeof(char) * len + );
if (!buf)
{
CCLOG("malloc space is not enough.");
}
//读取进的buf,单位大小,长度,文件指针
int rLen = fread(buf, sizeof(char), len, file);
buf[rLen] = '\0';
CCLOG("has read Length = %d", rLen);
CCLOG("has read content = %s", buf);
fclose(file);
free(buf);
}
else
{
CCLOG("open file error.");
}
CCLOG("============================================================");
}
void HelloWorld::saveCallback(Ref* pSender)
{
CCLOG("============================================================");
std::string path = CCFileUtils::sharedFileUtils()->getWritablePath() + "test.txt";
FILE* file = fopen(path.c_str(), "w");
if (file)
{
char* pContent = "this is a word";
fputs(pContent, file);
CCLOG("save file succeed.");
fclose(file);
}
else
{
CCLOG("save file error.");
}
CCLOG("============================================================");
}
程序运行调试图:

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
请尊重别人的劳动成果,让分享成为一种美德,欢迎转载。另外,文章在表述和代码方面如有不妥之处,欢迎批评指正。留下你的脚印,欢迎评论!
【Cocos2d-x游戏开发】Cocos2d-x中的数据存储技术的更多相关文章
- 【转】 [Unity3D]手机3D游戏开发:场景切换与数据存储(PlayerPrefs 类的介绍与使用)
http://blog.csdn.net/pleasecallmewhy/article/details/8543181 在Unity中的数据存储和iOS中字典的存储基本相同,是通过关键字实现数据存储 ...
- 【Cocos2d-x游戏开发】Cocos2d-x中的弱联网技术
在上一篇博客中,我们一起学习了如何在Cocos2d-x中存储数据和读取信息,本篇博客我们将一起讨论和数据存储同样重要的联网技术. 一.弱联网技术介绍 在网络游戏中许多重要的功能都需要网络连接,而根据需 ...
- iOS cocos2d 2游戏开发实战(第3版)书评
2013是游戏爆发的一年,手游用户也是飞速暴增.虽然自己不做游戏,但也是时刻了解手机应用开发的新动向.看到CSDN的"写书评得技术图书赢下载分"活动,就申请了一本<iOS c ...
- iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist)
iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist) 一.ios应用常用的数据存储方式 1.plist(XML属性列表归档) 2.偏好设置 3.NSKeydeArchiver归档(存 ...
- 67.Android中的数据存储总结
转载:http://mp.weixin.qq.com/s?__biz=MzIzMjE1Njg4Mw==&mid=2650117688&idx=1&sn=d6c73f9f04d0 ...
- iOS开发UI篇—ios应用数据存储方式(偏好设置)
iOS开发UI篇—ios应用数据存储方式(偏好设置) 一.简单介绍 很多iOS应用都支持偏好设置,比如保存用户名.密码.字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能 每个应用 ...
- iOS开发UI篇—ios应用数据存储方式(归档)
iOS开发UI篇—ios应用数据存储方式(归档) 一.简单说明 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦: 偏好设置(将所有的东西都保存在同 ...
- iOS开发UI篇—ios应用数据存储方式(归档) :转发
本文转发至:文顶顶http://www.cnblogs.com/wendingding/p/3775293.html iOS开发UI篇—ios应用数据存储方式(归档) 一.简单说明 在使用plist ...
- 20.1翻译系列:EF 6中自动数据迁移技术【EF 6 Code-First系列】
原文链接:https://www.entityframeworktutorial.net/code-first/automated-migration-in-code-first.aspx EF 6 ...
随机推荐
- wamp(win1064位家庭版+apache2.4.20+php5.5.37+mysql5.5.50)环境搭建
wamp环境搭建之软件准备 *php:http://windows.php.net/downloads/releases/php-5.5.37-Win32-VC11-x86.zip *apache:h ...
- 20145204&20145212信息安全系统实验三报告
实时系统的移植 实验目的与要求 1.根据实验指导书进行实时软件的安装 2.配置实验环境,并对软件进行测试. 3.正确使用连接线等仪器,注意保护试验箱. 实验内容与步骤 1.连接 arm 开发板 连接实 ...
- 理清Java中的编码解码转换
1.字符集及编码方式 概括:字符编码方式及大端小端 详细:彻底理解字符编码 可以通过Charset.availableCharsets()获取Java支持的字符集,以JDK8为例,得到其支持的字符集: ...
- Javascript 俄罗斯方块 游戏代码解释!
俄罗斯方块代码说明 /** 名称:Javascript 俄罗斯方块! 作者:Gloot 邮箱:glootz@gmail.com QQ:345268267 网站:http://www.cnblogs.c ...
- codevs1228 苹果树
题目描述 Description 在卡卡的房子外面,有一棵苹果树.每年的春天,树上总会结出很多的苹果.卡卡非常喜欢吃苹果,所以他一直都精心的呵护这棵苹果树.我们知道树是有很多分叉点的,苹果会长在枝条的 ...
- [Algorithm] 字符串匹配算法——KMP算法
1 字符串匹配 字符串匹配是计算机的基本任务之一. 字符串匹配是什么?举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串& ...
- SSAS动态添加分区(一)
一.动态分区的好处就不说了,随着时间的推移,不可能一个度量值组都放在一个分区中,处理速度非常慢,如何动态添加分区,如何动态处理分区,成为了很多新手BI工程师一个头痛的问题,废话不多说,分享一下我的经验 ...
- Java实现Excel的操作
JAVA EXCEL API: 开源项目,通过它Java开发人员可以读取Excel文件的内容.创建新的Excel文件.更新已经存在的Excel文件.使用该API非Windows操作系统也可以通过纯Ja ...
- PHP获取指定月份的第一天开始和最后一天结束的时间戳函数
<?php /** * 获取指定月份的第一天开始和最后一天结束的时间戳 * * @param int $y 年份 $m 月份 * @return array(本月开始时间,本月结束时间) */ ...
- CentOS6.3编译安装Memcached
要用到如下源码包: /usr/local/src/memcached/libevent-2.0.21-stable.tar.gz /usr/local/src/memcached/memcached- ...