算是BUG反馈的,重写ccs部分代码分享

前略,寄予我2天来疯狂死去的脑细胞。
:8: 我想要注解!!!(当然大家都知道程序猿都不喜欢写注解,当然cocos2d-js的可能发布之后就删了注解了?)
http://www.cocoachina.com/bbs/read.php?tid-293282.html

我曾经发帖问过关于此问题,也就是使用声音导致的BUG,根本没有人回我!!:8:

后来想想其实也是对的,毕竟音乐不能setPosition也是常理,是我使用不当:3:

当然我想实现的效果,当然不是这样的

没错,我想实现的效果是,在cocosStudio里使用音乐,然后在X帧上创建关键帧,然后在X关键帧的时间上播放,然后X关键帧上停止!!:2: :2: :2:

什么?你说cocosStudio音乐配置的右边—>特性—》有播放和停止按钮?(那个根本没有任何的效果!!!根本无法造成导出的json文件一个文字的改变)
当然我不能修改cocosStudio,所以只能修改cocosJS的代码了

于是我便啃起了源码

长篇大论的我就不写了。。。。。

简单的说一下这玩意

在源码中的\frameworks\cocos2d-html5\extensions\cocostudio\loader\load.js就是写ccs.load();方法的地方了

当然这个文件就算你怎么改,然而没有什么OO用,只是一个入口罢了

在这个load.js的同目录下有一个parsers文件夹,他存放着解析cocosStudio导出的json文件的代码(看parsers名字不就知道了?真的吗?我一开始真不知道啊。。)

完成这个伟大的目标有2件:

第一:解决BUG,如果cocosStudio在音乐node上加上帧,导出的json文件,再使用ccs.load读取会造成bug
第二:按照帧延迟来播放音乐(使用定时器)

第一步.在经历无数脑细胞思维之后,我终于找到罪魁祸首,

var layer=ccs.load("abc.json");
layer.node.runAction(layer.action);
layer.action.gotoFrameAndPlay(0,layer.action._duration,false);
this.addChild(layer.node);

```



这个最近还有人问“如何使用cocosStudio导出的文件”
而上面的代码便是如何使用,事实上这几段代码指出了,ccs.load读取后的layer会包含2个对象,1个是node,一个是action

(过程略)最后,我终于将目标锁定了,action对象是这个问题的所在

罪魁祸首:
\frameworks\cocos2d-html5\extensions\cocostudio\loader\parsers\action-2.x.js

然后经过观看我知道了,这个parsers的设计是很有意义的,使用注册方式的。

复制一遍这个文件代码,进行重写
将修改的代码放在读取完cocos代码之后,重新注册这个parsers,之后的cocos更新版本也可以安枕无忧了:2:  :2: 



以下是重写的方法,事实上我只加了关于ctype为的SimpleAudioObjectData的话就不生成action节点罢了
(从名字上看cocos以后会扩展ComplexAudioObjectData:7::7:  )

(什么?你说我获取东西的那几个连方块太黄太暴力了?没事反正读的是cocosStudio导出的文件不会报错的啦)

parseNode: function(json, resourcePath, file){
            if(!json)
                return null;
            if(cache)
                return cache.clone();

            var self = this,
            action = new ccs.ActionTimeline();

            action.setDuration(json"Duration"]);
            action.setTimeSpeed(json"Speed"] || 1);

//增加点
            var childrenData=cc.loader.getRes(file)"Content"]"Content"]"ObjectData"]"Children"];
            var unTags=];
            childrenData.forEach(function(obj){
                if(obj"ctype"]=="SimpleAudioObjectData")
                    unTags.push(obj"ActionTag"]);
            });
//增加点结束
            //The process of analysis
            var timelines = json"Timelines"];
            timelines.forEach(function(timeLine){
                var parser = self.parsers];
                var frame;
                if(parser)
                    frame = parser.call(self, timeLine, resourcePath);
                else
                    cc.log("parser does not exist : %s", timeLine"Property"]);
//修改点
                if(frame && !ArraysContains(unTags,timeLine"ActionTag"]))
                    action.addTimeline(frame);
            });

            cache = action;
            cache.retain();
            return action.clone();
        },


```


OK,再使用ccs.load就能够安心的回避问题

好了,至此,我们的第一步已经完成了,恩恩,也就是如果是cocosStudio导出的音乐对象,那么这个action的节点生成将会跳过,避免setPositon()的错误



第二步,相信看到此看官也觉得累了,我就直接讲结论吧(我也写累了)

想要实现延迟播放音乐首先要使用定时器。在load的时候根本办不到。。。

直接给干货(别在意我上面说过的设置了第二关键帧暂停播放音乐什么的,这里就只写了第一帧播放罢了)(也别在意我没写注释)

afterReadPlayMusic=function(json,_self){
    var resPath = (cc.path.dirname(res.jso) + "/").replace(/\/\/$/, "/");
    var timelinesDatas=cc.loader.getRes(json)"Content"]"Content"]"Animation"]"Timelines"];
    var childrenDatas=cc.loader.getRes(json)"Content"]"Content"]"ObjectData"]"Children"];
    childrenDatas.forEach(function(children){
        timelinesDatas.forEach(function(timeLine){
            if(children"ctype"]=="SimpleAudioObjectData" && children"ActionTag"]==timeLine"ActionTag"]){
                var frames=timeLine"Frames"];
                var path=resPath+children"FileData"]"Path"];
                var frame=frames;
                _self.scheduleOnce(
                        function(){
                            cc.audioEngine.playMusic(path, false);
                        }
                        ,frame"FrameIndex"]/60);
            }
        });
        
    });
    
}

```



好的,接下来,我们使用ccs.load之后该怎么做呢?

var layer=ccs.load("abc.json");
layer.node.runAction(layer.action);
layer.action.gotoFrameAndPlay(0,layer.action._duration,false);
afterReadPlayMusic("abc.json",_self);
this.addChild(layer.node);


```




好的,美工你可以干活了

顶一个,感谢分享:867::867: