FF7AC日本官网Flash菜单特效(AS2.0 OOP)

2006-11-26 20:31 | Army

还记得AC日本官网刚推出的时候,它的华丽令许多人叹为观止。后来虽然官网进行了改进,但新版里许多东西实质上还是原来就有的,只不过稍加变化而已。
我在那时也毫不例外对它如痴如醉,梦想着有一天自己也能作出如此优美的作品。后来下回整个swf文件并反编译成fla,看着里面成页的复杂代码我十分头疼,因为那时以我的水平是无论如何也无法将之领悟的。很有幸,今天我能把它改写成一个OOP的版本,并写成教程放在网络上。
一些声音、文字和图象之类的东西我省略了,而且为了容易书写,它与官网相比也有一些不同之处。

这个教程的源文件地址是(MX2004版本):
http://ff9.ffsky.cn/flash_teach\ff7ac/exp.rar

请允许我用一张图来说明整个文件的组成:



它只有1帧,分4个图层。其中:图层0放as代码;图层1放6个名为btn1、btn2、……、btn6的按钮,也就是那6个灰色的正6边形;图层2放那个FF7AC的LOGO;图层3放右上方的名为but的正6边形框。
border元件是一个白色正6变形边框,button元件是一个有渐变效果的正6变形。它俩最终组合成了button_b按钮,并把按钮分成6个实例放在舞台上——那6个名为btn1、btn2、……、btn6的按钮就是它们。
but元件是个正6边形框,but_m是以它为基础做的一个透明度渐变的MC,然后放到舞台上——那个but就是它。
logo是张位图,也就是FF7AC的LOGO。line是一个具有线性渐变效果的线条,line_m则是用它做成的一个透明度渐变的MC,许多条并排等距排列的ine_m合到一起就是line_m_all。以logo为底层,line_m_all为顶层,拼到一起成了logo_m,我把它放在了舞台的图层2上。
media是导入的一段flv视频,它出自官网。mask是一个白色的正6边形,以它作遮照层挡住media就形成了video这个MC,并且我给视频的6个小段都标上了帧标签:video1、video2、……、video6。它并没有实例化到舞台上,而是将链接命名为video(很多名称有重复,可能导致含义混淆,你需要下载源文件对照着理解)。

让我们看一下LoadButton.as文件:

class LoadButton {
  var i:Number, butx:Number, buty:Number, nowx:Number, nowy:Number;
  var bMove, bFade;

  function videoPlay():Void {
    for(i = 1; i <= 6; i++) {
      _root.attachMovie("video", "video" + i, i);
      eval("_root.video" + i)._x = eval("_root.btn" + i)._x;
      eval("_root.video" + i)._y = eval("_root.btn" + i)._y;
      eval("_root.video" + i).gotoAndPlay("video" + i);
      eval("_root.video" + i)._alpha = 30;
    }
  }
  function videoAlpha(num:Number, alpha:Number):Void {
    eval("_root.video" + num)._alpha = alpha;
  }
  function butInitialize():Void {
    _root.but._alpha = 0;
    _root.but._x = _root.btn1._x;
    _root.but._y = _root.btn1._y;
    _root.but.swapDepths(7);
  }
  function butMove(num:Number):Void {
    butx = eval("_root.btn" + num)._x;
    buty = eval("_root.btn" + num)._y;    
    nowx = (butx - _root.but._x) * 0.3;
    nowy = (buty - _root.but._y) * 0.3;
    _root.but._x += nowx;
    _root.but._y += nowy;
    _root.but._rotation = nowx;
    if(_root.but._x == butx && _root.but._y == buty) clearInterval(bMove);
  }
  function butFade(num:Number):Void {    
    if(num != 0) {
      _root.but._alpha += 20;
      if(_root.but._alpha >= 100) _root.but._alpha = 100;
    }
    else {
      _root.but._alpha -= 5;
      if(_root.but._alpha <= 0) _root.but._alpha = 0;
    }
  }
  function setFade(num:Number):Void {
    clearInterval(bFade);
    bFade = setInterval(this, "butFade", 20, num);
  }
  function setMove(num:Number):Void {
    clearInterval(bMove);
    bMove = setInterval(this, "butMove", 20, num);
  }
}


几个基本变量的声明不再赘述。

videoPlay方法是将那段视频分别嵌到6个按钮上边。这里用了个循环,attachMovie方法将链接名为video的MC放置到_root上,并重新命名为"video" + i(循环体内的含义就是video1、video2、……、video6),深度为i。
随后我用eval函数各自设置它们的坐标值和透明度,并让它们分别从标出的帧标签处开始播放。这样,一段视频看起来就像6段不同的视频效果了。你可以更改那6个帧标签的顺序从而使6个按钮上的视频播放起始处也随之更改。
本来我打算用with语句替换掉那一大串的eval的,但是后来我发现with和eval不能混用,而且with不支持像"_root.video" + i这样的字符串链接,所以只好放弃了。但愿在以后的版本里能看到Adobe增加这一功能。

videoAlpha方法是更改6段视频的透明度值,它接受两个数值型的参数。

butInitialize方法是初始化那个名为but的花6边形框,设置它的坐标值与_root.btn1相同并透明度为0。而且为了显示在6个视频的上边,我将它的层级设置成为7。

butMove方法在以前的几篇教程中都有类似的出现,就是以极限运算,让but这个MC的坐标值不断靠近所指的按钮,直至相等。最后的那句_root.but._rotation = nowx;可能一些人理解起来有困难(原来我感到最难的就是这句),其实它很简单,只要你稍微有些数学知识。
but是个正6边形,因此它的内角是120度,外角就是60度。把它水平放置,然后旋转一格,就是旋转了60度,2格就是120度。在舞台上2个相邻按钮之间的水平坐标差是114,因此nowx的取值就是114 * 0.3 = 34.2的整数倍。以but从btn1移向btn2为例,它在坐标值不断向按钮靠拢的同时,角度也不断减小变化(34.2、10.26、……、0),这样看起来就像翻了个跟头一样。移向距离远的按钮则相应地多翻一些跟头。

butFade方法则是控制这个花6边形框的消失与否的。每当鼠标移上按钮则透明度增加,到100停止;移出按钮时透明度减少,到0停止。

setFade和setMove方法各自控制butFade和butMove的执行函数,并传递相应的参数。记得在每次执行前先进行清除,否则可能会导致冲突。

最后则是在fla文件中的一些代码了,在主时间轴上,声明对象并调用初始化方法:

var lb:LoadButton = new LoadButton();
lb.videoPlay();
lb.butInitialize();


6个按钮上各自有相应的方法调用,参数不全相同。其中videoAlpha的首参和setMove的实参各为各自按钮名称的最后一位数字,其它的方法参数相同。

on(rollOver) {
  lb.videoAlpha(1, 100);
  lb.setMove(1);
  lb.setFade(1);
}
on(rollOut) {
  lb.videoAlpha(1, 30);
  lb.setFade(0);
}


在line_m这个MC的第2帧还有一些代码,用以实现这些光线随机变化。我本打算把它写成另一个类的,可是后来发现这样作反而增加了代码长度和复杂性,写起来也很困难,于是就直接写在时间轴上了。这也告诉我们,一些简单的事情不要把它做复杂了,有时候OOP未必就一定是个很好的选择。

var num:Number = Math.floor(Math.random() * 50);
if(num != 0) gotoAndPlay(1);


好了,全部内容我都叙述完毕了,去自己体会一下这华丽的官网菜单效果吧!当你随着教程与实例不断地积累知识和经验(这个过程可能是不容易察觉的),你就会发现,一些困难的东西逐渐变得简单,一些不可能的事情逐渐变得可能,一些原本没有的创意也逐渐出现在你脑海了。

让我们在感恩节之际感谢那些创建出伟大作品的艺术家!