书架效果再分析

      Flash学习笔记 2008-6-23 9:11

  以前曾写过一个书架效果的分析( http://blog.5d.cn/user12/dzxz/200612/336721.html ),现在改成AS3版本,算AS3的练习作业吧。

最终效果:

  之前的文件是反编译而来的,分析之后将相关注释写在了fla文件中,熟悉AS2 的朋友们可以先下载看看。

  转换成As3并不像我一开始想的那么简单,因为要从类的角度重新整理分析出最终效果里所包含的有用元素。

  完成之后将自己的分析过程总结如下:

  1、寻找对象。

  在一个书架效果中,页面是基本单位,页面之间只有运动上的相关性,内容上无相关性,于是可以将页面做为一个基础类来进行设计。

  2、寻找属性。

  在过去的编程中,少不了用到全局属性、局部属性,在以类为代码单元的设计中,类中的全局属性可以用静态变量来替代,局部属性就是普通的类自定义变量。对照原来的代码,可以找到的全局属性包括: 

  menu --- 手动与自动翻页的标志

  overAt ---- 当前显示的页面

  pageTimer ---- 当前页面的计数器,统计当前页面已经显示了多长时间。

  局部属性包括:

  pageID --- 当前页面的ID编号,用来确定显示的顺序及运动的方向,可以在实例化时进行动态的指定。

  3、寻找程序逻辑。

  所有的页面根据 overAt 的值进行相应的运动,当pageID 小于 overAt  时,表示该页面位于需要显示页面的左方,它还需要继续向左移动。当pageID 大于 overAt 时,表示该页面应该向右移动。对于overAt 的监视是在 EnterFrame 事件中进行的。

  鼠标滑入滑出时,只需要修正一下 menu 的值,以及页面计时器的数值,从而进入自动翻页的状态。

  4、寻找模式。

  在这个例子中不涉及数据加载(有兴趣可以添加上),不存在复杂的互动,所以模式似乎也用需要去考虑了。只是在类链接时有一点问题,就是AS3中不允许一个类文件链接多个元件中去,因此,我采用的办法是新造5个类来继承定义好的类,用这5个类去分别链接5个页面元件,在子类中刚好初始化一下相关属性,就是指定页面的ID,这样整个“系统”就可以正常运转了。

  类文件如下:

package dzxz.bookcase

 import flash.display.MovieClip;  
 import flash.events.Event;
 import flash.events.MouseEvent;
 /**
 * ...
 * @ 独自行走
 */
 public class  BookCase extends MovieClip
 {
  static var menu:Boolean = false;  // 手动\自动切换
  static var overAt:Number = 1;    // 当前显示的页面
  static var pageTimer = 100;        // 页面计时器
  
  static var bookWidth:Number = 30;  // 书本的厚度
  static var pageWidth:Number = 370;  // 页面的宽度  
  
  public var leftPsn:Number;   // 当前页面的左界位置
  public var rightPsn:Number;   // 当前页面的右边界位置  
  public var pageID:Number;       // 页面的 ID 编号,用于页面判定及 位置换算
  private var prevPsn:Number;      // 前一次的位置  
  
  public function elasticMove( dest:Number  )
  {
   var t:Number = x;
   var a:Number = 1.765000E+000;
   var b:Number = -7.800000E-001;
   x = a * ( x - dest) + b * (prevPsn - dest ) + dest;
   prevPsn = t;
  }
  
  public function BookCase()
  {
   prevPsn = x;   
  }
  public function initPage( num:Number)
  {
   pageID = num;   //指定当前的页号
   leftPsn = (num - 1) * bookWidth;   // 换算出运动的起始位置   
   rightPsn = leftPsn + pageWidth;  // 换算出运动的结束位置
   
   
   addEventListener(MouseEvent.ROLL_OVER, onRollOver);
   addEventListener(MouseEvent.ROLL_OUT, onRollOut);
   addEventListener(MouseEvent.CLICK, onClick );
   addEventListener(Event.ENTER_FRAME, onEnterFrame);
  }  
  function onEnterFrame(evt:Event )
  {
   if ( pageID > overAt)
   {
    //move to right
    elasticMove( rightPsn );
   } else
   {
    //move to left
    elasticMove( leftPsn );
   }   
   if ( pageTimer % 150 == 0 ) {
    //自动翻页效果,当到达一定的时间间隔时就自动翻页。
    if ( overAt == 5 ) {
     //如果已经翻到了最后一页,下次就翻回第一页。
     overAt = 1;  
     pageTimer = 1;
    } else {
     //自动向后翻页。
     overAt++;
    }// end else if   
    trace( pageID, overAt);  
   }   
   if (menu == false && pageID == overAt  ) {
    //设置自动翻页的时间累积参数。
    //第二个判断条件用来限定仅对当前页面进行时间累计,其它页面的 enterFrame 事件中不进行累计.
    ++pageTimer;
   }    
  }
  function onRollOver(evt:MouseEvent )
  {
   overAt = pageID; //指向当前页面
   pageTimer = 1;
   menu = true;   
   //trace( pageID, overAt );
  }
  function onRollOut(evt:MouseEvent )
  {     
   menu = false;
   pageTimer = 100;
  }
  function onClick(evt:MouseEvent )
  {
   // 点击之后打开相关网页
   // getURL();
  }
 }
 
}

字类定义示例

package dzxz.bookcase

 import dzxz.bookcase.BookCase;
 /**
 * ...
 * @ 独自行走
 */
 public class  Page1 extends BookCase
 {
  public function Page1()
  {   
   initPage(1)
   rightPsn = leftPsn ;   
  }
 }
}

原来的效果中,当页面移动到左边或是右边以后,会显示出一个书本的样子,这一步需要在元件自行设计好,做一段过渡动画,在BookCase中,加入一些代码,当pageID 不等于 overAt 时,元件向前播放,直到第一帧,当pageID 等于 overAt 时,元件向后播放,直到最后一帧。就是这么个逻辑,期待你能够自己完成这一步,我就不多写了。

源文件下载 压缩包下载

标签集:TAGS:as3 代码 示例
回复Comments() 点击Count()

回复Comments

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