studio导出的声音组件未被ccs.load的问题

先来看一下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:论坛的高亮插件有问题啊,会自动生成很多随机字符出来。。。 根本没法看。。

1赞

感谢反馈!
请问你的js版本号、studio版本号分别是多少呢?

我9月6号下载的最新版~

studio是最新版:2.3.2

我看了下框架的目录,frameworks目录下有
cocos2d-js-v3.6.1
cocos2d-x-3.7.1
cocos2d-x-3.8

项目代码中的frameworks目录下的文件是cocos2d-x-3.8的(cocos2d-x-3.8/web)。但是还有少许差别,通过对比,发现有一些跟声音的支持判断有关。但是跟声音组件无关。
手动合并文件,把代码里的框架升级到3.8后,与之前结果一样,声音组件还是没有的。

话说,那个cocos2d-js-v3.6.1是什么鬼。。。。 还有,那少许差异是什么鬼。。。。

请问这个问题 有结论了么?

:9::9::9::9::9::9::9::9::9: