Cocos2d-x数据模块教程01:UserDefault数据存储

2015年03月23日 12:58 0 点赞 0 评论 更新于 2025-11-21 18:16

这是一个关于Cocos2d-x的数据模块的系列教程,内容涵盖UserDefault数据存储、Json数据操作、XML数据操作、plist文件操作、CSV文件解析以及SQLite3数据库基础用法。

在游戏开发中,游戏存档功能是不可或缺的。在Cocos2d-x中,提供了一个数据存储类CCUserDefault,可作为轻量级数据库使用。它支持五种数据类型的存储,分别是boolintfloatdoublestring

Cocos2d-x 3.x版本的变化

在Cocos2d-x 3.x版本中,CCUserDefault类有以下主要变化:

  1. 去掉 “CC”:类名不再以“CC”开头。
  2. 获取单例方式改变sharedUserDefault() 方法改为 getInstance()
  3. 增加数据类型支持:新增了对 Data 类型的支持,相关接口如下:
    void setDataForKey(const char* pKey, const Data& value);
    Data getDataForKey(const char* pKey, const Data& defaultValue = Data::Null);
    
  4. 其他方面变化不大

CCUserDefault类概述

CCUserDefault 类和之前讲的 CCDirectorSimpleAudioEngine 一样,采用单例模式。可以通过 sharedUserDefault() 函数来获取其唯一的实例对象。

CCUserDefault 采用XML存储技术,以键值对的形式存储数据,类似于C++中的 map 映射,一个关键字对应一个值。其实现的接口简单实用,通过传统的 set()get() 方法来访问和修改值,支持存储 boolintfloatdoublestring 五种数据类型。

原理

  1. 键值映射:类似于 map 的映射关系,一个关键字对应一个值,通过 set()get() 方法进行访问。
  2. 数据存储位置:数据直接存储在一个XML文件中,文件名与程序项目的名字相同,例如 “MyTest.xml”。
  3. 自动创建文件:首次使用时,如果XML文件不存在,CCUserDefault 会自动创建相应的XML文件。

设置数据值(set)

通过键值对的方式设置数据,相关接口如下:

void setBoolForKey(const char* pKey, bool value);               // 设置一个bool值
void setIntegerForKey(const char* pKey, int value);            // 设置一个int值
void setFloatForKey(const char* pKey, float value);            // 设置一个float值
void setDoubleForKey(const char* pKey, double value);          // 设置一个double值
void setStringForKey(const char* pKey, const std::string& value); // 设置一个string值

获取数据值(get)

通过关键字从XML文件中获取数据值。若关键字不存在,会自动设置键值映射,并设置对应的默认值 defaultValue。相关接口如下:

bool getBoolForKey(const char* pKey, bool defaultValue = false);                   // 读取一个bool值
int getIntegerForKey(const char* pKey, int defaultValue = 0);                     // 读取一个int值
float getFloatForKey(const char* pKey, float defaultValue = 0.0);                 // 读取一个float值
double getDoubleForKey(const char* pKey, double defaultValue = 0.0);               // 读取一个double值
std::string getStringForKey(const char* pKey, const std::string& defaultValue = ""); // 读取一个string值

保存数据(flush)

当调用 set 方法设置数据后,数据不会马上保存到XML文件中。因此,一定要记得调用 flush() 方法来保存数据,否则数据会丢失,示例代码如下:

CCUserDefault::sharedUserDefault()->flush();

其他操作

还提供了一些其他操作,如获取单例对象、释放单例对象、获取XML文件路径、判断XML文件是否已经存在,相关接口如下:

static CCUserDefault* sharedUserDefault();  // 获取单例对象
static void purgeSharedUserDefault();       // 释放单例对象
const static std::string& getXMLFilePath(); // 获取XML路径
static bool isXMLFileExist();               // XML文件是否已创建

使用技巧

  1. 宏定义简化代码:每次操作都要写长长的 CCUserDefault::sharedUserDefault() 来获取单例对象,比较麻烦。可以通过宏定义来缩短代码长度,示例如下:
    #define UserDefault CCUserDefault::sharedUserDefault()
    
  2. 注意数据类型区别:在使用时,要特别注意 const char*const std::string 是不同的数据类型。
  3. 及时保存数据:当调用 set 方法设置数据后,一定要记得调用 flush() 方法来保存数据,否则数据会丢失。

代码实战

代码来源于TestCpp项目,以下是具体的实现步骤和代码:

1. 引用头文件和命名空间

因为要使用C++的 string 类型,需要引用以下头文件和命名空间:

#include <string>
using namespace std;

2. 宏定义获取单例对象的函数

#define UserDefault CCUserDefault::sharedUserDefault()

3. 编写数据存储相关操作,并在控制台输出数据值

// 设置set
UserDefault->setBoolForKey("bool", true);
UserDefault->setIntegerForKey("integer", 100);
UserDefault->setFloatForKey("float", 33.33f);
UserDefault->setDoubleForKey("double", 44.44);
UserDefault->setStringForKey("string", "1111111");

// 获取get,并输出到控制台
// 通过关键字,获取数据
bool b = UserDefault->getBoolForKey("bool");
int i = UserDefault->getIntegerForKey("integer");
float f = UserDefault->getFloatForKey("float");
double d = UserDefault->getDoubleForKey("double");
string ret = UserDefault->getStringForKey("string");

// 输出到控制台
CCLOG((b == true)? "bool is true" : "bool is false");
CCLOG("integer is %d", i);
CCLOG("float is %f", f);
CCLOG("double is %f", d);
CCLOG("string is %s", ret.c_str());

// 输出XML文件路径
if (UserDefault->isXMLFileExist()) // 是否存在
{
string path = UserDefault->getXMLFilePath();
CCLOG("XML file is exist!");
CCLOG("XML file path : %s", path.c_str());
}
else
{
CCLOG("XML file is not exist!");
}

// 保存数据
UserDefault->flush();

4. 运行结果

此处未给出具体运行结果,可自行运行代码查看。

5. 分析与总结

  • 浮点数精度问题:在输出结果中,可能会发现 float 类型数据存在精度问题。例如,设置 float 值为 33.33,输出的却是 33.330002。这是因为 float 是单精度浮点数,有效精度在 6 - 7 位,超过 7 位就可能会失真。而 double 是双精度浮点数,有效精度在 15 - 16 位,超过 16 位才会失真。具体原理可自行百度查询。
  • XML文件保存路径getXMLFilePath() 方法获取的XML文件路径为绝对路径,XML文件保存的路径为项目的 Debug.win32 目录中,说明XML文件是保存在应用程序所在目录下的。

作者信息

boke

boke

共发布了 3994 篇文章