用ActionScript在Flash中实现3D视角的控制

本文来自:9RIA

Flash CS4专业版的3D能力允许我们进行变焦和透视角度的改变,而且他的强大3D处理数学函数让它在3D场景的内外导航起来更加简单。现在游戏开发者和动画家 们能够轻而易举的导入三维视图和运动效果了。

这个教程探讨的两种改变舞台显示效果的方法

  1. 通过移动和变焦改变观察点
  2. 在三维空间里移动对象本身

移动观测角度是非常简单的,用起来就好像是相机的调焦镜头样。通过使用对象的x,y,z属性来移动对象也不是那么难,就像是你在手上托着一个物体, 然后将它上下,或左右移动也可以旋转。

教程里的代码对两种方法进行了演示,包括如何使用Matrix3D类实现多转换。这个样本文件包含了用户界面控制导航,以便我们进行通过两 种方法体验下效果,正如例子一所示。

http://wwwimages.adobe.com/www.adobe.com/devnet/flash/articles/3d_view_controller/fig03.swf

图1. 导航UI控制(点击改变导航样式,调整滑动条查看效果)

目录

[隐藏 ]

教程要求:

为了让你能充分利用这篇教程,你需要如下软件和文件。

Flash Player 10 or更高的版本: Download

Flash CS4 专业版: Try Buy

样本文件:

3dviewcontrol.zip (ZIP, 490 KB)

必备知识

你需要对Flash的特性有个基本的了解,比如Flash的创作接口,需要用到的符号,还有鼠标交互。

对3D有认识也是有用的;你应该对Mariko Ogawa的文章Exploring the new 3D features in Flash 有 了解。在这个教程的最后有许多关于3D知识的链接。

构建3D场景

即便是在3D世界中Flash显示的对象也是平面,比如Sprite对象。它们好像照片一样,你可以随意对进行移动。但是创建一个具有深度的正真的 3维结构,你需要许多显示对象。

这篇文章中我所创建的3D场景中,每一个墙或地面都是在自己的Sprite中创建的,然后旋转到正确的位置。正如例 2 所演示的一样,墙(粉色的矩形)原来是平的,通过改变旋转属性为90度,被“举”到了正确的位置。注意在例 2 中矩形左上角的标记点(0,0)点相对于其他的平面的位置保持不变。用过标记点和进行正确的3D旋转来定位是比较简单。我发现从这个模型的上方往下看来构 造这个场景也是非常简单的,那样的话x,y还是原来的x,y而z代表高度了,我在这个教程中就是这么做的。例2带有一点倾斜,那样就可以看到墙的高度了。

fig01.jpg

图2.将垂直的墙壁的Y轴旋转属性从0变到90度

为了垂直的平面更像一面墙,这个旋转就好像是拉着一个平面的一边使得这个矩形成了一面墙。一旦这个墙被固定,当你移动观测点的时 候,Flash Player就会进行所有的计算和重绘。

构建3D对象

这个Flash项目样品包含在样品文件3dviewcontrol.zip 中,构建一个包含在ModelSprite.as中的3D对象,ModelSprite.as为每一个墙,地面,屋顶都建立了一个新的Sprite。 ModelSprite类包含了 墙,屋顶的大小,位置实例,这样的话就可以再同一场所对他们进行设定值了。就像其 地面 一样 屋顶也是一个二维对象,但是当z减小的时候,它会越来越接近用户,所以它是在地面的上方的。墙被画成了矩形,然后沿着x,或者y轴进行旋转到正确的位置, 见例 2

用户界面控制

这个3DViewControl.fla包含了带有两个用于导航的广播按钮的舞台,一个是用于复原,还有为Slider而设定的标签,这些标签是用 AS构建的。大部分的构建都是在Scene.as文件中发生的,当用户点击任何一个按钮的时候,两个按钮分别连接了viewpointHandler() 和moveObjectHandler()方法——我们就是通过他们实现3D观测的。现在,场景已经构建好了,接下来我将描述下如何他们是怎么工作的。

3D导航

我设定了两个变量,控制观测3D观测。projectionCenter定义了观测者的x , y 坐标,fieldOfView定义了如何扩大观测者的观察范围。减小fildOfView的值就会实现照相机的缩小焦距的效果。两个变量同属 root.transform.perpectiveProjection 类。

移动摄像机(观测点或者项目中心)

通过改变projectionCenter的值可以改变观测点,就好像你将摄像机上下移动,左右移动。在代码里,通过 doDragProjecetionCenter函数改变会移动观测点,代码如下:

root.transform.perspectiveProjection.projectionCenter = new 
Point(center.x,center.y);

这段代码会设定projection点为鼠标所指的位置。 你可以通过按Shift健,上下移动鼠标,或者在舞台左边Slider进行调焦距。通过设定一个更小的fieldOfView值进行放大。

Z 排序问题

当移动场景时,在代码样本中有一个Z排序问题,因为当z轴坐标发生改变时,并未进行重新排序。当我们从左边观测时,粉色的墙本应该在前边的(这个顺 序没错),但是当我们的视角移到右边时棕色的墙本应该在前面的(却没有预期出项这个效果)。这个z排序还没有解决,这就意味着,这个粉色的墙式被画在了棕 色墙的上边的。基于新的观测点的出现,这是可以通改变显示顺序来解决的。Transformation类中的getRelativeMatrix3D方法 就能做到。在Programming ActionScript 3 的文件中,标题为 Using Matrix3D objects for reordering display的文件可以对这个解决办法做出解释。 当鼠标拖到舞台外面去的时候,我加了个Timmer,这样就能够继续移动projection 点了,观测点的变化范围就会更大,可以看到更加广阔的景象了。

在舞台上移动对象

第二种改变观察效果的方法是通过移动在场景中的所有对象,并保持观测点和视场不变。起初我以为这个会有更多的计算,但是这个和第一种“改变对象在舞 台上的位置”是一样简单的。Flash会处理3D视图的计算,通过设定代码中x,y,z 的值,可以将物体在x,y,z三个位面上进行移动。

点击Move Objects选项按钮,就会出现两个按钮:Pan和Orbit。选择Pan,你就可以将物体往左右,上下进行移动。通过使用Matrix3D设定多个变 量的值比较有效,因为它在每改变一个值时就会执行一次计算,而不是等所有的值都改变后才执行计算。在代码中,moveObjects()使用了 matrix3D.appendTranslation()方法在同一时刻设定了x,y的位置。

tray.transform.matrix3D.appendTranslation(offsetX, offsetY, 0);

通过减小z轴上的值,就可以变焦,实现物体靠近我们的效果。在代码中,就是这个tray.z+=offsetY中的起的作用,实现了视角的变焦。

我进一步实施了一个Oribit,它只能够通过改变对象本身的值来实现。Orbit是一个比较有意思的3D运动,对象会在同时x,y轴上进 行旋转,这样的话你就可以将它进行旋转,观看这个对象的侧面和背面了。简单的旋转可以通过改变rotationX和rotationY的属性值来完成,或 者使用matrix3D类来实现这些旋转,正如下代码:

//Perform both rotations together
tray.transform.matrix3D.prependRotation(-offsetX / 2, Vector3D.Y_AXIS);
tray.transform.matrix3D.prependRotation( offsetY / 2, Vector3D.X_AXIS);
fig02.jpg

图3. 在将x旋转值和y旋转值相乘以后定位z旋转值

然而,因为3D旋转不可交替的——这就意味着旋转的顺序是很重要的,代码在多次对x,y方向同时进行旋转后,这个图像会翘起来。为了看到这 个,点击Orbit,不要选择No Tilt框,将鼠标移动一圈。就好像我在旋转一个魔方一样去旋转,我会得到一个有点翘起的图像(如例3所示)。然而,这个是正常的,这个不是我想要的轨道 旋转特点,所以为避免翘起,或者是z方向的旋转,我加了个No Tilt复选框,在函数orbitObjects()中加了如下代码。这段代码没有执行先前的x旋转,然后启用了新的y方向上的旋转,然后是新的x方向上 的旋转。这个在旋转过程中,z旋转方向值始终0.

//"Undo" the X rotation from previous rotation
tray.transform.matrix3D.prependRotation(-currentXrotation, Vector3D.X_AXIS);

//Apply the new Y rotation
tray.transform.matrix3D.prependRotation(-offsetX / 2, Vector3D.Y_AXIS);

//Add the new X rotation to previous X rotation and "re"apply it currentXrotation += offsetY/2;
tray.transform.matrix3D.prependRotation(currentXrotation, Vector3D.X_AXIS);

尝试在选择No Tilt 选项的情况下,移动鼠标,然后在没有选择No Tilt选项的情况下移动鼠标。等结束后,在沿z方向上有一点上翘,即便是尝试着去讲对象旋转会原来的的位置时,也会出现同样的情况。将x,y旋转分开会 有助于减缓旋转。

这个resetPosition函数会存储对象的x,y,z的原始数据,然后将他们全都归零。

接下来去哪儿

在舞台上移动物体作为一种在3D场景中该变视角的方法,并没有比移动视角来的难。这个观察3D场景和在3D场景中改变视角的能力为我们开启一扇通往 以更加有用的方法去探索可视化数据的大门。

另一篇有关3D在flash和AS3中的使用,请参考我对应的文章3D moving stars in Flash using ActionScript 3

以下是一些关于flash和3d额外参考文档

Using Matrix3D objects for reordering display (Programming ActionScript 3 for Flash)

Creating and editing artwork: 3D graphics (Using Flash CS4 Professional)

Working in three dimensions

Matrix3D

PerspectiveProjection

关于作者

Rodney Smith已经在Adobe工作了6年,领导着Adobe的在线应用程序的更新和电子商务引擎的开发。他是Flex和Flash平台的强烈支持者,在 Adobe进入流媒体,移动设备和搜索之前就是如此。他的兴趣包括了软件安全和用户交互设计。

 

【国内下载】Flex 3 Builder :http://g.csdn.net/5120749
【国内下载】Adobe Flash Builder 4 :http://g.csdn.net/5105812
【官方下载】Flex 3 Builder :http://g.csdn.net/5121278
【官方下载】Adobe Flash Builder 4 :http://g.csdn.net/5120750

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值