笔者使用的是Cocos Creator v2.1.0,以这个版本为例来说明。
什么是JSON
JSON的英文全称是JavaScript Object Notation,即JavaScript对象表示法。
JSON的特点
1、是一种轻量级的文本数据交换格式,类似XML,但是比XML更小、更快、更易解析。
2、使用JavaScript语法来描述数据对象,JS程序无需解析器即可生成原生的JavaScript对象。
3、独立于语言和平台,目前大多数的编程语言都支持JSON。
JSON的语法
JSON语法是JavaScript语法的子集,具有以下规则:
- 数据在名称/值对中
- 数据由逗号分隔
- 大括号保存对象
- 中括号保存数组
读取方法
首先需要在assets文件夹下建立一个resources文件夹
resources文件夹是cocoscreator规定的动态加载的文件夹,如果需要动态加载资源,就需要使用该文件夹。
CocosCreator提供了cc.load.loadRes来专门加载位于 resources 目录下的文件,所以提前把JSON文件放到 asserts/resources 目录下即可。
以一个比较复杂的JSON文件为例
如下为levelSetting.json,是一个关卡配置文件。
{
"Levels": [{
"Lv": "1",
"Time": "20000",
"RejectBalls": "1,3,3",
"MainBall": "0,0",
"CollectBalls": [{
"Msg": "-200,-300,123,1"
},
{
"Msg": "300,300,123,3"
}
]
},
{
"Lv": "2",
"Time": "30000",
"RejectBalls": "0,1,2",
"MainBall": "0,200",
"CollectBalls": [{
"Msg": "-300,-350,123,3"
},
{
"Msg": "200,400,123,0"
}
]
}
]
}
该文件放到目标文件夹下,CocosCreator会对其进行处理,此时鼠标右键点击该文件,在弹出的选项中选择 “打开Libarary中的资源”。此时打开的文件,如下图,可见文件的Libarary形式已经添加了一些标识。(注意,文件内容本身并没有改变,如果通过文件资源管理器打开该文件,依然是原来的内容)
解析代码
public Init(completeCallback: () => void): void {
var self = this;//这里要把this存到self中,供loadRes的回调中使用,否则回调中直接调用this,是取不到的
cc.loader.loadRes(this.jsonFileName, function (err, object) {
if (err) {
console.log("error while read " + this.json + ", " + err);
return;
}
let allLevels = object.json.Levels;
for (let x = 0; x < allLevels.length; x++) {
const element = allLevels[x];
let lv = Number(element.Lv);
let time = Number(element.Time);
let rejectBall = element.RejectBalls.split(",");
let rejectBalls: number[] = [
Number(rejectBall[0]),
Number(rejectBall[1]),
Number(rejectBall[2]),
];
let mainBall: string[] = element.MainBall.split(",");
let mainBallPos: cc.Vec2 = new cc.Vec2(Number(mainBall[0]), Number(mainBall[1]));
let collectBall = element.CollectBalls;
let collectBalls: number[][] = [];
for (let i = 0; i < collectBall.length; i++) {
const element = collectBall[i];
let strs: string[] = element.Msg.split(",");
collectBalls[i] = [Number(strs[0]), Number(strs[1]), Number(strs[2]),Number(strs[3])];
}
let level: Level = new Level(lv, time, rejectBalls, mainBallPos, collectBalls);
self.levels[x] = level;
}
if (completeCallback != null) {
completeCallback();
}
})
}
Level.ts
@ccclass
export default class Level {
lvId: number = 0;
time: number = 1000;//单位毫秒,游戏关卡总时间
rejectBalls: number[] = null;//rejectBall数组,数据为颜色索引
mainBallPos: cc.Vec2 = null;//关卡中主发射球的位置
collectBalls: number[][] = null;//收集球数组,长度4,([0],[1]为位置信息; [2]为需要吸纳小球数量;[3]为可吸纳小球类型)
constructor(private LvID: number,
private Time: number,
private RejectBalls: number[],
private MainBallPos: cc.Vec2,
private CollectBalls: number[][]) {
this.lvId = LvID;
this.time = Time;
this.rejectBalls = RejectBalls;
this.mainBallPos = MainBallPos;
this.collectBalls = CollectBalls;
}
}
上述代码需要注意的地方有以下几点:
1,cc.loader.loadRes的回调中想通过使用this,获得当前ts脚本中的变量什么的是获取不到的。因此把cc.loader.loadRes放到一个方法体中调用,同时在调用前,把this赋值给局部变量self.
2,loadRes的回调中,object.json获得的即是解析后的json,再根据json文件中的key,即可获得对应value.
再来说说回调中的object
loadRes回调函数中的object,返回的就是加载后的对象,本文中就是json对象。
console.log("object:"+object);
console.log("object._name:"+object._name)
console.log("object.json:"+object.json)
上述代码打印内容为:
1,object._name正好对应上面Creator处理后的json libaray文件中的键_name对应的值,该值为字符串,故可以输出
2,object.json,是键json对应的值,json的内容是{},是对象。故输出[object Object]
3,至于object不输出任何内容,这里我也不太清楚具体原因。(object的内容为{},但是没有键,故不输出任何内容???)
其它JSON解析方法
JSON.parse(str):把json字符串解析为json对象。获得json对象后就可以通过Key/Value方式获得具体值了。
JSON.stringify(object):把json对象转换为字符串。
上述是浏览器提供的方法。