转载于:http://cn.cocos2d-x.org/tutorial/show?id=1250
在游戏中使用Json来储存数据,既方便读取,有方便管理。Cocos Studio就可以很好的帮助生成Json文件,目的是从Excel导入数据。
Cocos Studio下载地址:http://cn.cocos2d-x.org/download/
一.使用Cocos Studio生成Json文件
1. 先在Excel中编辑好数据
最后一个“可穿透”属性,本来应该是bool类型的,但因为Cocos Studio中文版会直接将“true”、“false”改为“真”、“假”,在读取时不是很方便,又因为Json在识别bool型是是直接识别“true”,“false”字符串的,需要更多的字符,所以我还是喜欢直接用0,1来代替,这样在储存在文件中时只需一个字符,可以减小文件大小。
2. 打开Cocos Studio,选择Data Editor,然后导入保存好的Excel。
打开后可以编辑属性数据(key->value)
3. 点击导出Json文件
这里可以选择导出两种格式:
1.属性方式
1
2
3
4
|
[{
"ID"
:1,
"名称"
:
"树"
,
"血量"
:500,
"防御力"
:100,
"攻击力"
:0,
"可穿透"
:0}
,{
"ID"
:2,
"名称"
:
"灌木"
,
"血量"
:150,
"防御力"
:50,
"攻击力"
:2,
"可穿透"
:1}
,{
"ID"
:3,
"名称"
:
"草丛"
,
"血量"
:50,
"防御力"
:20,
"攻击力"
:0,
"可穿透"
:1}
,{
"ID"
:4,
"名称"
:
"狗"
,
"血量"
:200,
"防御力"
:40,
"攻击力"
:20,
"可穿透"
:0}]
|
这种格式把属性名也一起写进对象中,适合对象属性不相同,生成文件较大。
2.对象方式
1
2
3
4
5
6
|
[[
"ID"
,
"名称"
,
"血量"
,
"防御力"
,
"攻击力"
,
"可穿透"
]
,[1,
"树"
,500,100,0,0]
,[2,
"灌木"
,150,50,2,1]
,[3,
"草丛"
,50,20,0,1]
,[4,
"狗"
,200,40,20,0]
]
|
此类型将属性和值对齐,文件较小 但需要格式相同。
二、使用rapidjson获取Json数据
Cocos2d-x 3.0 自带有rapidjson的支持文件,不需要像jsoncpp那样需要另外加,而且之所以使用rapidjson,因为他不仅也支持所有平台,而且存取效率就像他的名字一样比jsoncpp快了不知道多少,使用起来也很方便。各方面都perfect,当然要用它了!
使用时只要加入头文件:
1
2
3
4
5
6
|
#include "json/rapidjson.h"
#include "json/document.h"
//#include "json/filestream.h"
//#include "json/prettywriter.h"
//#include "json/writer.h"
//#include "json/stringbuffer.h"
|
如果只要对Json进行读操作只要加头两个文件就好了。
使用也很方便,就用上面两种格式为例,写读取数据的代码。
1.对属性方式存储的Json读取
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
bool
ShowJsonData1()
{
string filename=
"Json_test_1.json"
;
rapidjson::Document doc;
//判断文件是否存在
if
(!FileUtils::getInstance()->isFileExist(filename))
{
log
(
"json file is not find [%s]"
,filename);
return
false
;
}
//读取文件数据,初始化doc
std::string data=FileUtils::getInstance()->getStringFromFile(filename);
doc.Parse<rapidjson::kParseDefaultFlags>(data.c_str());
//判断读取成功与否 和 是否为数组类型
if
(doc.HasParseError() || !doc.IsArray())
{
log
(
"get json data err!"
);
return
false
;
}
for
(unsigned
int
i=0;i<doc.Size();i++)
{
//逐个提取数组元素(声明的变量必须为引用)
rapidjson::Value &v=doc[i];
int
id;
//ID
string name;
//名称
int
hp;
//血量
int
Defense;
//防御力
int
attack;
//攻击力
int
passable;
//是否可穿透(通行)
//判断各属性是否存在(可以支持中文(UTF8格式))
if
(v.HasMember(
"ID"
) && v.HasMember(A2U(
"名称"
)) && v.HasMember(A2U(
"血量"
))
&& v.HasMember(A2U(
"防御力"
)) && v.HasMember(A2U(
"攻击力"
)) && v.HasMember(A2U(
"可穿透"
)))
{
//按属性提取数据
id=v[
"ID"
].GetInt();
name=v[A2U(
"名称"
)].GetString();
hp=v[A2U(
"血量"
)].GetInt();
Defense=v[A2U(
"防御力"
)].GetInt();
attack=v[A2U(
"攻击力"
)].GetInt();
passable=v[A2U(
"可穿透"
)].GetInt();
log
(A2U(
"ID:%d,名称:%s,血量:%d,防御力:%d,攻击力:%d,可穿透性:%s"
),
id,name.c_str(),hp,Defense,attack,(passable ?
"true"
:
"false"
));
}
}
<span style=
"white-space:pre"
> </span>
return
true
;
}
|
只要把中文转换为UTF8格式就可惜通过中文下标来获取数据,A2U宏请看我上篇文章,就是将BGK转换为UTF8可以再Cocos2d-x上使用中文。
2.对对象方式储存的Json读取
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
bool
ShowJsonData2()
{
string filename=
"Json_test_1.json"
;
rapidjson::Document doc;
//判断文件是否存在
if
(!FileUtils::getInstance()->isFileExist(filename))
{
log
(
"json file is not find [%s]"
,filename);
return
false
;
}
//读取文件数据,初始化doc
std::string data=FileUtils::getInstance()->getStringFromFile(filename);
doc.Parse<rapidjson::kParseDefaultFlags>(data.c_str());
//判断读取成功与否 和 是否为数组类型
if
(doc.HasParseError() || !doc.IsArray())
{
log
(
"get json data err!"
);
return
false
;
}
//从第2行开始,因为第一行是属性
for
(unsigned
int
i=1;i<doc.Size();i++)
{
//逐个提取数组元素(声明的变量必须为引用)
rapidjson::Value &v=doc[i];
int
id;
//ID
string name;
//名称
int
hp;
//血量
int
Defense;
//防御力
int
attack;
//攻击力
int
passable;
//是否可穿透(通行)
//按下标提取
int
a=0;
id=v[a++].GetInt();
name=v[a++].GetString();
hp=v[a++].GetInt();
Defense=v[a++].GetInt();
attack=v[a++].GetInt();
passable=v[a++].GetInt();
log
(A2U(
"ID:%d,名称:%s,血量:%d,防御力:%d,攻击力:%d,可穿透性:%s"
),
id,name.c_str(),hp,Defense,attack,(passable ?
"true"
:
"false"
));
}
return
true
;
}
|
看一下输出结果: