美文网首页
MovieClip中的坑

MovieClip中的坑

作者: hello_小丁同学 | 来源:发表于2018-05-21 10:30 被阅读106次

    前言

    LayaAir引擎版本是1.7.14beta

    正文

    控制是否循环播放swf动画

    下面是官方提供的swf动画播放代码:

    module LayaDEMO { 
    {
          import MovieClip = Laya.MovieClip;
        export class MovieClipSample 
        {
            constructor() 
            {
                //初始化舞台
                Laya.init(1334, 750);
                //创建一个 MovieClip 实例
                var mc:MovieClip = new MovieClip();
                //加载swf资源,load方法的第二个参数不设置为散图模式加载,设置为true是采用图集方式加载。
                mc.load("res/swf/monkey.swf",true);
                //添加到舞台
                Laya.stage.addChild(mc);
            }
        }
    }
    

    代码运行后的效果是一个一直循环播放的动画,如果不想让动画循环播放怎么办呢?
    MovieClip中有一个loop属性,官方说明如下:


    api文档.png

    然而运行代码发现,将loop属性置为false后依旧不能阻止它循环播放动画。这时候存在三种可能的情况:

    1. UI输出的用flash工具制作的swf格式存在问题,可以让UI同学检查一下动画导出的方式是否正确
    2. 将swf格式动画转换为laya引擎支持的swf格式的时出现问题
    3. loop属性不能控制动画循环播放

    经过验证排除了1、2两种情况。验证第3种情况,主要看下laya源码里面怎么使用loop这个属性控制动画循环播放的。
    debug跟踪一下代码调用:
    在执行

    mc.load("res/swf/monkey.swf",true);
    

    时会回调下面的函数:

    /**
        *加载资源。
        *@param url swf 资源地址。
        *@param atlas 是否使用图集资源
        *@param atlasPath 图集路径,默认使用与swf同名的图集
        */
        __proto.load=function(url,atlas,atlasPath){
            (atlas===void 0)&& (atlas=false);
            this._url=url=URL.formatURL(url);
            // atlasPath设置为true的时候,会加载和swf格式同名的同路径下的json文件
            if(atlas)this._atlasPath=atlasPath?atlasPath:url.split(".swf")[0]+".json";
            this.stop();
            this._clear();
            this._movieClipList=[this];
            var urls;
            urls=[ {url:url,type:/*laya.net.Loader.BUFFER*/"arraybuffer" }];
            if (this._atlasPath){
                urls.push({url:this._atlasPath,type:/*laya.net.Loader.ATLAS*/"atlas" });
            }
            Laya.loader.load(urls,Handler.create(this,this._onLoaded));
        }
    
    

    执行Laya.loader.load(urls,Handler.create(this,this._onLoaded));
    在资源加载完成之后会回调this._onLoaded,进入this._onLoaded函数内部

        /**@private */
        __proto._onLoaded=function(){
            var data;
            data=Loader.getRes(this._url);
            if (!data){
                this.event(/*laya.events.Event.ERROR*/"error","file not find");
                return;
            }
            this.basePath=this._atlasPath?Loader.getAtlas(this._atlasPath).dir:this._url.split(".swf")[0]+"/image/";
            this._initData(data);
        }
    

    执行this._initData(data);函数:

    /**@private */
        __proto._initData=function(data){
            this._data=new Byte(data);
            var i=0,len=this._data.getUint16();
            for (i=0;i < len;i++)this._ids[this._data.getInt16()]=this._data.getInt32();
            this.interval=1000 / this._data.getUint16();
            this._setData(this._data,this._ids[32767]);
    //播放数据初始化
            this._initState();
    //调用play方法从1帧开始播放
            this.play(0);
            this.event(/*laya.events.Event.LOADED*/"loaded");
            if (!this._parentMovieClip)this.timer.loop(this.interval,this,this.updates,null,true);
        }
    

    进入 play函数
    ···
    /**
    *播放动画。
    *@param index 帧索引。
    */
    __proto.play=function(index,loop){
    (index===void 0)&& (index=0);
    (loop===void 0)&& (loop=true);
    this.loop=loop;
    this._playing=true;
    if (this._data)
    this._displayFrame(index);
    }
    ···
    this.loop的值会被play的loop参数覆盖掉。

    之后调用this._displayFrame(index);

        /**@private */
        __proto._displayFrame=function(frameIndex){
            (frameIndex===void 0)&& (frameIndex=-1);
            if (frameIndex !=-1){
                if (this._curIndex > frameIndex)this._reset();
                this._parse(frameIndex);
            }
        }
    

    从play传入的帧数开始解析,下面进入this._parse函数:

    
        /**@private */
        __proto._parse=function(frameIndex){
            var curChild=this;
            var mc,sp,key=0,type=0,tPos=0,ttype=0,ifAdd=false;
            var _idOfSprite=this._idOfSprite,_data=this._data,eStr;
            if (this._ended)this._reset();
            _data.pos=this._Pos;
            this._ended=false;
            this._playIndex=frameIndex;
            if (this._curIndex > frameIndex&&frameIndex<this._preIndex){
                this._reset(true);
                _data.pos=this._Pos;
            }
            while ((this._curIndex <=frameIndex)&& (!this._ended)){
                type=_data.getUint16();
                switch (type){
                    case 12:
                        key=_data.getUint16();
                        tPos=this._ids[_data.getUint16()];
                        this._Pos=_data.pos;
                        _data.pos=tPos;
                        if ((ttype=_data.getUint8())==0){
                            var pid=_data.getUint16();
                            sp=_idOfSprite[key]
                            if (!sp){
                                sp=_idOfSprite[key]=new Sprite();
                                var spp=new Sprite();
                                spp.loadImage(this.basePath+pid+".png");
                                this._loadedImage[this.basePath+pid+".png"]=true;
                                sp.addChild(spp);
                                spp.size(_data.getFloat32(),_data.getFloat32());
                                var mat=_data._getMatrix();
                                spp.transform=mat;
                            }
                            sp.alpha=1;
                            }else if (ttype==1){
                            mc=_idOfSprite[key]
                            if (!mc){
                                _idOfSprite[key]=mc=new MovieClip(this);
                                mc.interval=this.interval;
                                mc._ids=this._ids;
                                mc.basePath=this.basePath;
                                mc._setData(_data,tPos);
                                mc._initState();
                                mc.play(0);
                            }
                            mc.alpha=1;
                        }
                        _data.pos=this._Pos;
                        break ;
                    case 3:;
                        var node=_idOfSprite[ _data.getUint16()];
                        if (node){
                            this.addChild(node);
                            node.zOrder=_data.getUint16();
                            ifAdd=true;
                        }
                        break ;
                    case 4:
                        node=_idOfSprite[ _data.getUint16()];
                        node && node.removeSelf();
                        break ;
                    case 5:
                        _idOfSprite[_data.getUint16()][MovieClip._ValueList[_data.getUint16()]]=(_data.getFloat32());
                        break ;
                    case 6:
                        _idOfSprite[_data.getUint16()].visible=(_data.getUint8()> 0);
                        break ;
                    case 7:
                        sp=_idOfSprite[ _data.getUint16()];
                        var mt=sp.transform || Matrix.create();
                        mt.setTo(_data.getFloat32(),_data.getFloat32(),_data.getFloat32(),_data.getFloat32(),_data.getFloat32(),_data.getFloat32());
                        sp.transform=mt;
                        break ;
                    case 8:
                        _idOfSprite[_data.getUint16()].setPos(_data.getFloat32(),_data.getFloat32());
                        break ;
                    case 9:
                        _idOfSprite[_data.getUint16()].setSize(_data.getFloat32(),_data.getFloat32());
                        break ;
                    case 10:
                        _idOfSprite[ _data.getUint16()].alpha=_data.getFloat32();
                        break ;
                    case 11:
                        _idOfSprite[_data.getUint16()].setScale(_data.getFloat32(),_data.getFloat32());
                        break ;
                    case 98:
                        eStr=_data.getString();
                        this.event(eStr);
                        if (eStr=="stop")this.stop();
                        break ;
                    case 99:
                        this._curIndex=_data.getUint16();
                        ifAdd && this.updateZOrder();
                        break ;
                    case 100:
                        this._count=this._curIndex+1;
                        this._ended=true;
                        if (this._playing){
                            this.event(/*laya.events.Event.FRAME*/"enterframe");
                            this.event(/*laya.events.Event.END*/"end");
                            this.event(/*laya.events.Event.COMPLETE*/"complete");
                        }
                        this._reset(false);
                        break ;
                    }
            }
            if (this._playing&&!this._ended)this.event(/*laya.events.Event.FRAME*/"enterframe");
            this._Pos=_data.pos;
        }
    

    playTo函数的Complete回调问题

    playTo的complete回调最终被调用是在_update方法,然而,当你设置的endFrame>this.count-2得出的帧数时,handler.run();也就是我们赋值的complete函数永远都不会执行。

    /**
        *@private
        *动画的帧更新处理函数。
        */
        __proto._update=function(){
            if (!this._data)return;
            if (!this._playing)return;
            this._playIndex++;
            if (this._playIndex >=this._count){
                if (!this.loop){
                    this._playIndex--;
                    this.stop();
                    return;
                }
                this._playIndex=0;
            }
            this._parse(this._playIndex);
            if (this._labels && this._labels[this._playIndex])this.event(/*laya.events.Event.LABEL*/"label",this._labels[this._playIndex]);
            if (this._endFrame!=-1&&this._endFrame==this._playIndex){
                this._endFrame=-1;
                if (this._completeHandler !=null){
                    var handler=this._completeHandler;
                    this._completeHandler=null;
                    handler.run();
                }
                this.stop();
            }
        }
    

    相关文章

      网友评论

          本文标题:MovieClip中的坑

          本文链接:https://www.haomeiwen.com/subject/bhrftftx.html