2008/12/12 | Flash CS4 3D旋转的初识
类别(Flash学习笔记) | 评论(9) | 阅读(3106) | 发表于 12:08

  先来看一下旋转的效果,舞台上放一个_mc 元件,注册点位于左上角,每点击一次分别沿 x、 y、 z 轴进行旋转。

测试代码如下:

stage.addEventListener(Event.ENTER_FRAME,onEF);
stage.addEventListener(MouseEvent.CLICK,onChg);
function onChg(evt){
 k++;
}
var k:uint = 0;
function onEF(evt) {
 switch ( k%3) {
  case 0 :
   _mc.rotationX += 5;
   txt.text = "绕 X 轴旋转"
   break;
  case 1 :
   _mc.rotationY+=5;
   txt.text = "绕 Y 轴旋转"
   break;
  case 2 :
   _mc.rotationZ+=5;
   txt.text = "绕 Z 轴旋转"
   break;
 }
}

经过测试可以看到:

1、rotationX 逐渐增加时 x 轴的旋转方向符合右手法则,用右手握住 x 轴,大拇指指向正方向,其余手指弯曲,表示旋转方向,或者是rotationX 增大的方向。

2、rotationY 逐渐增加时 y 轴的旋转方向符合右手法则,用右手握住 y 轴,大拇指指向正方向,其余手指弯曲,表示旋转方向,或者是rotationY 增大的方向。

3、rotationZ 逐渐增加时 z 轴的旋转方向符合右手法则,用右手握住 z 轴,大拇指指向正方向,其余手指弯曲,表示旋转方向,或者是rotationZ 增大的方向。

4、连续多次点击之后,具体的旋转方向已经很难说清楚了,说明 _mc 发生旋转之后,其内部的3维坐标系也同时进行旋转,因此,rotationX、rotationY、rotationZ 都是相对于已经旋转后的坐标系而言的,换句话来说,影片剪辑内部的旋转度数只与它自身的坐标系有关,和外部的坐标系无关。

  下面的例子,测试之后了解到,元件所处的层深与它的 Z 轴深度并不直接相关,但是可以根据 Z 坐标的大小进行排序,Z 值小的层深高一些,从而实现正确的层深。旋转度数也是一样,它只负责自身坐标系中的旋转,要在舞台空间中绕指定的位置进行旋转,就必须与某个角度值进行关联。相对来说,实现空间旋转更加方便了。

  z 轴的深度可以自动的决定元件缩放的大小,因此这部分不需要去考虑了。

  之前这个例子用 x y 坐标来计算时, x 坐标应用 cos 函数,y坐标应用sin函数,在这里发现 z 用cos ,x用sin 更准确一些,主要原因还是因为 z 的正方向是指向屏幕里面的缘故。

代码如下:

// 全局参数
var numOfBalls:Number = 5;
var radiusX:Number = 250;
var radiusY:Number = 30;
var centerX:Number = stage.stageWidth / 2;
var centerY:Number = stage.stageHeight / 2;
var speed:Number = 0.01;
var arr = new Array();
//创建对象
for (var i=1; i<=numOfBalls; i++) {
 var t = this["m" + i]; 
 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].z > arr[i].z) {
    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.sin(t.angle) * radiusX + centerX;
 t.y = Math.sin(t.angle) * radiusY + centerY;
 t.z = Math.cos(t.angle) * radiusY * 8 + centerY;
 t.rotationY = t.angle * 180/Math.PI; 
 //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)/3000;
}

4

评论Comments