应用思考-教育技术论坛

标题: 关于MovieClip的跳帧探讨 [打印本页]

作者: etthink    时间: 2010-7-27 14:37
标题: 关于MovieClip的跳帧探讨
在AS 1.0 - AS 2.0时代,几乎所有的编程开发都是围绕着MovieClip这个Flash唯一的显示对象来进行的,直到AS 3.0 时代,MovieClip在之前的功能才被分散到了 Shape Bitmap Sprite Loader 等类当中,然而作为最具备Flash代表性的对象,MovieClip依旧占据非常重要的位置。而此文就是围绕着 ActionScript 3.0 的 MovieClip 对象来展开讨论。
MovieClip在执行跳帧行为的时候(gotoAndStop(frame), nextFrame(), prevFrame())会先比较两帧之间的差别,如果两帧之间的内容只是进行了尺寸,位移,等属性级别的变更则只修改属性,并且执行对应帧上的ActionScript,如果两帧之间的内容不同,则移除不应该显示的对象,并且创建需要显示的对象实例并且添加到显示列表当中,最后再执行对应帧上的ActionScript。帧实际上是记录了一系列的显示物品状态和动作脚本。
继续研究下去不难发现,我们写在每个帧上的ActionScript代码类似是写在一个函数里面,而这个函数会在MovieClip跳到此帧的时候被执行,为什么只说类似函数呢?不同的地方在于在时间轴上声明的变量的作用域是在此MovieClip内而非函数体作用域内。也就是说你在第一帧上声明的变量,在其他帧上也能获取到此变量。


下面我们来创建一个测试用例,觉得麻烦的可以直接下载文章的范例附件。
第一步:
在舞台上创建一个MovieClip原件,取名为: ch,并且双击打开ch 并且在 ch的第一帧随便画一个矢量图,将此矢量图也转换成一个 MovieClip 元件,然后在第二帧按下 F7 创建一个空白的关键帧,再随便画一个矢量图,也和刚刚一样转换成 MovieClip 元件,最后在第三帧按下 F6 创建关键帧,此时第三帧应该有第二帧创建的元件,这次只用鼠标移动下此MovieClip元件的位置。
第二步:
在 ch 的第一帧上写下如下脚本:
stop();

var c:int = 12;

trace("declare variable c at frame 1;");在 ch 的第二帧上写下如下脚本:
trace("run timeline actionscript at: " + getTimer());

trace("typeof c at frame 2 is:" + typeof c);第三步:
返回到舞台,并且在舞台的时间轴上的第一帧写下如下脚本:
ch.addEventListener(Event.ADDED, handleChildAdded);

ch.addEventListener(Event.REMOVED, handleChildRemoved);

ch.gotoAndStop(2);

setTimeout(function():void{ch.gotoAndStop(3);}, 1000);

trace("gotoAndStop function executed at: " + getTimer());

var m:DisplayObject = ch.getChildAt(0);

if (m)

{

    trace("i have child at 0!");

}

else

{

    trace("oops, nothing there...");

}

function handleChildRemoved(e:Event):void

{

    trace("removed some children!");

}

function handleChildAdded(e:Event):void

{

    var t:int = getTimer();

    var target:DisplayObject = e.target as DisplayObject;

    //当有新的显示对象被添加到显示列表,会trace出信息

    trace(target + " added at: " + t);

}第四步:
把发布设置成: Flash Player 10, ActionScript 3.0
然后 Ctrl + Enter or Command + Enter,看output输出的信息:
removed some children!

[object Shape] added at: 5

[object MovieClip] added at: 5

run timeline actionscript at: 5

typeof c at frame 2 is:number

gotoAndStop function executed at: 6

i have child at 0!

this frame 3再把发布设置改成:Flash Player 9, ActionScript 3.0
然后 Ctrl + Enter or Command + Enter,看output输出的信息:
removed some children!

gotoAndStop function executed at: 6

oops, nothing there...

[object Shape] added at: 6

[object MovieClip] added at: 6

run timeline actionscript at: 6

typeof c at frame 2 is:number

run timeline actionscript at: 6

typeof c at frame 2 is:number

this frame 3通过上面的测试,会发现之前没有留意的细节:
1、Flash Player 10 和 Flash Player 9 在 gotoAndStop 方法调用之后执行的方式非常不同。
通过上面的图示可以看出Flash Player 9和10之间在跳帧的时候执行逻辑的差异,Flash Player 9相当于在跳帧的时候异步执行了该帧上的脚本,也许是出于优化性能的考虑,但是这给开发带来了很多麻烦,比如每次跳帧的时候需要检查显示对象是否已经被添加到了显示列表当中,通过 Event.ADDED事件进行这一恶心麻烦的判断。相比之下 Flash Player 10的逻辑就清晰很多,开发不用担心上面说的问题。
2、Flash Player 9 第二帧的脚本被执行了两次(WTF~)!
这个着实让我想不明白,暂且作为这篇文章的一个遗留问题吧,希望各位高手一起来看是为什么。

(, 下载次数: 18)




欢迎光临 应用思考-教育技术论坛 (http://etthink.com/) Powered by Discuz! X3.4