一直都以为Flash中对图片的处理是比较弱的,但偶然在网上找到的一个例子彻底地打消了我的这个想法。先来看看实例,点击按钮,对各个参数设置一定的值,就可以看到相应的图片实例效果,一共有十八种不同的实例。
效果图:
原理其实是非常简单的,将要操作的图片分成一小块一小块,每一次通过不断操作分割后图片的_x、_y、_xscale、_yscale、_rotation值来实现处理效果。
具体实现中,可以用遮照效果将图片分割成小块,实现简单而且操作方便。对_x、_y、_xscale、_yscale、_rotation的操作可以封装在帧函数里面,不断调用,就可以实现效果。
下面我们来具体看看实例。
1、在Flash MX中新建一个fla文件,按Ctrl + F8新建一个Movie Clip,命名为“slider clip”,类型为“Movie Clip”。在此Clip的场景中用矩形工具绘制一个正方形。
2、按Ctrl + F8新建一个Movie Clip,命名为“slider”,类型为“Movie Clip”。在此Clip的场景中用矩形工具绘制一个长方形。将上一步中制作的Clip “slider clip”拖到此Clip的场景中长方形的下端,命名为“button”。用文本工具在Clip “slider”场景中的长方形的下面拉一个文本输入框,属性设置如图1所示。并在Clip “slider”的帧的Action 面板上面增加如下语句:

function setY (value) { //注释1
_level0[change]=value; //注释2
range = top-base;
button._y=-(value-base)/(range/200); //注释3
}
function go () {
var buttonY = -button._y;
var value = base+((range/200)*buttonY); //注释4
_level0[change]=value;
}
function reset() { //注释5
setY(_level0[change]);
}
reset(); //注释6
注释1:定义一个函数,传入的参数是value。
注释2:这里chang分别代表的是制作过程第11步所增加的Action语句里面所赋的值。
注释3:定位button的位置。
注释4:取得button的最大位置。
注释5:封装上面所定义的函数。
注释6:调用上面所定义的函数
3、按Ctrl + F8新建一个Movie Clip,命名为“slider button”,类型为“Button”。在此Button的场景中用矩形工具绘制一个正方形。
4、按Ctrl + F8新建一个Movie Clip,命名为“preset selector”,类型为“Movie Clip”。用文本工具在此Clip场景中拉一个文本输入框,属性设置也如图1所示。将上一步制作的Button“slider button”拖到此Clip的场景中,并在此Button的Action面板上面增加如下语句:
on (release) {
_level0.preSet(_level0["pre"+num]); //注释1
}
注释1:调用主场景中所定义的帧函数preSet,传入参数中的num是制作过程第10步中所传入的参数。
5、按Ctrl + F8新建一个Movie Clip,命名为“img selector”,类型为“Movie Clip”。用文本工具在此Clip场景中拉一个文本输入框,属性设置如图1所示。将Button“slider button”拖到此Clip的场景中,并在此Button的Action面板上面增加如下语句:
on (release) {
_level0.setUp(me); //注释1
}
注释1:调用主场景中所定义的帧函数setUp,传入的参数me是制作过程第12步中所传入的参数。
6、按Ctrl + F8新建一个Movie Clip,命名为“img Holder”,类型为“Movie Clip”。通过菜单命令File / Import导入一个图片到图库中,并拖到此Clip的场景中。在此Clip的第一帧的Action面板上面增加如下语句:
gotoAndStop(_parent.type);
注释:图片是可以动态导入进这里来的,如果是动态导入的话,操作是差不多的。
7、按Ctrl + F8新建一个Movie Clip,命名为“slice”,类型为“Movie Clip”。设置此Clip的Linkage如图2所示。将Clip“img Holder”拖到此Clip的场景中,命名为“img”。在Clip“slice”的时间轴上面增加一个新的图层“Layer 2”,在新增图层“Layer 2”的场景中用矩形工具绘制一个长方形,长方形的长要跟Clip“img Holder”差不多。

8、调整Clip“slice”时间轴中图层的位置,让有Clip“img Holder”的“Layer 1”图层在“Layer 2”图层的下面。鼠标右键点击“Layer 2”图层的名字,选择“Mask”项。鼠标右键点击“Layer 1”图层的第五十帧,在第五十帧上面插入关键帧,让第五十帧的场景中的Clip“img Holder”位置向左偏移一定的距离。点击“Layer 1”图层的第一帧,设置帧的属性面板如图3所示。

9、按Ctrl + F8新建一个Movie Clip,命名为“slice holder”,类型为“Movie Clip”。设置此Clip的Linkage如图4所示。
10、回到影片的主场景中,从图库中拖19个Clip“preset selector”到场景中排列好,并依次在各个Clip实例的Action面板上面增加语句。
在实例1的Action面板上面增加如下语句:
onClipEvent (load) {
label="Reset";
num=0;
}
在实例2的Action面板上面增加如下语句:
onClipEvent (load) {
label="Wave";
num=1;
}
在实例3的Action面板上面增加如下语句:
onClipEvent (load) {
label="Twist";
num=2;
}
在实例4的Action面板上面增加如下语句:
onClipEvent (load) {
label="Reflect";
num=3;
}
在实例5的Action面板上面增加如下语句:
onClipEvent (load) {
label="Esculator";
num=4;
}
在实例6的Action面板上面增加如下语句:
onClipEvent (load) {
label="Spiral";
num=5;
}
在实例7的Action面板上面增加如下语句:
onClipEvent (load) {
label="Flip";
num=6;
}
在实例8的Action面板上面增加如下语句:
onClipEvent (load) {
label="Pong";
num=8;
}
在实例9的Action面板上面增加如下语句:
onClipEvent (load) {
label="Reflect2";
num=7;
}
在实例10的Action面板上面增加如下语句:
onClipEvent (load) {
label="Bend";
num=9;
}
在实例11的Action面板上面增加如下语句:
onClipEvent (load) {
label="Trance";
num=10;
}
在实例12的Action面板上面增加如下语句:
onClipEvent (load) {
label="Spring";
num=11;
}
在实例13的Action面板上面增加如下语句:
onClipEvent (load) {
label="Sway";
num=12;
}
在实例14的Action面板上面增加如下语句:
onClipEvent (load) {
label="Fire";
num=13;
}
在实例15的Action面板上面增加如下语句:
onClipEvent (load) {
label="Ghost";
num=14;
}
在实例16的Action面板上面增加如下语句:
onClipEvent (load) {
label="Ripple";
num=15;
}
在实例17的Action面板上面增加如下语句:
onClipEvent (load) {
label="Flame";
num=16;
}
在实例18的Action面板上面增加如下语句:
onClipEvent (load) {
label="Waterfall";
num=17;
}
在实例19的Action面板上面增加如下语句:
onClipEvent (load) {
label="Structure";
num=18;
}
11、从图库中拖11个Clip“slider”到场景中排列好,依次更改各个Clip实例的实例名,并在其Action面板上面增加相应语句。
将实例1命名为“mwaveLength”,在其Action面板上面增加如下语句:
onClipEvent (load) {
change="waveLength";
base=0;
top=-3.14;
label="w/l";
}
将实例2命名为“mdrift”,在其Action面板上面增加如下语句:
onClipEvent (load) {
change="drift";
base=-0.05;
top=0.05;
label="drift"
}
将实例3命名为“mdist”,在其Action面板上面增加如下语句:
onClipEvent (load) {
change="dist";
base=0;
top=100;
label="amp";
}
将实例4命名为“msangle”,在其Action面板上面增加如下语句:
onClipEvent (load) {
change="sangle";
base=0;
top=-10;
label="offset";
}
将实例5命名为“mpicDrift”,在其Action面板上面增加如下语句:
onClipEvent (load) {
change="picDrift";
base=1.9;
top=-1.9;
label="slide";
}
将实例6命名为“mrotate”,在其Action面板上面增加如下语句:
onClipEvent (load) {
change="rotate";
base=-180;
top=180;
label="rotation";
}
将实例7命名为“moptx”,在其Action面板上面增加如下语句:
onClipEvent (load) {
change="optX";
base=-1;
top=1;
label="X";
}
将实例8命名为“mopty”,在其Action面板上面增加如下语句:
onClipEvent (load) {
change="optY";
base=-1;
top=1;
label="Y";
}
将实例9命名为“moptxs”,在其Action面板上面增加如下语句:
onClipEvent (load) {
change="optXS";
base=-1;
top=1;
label="Xs";
}
将实例10命名为“moptys”,在其Action面板上面增加如下语句:
onClipEvent (load) {
change="optYS";
base=-1;
top=1;
label="Ys";
}
将实例11命名为“moptr”,在其Action面板上面增加如下语句:
onClipEvent (load) {
change="optR";
base=-1;
top=1;
label="R";
}
注意制作过程第10步和第11步,用到的Clip都是制作过程第3步和第4步中所制作的,通过传入的参数不同而实现不同的操作,这种实现方法很值得学习。
12、从图库中拖一个Clip“img selector”到场景中放好,并在其Action面板上面增加如下语句:
onClipEvent (load) {
me="img1";
label="image 1";
}
13、从图库中拖一个Clip“slice holder”到场景中放好,将其命名为“holder”,并在其Action面板上面增加如下语句:
onClipEvent (enterFrame) { //注释1
_level0.render(); //注释2
}
onClipEvent (keyDown) { //注释3
if (Key.getCode() eq"32") { //注释4
_level0.readPre();
}
}
注释1:这个函数相当于是整个影片的引擎,影片会不断地调用这个函数。
注释2:调用主场景的帧中所定义的函数,不断地渲染。
注释3:响应按键。
注释4:32所对应的是空格键。
14、点击主场景中时间轴的第一帧,在它的Action面板上面增加如下语句:
fscommand ("allowscale", false); //注释1
_quality = "low"; //注释2
pre0=[0,0,0,0,0,0,0,0,0,0,0]; //注释3
pre1=[-0.154645,0,12.475,0.005125,0,0,0,1,0,0,0];
pre2=[-0.04396,0,89.775,0.0009,-1.9,0,0.001,0,0,0,1]
pre3=[-1.97977,0,100,0.0409,0,90,0.001,0,0,1,0.008]
pre4=[-0.124815,0,100,0.00057,0,-90.54,-0.8255,-1,0.254,0.266,-0.0129]
pre5=[-0.069865,0,100,-0.00175,0,0,0.188,1,0,1,1]
pre6=[-0.0314,0,100,0.0017,0,0,0,0.0355,0,1,0]
pre7=[-1.088795,0,12.475,0.005125,0.06459,-90,0,1,0,0,0]
pre8=[-1.256,0,100,0.003975,0,0,1,1,1,1,1]
pre9=[-0.1256,-5.88,100,0,-1.9,0,0.3825,0.163,0,0,-0.152]
pre10=[-0.1256,0,100,0.003975,-1.9,0,-1,0.6865,0,-0.733,1]
pre11=[-0.035325,0,40.875,-0.005125,0,0,-0.951,0.3265,-0.209,-1,1]
pre12=[-0.05338,0,100,0.00235,0,0,0,0,0,0,1]
pre13=[-2.355,0,18.225,0.0108,0,0,0,1,0,1,0]
pre14=[-3.14,0,100,0.00345,0,0,-0.8475,1,0,-0.385,0]
pre15=[-0.59974,0,5.625,0.02555,0,0,0,0.058,0,1,0]
pre16=[-1.14296,0,12.475,-0.00455,0,-180,0,1,0,-1,0]
pre17=[-0.5338,0,100,0.00285,0,0,-0.1185,1,-1,-1,0]
pre18=[-0.303795,0,100,0,1.9,0,-0.0795,0.2795,0,0.164,0.768]
function setUp(type) { //注释4
var myStage=_level0.holder; //注释5
for (i=1; i<51; i++) { //注释6
myStage.attachMovie("pic", "p_"+i, i);
pic = myStage["p_"+i];
pic.type=type;
pic._x = (i*2.9)-(25*2.9); //注释7
nangle += waveLength;
angle = sangle+nangle;
scale = dist*Math.sin(angle);
pic._yscale = 100-scale;
}
}
function render () { //注释8
var nangle;
var myStage=_level0.holder;
myStage._rotation=_level0.rotate; //注释9
for (i=1; i<51; i++) {
pic = myStage["p_"+i];
nangle += _level0.waveLength;
_level0.sangle+=_level0.drift;
var angle = _level0.sangle+nangle;
var scale = _level0.dist*Math.sin(angle);
pic._x = ((i*2.9)-(25*2.9))-(scale*optX); //注释10
pic._y = scale*optY;
pic._xscale = 100+(scale*optXS);
pic._yscale = 100-(scale*optYS);
pic._rotation = (scale*optR);
if (int(_level0.picDrift) == 0) { //注释11
myFrame=i;
} else {
pic.frame-=int(_level0.picDrift);
myframe=pic.frame;
if (myframe<1) {
myframe=50;
} else if (myframe > 50) {
myframe=1;
}
pic.frame=myframe;
}
pic.gotoAndStop(myframe);
}
}
function preset (choice) { //注释12
_level0.waveLength = choice[0];
_level0.mwaveLength.reset();
_level0.sangle=choice[1];
_level0.msangle.reset();
_level0.dist=choice[2];
_level0.mdist.reset();
_level0.drift=choice[3];
_level0.mdrift.reset();
_level0.picDrift=choice[4];
_level0.mpicDrift.reset();
_level0.rotate=choice[5];
_level0.mrotate.reset();
_level0.optX=choice[6];
_level0.moptX.reset();
_level0.optY=choice[7];
_level0.moptY.reset();
_level0.optXs=choice[8];
_level0.moptXs.reset();
_level0.optYs=choice[9];
_level0.moptYs.reset();
_level0.optR=choice[10];
_level0.moptR.reset();
}
function readPre () { //注释13
var choice=new Array()
choice.push(_level0.waveLength);
choice.push(_level0.sangle);
choice.push(_level0.dist);
choice.push(_level0.drift);
choice.push(_level0.picDrift);
choice.push(_level0.rotate);
choice.push(_level0.optX);
choice.push(_level0.optY);
choice.push(_level0.optXs);
choice.push(_level0.optYs);
choice.push(_level0.optR);
trace(choice);
}
preset(_level0.pre0); //注释14
setUp("img1"); //注释15
注释1:设置播放时不能缩放。
注释2:设置影片的播放质量为低,这样在低配置的机器上面也可以比较快的运行。
注释3:定义初始化数组,这些值分别对应一个图形效果。
注释4:定义函数,这个函数是用来在一开始运行的时候对图片进行操作的。
注释5:取得要操作的图片,可以在这里更改要操作的图片。
注释6:通过循环来依次操作图片的一部分。
注释7:循环中更改的都是图片的属性,如:_x、_y、_yscale等。
注释8:定义函数,这个函数是用来渲染显示效果的,是整个影片中最核心的东西。
注释9:定义图片的旋转效果。
注释10:图片的处理效果,都是通过对_x、_y、_xscale、_yscale、_rotation的操作来实现的。
注释11:每一次显示图片的不同部分,是通过遮照效果来实现的。
注释12:初始化场景中的滚动条。
注释13:将场景中每一个滚动条所对应的值存在数组中。
注释14:调用函数,初始化场景。
注释15:调用函数,初始化要操作的图片。
三、小结
实例的制作到此就完成了,其关键之处在于主场景中第一帧上面定义的那几个函数,其他地方的都只是引用了这个几个函数而已。从实例中也可以看到,单靠图形变换制作很麻烦的效果,其实只是需要几个AS语句就可以完成,看来,学好AS对提高Flash水平还是大有裨益的。
本实例在Flash MX环境下面调试通过。如果是在Flash MX 2004中做的,只要设置输出的格式为Flash 6也是一样可以看到效果的。