2008/10/04 | carousel 旋转木马效果 的AS 代码
类别(Flash学习笔记) | 评论(0) | 阅读(965) | 发表于 20:36

http://www.gotoandlearn.com/  站里有一个旋转木马的效果(carousel 的英译),

源文件的下载地址是:

http://gotoandlearn.com/files/carousel.zip

该源文件为 AS2.0 版的代码,代码如下:

var numOfBalls:Number = 10;
var radiusX:Number = 250;
var radiusY:Number = 75;
var centerX:Number = Stage.width / 2;
var centerY:Number = Stage.height / 2;
var speed:Number = 0.05;

for(var i=0;i<numOfBalls;i++)
{
 var t = this.attachMovie("ball","b"+i,i+1);
 t.angle = i * ((Math.PI*2)/numOfBalls);
 t.onEnterFrame = mover;
}

function mover()
{
 this._x = Math.cos(this.angle) * radiusX + centerX;
 this._y = Math.sin(this.angle) * radiusY + centerY;
 var s = this._y /(centerY+radiusY);
 this._xscale = this._yscale = s*100;
 this.angle += this._parent.speed;
 this.swapDepths(Math.round(this._xscale) + 100);
}

this.onMouseMove = function()
{
 speed = (this._xmouse-centerX)/1500;
}

在尝试改写为 AS3.0 代码的过程中,发现层深的调整是最麻烦的部分,根据 y 轴上的分布关系来调整层深,就必须进行排序的处理,于是想到了冒泡法排序,有了下面的代码:

// 全局参数
var numOfBalls:Number = 10;
var radiusX:Number = 250;
var radiusY:Number = 75;
var centerX:Number = stage.stageWidth / 2;
var centerY:Number = stage.stageHeight / 2;
var speed:Number = 0.05;
var arr = new Array();
//创建对象
for (var i=0; i<numOfBalls; i++) {
 var t = new Ball();
 addChild(t);
 t.angle = i * ((Math.PI*2)/numOfBalls);
 t.addEventListener(Event.ENTER_FRAME, mover);
 arr.push( t );
}
//冒泡法排序
function sortArr() {
 var i,bound;
 var j =arr.length - 1;
 while ( j>0 ) {
  bound = j;
  j = 0;
  for ( i= 0; i<= bound -1; i++) {
   if ( arr[i+1].y < arr[i].y ) {
    swapChildrenAt(i,i+1);
    var xt = arr[i];
    arr[i] = arr[i+1];
    arr[i+1] = xt;
    j = i;
   }
  }
 }
}
//摆放对象
function mover(evt:Event) {
 var t = evt.target;
 t.x = Math.cos( t.angle) * radiusX + centerX;
 t.y = Math.sin( t.angle) * radiusY + centerY;
 var s = t.y /(centerY+radiusY);//求出缩放比
 t.scaleX = t.scaleY = s;
 t.angle += speed;//设置移动速度
 sortArr();
}
//鼠标侦听
addEventListener(MouseEvent.MOUSE_MOVE, onMM);
function onMM(evt:MouseEvent) {
 speed = ( mouseX - centerX)/1500;
}

上面的代码,除了增加了一个数组,和一个排序函数以外,其它结构与 AS2 版的代码相同,从执行的效率来看,还是蛮不错的。

排序函数不易理解,于是考虑有没有更简便的方法。详读数组的排序函数之后,终于知道这样两种方案:

方案一 使用 数组的 sort  方法,指定比较函数,从而得到按 y 值进行排序的数组:

function sortArr() {
arr.sort(sortOnY);
for (i=0; i<numOfBalls; i++) {
 swapChildrenAt(getChildIndex(arr[i]),i); 
}   }

function sortOnY(a:Light, b:Light):Number {
 var aValue:Number = a.y;
 var bValue:Number = b.y;

 if (aValue > bValue) {

 // swapChildren(a,b); 
// 测试中发现,此函数中直接加入交换层深代码,得不到正确的结果。原因可能是 sort 的内部交换算法的先后次序未知,造成。
  return 1;
 } else if (aValue < bValue) {
  return -1;
 } else {
  //aValue == bValue
  return 0;
 }
}

方案二 使用 数组的 sortOn  方法,指定比较的属性“y”,从而得到按 y 值进行排序的数组:

function sortArr() {
 arr.sortOn("y");
 for (i=0; i<numOfBalls; i++) {
  swapChildrenAt(getChildIndex(arr[i]),i);
 }
}

第二个方案的办法,结构比较简单,效率不如直接用冒泡法高,在赶时间的情况下,可以考虑采用。

最终效果如下:

0

评论Comments