查看完整版本: Action Script2 三维制作方法(制作AS三维正方体与AS特效) 精华版

KillerBob 2008-6-25 18:46

Action Script2 三维制作方法(制作AS三维正方体与AS特效) 精华版

前些日子(其实几个月了),我一直在专攻三维,现在有所学到,给那些不会的人启启蒙。在这里,我们学习一些数学公式(小朋友也学的会的,其实我只有10岁)和程序语法。制作一些实例。
    好了,废话不多说了,先进行恐怖,艰难的第一步——理论。
    在一个三维空间里,组成一个点需要三个坐标:X、Y、Z。X和Y是大家都知道的横竖轴,要注意它们在这里不是直接投到屏幕上的,而是要参与计算。Z是一个新的坐标,代表点与屏幕的距离。另外还要说明一个基本的变量——DIS,它是英文DISTANCE(距离)的缩写,代表坐在电脑前的我们离电脑的距离。DIS是虚拟的,因为我们不可能把头伸进电脑显示器里。可以简单的理解为物体的缩放比例。还有ZFACTOR,意思是转换量。CENTERX和CENTERY也很重要,因为FLASH坐标与笛卡尔坐标不同,所以需要把一个点的X坐标加上CENTERX,Y坐标加上CNETERY。
    在写出转换公式前,先介绍一下一个必要的词——投影。众所周知,我们要把三维坐标转换成二维坐标,这个过程就叫投影。
    投影的第一步是出去把你的脸洗干净,要看仔细了(只是个玩笑)。要先算出转换量。公式:
    zfactor=dis/z
    中文:Z转换量=距离/Z坐标
    我们假设一下:
    设点的X=3,Y=4,Z=5,我离屏幕有10,那么:
    zfactor=dis/z
    zfactor=10/5
    zfactor=2
    针对于这个点的Z转换量出来了,是2个长度单位。这里要注意Z转换量只是针对这个点的!另外,单位要一置。
    下一步是转换,是最难的一步,因为要让Z消失在X和Y中。但懂了以后会认为和泡方便面一样简单。
    公式:
    X=X*zfactor+centerX
    Y=Y*zfactor+centerY
    中文:
    转换后的X坐标=原来的X坐标*Z转换量+中心X
    转换后的Y坐标=原来的Y坐标*Z转换量+中心Y
    一般FLASH的中心X=FLASH的宽/2,中心Y=FLASH的高/2,如果FLASH动画的高为400,宽为550,那么中心X为275,中心Y为200。
    继续我们的例子:
    X=X*zfactor+centerX
    X=3*2+275
    X=6+275
    X=281
    Y=Y*zfactor+centerY
    Y=4*2+200
    Y=8+200
    Y=208
    祝贺你,投影成功,你应该去买瓶可乐庆祝庆祝了。我们得到了一个X为281,Y为208的点。想一想,如果每个点之间都连上线,2个点是一条线,4个点是一个平面,5个点是一个金字塔,6个点是一个三棱柱,8个点是一个长方体,十几个点是一张床,几百个点是一辆汽车,几千个点就是一架飞机了!但这还为时过早,下面介绍几个实例。
    (1)新建一个元件,命名“Circle”,在它里面画个小球,放在正中央。
    (2)右键点库中的“Circle”,选择“链接”,在“链接”对话框中选择“为ACTIONSCRIPT导出”与“为第一帧导出”。
    (3)在场景第一帧上输入AS:
dis = 800;
centerX = 275;
centerY = 200;
ang = 0;//弧度
function project(){
if(this.z<40){
  this._visible=false;//如果点离自己很近,就让它消失
}else{
  this._visible=true;
  var zfactor=dis/this.z;//计算Z转换量
  this._x=this.x*zfactor+centerX;//投影
  this._y=this.y*zfactor+centerY;//投影
  this._xscale=100*zfactor;//改变大小
  this._zscale=100*zfactor;//改变大小
  this.swapDepths(Math.floor (100000-this.z));//让大的点遮住小的点
}
}
for (var i = 0; i<1250; i++) {
var nm = "Circle"+i;
_root.attachMovie("Circle", nm, i);//把球放入场景
_root[nm].x = Math.cos(ang)*200;//设置球在三维世界中的X
ang += 0.2;//弧度要改变
_root[nm].y = 400;//球在三维世界中的Y都是400
_root[nm].z = (i*50)+1400;//球的Z根据生成先后变化
var zfactor = dis/_root[nm].z;//计算Z转换量
_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));//让大的点遮住小的点
}
    自己有性趣就测试一下吧。
    接下来,我们讨论如何让球自己会动。
    把上个实例里第一帧的AS改一下:
dis = 800;
centerX = 275;
centerY = 200;
ang = 0;
function project() {
if (this.z<40) {
  this._visible = false;
} else {
  this._visible = true;
  var zfactor = dis/this.z;
  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 = "Circle"+i;
_root.attachMovie("Circle", nm, i);
_root[nm].x = Math.cos(ang)*200;
ang += 0.2;
_root[nm].z = (i*50)+dis;
_root[nm].project = project;
_root[nm].myAngle = i;
_root[nm].onEnterFrame = function() {
  this.y = 100+Math.cos(this.myAngle/3) * 100;
  this.myAngle -= 0.4;
  this.project();
};
}
    其实基本相同,只不过多了onEnterFrame,我不加注释了。
    如果是真正的3D,不应少了改变观测点,我们要认识三个新变量:xoff、yoff、zoff它们指观测者在三维空间内的坐标。
    我们看一个实例,把上个实例的代码改成:
dis = 800;
centerX = 275;
centerY = 200;
ang = 0;
xoff = 0;
yoff = 0;
zoff = 0;
function project() {
if (this.z-zoff<40) {
  this._visible = false;
} else {
  this._visible = true;
  var zfactor = dis/(this.z-zoff);
  this._x = (this.x-xoff)*zfactor+centerX;
  this._y = (this.y-yoff)*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 = "Circle"+i;
_root.attachMovie("Circle", nm, i);
_root[nm].x = Math.cos(ang)*500;
ang += 0.2;
_root[nm].y = 100+Math.cos(i/3)*100;
_root[nm].z = (i*50)+dis;
_root[nm].project = project;
_root[nm].onEnterFrame = project;
}
    在场景里放一个空按扭,上面写程序:
on (keyPress "<Up>") {
yoff-=3;
}
on (keyPress "<Down>") {
yoff+=3;
}
on (keyPress "<Left>") {
xoff-=3;
}
on (keyPress "<Right>") {
xoff+=3;
}
on (keyPress "Q") {
zoff+=3;
}
on (keyPress "A") {
zoff-=3;
}
    注意不同的地方:
    var zfactor = dis/(this.z-zoff);
    this._x = (this.x-xoff)*zfactor+centerX;
    this._y = (this.y-yoff)*zfactor+centerY;
    这个实例用方向键与Q、A操纵,自己试试看吧!
   最后一个实例是一个正方形,技术飞跃比较大,学习一下新知识:
·Array(数组)
    数组可以方便地存贮多个数。
    x=[100,150,10,0,150]代表创造一个叫“X”的数组,组内有100、150、10、0、150五个值。
    trace(x[3])代表输出X的第四个数,为什么不是第三个数呢?因为100的代号是0,150的代号是1,10的代号是2,0的代号才是3。
·Draw(画图)
    学会了它,你可以通过ACTIONSCRIPT在屏幕上画图。
    clear();代表清除你用AS在屏幕上画的图。
    lineStyle(2, 0xff0000, 100);代表设置画笔的粗细为2,色彩为0xff0000(红),不透明度为100,不透明。
    moveTo(100,120);代表移动画笔到X100,Y120的地方。
    lineTo(430,360);跟在moveTo的后面,代表画一条线,从100,120到430,360。
    好了,把上个实例第一帧代码改成:
dis = 800;
centerX = 275;
centerY = 200;
ang = 0;
xoff = 0;
yoff = 0;
zoff = 0;
xObj = [100, 50, 100, 50, 100, 50, 100, 50];
yObj = [50, 50, 100, 100, 50, 50, 100, 100];
zObj = [150, 150, 150, 150, 200, 200, 200, 200];
function project() {
if (this.z-zoff<40) {
  this._visible = false;
} else {
  this._visible = true;
  var zfactor = dis/(this.z-zoff);
  this._x = (this.x-xoff)*zfactor+centerX;
  this._y = (this.y-yoff)*zfactor+centerY;
  this.swapDepths(Math.floor(100000-this.z));
}
}
for (var i = 0; i<8; i++) {
var nm = "Circle"+i;
_root.attachMovie("Circle", nm, i);
_root[nm].x = xObj[i];
ang += 0.2;
_root[nm].y = yObj[i];
_root[nm].z = zObj[i];
_root[nm].project = project;
_root[nm].onEnterFrame = project;
}
onEnterFrame = function () {
this.clear();
this.lineStyle(2, 0xff0000, 100);
_root.moveTo(Circle2._x, Circle2._y);
_root.lineTo(Circle3._x, Circle3._y);
_root.moveTo(Circle3._x, Circle3._y);
_root.lineTo(Circle7._x, Circle7._y);
_root.moveTo(Circle7._x, Circle7._y);
_root.lineTo(Circle6._x, Circle6._y);
_root.moveTo(Circle6._x, Circle6._y);
_root.lineTo(Circle2._x, Circle2._y);
_root.moveTo(Circle5._x, Circle5._y);
_root.lineTo(Circle4._x, Circle4._y);
_root.moveTo(Circle5._x, Circle5._y);
_root.lineTo(Circle7._x, Circle7._y);
_root.moveTo(Circle4._x, Circle4._y);
_root.lineTo(Circle6._x, Circle6._y);
_root.moveTo(Circle0._x, Circle0._y);
_root.lineTo(Circle1._x, Circle1._y);
_root.moveTo(Circle0._x, Circle0._y);
_root.lineTo(Circle4._x, Circle4._y);
_root.moveTo(Circle0._x, Circle0._y);
_root.lineTo(Circle2._x, Circle2._y);
_root.moveTo(Circle1._x, Circle1._y);
_root.lineTo(Circle3._x, Circle3._y);
_root.moveTo(Circle1._x, Circle1._y);
_root.lineTo(Circle5._x, Circle5._y);
};
    测试一下吧![/i][/i][/i]
[i]我的邮箱有两个,GMAIL的不用了,要发给我邮件用另外一个:[/i]
[i][email=sleep_walking@163.com]sleep_walking@163.com[/email][/i]

KillerBob 2008-6-25 18:48

作者发言

有问题,发过来,我有时会在线等。

zccicy 2008-7-9 21:27

着实获益 谢谢~

kinglovefeng 2008-9-17 15:49

后面两个我复制了代码,但是  一直不对.     倒数第二个是QA不能控制 远近..
倒数第一个是 不能正确居中显示  正方体

lh19851010 2008-9-18 23:06

:)  远近能不能 弄成可以控制的啊 用AS2的啊`` 这样远近是已经设定好了的啊

qi7yoyo 2008-9-22 17:54

我顶

[size=2]支持你,帮你顶!














------------------------------------------------------------------------------------------------------------
[/size][size=1]签名:[/size][url=http://www.careermen.net/A_173_788.htm][size=1][color=black]电接点压力表[/color][/size]

12girlsfan 2008-10-13 10:19

写得很不错啊,顶你 `
页: [1]
查看完整版本: Action Script2 三维制作方法(制作AS三维正方体与AS特效) 精华版