在cocos2dx中提供了一个数据存储类CCUserDefault,可以作为一个轻量级的数据库来使用。它支持五种数据bool、int、float、double、string的存储。

【3.x】

    (1)去掉 “CC”

    (2)获取单例:sharedUserDefault() 改为 getInstance()

    (3)增加数据值:Data

//
void setDataForKey(const char* pKey, const Data& value);
Data getDataForKey(const char* pKey, const Data& defaultValue = Data::Null);
//

【CCUserDefault】

CCUserDefault类和之前讲的CCDirector、SimpleAudioEngine一样,都是采用单例模式。

可以通过sharedUserDefault()函数来获取其唯一的实例对象。

CCUserDefault采用XML存储技术,就是一般的键值对,这个类似C++中的map的映射(键——值)。一个关键字对应一个值。其实现的接口也比较简单实用,通过传统的set()、get()方法访问和修改值。

它支持五种数据:boolintfloatdoublestring

1、原理

(1)类似map的映射(键——值)。一个关键字对应一个值,并利用set()/get()进行访问。

(2)数据直接存储在一个XML文件中,并且文件名为程序项目的名字,如“MyTest.xml”。

(3)首次使用时,XML不存在,CCUserDefault会自动创建相应的XML文件。

2、设置数据值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值
//

3、获取数据值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值
//

4、保存flush

当set完后,数据不会马上保存到XML文件中。

所以一定要记得用flush()来保存数据,否则会丢失!

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

5、其他操作

获取单例对象、释放单例对象、获取XML文件路径、判断XML文件是否已经存在。

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

6、使用技巧

(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、分析与总结

(1)不知道大家是否发现输出的结果有问题?float我设置的是33.33,为何输出的是33.330002。不是应该输出33.330000才对吗?

这个就要讲讲C++浮点数的精度问题了,float是单精度浮点数,而double是双精度浮点数。float的有效精度在6~7位,超过7位就可能会失真,就像上面的那个例子一样。而double的有效精度在15~16位,超过16位才会失真。

(2)getXMLFilePath()获取的XML文件路径为绝对路径。另外XML文件保存的路径为项目的Debug.win32中,说明XML文件是保存在应用程序所在目录下的。

cocos2dx基础篇(18) 数据存储CCUserDefault的更多相关文章

  1. cocos2dx基础篇(3) 常用重要类

    ---------------------------------------- 入口类main.cpp 主要控制类AppDelegate.cpp -------------------------- ...

  2. 有评论就是我最大的动力~MySQL基础篇完结(存储引擎和图形化管理工具)

    hi 今天登上来,发现竟然有了3个评论~~加油吧! 这周的计划其实远远没有达到,然后下周还有一大堆事情...那么...周末好好玩吧~ 今天试图完结MySQL的基础篇知识,小白变为大白? 1.MySQL ...

  3. 3.Ceph 基础篇 - RBD 块存储使用

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247485253&idx=1&sn=24d9b06a ...

  4. Android 基础-3.0 数据存储方式

    Android几种数据存储方式 文件存储 SharedPreference存储 Json解析 SQLite数据库存储 文件存储 文件存储是Android中最基本的一种存储方式,和Java中实现I/O的 ...

  5. 【读书笔记《Android游戏编程之从零开始》】20.游戏开发基础(游戏数据存储)

    对于数据的存储,Android 提供了4种保存方式. (1)SharedPreference 此方法适用于简单数据的保持,文如其名,属于配置性质的保存,不适合比较大的情况,默认存放在手机内存里 (2) ...

  6. Android开发手记(18) 数据存储三 SQLite存储数据

    Android为数据存储提供了五种方式: 1.SharedPreferences 2.文件存储 3.SQLite数据库 4.ContentProvider 5.网络存储 SQLite 是以嵌入式为目的 ...

  7. Android学习之基础知识九—数据存储(持久化技术)

    数据持久化是将那些内存中的瞬时数据保存到存储设备,保证即使在手机或电脑关机的情况下,这些数据仍然不会丢失. Android系统中主要提供了3种方式用于简单地实现数据持久化功能:文件存储.SharedP ...

  8. iOS UI基础-13.0 数据存储

    应用沙盒 每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应用必须待在自己的沙盒里,其他应用不能访问该沙盒 应用沙盒的文件系统目录,如下图所示(假设应用的名称叫Lay ...

  9. cocos2dx基础篇(26) 单例模式

    单例模式,说的通俗一点就是:创建某个类的全局唯一静态实例对象.也就是说从它创建开始,一直到整个游戏程序结束才会释放资源,期间一直保存的着数据. 单例类在大部分游戏中应该是必不可少的部分,如整个游戏音乐 ...

随机推荐

  1. (转) Java中的负数及基本类型的转型详解

    (转) https://my.oschina.net/joymufeng/blog/139952 面这行代码的输出是什么? 下面两行代码的输出相同吗? 请尝试在Eclipse中运行上面的两个代码片段, ...

  2. robotframework调用外部python多次运行拿到的都是同一个值

    外部python是一个爬虫,爬取的内容的定义没有放入函数中.导致一次爬取多次使用的情况出现. 第一版函数如下: 改版后:

  3. Windows10家庭版的功能中没有Hyper-V的解决方法

    1.在桌面新建记事本 将下面的内容复制到编辑器或者记事本当中 pushd "%~dp0" dir /b %SystemRoot%\servicing\Packages\*Hyper ...

  4. 流式布局和viewport

    流式布局 百分比布局,非固定宽度,内容向两边填充,流动的布局. viewport(视口) PC端的网页在手机端的浏览器显示是不会出现网页的,这是因为移动端的网页不是直接放在移动端的浏览器中,而是放在移 ...

  5. Canvas + WebSocket + Redis 实现一个视频弹幕

    原文出自:https://www.pandashen.com 页面布局 首先,我们需要实现页面布局,在根目录创建 index.html 布局中我们需要有一个 video 多媒体标签引入我们的本地视频, ...

  6. docker安装踩坑记录

    .docker安装包安装很顺利, yum安装安装源在官网或镜像网站下载, fedora/centos分别下载不同的, 在/etc/yum.repos.d/doccker-ce.repo, 把网址改为镜 ...

  7. iOS中延迟执行和取消的几种方式

    公用延迟执行的方法: - (void)delayMethod { NSLog(@"delayMethodEnd"); } 方法一.performSelector 方法 1.延迟执行 ...

  8. 6407. 【NOIP2019模拟11.05】小 D 与随机

    题目描述 Description Input 第一行两个个整数 n,k. 之后 n -1 行,第 i 行两个整数 ui, vi, 表示一条树边. 保证输入的数据构成一棵树. Output 一行一个数表 ...

  9. 新年第一发--HDU1848--Fibonacci again and again(SG函数)

    Problem Description 任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的:F(1)=1;F(2)=2;F(n)=F(n-1)+F(n-2 ...

  10. php的数组

    Array 数组 PHP 中的数组实际上是一个有序映射.映射是一种把 values 关联到 keys 的类型.此类型在很多方面做了优化,因此可以把它当成真正的数组,或列表(向量),散列表(是映射的一种 ...