[Flash]Flash3D编程探秘一

作者:Yang Zhou
感谢:Crystal

介绍

对学习Flash中的3D编程感兴趣?那么你来对地方了。在这篇文章中,我将陆续的介绍在Flash中使用Actionsript进行3D编程一些实例。 这是一篇初级到中级难度的学习资料,如果你具有一些基本的几何知识,那对你来说不会太难。虽然例子中运用了非常简单的程序构架和实现方法,但是我还是期望 你已经有大量的Actionscirpt和Flash经验,这样你在使用以及理解Actionscript语言的时候不会有太大的障碍。如果你在阅读中发 现很多地方不清楚,或者这些对你来说是比较新的东西,那么我建议你参考我写过的另外几篇3D的基础知识的文章。

文章中含有大量的代码和一些算法的实现,在这里你可以完全拷贝我写的代码去使用,但是请务必注明出处。

 

点此下载本节源文件

 

Flash 和 3D空间

第一件事情我想你知道的是,在Flash里,并不存在真正的3D。我们所做的是运用Flash里的2D绘制方法去模拟3D绘制。或者我应该 说,Flash并不支持3D绘制,Flash并不知道3D是什么也不知道如何去处理3D对象。但是好消息是所有的3D处理和3D计算都是建立在数学计算的 基础上的,加上 Flash知道如何的处理数学计算。太好了,我们有了这些工具便可以创造出我们自己的动画了。这并不是说Flash里的3D编程要简单,如果你打算深入去 探索的话你会发现恰恰相反。不管怎样,在这篇文章中我会用最大的努力把数学部分变得简单。

在Flash里,有两种3D处理方式,一种是提前处理好3D模型,另外一种是在程序运行时通过数学计算处理3D图形。运用第一种方法,我们可以提前 处理好一系列的图形,然后通过对祯或者是时间进行动画播放,以达到3D效果。相对来说,第一种方法对美工的要求比较高。后一种方法我们通过大量的数学计算 对物体进行操作,这也是在这篇文章里所关心的。

 

3D程序

如今你在互联网上搜索3D Flash你会找到很多的工具和程序,利用这些程序你可以绘制一些3D图形并导出你需要的格式,甚至完全使用在你的项目里。基本上你可以不必操心如何绘制 3D图形。但是这些程序都是提前做好的模版,不能够作太多的编辑。于是我们发现我们自己也有大脑,我们自己也可以制作简单的缩放动画,还可以制作复杂的 3D绘制引擎。

毕竟我们是从最基础的2D绘制开始制作3D对象。这并不像我们在使用显卡语言或者OpenGL时的绘制,一切3D的物体我们都要自己动脑动手加上数 学运算进行绘制,这就增加了一些数学上的挑战。不过我认为,这对你来说应该不是问题,用Flash作3D图形一样会给你带来你意想不到的乐趣。那么开始 吧!

 

3D空间坐标系

从技术角度而言,Flash中并不存在3D,也就是说z轴并不存在,所以所谓的z轴是由你来制造的,也就是远景物体的大小。那么也就是说,对于一个 3D虚拟空间,z轴存在于当你看进显示器,x轴和y轴分别为横向和纵向。可是我们用什么方法来表达3D空间呢?我们需要两种手法来处理3D显示,缩放和层 叠。

 

 2D与3D坐标系

 

 

对于z轴的解释

在现实中,当一个物体离你远去,那么对你的眼睛来说,你所看到的是物体越来越小。当然并不只有物体的大小在改变,物体离你的距离也在增大。那么我们可以假定,在3D空间里,离得人眼越远的物体,它的大小就越小,那么它在x和y轴上的移动就越缓慢。很简单对吧?很好。

 

原点

Flash 中3D空间是围绕坐标系原点的,原点的坐标我们用Point(x, y, z), (0, 0, 0) 来表示。在Flash 2D中,原点存在于程序的左上角Point(0, 0),那么对于3D来说,原点也自然存在于程序的左上角,也许你会发现,如果原点在左上角的话,那么你所在的位置肯定是成一定角度来看程序中3D空间中的 物体的。当然我们可以把3D空间的原点向右再向下移动,那么我们在围绕原点绘制物体的时候会发现方便很多。

 

缩放物体

离人眼越近,那么物体就越大,反之物体就越小。物体缩放的比率以及移动速率与物体z的大小成反比。现在我用一个实例给你说明如何制造3D动画效果, 在这个例子中,我手工绘制了几个小球,作为我们关心的物体,让它们沿着z轴在舞台上来回移动,以制造3D效果。虽然很基本,不过别担心,把这些简单的东西 掌握好是深入探索的基础。

小球与3D空间(无层次)

 

动画制作步骤

1. 第一步,用Flash画出一个你喜欢的物体,任何物体都可以。在这个例子中我画了一个蓝色的小球。当然你可以导入你喜欢的图片,只不过不要忘记在 Library你创建的物体上点击右键,选择Linkage,然后在Export For Actionscript上打勾。

2. 下一步,详细解说一下代码。当然一开始我们要设置一些变量,原点和焦距(摄像机)。Focal length(焦距)确定了摄像机(在本例子中为人眼的)的凸透镜的焦距,值越大,那么物体的扭曲就会越小。我们把它设为300,这是一个在本例子中适中的数值。

var origin = new Object();
origin.x 
= stage.stageWidth/2;
origin.y 
= stage.stageHeight/280;

 

var focal_length = 400;

 

3. 创建一个舞台,并且把它的x和y设置为原点,这样我们在参照物体的时候就会非常简单易读了。

var scene = new Sprite();
this.addChild(scene);
scene.x 
= origin.x;
scene.y 
= origin.y;

 

4. 然后我们要在舞台上添加一些我们绘制好的小球。在这个例子中我们绘制3个,分别在左中右。把它们的x_3d, y_3d, z_3d,也就是他们的3D空间的x,y,z的值设为相应的数值,我把它们排为一排。给他们添加一个direction属性,1代表向屏幕方向移动,-1 代表向我们的方向移动。然后设置他们的移动速度,并且把它们添加到舞台上。这时你如果编译的话,你会看到有3个球在舞台上,那么下一步我们让它们运动起 来。

for (var i = 0; i < 3; i++)
{
    var sphere 
= new Sphere();
    sphere.x_3d 
= 190+i*160;
    sphere.y_3d 
= 80;
    sphere.z_3d 
= i*100;
    sphere.direction 
= 1;
    sphere.speed 
= 6;
    scene.addChild(sphere);
}

 

5. 下面这个函数,在每一次执行,都会把小球移动到相应的位置,并且对小球进行缩放。当小球的z大于600时,我们让它向相反的方向移动。当小球的z_3d值 变化后,我们计算小球当前的大小和位置,把小球移动到相应的位置然后对其进行缩放,这样在一连串的函数执行后,我们就会得到动画效果。

function run(e:Event)
{
    
for (var i = 0; i < scene.numChildren; i++)
    {
        scene.getChildAt(i).z_3d 
+= scene.getChildAt(i).speed*scene.getChildAt(i).direction;
        
if (scene.getChildAt(i).z_3d > 600)
        {
            scene.getChildAt(i).z_3d 
= 600;
            scene.getChildAt(i).direction 
= 1;
        }
        
else if (scene.getChildAt(i).z_3d < 0)
        {
            scene.getChildAt(i).z_3d 
= 0;
            scene.getChildAt(i).direction 
= 1;
        }
        
        var scale 
= focal_length/(focal_length+scene.getChildAt(i).z_3d);
        scene.getChildAt(i).x 
= scene.getChildAt(i).x_3d*scale;
        scene.getChildAt(i).y 
= scene.getChildAt(i).y_3d*scale;
        scene.getChildAt(i).scaleX 
= scene.getChildAt(i).scaleY = scale;
    }
}

 

6. 最后,在舞台上添加一个函数循环响应时间。让第5步我们写的函数循环执行。发布看一下,现在小球在3D舞台上移动了。

Hooray!你的第一个Flash3D程序完成了。总结一下,其实我们并没有使用任何高深的技巧,只不过是利用了变化物体的x和y以及小球的缩放来制造3D效果。

 

层叠

在Flash中表现3D空间,仅有缩放是不够的,我们还需要层叠。基本概念是,离人眼较近的物体会在离人眼较远的物体之上显示。
在上一节的例子里面,我们缩放小球,以达到3D效果。可是你会发现,3个小球之间的x距离都很大。你也许会想如果3个小球离得很近的话,会出现什么现象 呢?尝试把上面例子中小球之间的x距离变小,你会发现,不管小球离我们多远,右边的小球始终在最上面。即使中间的小球应该盖过右边小球的时候,右边的小球 还会在上面。这是因为在把小球添加到舞台上的时候,我们已经给了小球层次,也就是说最后添加的小球(右边的小球)就在最上面。

小球3D空间(无层次)间距太小啦!

我们应该设计一种方法实现小球的层次感,当小球离我们远的时候,那么它的层次就比较靠后,以此类推。换句话说,我们利用小球的z值给小球们分开层次,这也是我们即将要做的。在这个例子中,我们用7个小球的运动来说明是如何实现层次的。

小球3D空间(有层次)好多了!

 

动画制作步骤

1. 和上次的例子一样,重复6个步骤。不同的是我们初始化7个小球,并且把它们的x距离缩短。

for (var i = 0; i < 7; i++)
{
    var sphere 
= new Sphere();
    sphere.x_3d 
= 150+i*40;
    sphere.y_3d 
= 80;
    sphere.z_3d 
= Math.random()*(0600)+600;
    sphere.direction 
= 1;
    sphere.speed 
= Math.random()*(512)+12;    
    scene.addChild(sphere);
}

 

2. 利用Bubble Sort算法,在每一次对小球x,y和大小设置后,对所有的小球在舞台上的层次进行操作。这里使用的理论是最小的z值的小球,它所在层次就应该在最上面。

function swap_depth(container:Sprite)
{
    
for (var i = 0; i < container.numChildren  1; i++)
    {
        
for (var j = container.numChildren  1; j > 0; j)
        {
            
if (Object(container.getChildAt(j1)).z_3d < Object(container.getChildAt(j)).z_3d)
            {
                container.swapChildren(container.getChildAt(j
1), container.getChildAt(j));
            }
        }
    }
}

 

3. 然后在循环函数里的最后加上

swap_depth(scene);

 

本文章旨在讨论如何在Flash中实现3D动画,对于一些算法,比如这一节中使用到的冒泡排序算法,我就不再多说了。当然你可以选择使用插入排序 (可能运算起来比较快40%?!)。你可以完全拷贝我写的代码去使用,但是请务必注明出处。如果是排序的话,google或者百度一下,我相信你会找到更 详细的说明文字来解释冒泡排序。

OK,你已经学会了如果使用缩放和一些简单的设置产生3D效果的动画。在后面的几篇中,我们会逐渐深入探讨更有趣的内容。加油!

 

点此下载本节源文件


作者:Yang Zhou
出处:http://yangzhou1030.cnblogs.com
感谢:Yunqing
本文版权归作者和博客园共有,转载未经作者同意必须保留此段声明。请在文章页面明显位置给出原文连接,作者保留追究法律责任的权利。

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏