先来看一下旋转的效果,舞台上放一个_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;
}