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

  一、引言

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

  其实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这个类具体是怎么使用的,先上代码:

 1 bool HelloWorld::init()
 2 {
 3     if ( !Layer::init() )
 4     {
 5         return false;
 6     }
 7     auto* background = LayerColor::create(Color4B(255, 255, 255, 255));
 8     addChild(background);    //创建一个菜单按钮
 9     auto* readLabel = Label::create("read", "Arial", 56);
10     readLabel->setColor(Color3B(0, 0, 0));
11     auto* pReadLabel = MenuItemLabel::create(readLabel, this, menu_selector(HelloWorld::readCallback));
12     auto* buttonReadLabel = Menu::create(pReadLabel, NULL);
13     buttonReadLabel->setPosition(320, 260);
14     addChild(buttonReadLabel);
15     auto* saveLabel = Label::create("save", "Arial", 56);
16     saveLabel->setColor(Color3B(0, 0, 0));
17     auto* pSaveLabel = MenuItemLabel::create(saveLabel, this, menu_selector(HelloWorld::saveCallback));
18     auto* buttonSaveLabel = Menu::create(pSaveLabel, NULL);
19     buttonSaveLabel->setPosition(320, 100);
20     addChild(buttonSaveLabel);
21     UserDefault::sharedUserDefault()->setBoolForKey("isExisted",false);
22     return true;
23 }
24 void HelloWorld::readCallback(Ref* pSender)
25 {
26     CCLOG("============================================================");
27     CCLOG("reading begin!");    //根据isExisted的值来判断,是否数据被写入
28     if (UserDefault::sharedUserDefault()->getBoolForKey("isExisted"))
29     {      //读取键值为Int的内容并输出
30         int intVar = UserDefault::sharedUserDefault()->getIntegerForKey("int");
31         CCLOG("the int is:%d", intVar);      //读取键值为float的内容并输出      
32         float floatVar = UserDefault::sharedUserDefault()->getFloatForKey("float");
33         CCLOG("the float is:%f", floatVar);      //读取键值为string的内容并输出
34         std::string str = UserDefault::sharedUserDefault()->getStringForKey("string");
35         CCLOG("the string is:%s", str);
36     }    //如果isExisted的键值为false的话,说明信息没有被保存,不可用
37     else
38     {
39         CCLOG("not exist!");
40     }
41     CCLOG("============================================================");
42 }
43 void HelloWorld::saveCallback(Ref* pSender)
44 {
45     CCLOG("============================================================");
46     CCLOG("save begin!");
47     UserDefault::sharedUserDefault()->setIntegerForKey("int", 999);
48     UserDefault::sharedUserDefault()->setFloatForKey("float", 3.1415926);
49     UserDefault::sharedUserDefault()->setStringForKey("string", "this is a string!");
50     UserDefault::sharedUserDefault()->setBoolForKey("isExisted", true);
51     CCLOG("saved file path is %s", UserDefault::sharedUserDefault()->getXMLFilePath());
52     CCLOG("============================================================");
53 }

  程序运行起来以后可以看到read和save两个按钮,点击他们可以看到在控制台打印出来的信息,如下图:

  

  可以看到,数据信息已经被成功的写入并且读取出来了,而且还打印了文件的存放路径。这种方式特别适合保存游戏进度和最高分、排行榜等内容比较少的数据。但是如果数据量比较大的时候就需要采取别的方式了,比如文件读写的方式。

  二、Cocos2dx中的文件读写

 1 bool HelloWorld::init()
 2 {
 3     if ( !Layer::init() )
 4     {
 5         return false;
 6     }
 7     // 创建一个菜单按钮,用于读取文件中的内容
 8     auto* background = LayerColor::create(Color4B(255, 255, 255, 255));
 9     addChild(background);
10     auto* readLabel = Label::create("read", "Arial", 56);
11     readLabel->setColor(Color3B(0, 0, 0));
12     auto* pReadLabel = MenuItemLabel::create(readLabel, this, menu_selector(HelloWorld::readCallback));
13     auto* buttonReadLabel = Menu::create(pReadLabel, NULL);
14     buttonReadLabel->setPosition(320, 260);
15     addChild(buttonReadLabel);
16     auto* saveLabel = Label::create("save", "Arial", 56);
17     saveLabel->setColor(Color3B(0, 0, 0));
18     auto* pSaveLabel = MenuItemLabel::create(saveLabel, this, menu_selector(HelloWorld::saveCallback));
19     auto* buttonSaveLabel = Menu::create(pSaveLabel, NULL);
20     buttonSaveLabel->setPosition(320, 100);
21     addChild(buttonSaveLabel);
22     return true;
23 }
24 void HelloWorld::readCallback(Ref* pSender)
25 {
26     CCLOG("============================================================");
27     std::string path = FileUtils::sharedFileUtils()->getWritablePath()+"test.txt";
28     // 输出文件路径
29     CCLOG("path = %s", path.c_str());
30     // 创建一个文件指针
31     FILE* file = fopen(path.c_str(), "r");
32     if (file) {
33         char* buf;  //要获取的字符串
34         int len;    //获取的长度
35         // 获取文件长度长度
36         fseek(file, 0, SEEK_END);   //移到尾部
37         len = ftell(file);          //提取长度
38         rewind(file);               //回归原位
39         CCLOG("count the file content len = %d", len);
40         //分配buf空间
41         buf = (char*)malloc(sizeof(char) * len + 1);
42         if (!buf)
43         {
44             CCLOG("malloc space is not enough.");
45         }
46         //读取进的buf,单位大小,长度,文件指针
47         int rLen = fread(buf, sizeof(char), len, file);
48         buf[rLen] = ‘\0‘;
49         CCLOG("has read Length = %d", rLen);
50         CCLOG("has read content = %s", buf);
51         fclose(file);
52         free(buf);
53     }
54     else
55     {
56         CCLOG("open file error.");
57     }
58     CCLOG("============================================================");
59 }
60 void HelloWorld::saveCallback(Ref* pSender)
61 {
62     CCLOG("============================================================");
63     std::string path = CCFileUtils::sharedFileUtils()->getWritablePath() + "test.txt";
64     FILE* file = fopen(path.c_str(), "w");
65     if (file)
66     {
67         char* pContent = "this is a word";
68         fputs(pContent, file);
69         CCLOG("save file succeed.");
70         fclose(file);
71     }
72     else
73     {
74         CCLOG("save file error.");
75     }
76     CCLOG("============================================================");
77 }

 程序运行调试图:

 

  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 
请尊重别人的劳动成果,让分享成为一种美德,欢迎转载。另外,文章在表述和代码方面如有不妥之处,欢迎批评指正。留下你的脚印,欢迎评论!

时间: 2024-10-17 07:54:41

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

【转】 [Unity3D]手机3D游戏开发:场景切换与数据存储(PlayerPrefs 类的介绍与使用)

http://blog.csdn.net/pleasecallmewhy/article/details/8543181 在Unity中的数据存储和iOS中字典的存储基本相同,是通过关键字实现数据存储与调用. 下面来介绍一下Unity用来存储数据的PlayerPrefs 类. 使用PlayerPrefs可以在在游戏会话中保持并访问玩家偏好设置. 在Mac OS X上PlayerPrefs存储在-/Library/PlayerPrefs文件夹, 名文unity/[companyname]\[pro

cocos2d 游戏开发:Cocos2d v3 "hello world"+显示飞船

V3 RC4 版本图片 显示一个飞船 将Chapter1中 SpaceCargoShip.png 文件 添加到项目里面. 代码在 init : CCSprite *spaceCargoShip = [CCSprite spriteWithImageNamed:@"SpaceCargoShip.png"]; [spaceCargoShip setPosition:ccp(200.0f,150.9f)]; [self addChild:spaceCargoShip]; 在上面的代码下增加如

小程序云开发向数据库中新增数据

小程序云开发向数据库中新增数据,基本操作在新建完一个云项目后都有了,右键上传部署login云函数后,就可以在模拟器中简单地操作数据库了 这是databaseGuide.js生成时就给出的代码,增删改查都需要先将相关部分的代码去掉注释. // pages/databaseGuide/databaseGuide.js const app = getApp() Page({ data: { step: 1, counterId: '', openid: '', count: null, queryRe

iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist

iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist) 一.ios应用常用的数据存储方式 1.plist(XML属性列表归档) 2.偏好设置 3.NSKeydeArchiver归档(存储自定义对象) 4.SQLite3(数据库,关系型数据库,不能直接存储对象,要编写一些数据库的语句,将对象拆开存储) 5.Core Data(对象型的数据库,把内部环节屏蔽) 二.应用沙盒 每个iOS应用都有?己的应?沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应?必须待在?己的沙盒里,其

安卓开发_数据存储技术_sqlite

一.SQLite SQLite第一个Alpha版本诞生于2000年5月,它是一款轻量级数据库,它的设计目标是嵌入式的,占用资源非常的低,只需要几百K的内存就够了.SQLite已经被多种软件和产品使用 二.SQLite特性 1 2 1.轻量级 3 SQLite和C\S模式的数据库软件不同,它是进程内的数据库引擎,因此不存在数据库的客户端和服务器.使用SQLite一般只需要带上它的一个动态库,就可以享受它的全部功能.而且那个动态库的尺寸也相当小. 4 2.独立性 5 SQLite数据库的核心引擎本身

OS开发UI篇—ios应用数据存储方式(归档)

OS开发UI篇—ios应用数据存储方式(归档)  一.简单说明 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦: 偏好设置(将所有的东西都保存在同一个文件夹下面,且主要用于存储应用的设置信息) 归档:因为前两者都有一个致命的缺陷,只能存储常用的类型.归档可以实现把自定义的对象存放在文件中. 二.代码示例 1.文件结构 2.代码示例 YYViewController.m文件 1 // 2 // YYViewController.m 3 // 02

iOS开发UI篇—ios应用数据存储方式(归档)

iOS开发UI篇-ios应用数据存储方式(归档)  一.简单说明 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦: 偏好设置(将所有的东西都保存在同一个文件夹下面,且主要用于存储应用的设置信息) 归档:因为前两者都有一个致命的缺陷,只能存储常用的类型.归档可以实现把自定义的对象存放在文件中. 二.代码示例 1.文件结构 2.代码示例 YYViewController.m文件 1 // 2 // YYViewController.m 3 // 0

67.Android中的数据存储总结

转载:http://mp.weixin.qq.com/s?__biz=MzIzMjE1Njg4Mw==&mid=2650117688&idx=1&sn=d6c73f9f04d02ede7a741b45e801d74e#rd 本篇文章会帮助大家快速了解Android中各种数据存储机制的应用场景以及基本使用方法,力求在头脑中建立一个“目录”.有了这个目录,具体使用细节在实际应用时再查询文档即可得到. 0. 概述 Android为我们提供了以下存储机制: Shared Preferenc

iOS开发UI篇—ios应用数据存储方式(偏好设置)

iOS开发UI篇—ios应用数据存储方式(偏好设置) 一.简单介绍 很多iOS应用都支持偏好设置,比如保存用户名.密码.字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能 每个应用都有个NSUserDefaults实例,通过它来存取偏好设置.比如,保存用户名.字体大小.是否自动登录 存储位置: 存储形式: 二.代码示例 1.storyboard 2.代码 1 // Created by 鑫 on 14-10-24. 2 // Copyright (c) 2014年 梁镋鑫.