准备:以下三个实例的元件一样,只是代码不同,元件在库中,40×40像素的球体,链接名为:sphere
代码处的解释部分用红色字体表示
A.静态的三维绳制作
过程:
准备好元件,在主场景中第1帧输入代码:
d =800;
centerX = 275;
centerY = 200;
ang = 0;
for (var i = 0; i<1250; i++) {
var nm = "sphere"+i;
_root.attachMovie("sphere", nm, i);
//我们首先定义了一个名为ang的变量,初始化为0,我们将在余弦波的循环体内使用该变量。
接下来我们创建了1250个小球的MC,实例名分别为:sphere0,sphere1,sphere2,...等等。我们将这些MC添加到_root上,然后将它们深度级别定义为i,小球的深度稍后将会根据它们的Z值进行修改,以准确地反映它们的层次。
接下来:
_root[nm].x = Math.cos(ang)*200;
ang += 0.2;
_root[nm].y = 400;
这就是我们创建余弦波的方法。每个小球的X位置设置为Math.cos(ang)*200,这就意味着X将是介于-200和200之间的某个数值,前后循环变化。同样对每个成功创建的小球的ang加上0.2。
注意变量x和y就是x和y,而不是_x和_y。记住这是三维空间内的虚拟位置,而不是屏幕坐标。
接下来:
_root[nm].z = (i*50)+1400;
var zfactor=d/_root[nm].z;
//第一个小球将在(Z轴上)1400,第二个是1450。。。。,接下来我们计算小球的屏幕位置:
_root[nm]._x=_root[nm].x*zfactor+centerX;
_root[nm]._y=_root[nm].y*zfactor+centerY;
//接下来我们设置小球的比例,使得远的小球显得小些。
_root[nm]._xscale=100*zfactor;
_root[nm]._yscale=100*zfactor;
//最后:
_root[nm].swapDepths(Math.floor(100000-_root[nm].z));
}
//为什么使用swapDepths:这能使得较远的对象看起来在较近的对象之后。我们让具有较高Z值的小于有较低的深度。
如果我们禁用swapDepths函数,就会得到如下:
(看上去,远处的小球反而叠在近的小球的上面)
B.移动的球形绳
准备同A,
第1帧代码:
d = 1000;
centerX = 275;
centerY = 200;
ang = 0;
function project() {
if (this.z<40) {
this._visible = false;
}
我们在这里执行了一个重要的检测。如果对象的Z值小于40,我们就认为它实际上是在用户的后方,因此我们根本就不必绘制它。想像小球向我们靠近,究竟是在哪一点上让我们注意 到小球的通过,而后到达我们的后侧而无法看到的呢?在我们的示例中,似乎40是较好的Z值。不要用“if(this.z<40)”,因为当某个小球的Z值达到0时,它是那么无限地接近观察者,看起来似乎无穷大。在Z值为40的位置,小球看上去相当大且距离相当近,因此可以认为这就是小球通过我们的点。
接下来:
else {
this._visible = true;
var zfactor = d/this.z;
等价于:this.z>0时我们让小球可见(小球不在我们的后方)
this._x = this.x*zfactor+centerX;
this._y = this.y*zfactor+centerY;
this._xscale = 100*zfactor;
this._yscale = 100*zfactor;
this.swapDepths(Math.floor(100000-this.z));
}
}
for (var i = 0; i<40; i++) {
var nm = "sphere"+i;
_root.attachMovie("sphere", nm, i);
_root[nm].x = Math.cos(ang)*200;
ang += 0.2;
_root[nm].y = 400;
_root[nm].z = (i*50)+d;
_root[nm].project = project; //将project函数添加到小球MC内名为project的方法之下。接下来,只要通过调用sphere.project()方法,即可以让小球改变自身位置、缩放比例和图层。
_root[nm].onEnterFrame = function() {
this.y-=3;
this.project();
};
}
//这就是我们将对象改变为动态的地方,首先将每个小球的y值(不是_y值)减1,然后调用每个小球的project方法,以促使屏幕更新。
把代码最后的:this.y-=3,改成this.x-=3;this.z-=3;试一下。
C.移动视点
到此为止,我们已经讨论了移动对象本身,现在让我们看一下怎样才能移动整个视图以使得用户的透视图看起来在运动,并且对象保持固定,而不是用户保持固定而对象在移动.
元件:一个40*40的球形,链接名:sphere
在主场景第一帧代码如下:
//xoff,yoff,zoff用来确定我们观察者所处的位置.
xoff=0;
yoff=0;
zoff=0;
d=1000;
centerX=275;
centerY=200;
ang=0;
function project()
{
if((this.z-zoff)<40)
{
this._visible=false;
}
else
{
this._visible=true;
var zfactor=d/(this.z-zoff);
this._x=(this.x-xoff)*zfactor+centerX;//在上一个效果中公式中少了一个xoff,因为现在的球位置都是相对于观察者的.
this._y=(this.y-yoff)*zfactor+centerY;
this._xscale=100*zfactor;
this._yscale=100*zfactor;
this.swapDepths(Math.floor(100000-(this.z-zoff)));//让近的球摆在上面.
}
}
//接下来用于生成小球....
for(var i=0;i<40;i++)
{
var nm="sphere"+i;
_root.attachMovie("sphere",nm,i);
_root[nm].x=Math.cos(ang)*200;
ang+=0.2;
_root[nm].y=100+Math.cos(i/3)*100;
_root[nm].z=(i*50)+d;
_root[nm].project=project;
_root[nm].onEnterFrame=project;
}
//建一个侦听器,侦听鼠标的活动.
mouseListener=new Object();
mouseListener.onMouseWheel=function(diff)
{
zoff+=(diff*50)
}
mouseListener.onMouseMove=function()
{
xoff=_xmouse-centerX;
yoff=_ymouse-centerY;
}
Mouse.addListener(mouseListener);