您的位置:首页 > 移动开发 > Cocos引擎

【Cocos2d-x游戏开发】Cocos2d-x中的数据存储技术

2016-08-07 11:33 701 查看
  一、引言

  数据存储和网络功能可以说是一款游戏中必不可少的功能,如果一款游戏不能保存进度那么它的可玩性必然大打折扣(试想一下,玩家辛辛苦苦玩了一整天的游戏,结果退出时告诉人家不能保存关卡信息,你明天还得从头来再玩一遍。那玩家一定会掏出准备已久的西瓜刀~)

  其实Cocos2d-x引擎早已为我们开发者封装好了多种数据存储的类或者方法,包括简单信息的存储,文件的读写,SQLite数据库和RAR格式的压缩文件的读取等等。(用心良苦啊!)其中大部分的存储功能被封装到了UserDefault类中。

  二、数据存储

  1.UserDefault类

  UserDefault 是一个小型的数据管理类。你可以通过这个类保存并获得基本类型值的数据。 例如:
setBoolForKey("played", true)
将在数据库中添加一个值为 true 的布尔型数据。 它的 key 是 "player"。可以通过
getBoolForKey("player")
获取这个数据。

  UserDefault类提供了一些常用的方法用于读取和存储数据信息,如下表:

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(255, 255, 255, 255));
addChild(background);
    //创建一个菜单按钮
auto* readLabel = Label::create("read", "Arial", 56);
readLabel->setColor(Color3B(0, 0, 0));
auto* pReadLabel = MenuItemLabel::create(readLabel, this, menu_selector(HelloWorld::readCallback));
auto* buttonReadLabel = Menu::create(pReadLabel, NULL);
buttonReadLabel->setPosition(320, 260);
addChild(buttonReadLabel);
auto* saveLabel = Label::create("save", "Arial", 56);
saveLabel->setColor(Color3B(0, 0, 0));
auto* pSaveLabel = MenuItemLabel::create(saveLabel, this, menu_selector(HelloWorld::saveCallback));
auto* buttonSaveLabel = Menu::create(pSaveLabel, NULL);
buttonSaveLabel->setPosition(320, 100);
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", 999);
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(255, 255, 255, 255));
addChild(background);
auto* readLabel = Label::create("read", "Arial", 56);
readLabel->setColor(Color3B(0, 0, 0));
auto* pReadLabel = MenuItemLabel::create(readLabel, this, menu_selector(HelloWorld::readCallback));
auto* buttonReadLabel = Menu::create(pReadLabel, NULL);
buttonReadLabel->setPosition(320, 260);
addChild(buttonReadLabel);
auto* saveLabel = Label::create("save", "Arial", 56);
saveLabel->setColor(Color3B(0, 0, 0));
auto* pSaveLabel = MenuItemLabel::create(saveLabel, this, menu_selector(HelloWorld::saveCallback));
auto* buttonSaveLabel = Menu::create(pSaveLabel, NULL);
buttonSaveLabel->setPosition(320, 100);
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, 0, SEEK_END);   //移到尾部
len = ftell(file);          //提取长度
rewind(file);               //回归原位
CCLOG("count the file content len = %d", len);
//分配buf空间
buf = (char*)malloc(sizeof(char) * len + 1);
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中的弱联网技术。

作者:马三小伙儿
出处:/article/11872676.html
请尊重别人的劳动成果,让分享成为一种美德,欢迎转载。另外,文章在表述和代码方面如有不妥之处,欢迎批评指正。留下你的脚印,欢迎评论!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐