用AS实现精彩的3D旋转效果

      FLASH 2004-11-19 16:3
作者: 翅膀
众所周知,Flash中要实现3D效果是比较麻烦的,下面我们就用Action Script来实现一个比较简单的3D效果。先看看最终效果,一个看起来像是3D效果的花在场景中旋转,在旋转的过程中会改变颜色,还会响应鼠标作相应的动作。静态效果如图1所示。

  最终效果演示:

一、实现原理
  要在只能显示二维图形的Flash中显示三维图形,很关键的一点就是如何将三维坐标转换为二维坐标。另外,如何对三维坐标进行操作,如何渲染最终的显示效果,都是颇有难度的。
  在此实例中,我们首先将三维的坐标值保存在数组里面,对这些坐标值进行操作后,根据一定的规则对数组里面的值进行相应计算,转换成二维坐标,对二维坐标值进行渲染和显示控制,就得到了最终的显示效果。
二、实现步骤
  1、打开Flash MX 2004,新建一个场景,设置场景的大小为700 px * 525 px,背景为黑色。
  2、按“Ctrl + F8”新建一个Movie Clip,命名为“circle”,类型为Movie Clip,在此Clip中用“Oval tool”绘制一个椭圆形如图2所示。

  3、按“Ctrl + F8”新建一个Movie Clip,命名为“line”,类型为Movie Clip,将上一步制作的“circle”Clip拖到此Clip的场景中,命名为“circle”。在此Clip的时间轴的第30帧上面点击鼠标右键,选取“Insert key frame”,从而插入关键帧。选取第30帧的场景里面的“circle” Clip,设置属性如图3所示。在第60、90帧上面插入关键帧,分别设置场景里面的“circle” Clip属性如图4、5所示。最后在第120帧上面插入关键帧。



  4、点击 “line”Clip中时间轴上面的第1帧、第30帧、第60帧、第60帧,分别设置帧的属性如图6所示。

  5、按“Ctrl + F8”新建一个Movie Clip,命名为“vertex”,类型为Movie Clip,在此Clip的场景中用文本工具输入“loading”这几个字。
  6、返回到主场景中,将“line”Clip和“vertex”Clip都拖到场景中,并分别将它们的实例名设置为“wire”和“point”。
7、在主场景的时间轴上面,插入一个新的层,命名为“Scripts”,分别在此层的第2帧、第3帧上面插入关键帧。
  8、在“Scripts”层的第1帧的Action面板上面添加如下语句:
var variable, buffer, no;Points = 11; // 注释1Lines = 10; // 注释2Viewport = 500; // 注释3line = new Array(Lines); // 注释4vertex = new Array(Points);project = new Array(Points);fscommand ("fullScreen", true); // 注释5for (i=0; i != Lines; i++) { wire.DuplicateMovieClip("l" add i, i); // 注释6 line[i] = eval("l" add i);}for (i=0; i != Points; i++) { point.DuplicateMovieClip("v" add i, (Lines*2)+i); // 注释7 vertex[i] = eval("v" add i);}vertex[0].x = 0; // 注释8vertex[1].x = -100;vertex[2].x = -150;vertex[3].x = -150;vertex[4].x = 0;vertex[5].x = 100;vertex[6].x = 150;vertex[7].x = 100;vertex[8].x = 150;vertex[9].x = 0;vertex[10].y = 0;vertex[0].y = 0;vertex[1].y = -100;vertex[2].y = 0;vertex[3].y = 100;vertex[4].y = 150;vertex[5].y = 100;vertex[6].y = 0;vertex[7].y = -100;vertex[8].y = -150;vertex[9].y = 0;vertex[10].y = 0;vertex[0].z = 0;vertex[1].z = -100;vertex[2].z = 0;vertex[3].z = 100;vertex[4].z = 0;vertex[5].z = 100;vertex[6].z = 0;vertex[7].z = -100;vertex[8].z = 0;vertex[9].z = -150;vertex[10].z = 150;line[0].a = 0; // 注释9line[0].b = 1;line[1].a = 0;line[1].b = 2;line[2].a = 0;line[2].b = 3;line[3].a = 0;line[3].b = 4;line[4].a = 0;line[4].b = 5;line[5].a = 0;line[5].b = 6;line[6].a = 0;line[6].b = 7;line[7].a = 0;line[7].b = 8;line[8].a = 0;line[8].b = 9;line[9].a = 0;line[9].b = 10;function Rotate (x, y, z) { // 注释10 rad = (3.14*2)/360; // 注释11 radx = rad*x; // 注释12 rady = rad*y; radz = rad*z; for (i=0; i != Points; i++) { // 注释13 if (x != 0) { vertex[i].x1 = vertex[i].x; vertex[i].y1 = (Math.cos(radx)*vertex[i].y)-(Math.sin(radx)*vertex[i].z); vertex[i].z1 = (Math.sin(radx)*vertex[i].y)+(Math.cos(radx)*vertex[i].z); } if (y != 0) { vertex[i].x2 = (Math.cos(rady)*vertex[i].x1)-(Math.sin(rady)*vertex[i].z1); vertex[i].y2 = vertex[i].y1; vertex[i].z2 = (Math.sin(rady)*vertex[i].x1)+(Math.cos(rady)*vertex[i].z1); } if (z != 0) { vertex[i].x3 = (Math.cos(radz)*vertex[i].x2)-(Math.sin(radz)*vertex[i].y2); vertex[i].y3 = (Math.sin(radz)*vertex[i].x2)+(Math.cos(radz)*vertex[i].y2); vertex[i].z3 = vertex[i].z2; } }}function toScreen () { // 注释14 for (i=0; i != Points; i++) { vertex[i].dx = (vertex[i].x3*viewport)/(vertex[i].z3+600)+350; //注释15 vertex[i].dy = (vertex[i].y3*viewport)/(vertex[i].z3+600)+262.5; }}function render () { // 注释16 for (i=0; i != lines; i++) { with (line[i]) { _visible = true; _x = vertex[line[i].a].dx; _y = vertex[line[i].a].dy; _xscale = vertex[line[i].b].dx-vertex[line[i].a].dx; _yscale = vertex[line[i].b].dy-vertex[line[i].a].dy; } } for (i=0; i != points; i++) { with (vertex[i]) { _x = dx; _y = dy; _xscale = 75+(((((500-z3[i])/10)*30)/100)*(-1)); _yscale = 75+(((((500-z3[i])/10)*30)/100)*(-1)); _alpha = ((((z3[i]*(-1))+500)/10)) } }}var ax, ay, az, oldx, oldy, bx, by, bz, nu;

  注释1:定义显示的文字为11个。
  注释2:定义组成3D图形的元素有10个。
  注释3:定义一个控制3D图形显示比例的变量。
  注释4:在这里定义几个数组,大小为刚刚所定义的变量,用来放置3D图形的各种细节。
  注释5:为了使效果看起来更好,这里实现全屏效果,有关fscommand更多的细节可以查看Flash中自带的帮助文件。
  注释6:复制文字Movie Clip,个数为前面所定义的变量值。
  注释7:复制组成图形的元素的Movie Clip,个数为前面所定义的变量值。
  注释8:设置3D图形中的文字的x、y、z坐标值,这里是3维的,改变这些值就改变了文字在3D图形中的位置。
  注释9:设置3D图形中的图形元素的x、y、z坐标值,因为图形元素已经是2维的,所以只需要2个值就可以表示3维的效果。
  注释10:定义一个函数,在这个函数里面,根据传入的x、y、z的坐标值,改变在相应数组中的值,从而实现了旋转的效果。
  注释11:定义一个常量,在将值转换成弧度的时候用。
  注释12:因为在下面的sin/cos函数中只能使用弧度,所以将传入的x、y、z坐标值转换成弧度。
  注释13:在这个循环里面,依次改变数组中的x、y、z的值,实现旋转效果。
  注释14:在Flash中只能显示二维坐标,这个函数就实现了将三维坐标转换成二维坐标,这里的实现方法很值得深思。
  注释15:这里的350和262.5分别为图形元素的长和宽,如果改变了图形元素的大小,也要相应的改变这两个值。
  注释16:这个函数实现了对最终生成三维图形进行显示和渲染,若要实现不同的显示效果,修改里面相应的值即可。

  9、在“Scripts”层的第2帧的Action面板上面添加如下语句:
rotx = (oldy-_ymouse)/2; // 注释1roty = (oldx-_xmouse)/2;oldx = _xmouse;oldy = _ymouse;ax++; // 注释2ay++;ax += rotx; // 注释3ay += roty;ay += by;ax += bx;az += bz;bx = 0; // 注释4by = 0;bz = 0;rotate(ax, ay, az); // 注释5az++;if (ax>360) { // 注释6 ax -= 360;}if (ay>360) { ay -= 360;}if (az>360) { az -= 360;}toScreen(); // 注释7render(); // 注释8nu = 4;

  注释1:这里的四行是取得鼠标的位置。
  注释2:这里将x、y、z的值自增一,是为了在鼠标不动的时候,图形还可以保持旋转。
  注释3:这里是为了响应鼠标的动作而设置的值。
  注释4:将值设置为0,在下次循环的时候使用。
  注释5:调用第一帧里面所定义的函数,旋转传入的坐标值。
  注释6:旋转一周为360度,要对超过360的值进行处理。
  注释7:调用第一帧里面所定义的函数,将三维的坐标转换成可以在Flash显示的二维坐标。
  注释8:调用第一帧里面所定义的函数,渲染、显示所生成的三维图形。

  10、在“Scripts”层的第3帧的Action面板上面添加如下语句:
gotoAndPlay(2);


  注释:回到第二帧,使效果看起来连贯。

  三、小结
  至此,实例就制作完了,效果虽然比较简单,但也为在Flash中实现3D效果提供了一种思路。
  相信经过本实例的研究,对Flash中函数的操作、坐标的转换、用Action Script控制图形的显示、Action Script数组的操作等等都会变的得心应手,仔细研究一下,还是值得的。
  另外,将实例中涉及的文字和图形元素进行变换,可以得到不同的效果。对相应的值进行修改,也可以改变显示的效果,如大小,位置,透明度等等。

源文件
标签集:TAGS:
回复Comments() 点击Count()

回复Comments

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