独上高楼网站
  •    你所在位置:首页 Flashflash实例〉Flash与3D编程探秘(一)- Flash与3D空间
  • Flash与3D编程探秘(一)- Flash与3D空间
  • 作者:Yang Zhou  文章来源:博客园  发布日期:2008-11-10  浏览次数:121
  • 打印这篇文章
  • 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轴上的移动就越缓慢。很简单对吧?很好。

    注意:

    如果你用过OpenGL,那么你知道y轴的正方向是指向上方,z轴正方向是指向屏幕外的反向,然而我们文章中的Flash 3D空间的y轴和z轴是相反的。
     

     

    原点

    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(焦距)确定了摄像机(在本例子中为人眼的)的凸透镜的焦距,值越大,那么物体的扭曲就会越小。我们把它设为400,这是一个在本例子中适中的数值。

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

     

    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值变化后,我们计算小球当前的大小和位置,把小球移动到相应的位置然后对其进行缩放,这样在一连串的函数执行后,我们就会得到动画效果。代码里scale代表物体应该缩放的比率,因为当物体沿z轴移动的时候,物体的大小以及x和y值都会改变。所以我们要计算出这个比率,那么我们才能把物体缩放到合适的大小并且把物体移动到相应的Flash 2D空间位置。

    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()*(0-600)+600;
        sphere.direction 
    = 1;
        sphere.speed 
    = Math.random()*(5-12)+12;    

        scene.addChild(sphere);
    }

     

    2. 利用Bubble Sort算法,在每一次对小球x,y和大小设置后,对所有的小球在舞台上的层次进行操作。这里使用的理论是最小的z值的小球,它所在层次就应该在最上面。不要小看我写的这短短几行代码哦!它可以把所有的小球分配到相应的层次!只要你的CPU够块,不管多少小球都可以。

    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(j-1)).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或者百度一下,我相信你会找到更详细的说明文字来解释冒泡排序。


     

    一个简单Particle System例子

    这是一个使用缩放的基本概念的例子,你可以使用键盘上下左右键移动你的观看位置,按下W键加速前进,按下S键减速。由于涉及到摄像机,在这篇文章中就不再讲解。源文件在文章的下载页可以找到,你可以尝试改变星星的数量,星星很多的话,移动你的摄像机,你应该会看到一个很长的星带(题外话:我在我的电脑里运行2000个星星就有些慢了,Dual Core 2.0GHZ,如果你有更强大的CPU的话,那你看到星空要比我的漂亮的多)。


     


     

    3D星空,简单的Particle System,WASD移动观看位置,K键加速,L键减速


     

    OK,你已经学会了如果使用缩放和一些简单的设置产生3D效果的动画。在后面的几篇中,我们会逐渐深入探讨更有趣的内容。加油! 
     作者:Yang Zhou
    出处:http://yangzhou1030.cnblogs.com
    感谢:Yunqing
    本文版权归作者和博客园共有,未经作者同意禁止转载,作者保留追究法律责任的权利。

     

     

    点此下载程序源文件

  • 打印这篇文章
  • 与本文主题相关的文章
  • 返回首页