数据本地化
a ccuserdefault
系统会在默认路径cocos2d-x-2.2.3\projects\hello\proj.win32\debug.win32下生成一个名为userdefault.xml.所有的key皆为char
*型,value类型为bool intfloat double std::string.
读操作
bool getboolforkey(const char* pkey);
bool getboolforkey(const char* pkey, bool defaultvalue);
int getintegerforkey(const char* pkey);
int getintegerforkey(const char* pkey, int defaultvalue);
float getfloatforkey(const char* pkey);
float getfloatforkey(const char* pkey, float defaultvalue);
double getdoubleforkey(const char* pkey);
double getdoubleforkey(const char* pkey, double defaultvalue);
std::string getstringforkey(const char * pkey);
std::string getstringforkey(const char* pkey,const std::string &defaultvalue);
对于没有defaultvalue的get方法,如果文件中没有相应的key,则得到的是0,如果有则相应的值。
对于有defaultvalue的get方法,如果文件中没有相应的key,则得到的是defaultvalue,如果有,则返回文件中的相应的值。
b
写操作
void setboolforkey(const char* pkey, bool value);
void setintegerforkey(const char* pkey, int value);
void setfloatforkey(const char* pkey, float value);
void setdoubleforkey(const char* pkey, double value);
void setstringforkey(const char* pkey, const std::string & value);
set方法有个特点,是对于相对的key后面会对前面产生覆盖效果。
c
写入文件
ccuserdefault::shareduserdefault()->flush();
虽然window平台是空,但是由于跨平台所导致的。
2 xml文档格式
简介
xml被设计用来传输和存储数据
语法
a
开头
<?xml version=”1.0” encoding=”utf-8”?>
b xml文档必须有根元素
xml文档必须有一个元素是所有其他元素的父元素。该元素称为根元素。
<root>
<child>
<subchild>…..</subchild>
</child>
</root>
所有xml元素都必须有关闭标签
<p>this is a paragraph</p>
<p>this is another paragraph</p>
d
在xml中,xml的属性值须加引号。
<note date="08/08/2008">
<to>george</to>
<from>john</from>
</note>
e xml中的注释
<!— this is a comment -->
xml元素
指的是从(且包括)开始标签直到(且包括)结束标签的部分。
元素可包含其他元素、文本或者两者的混合物。元素也可以拥有属性。
<bookstore>
<book category="children">
<title>harry potter</title>
<author>j k. rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="web">
<title>learning xml</title>
<author>erik t. ray</author>
<year>2003</year>
<price>39.95</price>
</bookstore>
例:
<?xml version="1.0" encoding="iso-8859-1"?>
<note>
<heading>reminder</heading>
<body>don't forget the meeting!</body>
f:
生成xml文档
头文件
#include "support/tinyxml2/tinyxml2.h"
using namespace tinyxml2;
void makexml(const char * filename)
{
std::string filepath =
ccfileutils::sharedfileutils()->getwritablepath() + filename;
tinyxml2::xmldocument *pdoc = new tinyxml2::xmldocument();
//xml
声明(参数可选)
xmldeclaration *pdel = pdoc->newdeclaration("xml version=\"1.0\" encoding=\"utf-8\"");
pdoc->linkendchild(pdel);
//添加plist
节点
xmlelement *plistelement = pdoc->newelement("plist");
plistelement->setattribute("version", "1.0");
pdoc->linkendchild(plistelement);
xmlcomment *commentelement = pdoc->newcomment("this is xml comment");
plistelement->linkendchild(commentelement);
//添加dic
xmlelement *dicelement = pdoc->newelement("dic");
plistelement->linkendchild(dicelement);
//添加key
xmlelement *keyelement = pdoc->newelement("key");
keyelement->linkendchild(pdoc->newtext("text"));
dicelement->linkendchild(keyelement);
xmlelement *arrayelement = pdoc->newelement("array");
dicelement->linkendchild(arrayelement);
for (int i = 0; i < 3; i++) {
xmlelement *elm = pdoc->newelement("name");
elm->linkendchild(pdoc->newtext("cocos2d-x"));
arrayelement->linkendchild(elm);
}
pdoc->savefile(filepath.c_str());
pdoc->print();
delete pdoc;
在cocos2d-x-2.2.3\projects\hello\proj.win32\debug.win32下
<?xml version="1.0" encoding="utf-8"?>
<plist version="1.0">
<!--this is xml comment-->
<dic>
<key>text</key>
<array>
<name>cocos2d-x</name>
</array>
</dic>
</plist>
17.3.4解析xml
void parsexml(const char * filename) {
std::string filepath = ccfileutils::sharedfileutils()->getwritablepath() + filename;
xmlerror errorid = pdoc->loadfile(filepath.c_str());
if (errorid != 0) {
格式错误
return;
xmlelement *rootele = pdoc->rootelement();
//获取第一个节点属性
const xmlattribute *attribute = rootele->firstattribute();
//打印节点属性名和值
cclog("attribute_name = %s,attribute_value = %s", attribute->name(),
attribute->value());
xmlelement *dicele = rootele->firstchildelement("dic");
xmlelement *keyele = dicele->firstchildelement("key");
if (keyele) {
cclog("keyele text= %s", keyele->gettext());
xmlelement *arrayele = keyele->nextsiblingelement();
xmlelement *childele = arrayele->firstchildelement();
while (childele) {
cclog("childele text= %s", childele->gettext());
childele = childele->nextsiblingelement();
attribute_name = version,attribute_value = 1.0
keyele text= text
childele text= cocos2d-x
userdefault.xml操作案例:
t22userdefault.h
#ifndef
__t22ccuserdefault_h__
#define
#include
"cocos2d.h"
"tback.h"
class
t22ccuserdefault :public
tback
public:
create_func(t22ccuserdefault);
bool
init();
static
ccscene *
scene();
void
makexml(char
* filename);
parsexml(char
};
#endif
t22userdefault.cpp
"t22userdefault.h"
"appmacros.h"
"support/tinyxml2/tinyxml2.h"
using
namespace
tinyxml2;
t22ccuserdefault::scene()
scene =
ccscene::create();
t22ccuserdefault *
layer =
t22ccuserdefault::create();
scene->addchild(layer);
return
scene;
t22ccuserdefault::init()
tback::init();
//通过这种方式向userdefault.xml中写内容
ccuserdefault::shareduserdefault()->setintegerforkey("integer",
100);
ccuserdefault::shareduserdefault()->setstringforkey("string","oooo");
//获得xml的路径
std::string
str =
ccuserdefault::shareduserdefault()->getxmlfilepath();
//打印xml的路径
cclog("path
= %s",
str.c_str());
cclog("isxmlexist
= %d",
ccuserdefault::shareduserdefault()->isxmlfileexist());
//如果有这个key的值则打印出,如果没有这个key则返回默认的值120
int
value =
ccuserdefault::shareduserdefault()->getintegerforkey("integer",
120);
cclog("value
value);
true;
运行结果:
userdefault.xml的内容:
操作xml和解释xml
makexml("test");
parsexml("test");
t22ccuserdefault::makexml(char
* filename) {
filepath =
ccfileutils::sharedfileutils()->getwritablepath()
+ filename;
tinyxml2::xmldocument
*pdoc =
new
tinyxml2::xmldocument();
xmldeclaration *pdel
= pdoc->newdeclaration("xml
version=\"1.0\" encoding = \"utf-8\"");
//添加 plist
xmlelement *plistelement
= pdoc->newelement("plist");
plistelement->setattribute("version",
"1.0");
xmlcomment *commentelement
= pdoc->newcomment("this
is x comment");
//添加 dic
xmlelement *dicelement
= pdoc->newelement("dic");
//添加 key
xmlelement *keyelement
= pdoc->newelement("key");
xmlelement *arrayelement
= pdoc->newelement("array");
for (int
i = 0;
i < 3;
i++) {
xmlelement *elm
= pdoc->newelement("name");
delete
pdoc;
t22ccuserdefault::parsexml(char
* filename)
xmlerror
errorid =
pdoc->loadfile(filepath.c_str());
if (errorid
!= 0) {
xmlelement *rootele
= pdoc->rootelement();
const
xmlattribute *attribute
= rootele->firstattribute();
cclog("attribute_name
= %s,attribute_value = %s",
attribute->name(),
xmlelement *dicele
= rootele->firstchildelement("dic");
xmlelement *keyele
= dicele->firstchildelement("key");
if (keyele)
cclog("keyele
text= %s",
keyele->gettext());
xmlelement *arrayele
= keyele->nextsiblingelement();
xmlelement *childele
= arrayele->firstchildelement();
while (childele)
cclog("childele
childele->gettext());
childele =
childele->nextsiblingelement();
xml文件:
ccstring,ccarray,ccdictionary
init()方法中
ccstring *str
= ccstring::create("1234");
cclog("ccstring
str = %s",
str->getcstring());
inttypevalue = %d",
str->intvalue());
数据结构:ccstring
/*使用std::string
创建了一个字符串,
你也可以传递一个c
字符串指针,因为
std::string
的构造函数可以访问c
字符串指针
* @返回的ccstring
指针是一个自动释放对象,
*也就意味着你不需要调用release
操作,除非你retain
了.
*/
static ccstring* create(const std::string& str);
/*使用格式化方式来创建一个字符串,这个方法和c
语言里面的‘sprintf’类似,默认
缓存大小是(1024*100)bytes
*假如你想要改变这个缓存大小,你可以去ccstring.cpp
中,更改kmaxstringlen
这个宏定义。
static ccstring* createwithformat(const char* format, …);
/*
使用二进制数据来创建字符串
static ccstring* createwithdata(const unsigned char* pdata, unsigned
long nlen);
/*使用一个文件来创建一个字符串,
* @return a ccstring pointer which is an autorelease object pointer,
* it means that you needn't do a release operation unless you retain
it.
static ccstring* createwithcontentsoffile(const char* pszfilename);
转换
ccstring
允许ccstring
实例变量转换为另外类型的变量。
/* convert to int value */
int intvalue() const;
/* convert to unsigned int value */
unsigned int uintvalue() const;
/* convert to float value */
float floatvalue() const;
/* convert to double value */
double doublevalue() const;
/* convert to bool value */
bool boolvalue() const;
常见的宏定义
#define ccstringmake(str) ccstring::create(str)
#define ccs ccstringmake
ccarray
ccarray是一个面向对象包装类
ccarray继承至ccobject(ccobject主要是为了自动内存管理而创建的)并且提供了一系列接口。
创建
/**
创建一个数组*/
static ccarray* create();
使用一些对象创建数组*/
static ccarray* create(ccobject* pobject, …);
使用一个对象创建数组*/
static ccarray* createwithobject(ccobject* pobject);
创建一个指定大小的数组*/
static ccarray* createwithcapacity(unsigned int capacity);
使用一个现有的ccarray
数组来新建一个数组*/
static ccarray* createwitharray(ccarray* otherarray);
插入
插入一个对象*/
void addobject(ccobject* object);
插入别外一个数组里面的全部对象*/
void addobjectsfromarray(ccarray* otherarray);
在一个确定的索引位置插入一个对象*/
void insertobject(ccobject* object, unsigned int index);
删除
移除最后的一个对象*/
void removelastobject(bool breleaseobj = true);
/**移除一个确定的对象*/
void removeobject(ccobject* object, bool breleaseobj = true);
移除一个确定索引位置的元素*/
void removeobjectatindex(unsigned int index, bool breleaseobj = true);
移除全部元素*/
void removeobjectsinarray(ccarray* otherarray);
移除所有对象*/
void removeallobjects();
快速移除一个对象*/
void fastremoveobject(ccobject* object);
快速移除一个确定索引位置的对象*/
void fastremoveobjectatindex(unsigned int index);
remove
和fastremove
有什么区别,可以看看源代码,remove
是从ccarray中完全的移除,fastremove
只是将ccarray
中对应的对象释放掉了,没够改变整个ccarray
的结构。从代码上来看,区别在于删除元素之后,是否把数组之后的元素向前移动覆盖掉之前位置的元素。代码上的差别如下所示:
unsigned int remaining = arr->num - index;
if(remaining>0)
memmove((void *)&arr->arr[index], (void *)&arr->arr[index+1],
remaining * sizeof(ccobject*));
遍历
ccarray_foreach(arr, obj)
主要事项
一般不会被增加到其他类中,所以他的引用计数是1,并且设置为autorelease
对象。创建ccarray
对象并且retain,然后在这个类中的析构函数中调用release
方法来释放内存。
如果ccobject
对象添加到ccarray
中,那么ccobject
对象的引用计数将
会加1.
ccdictionary
ccdirtionary使用uthash实现的
关键字类型
ccdictionary支持两种类型的关键字,一个是std::string,一个是int.一个ccdictionary实例对象只支持唯一的关键字。所以在你调用”setobject”方法的时候,你需要确认一下。
static ccdictionary * create();
static ccdictionary * createwithdictionary(ccdictionary *srcdict)
static ccdictionary * createwithcontentsofffile(const char * pfilename);
相同key的value会发生覆盖行为。
void setobject(ccobject *pobject,const std::string &key);
void setobject(ccobject *pobject,intptr_t key);
void removeobjectforkey (const std::string &key)
void removeobjectforkey (intptr_t key)
void removeobjectsforkeys (ccarray *pkeyarray)
void removeobjectforelememt (ccdictelement *pelement)
void removeallobjects ()
实现了ccdict_foreach
方法来遍历整个字典。而且使用ccdict_foreach
的方式和使用ccarray_foreach
的方式非常类似
ccdictelement* pelement = null;
ccdict_foreach(thedict, pelement)
ccobjectsubclass* psubclassobj = (ccobjectsubclass*)pelement->getobject();
//
你也可以得到当前key,但是你需要确定key
的类型。
std::string onestrkey = pelement->getstrkey(); //
假如key
的类型是string
// int oneintkey = pelement->getintkey(); //
假如有key
的类型是integer
下面就可以使用上面psubclassobj
对象做一些操作了
举例
// create a dictionary, return an autorelease object.
ccdictionary* pdict = ccdictionary::create();
// insert objects to dictionary
ccstring* pvalue1 = ccstring::create("100");
ccstring* pvalue2 = ccstring::create("120");
ccinteger* pvalue3 = ccinteger::create(200);
pdict->setobject(pvalue1, "key1");
pdict->setobject(pvalue2, "key2");
pdict->setobject(pvalue3, "key3");
// get the object for key
ccstring* pstr1 = (ccstring*)pdict->objectforkey("key1");
cclog("{ key1: %s }", pstr1->getcstring());
ccinteger* pinteger = (ccinteger*)pdict->objectforkey("key3");
cclog("{ key3: %d }", pinteger->getvalue());
结合xml支持中文
ccdictionary * dic = ccdictionary::createwithcontentsoffile("chinese.xml");
ccstring * str = (ccstring *)dic->objectforkey("people1");
cclabelttf * ttf = cclabelttf::create(str->getcstring(), "arial",20);
ttf->setposition(ccp(240, 160));
addchild(ttf);
return true;
案例:
ccdictionary *
dic =
ccdictionary::create();
dic->retain();
ccstring *value1
= ccstring::create("100");
ccstring *value2
= ccstring::create("200");
//第一个是value,第二个是key的意思
dic->setobject(value1,
"key1");
dic->setobject(value2,
"key2");
ccstring *
str2 = (ccstring
*)dic->objectforkey("key1");
//运行结果100
cclog("%d",
str2->intvalue());
cclabelttf *
ttf =
cclabelttf::create(str2->getcstring(),
"courier new", 30);
ttf->setposition(ccp(240,160));