先来看一下studio导出的json片段
{
"Volume": 1.0,
"FileData": {
"Type": "Normal",
"Path": "victory.mp3",
"Plist": ""
},
"AnchorPoint": {},
"Position": {
"X": 303.5767,
"Y": 291.8211
},
"Scale": {
"ScaleX": 1.0,
"ScaleY": 1.0
},
"CColor": {},
"IconVisible": true,
"PrePosition": {
"X": 0.4743,
"Y": 0.304
},
"PreSize": {
"X": 0.0,
"Y": 0.0
},
"LeftMargin": 303.5767,
"RightMargin": 336.4233,
"TopMargin": 668.1789,
"BottomMargin": 291.8211,
"Tag": 64,
"ActionTag": -718777026,
"Size": {
"X": 0.0,
"Y": 0.0
},
"Name": "Audio_2",
"ctype": "SimpleAudioObjectData"
}
ctype为SimpleAudioObjectData。通过这个,找到frameworks\cocos2d-html5\extensions\cocostudio\loader\parsers下的timelineParser-2.x.js文件中1200行左右,代码片段如下:
/**
* SimpleAudio
* @param json
* @param resourcePath
*/
parser.initSimpleAudio = function(json, resourcePath){
var node = new ccs.ComAudio();
var loop = json"Loop"] || false;
//var volume = json"Volume"] || 0;
//cc.audioEngine.setMusicVolume(volume);
node.setLoop(loop);
loadTexture(json"FileData"], resourcePath, function(path, type){
node.setFile(path);
});
};
可以看到此函数并未return任何值,可见当作node的children是不可能了~
通过查看ccs.ComAudio的定义可知道,这是一个ccs.Component子类,而另一个已经被studio支持的组件是自定义属性,会出现在node的_componentContainer中。
再看一个输入框添加自定义属性的json片段:
{
"FontSize": 20,
"IsCustomSize": true,
"LabelText": "",
"PlaceHolderText": "Username",
"UserData": "a=1&b=2",
"Tag": 98,
"ActionTag": -1097765139,
"Size": {
"X": 350.0,
"Y": 27.0
},
"Name": "txt_username",
"ctype": "TextFieldObjectData"
}
ctype为TextFieldObjectData,查找对应的loader为:initTextField
/**
* TextField
* @param json
* @param resourcePath
* @returns {ccui.TextField}
*/
parser.initTextField = function(json, resourcePath){
var widget = new ccui.TextField();
var passwordEnabled = json"PasswordEnable"];
if(passwordEnabled){
widget.setPasswordEnabled(true);
var passwordStyleText = json"PasswordStyleText"] || "*";
widget.setPasswordStyleText(passwordStyleText);
}
var placeHolder = json"PlaceHolderText"];
if(placeHolder != null)
widget.setPlaceHolder(placeHolder);
var fontSize = json"FontSize"];
if(fontSize != null)
widget.setFontSize(fontSize);
var fontName = json"FontName"];
if(fontName != null)
widget.setFontName(fontName);
var maxLengthEnabled = json"MaxLengthEnable"];
if(maxLengthEnabled){
widget.setMaxLengthEnabled(true);
var maxLength = json"MaxLengthText"] || 0;
widget.setMaxLength(maxLength);
}
//var isCustomSize = json"IsCustomSize"];
this.widgetAttributes(widget, json); // 这里是关键
var text = json"LabelText"];
if(text != null)
widget.setString(text);
var fontResource = json"FontResource"];
if(fontResource != null){
var path = fontResource"Path"];
//resoutceType = fontResource"Type"];
if(path != null){
if (cc.sys.isNative) {
fontName = cc.path.join(cc.loader.resPath, resourcePath, path);
} else {
fontName = path.match(/(^\/]+)\.(\S+)/);
fontName = fontName ? fontName : "";
}
widget.setFontName(fontName);
}
}
widget.setUnifySizeEnabled(false);
widget.ignoreContentAdaptWithSize(false);
var color = json"CColor"];
if(color != null)
widget.setTextColor(getColor(color));
if (!widget.isIgnoreContentAdaptWithSize()){
setContentSize(widget, json"Size"]);
if (cc.sys.isNative)
widget.getVirtualRenderer().setLineBreakWithoutSpace(true);
}
return widget;
};
可以看到函数中有一个this.widgetAttributes(widget, json); 函数调用,此函数的内容:
////////////
// WIDGET //
////////////
parser.widgetAttributes = function (widget, json, enableContent) {
widget.setCascadeColorEnabled(true);
widget.setCascadeOpacityEnabled(true);
widget.setUnifySizeEnabled(false);
//widget.setLayoutComponentEnabled(true);
widget.ignoreContentAdaptWithSize(false);
!enableContent && setContentSize(widget, json"Size"]);
var name = json"Name"];
if (name)
widget.setName(name);
var actionTag = json"ActionTag"] || 0;
widget.setActionTag(actionTag);
//====================这里开始 是根据json中的值,初始化自定义属性组件====================
var extensionData = new ccs.ComExtensionData();
var customProperty = json"UserData"];
if(customProperty !== undefined)
extensionData.setCustomProperty(customProperty);
extensionData.setActionTag(actionTag);
if (widget.getComponent("ComExtensionData"))
widget.removeComponent("ComExtensionData");
widget.addComponent(extensionData);
//====================初始化自定义属性组件完毕====================
widget.setTag(json"Tag"] || 0);
var touchEnabled = json"TouchEnable"] || false;
widget.setTouchEnabled(touchEnabled);
var callBackType = json"CallBackType"];
if (callBackType != null)
widget.setCallbackType(callBackType);
var callBackName = json"CallBackName"];
if (callBackName)
widget.setCallbackName(callBackName);
setLayoutComponent(widget, json);
bindCallback(widget, json);
};
只看那段初始化自定义属性组件的代码即可,如果json中有UserData,那么就会被正确的赋值到组件上。
再来看一下场景的加载过程。studio中导出的json片段:
"Name": "Scene",
"ctype": "SingleNodeObjectData"
可看到ctype为SingleNodeObjectData,对应的parser函数为:initSingleNode。代码如下:
/**
* SingleNode
* @param json
* @returns {cc.Node}
*/
parser.initSingleNode = function(json){
var node = new cc.Node();
this.generalAttributes(node, json);
var color = json"CColor"];
if(color != null)
node.setColor(getColor(color));
return node;
};
自定义数据的组件在json文件中,是作为属性存在的。而声音是作为children存在的。
这段代码调用了this.generalAttributes(node, json);函数,会对自身的组件做处理。但是没有对studio中Children定义的声音做处理。所以,导致了声音节点就直接被忽略掉了。(由于initSimpleAudio根本没有返回值,所以不会出现在父节点的children中)
==================================================分割线==================================================================
看了一天源码了,把studio导出的json文件如何转换为cocos js中的对象有了一些认识。也发现了声音组件在js中就是没有被处理的问题。
希望官方查证下这个问题,也希望高手指点一下游戏中对声音的管理。
Ps:既然出了studio,极大的提升了生产力,就应该把它做好。希望例子也再多一些,目前只发现一篇:http://cn.cocos2d-x.org/tutorial/lists?id=159 感谢作者。
附上studio导出的json文件 MainScene.zip (2 KB)
Ps:论坛的高亮插件有问题啊,会自动生成很多随机字符出来。。。 根本没法看。。
