通过对上面特效的学习与讲解,读者可能会觉得它仅仅是一个编程技巧,在实际使用过程中根本用不到这种线的效果。那么,先看图3-3所示的效果图片吧。

图3-3
这个效果酷不酷?想想这种效果如果用手工来制作会不会累死人?那么这样的花色效果是如何制作出来的呢?其实也跟上面的原理相似——堆栈加遍历,程序代码如下:
makeClip = function (clipParent, clip_num, high, place) {
// 创建一个空的动画片断,同时继承了这个动画片断的大小与位置
son=clipParent.createEmptyMovieClip("s_"+clipParent.depth+"_"+clip_num,clip_num);
// 由于它是子节点位置,所以层数要加1
son.depth = clipParent.depth+1;
//子入栈
_root.arr.push(son);
// 用随机色进行填充,透明度为40
son.beginFill(Math.random()*0xFFFFFF, 40);
// 先画一个正方形
son.lineTo(100, 0);
son.lineTo(100, 100);
son.lineTo(0, 100);
son.endFill();
// 设置其摆放位置,high与place的取值只有0与1
// 这里用来控制色块左右分半还是上下分半的变量是high
// 当完成把一个块切成两半的任务之后,用来控制位置色块位置的变量是place
// 经过这两项设置,色块就按随机方式摆放成上下两半,或者是左右两半
(high) ? (son._y=place*50) : (son._x=place*50);
// 通过设置其长与宽的比例
// high=1时表示是上下对半分,high=0时表示是左右对半分
son._xscale = 150-(son._yscale=(high) ? (50) : (100));
};
makeNew = function () {
// 从数组中随机取一个位置来计算
p = arr[a=Math.floor(Math.random()*(len=arr.length))];
// 删除该数值
arr.splice(a, 1);
// 最多只允许8层
if (p.depth<8) {
// 产生随机的是与非的值,用于控制色块是横切还是纵切
_root.hv = Math.round(Math.random());
// 产生随机的是与非的值,用来控制两个不同块的摆放
_root.lr = Math.round(Math.random());
// 创建第一半
makeClip(p, 1, _root.hv, _root.lr);
// 创建另一半
makeClip(p, 2, _root.hv, !_root.lr);
}
//如果子类全部产生完毕则结束
if (!len) {
clearInterval(intID);
}
};
this.onMouseDown = function() {
arr = [c=_root.createEmptyMovieClip("clip", 1)];
c._xscale = c._yscale=400;
intID = setInterval(makeNew, 1);
};
这个特效的代码要讲解起来非常难,因为它是一个纯粹的程序,用到的知识点也比较多。
程序代码连写
Flash程序代码可以写在一行里,甚至在一个表达式里可以包含其他的表达式。比如上面的p = arr[a=Math.floor(Math.random()*(len=arr.length))]语句其实就包括了三个表达式:
len=arr.length;
a=Math.floor(Math.random()*len;
p = arr[a];
当然了,这样写的目的仅仅是为了说明Flash的代码可以这样写,当别人这样写的时候也可以看得懂,但是建议大家自己的程序还是不要这样写!笔者认为连写表达式最合理的就是c._xscale = c._yscale=400这一句,它可以简化程序代码,并且让程序思路更加清楚。
产生随机色
在上一章“闪亮的光环”特效中有一个产生随机灰色的语句,如果按那种产生随机色的思路来创建随机色,代码就比较复杂:
red_color = random(256);
green_color = random(256);
blue_color = random(256);
colourobj = new Color(this);
colourobj.setRGB(red_color << 16 | green_color<<8 | blue_color);
但是在这里用一个非常简单的表达式就可以搞定:
Math.random()*0xFFFFFF
这种方式简单易懂,比上一个“画方格”的方法更简单,建议大家在以后要产生真正意义上的随机色时用这种办法。
遍历的结束控制
在前面讲到的“用队列画方格”特效中结束控制是用堆栈的长度来控制,这在很多复杂的遍历中是难以计算的,甚至是无法计算的。而本特效结束标志是用depth深度来控制,这就方便与简单得多了,程序也易于理解,它惟一要做的就是每次入栈时要把它的深度值也一同入栈。在这里,因为已经把这个值与相应的动画片断封装,所以处理起来非常方便。
定时器控制
在本书的精华集1中讲到了定时器的使用。在本特效中通过定时器来控制色块的生成,从而产生出一种“逐渐细化”的过程,当然了,最后在全部细化完成时没有忘记清除定时器。虽然这种“逐渐细化”效果也可以用onEnterframe方式来实现,而且产生的结果一样,但是当最后细化结束时,要清除onEnterframe事件函数的运行就相对麻烦一些,如果不清除这个事件函数的运行,则对动画的其他程序的运行效率就会产生一定的影响。
效果对比
最后,为了便于大家理解这段代码,把if (p.depth<8) …一句改成if (p.depth<3),它的效果如图3-4~图3-7所示。看了这些三层深度遍历的效果,再与前面的效果相对比,应该可以理解整段程序的算法与构思了。

图3-4 图3-5

图3-6 图3-7