from url: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中编辑好数据

1407132382386539.jpg

最后一个“可穿透”属性,本来应该是bool类型的,但因为Cocos Studio中 文版会直接将“true”、“false”改为“真”、“假”,在读取时不是很方便,又因为Json在识别bool型是是直接识别 “true”,“false”字符串的,需要更多的字符,所以我还是喜欢直接用0,1来代替,这样在储存在文件中时只需一个字符,可以减小文件大小。


2. 打开Cocos Studio,选择Data Editor,然后导入保存好的Excel。

1407132501128222.jpg

打开后可以编辑属性数据(key->value)


3. 点击导出Json文件

20140312215221140.jpg


这里可以选择导出两种格式:

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数据

Cocos2d-x 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可以再Cocos2d-x上使用中文。


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;  
}

看一下输出结果:

1407133026954002.jpg