论坛交流
首页办公自动化| 网页制作| 平面设计| 动画制作| 数据库开发| 程序设计| 全部视频教程
应用视频: Windows | Word2007 | Excel2007 | PowerPoint2007 | Dreamweaver 8 | Fireworks 8 | Flash 8 | Photoshop cs | CorelDraw 12
编程视频: C语言视频教程 | HTML | Div+Css布局 | Javascript | Access数据库 | Asp | Sql Server数据库Asp.net  | Flash AS
当前位置 > 文字教程 > Flash AS编程教程
Tag:2.0,3.0菜鸟,游戏,,cs,技巧,源码,,文本,文字,函数,音乐,随机,拖拽,asp,access,xml,mc,视频教程

[AS 3.0 狂想曲 K.02] 渐退方格效果

文章类别:Flash AS编程 | 发表日期:2008-10-6 17:44:28


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

    图中我们看到,方格 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.fs2you.com/files/40a8bf70-21ad-11dd-a2c5-00142218fc6e/

 

教程到此结束
QQ:147461195 (FL车在臣)
视频教程列表
文章教程搜索
 
Flash AS推荐教程
Flash AS热门教程
看全部视频教程
购买方式/价格
购买视频教程: 咨询客服
tel:15972130058