[Flash]Flash3D编程探秘二

作者:Yang Zhou
感谢:Crystal

介绍

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

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

 

点此下载本节源文件

 

静态长方体

那么我们接着上一节所学习的内容,来制作一个静态的长方体,并且让它在屏幕上来回的运动。这个例子和上一节的例子非常的相似,同样主要关心3D空 间。不同的是,上一节我们利用了一个事先画好的小球,这一节我们改变方式,在程序执行时,我们计算出长方体的每个顶点的位置然后使用Flash的图形 API绘制出一个长方体,这样在一系列的绘制后,我们所看到的就是长方体移动的动画!

移动的静态长方体

 

动画制作步骤

1. 在这一个例子中,我们需要发挥一下我们的空间想象力去定位长方体的顶点。至于场景上的网格,我想大家可以先把它放在场景的底部,等动画完成后再把它向上移动到合适的位置。

2. 开始和以前一样,定义原点以及焦距。另外我们也要初始几个常量。长方体围绕y轴公转,R是长方体公转的半径。

var PI = 3.1415926535897932384626433832795;

var R = 100;

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

var focal_length = 300;
var angular_Velocity = PI/160;
var _angle_xz = 0;

 

3. 接下来定义一个3D空间的点,我们绘制的长方体就围绕这个点进行旋转。

var spin_center = new Object();
spin_center.x 
= 0;
spin_center.y 
= 0;
spin_center.z 
= 100;

 

4. 创建一个场景舞台,用来盛放我们绘制的长方体。创建一个长方体的空Sprite并且把它添加到舞台上。

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

 

5. 下面我们需要一个函数来创建3D空间的点。

function vertex(x, y, z):Object
{
    var point3d 
= new Object();
    point3d.x 
= x;
    point3d.y 
= y;
    point3d.z 
= z;
    
return point3d;
}

 

6. 你肯定猜到下一步我们要做的,那就是把一个3D空间的点转换成Flash能够理解的2D空间的点。转换的原理和第一节是一样的,这里就不解释了。

function convert(point3d, focal_length):Object
{
    var point2d 
= new Object();
    var scale_ratio 
= focal_length/(focal_length+point3d.z);
    point2d.x 
= point3d.x * scale_ratio;
    point2d.y 
= point3d.y * scale_ratio;
    
return point2d;
}

 

7. 下一步也就是我们主要关心的循环函数。首先我想你明确这个函数要做的工作,那就是计算出长方体每个顶点的3D坐标,然后把他们转化成2D坐标,最后用 Flash的绘制API建立图形。每一次函数执行,我们把长方体围绕y轴旋转的角度增加。(当然这里你可以长方体的运动改为以时间为依据的运动)然后根据 这个角度,我们便可以计算出长方体中心点(对角线的交点)cente.x,center.y,center.z。很好,下面我们就可以确定这个长方体的每 个点的坐标了。在这里我使用了一个边长为80正方体,你可以更改参数调试出你喜欢的长方体。

 

俯瞰长方体的移动

 

 

那么紧接着,使用我们之前写的函数,把长方体的6个3D顶点转换成2D点。然后用Flash的绘制函数绘制出来长方体。需要注意的是,我们在这里是对空间中的点进行操作而不是对一个Sprite进行操作。

function move(e:Event):void
{
    var screen_points 
= new Array();
    
    _angle_xz 
+= angular_Velocity;
    
if (_angle_xz > 360)
    {
        _angle_xz 
-= 360;
    }
    var center 
= new Object();
    center.x 
= R*Math.cos(_angle_xz) + spin_center.x;
    center.y 
= 0 + spin_center.y;
    center.z 
= R*Math.sin(_angle_xz) + spin_center.z;
    
    var points 
= [
            vertex(center.x
4040, center.z40),    
            vertex(center.x
+4040, center.z40),        
            vertex(center.x
+4040, center.z+40),
            vertex(center.x
4040, center.z+40),
                    
            vertex(center.x
4040, center.z40),
            vertex(center.x
+4040, center.z40),
            vertex(center.x
+4040, center.z+40),
            vertex(center.x
4040, center.z+40)
             ];
    
for (var i = 0; i < points.length; i++)
    {
        screen_points[i] 
= convert(points[i], focal_length);
    }
    
    with (box.graphics)
    {
        clear();
        lineStyle(.
50x0000001);
        moveTo(screen_points[
0].x, screen_points[0].y);    
        lineTo(screen_points[
1].x, screen_points[1].y);
        lineTo(screen_points[
2].x, screen_points[2].y);
        lineTo(screen_points[
3].x, screen_points[3].y);
        lineTo(screen_points[
0].x, screen_points[0].y);
        
        moveTo(screen_points[
4].x, screen_points[4].y);    
         lineTo(screen_points[
5].x, screen_points[5].y);
        lineTo(screen_points[
6].x, screen_points[6].y);
        lineTo(screen_points[
7].x, screen_points[7].y);
        lineTo(screen_points[
4].x, screen_points[4].y);
        
        moveTo(screen_points[
0].x, screen_points[0].y);    
        lineTo(screen_points[
4].x, screen_points[4].y);
        moveTo(screen_points[
1].x, screen_points[1].y);
        lineTo(screen_points[
5].x, screen_points[5].y);
        moveTo(screen_points[
2].x, screen_points[2].y);
        lineTo(screen_points[
6].x, screen_points[6].y);
        moveTo(screen_points[
3].x, screen_points[3].y);
        lineTo(screen_points[
7].x, screen_points[7].y);
    }
}

 

8. 最后在场景上添加一个循环执行事件。

this.addEventListener(Event.ENTER_FRAME, move);

 

我希望你能够明确我们制作这个动画的思路:建立场景,创建3D物体,把顶点转换成为2D点,使用Flash绘制。So far so good? Great! 后面我们开始介绍摄像机以及相关的要素,希望你能跟上。

建议:

在你的脑海中建立一个长方体应该不是很困难。我的方法是首先勾勒出正面,然后后面,上面,下面,左面和右面。如果你觉得用脑海想象比较困难的话,可以试着用笔和纸画出一个长方体,然后标出坐标。

建议:

在Flash里,2D空间的原点在左上角(0,0)。在这上面的两节的例子中,我们在程序一开始就把3D空间的原点向右再向下移动了,那么在屏幕上的映射 面也就到了屏幕的中间。我是刻意这样写的,好处在于如果你是新接触3D空间这个课题的话,那么想象物体在原点附近对你来说要容易一些。当然你可以尝试不移 动原点,取而代之移动物体,看看和原程序有什么不同。

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

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

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

支付宝扫一扫打赏

微信扫一扫打赏