前言
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后依旧不能阻止它循环播放动画。这时候存在三种可能的情况:
- UI输出的用flash工具制作的swf格式存在问题,可以让UI同学检查一下动画导出的方式是否正确
- 将swf格式动画转换为laya引擎支持的swf格式的时出现问题
- 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();
}
}
网友评论