remove vs. unload vs. visible

      Flash 2004-11-12 17:57
要把一个mc,让它从场景上滚蛋,有三个方法

1. mc._visible = false;
2. mc.unloadMovie();
3. mc.removeMovieClip();

上面3个是用'纯'程序实现,如果用点'技巧'的话,方法就多了,比如场景下一帧你别放这个mc,或者在mc的第二帧建立一个空帧,然后让mc,goto到frame 2....等等
以上等技巧留给大家去创造吧...这里只说一下开始提到的3中方法

首先,如果你是一个画画高手,那么flashplayer每次再运行你画的杰作的时候,会很累,因为flash是矢量图的,她总是要先算啊算的,然后再显示出来,所以cpu消耗是恐怖了点的,当你的图一大,一复杂就会慢了,机器再破点,一个swf当幻灯片看是正常事情...ok,flashplayer的机制废话不多说了,再多说偶就露馅了 -w-

所以呢我们需要给flashplayer减减负,mm他们提供给偶们程序员3种可以减负的方法
第一种 mc._visible = false
当你这么设置以后,mc就不可见了,她和mc._alpha = 0;是不一样的,虽然对只会用眼睛看的人是一样的,但实际上,在mc里面的所有按钮触发事件已经不起作用
如果你在mc里面写了(按钮是继承mc的,所以这里一并提过)
on(press){trace("我是个mc,哈哈");}
但是如果你已经把mc设置为不可见,你就不能再点击这个mc,直到你设置回来.
可是mc是存在的,她没有把她所占用的资源还给你,相反,某些时候还会让你郁闷,比如在你设置她不可见以后,仍然使用hitTest();
那么她hit到了些什么,她就会一五一十的告诉你
onClipEvent(enterFrame){if(hitTest(_root._xmouse,_root._ymouse,true)trace("鼠标鼠标,你碰到我了,虽然控制你的人看不见我,嘿嘿");}
....嗯..在碰到这种情况的时候,你只好把她清除出场(后两种方法)

虽然这么看上去 visible 似乎没什么大用,不过却可以让你的播放器少算一点,这样也能增加你的播放速度,而且她是一直存在的,如果你给她一个onEnterFrame,她也是一直执行的,只要你高兴,你可以让她再"重见天日",而不是"重新做人"

第二种 mc.removeMovieClip()
哈哈,这个方法好啊,直接让你的mc再见,并且把她占用的资源都还给你了...不过使用她需要注意一点,这关系到mm定义mc的层问题...范围是{-16383 ~ ???}到多少忘了..来这里看看,-16384也可以放东西,385就不行了用attachMovie加载一下就知道了,反正你在什么都没有的帧里面拖一个mc,她默认的depth就是-16383...ok,这里没什么好多少的,但是要记住,你要removeMovieClip某个mc,这个mc的depth一定要>= 0

所以新手们,会被如何remove掉拖放在场景中的mc这样的问题,郁闷一会儿,其实第三个方法就是针对场景中mc的,等下再说,这里就第二个方法说一下,假如你有一个实力名为myMc的mc在场景中,以下代码可以帮你的忙
myMc.swapDepths(this.getNextHighestDepth());
myMc.removeMovieClip();
关于swapDepths就是交换层深,里面的参数是本"级"(level)中可以用到的最高层数的空层(我为什么要无聊的解释字面上就看的懂的东东>o<)
getNextHighestDepth()最低是0,这样能确保你顺利踢走不要的mc.

这么做真的很方便,东西没了什么都没了,mc上的按钮代码,事件代码都太太平平的走人了,如果你有这么做
mc.onEnterFrame = function(){};
当你remove掉这个mc后,你可以连delete mc.onEnterFrame;都省略掉,呵呵,不过偷懒不是什么好事情^^"

我把使用层深交换再remove掉的办法简称 super remove,哈哈,反正都是s打头,好记好记啊~~~而且如果你没有使用组件把getNextHighestDepth搞乱(看上面的层范围链接),这个方法可以删除你能看到的一切mc...而且没有什么隐患.因为她的作风是"斩草除根"....

第三种方法 mc.unloadMovie();
老实说,这个方法偶都没怎么用,因为我了解她竟然是在知道了super remove之后>_<||
不过呢,这个方法也真很不错,至少,你不用去了解depth这个概念,只要随手一用,不管你mc的depth是什么数,都和你招手再见了....
我一段时候一直以为这个unloadMovie就是内嵌了类似super remove的方法...可惜偶的想法总是太简单|o|....因为不久前偶发现了一个,不是很多见的....??好像不能说是bug吧-w-
具体现象
拖一个库里的mc到场景命名myMc,然后在myMc里面写代码
onClipEvent(enterFrame){trace("我就是那个mc,啦啦啦");}
然后在场景帧上写,myMc.unloadMovie();
测试一下,你就又会发现一个mm让偶们不知所以的怪毛病...嗯,你说的对,trace在不停的输出着
那么我怀疑这个叫myMc的其实没有滚蛋...而是给我藏起来了,可是在我用
myMc.onEnterFrame = function(){trace("我就是那个mc,啦啦啦");}
测试以后,我再一次被mm郁闷了....这个trace没有再执行 -.-!
于是我又多做几次测试...反正也被郁闷惯了
发现在onClipEvent(mouseDown){trace("你点我呀");}
她是输出的
而onClipEvent(mouseDown){if(hitTest(_root._xmouse,_root._ymouse,true))trace("你怎么不点我呀");}
她却是不输出的
.....

到此我想到了什么
onKeyDown需要用一个obj注册监听器,而onClipEvent(keyDown){};却可以直接使用
于是我又开始哥德巴赫猜想....
onClipEvent()里面的一些事件机制和场景中的一些事件机制是不同的,有可能在5.0时期之前没有场景事件时,mm在onClipEvent内就建立了一些监听机制...而这些机制在unloadMovie的时候是不会被删除的,也就是某个监听对象并不是绑定在这个mc上的....嗯~~~
所以unloadMovie执行后,只是把mc踢了,但没有把场地打扫一下,仍然留下了一些让人不在意,却是问题的问题

这一点super remove要做的好多了...她是确确实实的把mc留下的一切东西kick away!

总要总结一下吧
三个方法,各有利弊,真要比哪个好哪个坏,是没意思和意义的
第一种方法,虽然不能释放资源,但是可以帮你隐蔽东西
第二,第三种方法,虽然释放了资源,但是却不能让你的mc继续执行代码
第二种方法,如果不是super remove是有局限性的
第三种方法,也存在上面提到的隐患

我唾沫喷那么半天,主要是说明一些不太注意的地方让大家注意
该用什么不用什么都取决于代码本身的适用性...哈哈

欢迎大家砸砖
标签集:TAGS:
回复Comments() 点击Count()

回复Comments

{commentauthor}
{commentauthor}
{commenttime}
{commentnum}
{commentcontent}
作者:
{commentrecontent}