你的分享就是我们的动力 ---﹥

渐退方格效果(AS3)

时间:2011-10-11 21:12来源:www.chengxuyuans.com 点击:
效果:
http://www.68design.net/download/20088/20080730174403138.swf

见到这样排列的方格格,我们很容易想到二维数组,因为最起码要用双重循环才有可能将它们排列成这样。那么这种渐退的效果又是怎样形成的呢?我们给每个小格一个等待时间,按照点击到的方格的位置逐渐向外增加,离点击到的方格越远则等待时间就越长一些。



图中我们看到,方格 0 的位置,代表点击到的小方格,那么它的等待时间是 0,就是说点击后立即消失。然后向外围扩展,每向外一圈则等待时间就越长一些。我们用顺序的数字表示等待时间。这些数字并非真正的等待时间,可以作为等待时间的系数,这样就更加灵活了。如何构造这样一个二维数组呢?我想了很多办法,最开始用的是数组操作,加入各种的判断,没能实现;后来又试用递归的方法,搞得越来越复杂。画过 N 张图表后,终于发现了规律,得出了一个简单得难以至信的算法。OK,来看一下程序,大家可以直接复制到“动作-帧”当中,这里我们假设点击到的小格位于数组的 5,5 这个位置:
var Row:Number = 10;
var Colum:Number = 10;
// 10 行 10 列
var ci:uint = 5;
var cj:uint = 5;
// 点击到的数组位置 5,5
var a:Array = new Array();
for (var i:uint = 0; i < Row; i++) {
 a[i] = new Array();
 for (var j:uint = 0; j < Colum; j++) {
  a[i][j] = Math.abs(i-ci) > Math.abs(j-cj) ? Math.abs(i-ci) : Math.abs(j-cj);
 }
}

for (i = 0; i < Row; i++) {
 trace(a[i]);
}

输出结果如下:
5,5,5,5,5,5,5,5,5,5
5,4,4,4,4,4,4,4,4,4
5,4,3,3,3,3,3,3,3,4
5,4,3,2,2,2,2,2,3,4
5,4,3,2,1,1,1,2,3,4
5,4,3,2,1,0,1,2,3,4
5,4,3,2,1,1,1,2,3,4
5,4,3,2,2,2,2,2,3,4
5,4,3,3,3,3,3,3,3,4
5,4,4,4,4,4,4,4,4,4

测试一下。核心语句,就这一句,OK,搞定,呼呼
a[i][j] = Math.abs(i-ci) > Math.abs(j-cj) ? Math.abs(i-ci) : Math.abs(j-cj);
这句话可以理解为,当前数组小格的行和列(i 和 j)与点击到的方格的 i 和 j 相比较,找出这两个比较后哪个绝对值最大,就用这个绝对值最大的数填入当前的数组元素中。OK,写到这里,这个程序的难点就介绍完了。骨架有了,下面开始填肉。既然已经进入了 AS 3 时代,就不能想 AS 2 时候那么奔放了,不能够动态地加入属性或方法了。因为我们的类是密封类,无法在运行时添加其他属性和方法。密封类对象实例没有内部哈希表,从而提高内存使用效率和访问性能。所以说事物都是有两面性的,好处是提高了效率,那么缺点就是我们要多敲些代码了。解决办法就是创建自定义的类。

看过前面 Making Things Move 的朋友们应该很熟悉了吧。好了,不多说了,看这个 Box 类:
package {
 import flash.display.Sprite;
 public class Box extends Sprite {
  public var BufTime:Number = 0;
  public var ci:uint = 0;
  public var cj:uint = 0;
  public var Count:Number = 0;
  public function Box(W:Number,H:Number) {
   graphics.beginFill(0x66CCFF)
   graphics.drawRect(0, 0, W, H)
   graphics.endFill();
  }
 }
}

首先它是 Sprite 的子类。那么说是子类大还是父类大?按照辈分来讲当然是父类大。呵呵,不过在 OOP 世界里就不一样了,一般来讲,子类都是大于父类的,因为子类继承了父类的一切,并且在父类的基础上发展出了更多的功能(属性和方法),所以从功能上讲,子类要比父类大。
我们给 Box 影片,自定义几个成员变量(类变量),分别是:BufTime(存储等待时间),ci(该小格位于数组中的 i 下标),cj(该小格位于数组中的 j 下标),Count(用于计数时间)。通过构造函数给出 Box 的大小,例如:Box(40,40)。将 Box 类保存起来(Box.as)。下面来看文档类 MainBox.as:
package {
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.events.MouseEvent;
 public class MainBox extends Sprite {
  // 方格的宽和高为 10 * 10
  var Box_w:Number = 10;
  var Box_h:Number = 10;
  // 根据舞台大小和方格大小,求出可以放入多少行,多少列个小方格
  var Colum:int = stage.stageWidth / Box_w;
  var Row:int = stage.stageHeight / Box_h;
  // boxAry 用于保存每个小方格的引用
  var boxAry:Array = new Array();
  
  public function MainBox() {
   init();
  }
  
  function init():void {
   for (var i = 0; i < Row; i++) {
    for (var j = 0; j < Colum; j++) {
     // 生成新的方格,保存每个的引用,码放好位置
     var box:Box = new Box(Box_w, Box_h);
     boxAry.push(box);
     addChild(box);
     box.x = j * (Box_w + 1);
     box.y = i * (Box_h + 1);
     // 保存方格对应数组中的行和列,并添加侦听
     box.ci = i;
     box.cj = j;
     box.addEventListener(MouseEvent.MOUSE_DOWN,MouseDown);
    }
   }
  }
  
  function MouseDown(evt:MouseEvent):void {
   // 根据点击的方格的数组下标,计算出二维数组
   var ci = evt.target.ci;
   var cj = evt.target.cj;
   var a:Array = new Array();
   for (var i:uint = 0; i < Row; i++) {
    a[i] = new Array();
    for (var j:uint = 0; j < Colum; j++) {
     a[i][j] = Math.abs(i-ci) > Math.abs(j-cj) ? Math.abs(i-ci) : Math.abs(j-cj);
    }
   }
   // 按照二维数组的顺序,为每个 box 设置等待时间
   var count:uint = 0;
   for (i = 0; i < Row; i++) {
    for (j = 0; j < Colum; j++) {
     var box:Box = boxAry[count] as Box;
     // 设置等待时间
     //  + Math.random() * 4 可让时间有些差异
     box.BufTime = a[i][j] + Math.random() * 4;
     count++;
    }
   }
   addEventListener(Event.ENTER_FRAME,EnterFrame);
  }
  
  function EnterFrame(evt:Event):void {
   // 每帧每个 box 的 Count 加一,大于延迟时间后删除 box。
   for (var i = boxAry.length-1; i >=0; i--) {
    var box:Box = boxAry[i] as Box;
    if (box.Count++ > box.BufTime) {
     removeChild(box);
     boxAry.splice(i,1);
    }
   }
  }
 }
}
   
这里使用的延迟方法,是在每帧都将变量加 1,加到 BufTime 为止。这种方法虽然有些不精确,但是要比使用 Timer 灵活许多。如果可以把这些小方块制作当作遮罩,实现图片的转场效果也不错哟。

本文地址http://www.chengxuyuans.com/Flash/23864.html