在游戏中使用Json来储存数据,既方便读取,有方便管理。
cocostudio就可以很好的帮助生成Json文件,目的是从Excel导入数据。
cocostudio下载地址:http://www.cocostudio.org/
一.使用cocostudio生成Json文件
1.先在Excel中编辑好数据
最后一个“可穿透”属性,本来应该是bool类型的,但因为cocostudio中文版会直接将“true”、“false”改为“真”、“假”,在读取时不是很方便,又因为Json在识别bool型是是直接识别“true”,“false”字符串的,需要更多的字符,所以我还是喜欢直接用0,1来代替,这样在储存在文件中时只需一个字符,可以减小文件大小,。
2.打开cocostudio,选择Data Editor,然后导入保存好的Excel。
打开后可以编辑属性数据(key->value)
3.点击导出Json文件
这里可以选择导出两种格式:
1.属性方式
[{"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.对象方式
[["ID","名称","血量","防御力","攻击力","可穿透"]
,[1,"树",500,100,0,0]
,[2,"灌木",150,50,2,1]
,[3,"草丛",50,20,0,1]
,[4,"狗",200,40,20,0]
]
此类型将属性和值对齐,文件较小 但需要格式相同
二.使用rapidjson获取Json数据
cocos2dx 3.0 自带有rapidjson的支持文件,不需要像jsoncpp那样需要另外加,而且之所以使用rapidjson,因为他不仅也支持所有平台,而且存取效率就像他的名字一样比jsoncpp快了不知道多少,使用起来也很方便。各方面都perfect,当然要用它了!
使用时只要加入头文件
#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读取
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"));
}
}
return true;
}
只要把中文转换为UTF8格式就可惜通过中文下标来获取数据,A2U宏请看我上篇文章,就是将BGK转换为UTF8可以再cocos2dx上使用中文。
2.对对象方式储存的Json读取
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;
}
*****************************************************************************
看一下输出结果:
关于json的操作就学习到这了,最后再极力推荐大家使用rapidjson,和rapidjson比jsoncpp弱爆了!