PV3D2构建你的第一个应用Word文件下载.docx
《PV3D2构建你的第一个应用Word文件下载.docx》由会员分享,可在线阅读,更多相关《PV3D2构建你的第一个应用Word文件下载.docx(23页珍藏版)》请在冰豆网上搜索。
varmyObject3D:
DisplayObject3D=newDisplayObject3D();
一旦知道了如何使用类,就可以创建自己类了.
创建自定义类
ActionScript类是存放于计算机上以.as结尾的文本文件,包括ActionScript脚本代码.这些代码就是前面所说的对象的设计.现在看看设计是什么样子:
package{
publicclassExampleClass
{
publicvarmyName:
String="
Paul"
;
publicfunctionExampleClass()
}
publicfunctionreturnMyName():
String
return"
Mynameis"
+myName;
}
第一行,是包(package)语句,紧随其后的是左大括号({)和类下面的右大括号(}).包是组织类的一种方式,代表了存放类文件的目录.假设你创建了一个名为myPackage的目录并将FLA或源码文件存放在其中.为了访问此目录及里面的类,需要用目录名来定义包,如下:
packagemyPackage{
...
子目录的工作情况也一样.现在假设在myPackage目录下有一个名为subPackage的子目录.应该这样来定义子目录subPackage:
packagemyPackage.subPackage{
...
如果你没有创建一个目录来组织你的类,可以使用默认包来代替相应的包名,(即不写包名)本书的所有例子都使用默认包.实际上,为了避免命名冲突,必须用包来组织众多的类.
包定义之后,将看到类的定义,看起来如:
publicclassExampleClass
{
类的名字必须和类文件的名字一致.本例中,类文件必须存为ExampleClass.as.
实际上,包是一种很好的类文件组织方式,可以让项目中每个类都有唯一的名字.避免命名冲突.
在class的前面有一个public,这是一个关键字用来表明项目中所有代码都可以访问此类.这个关键字被称为访问控制符.
类的名字将被用来实例化类.像这样来实例化类:
varclassExample:
ExampleClass=newExampleClass();
在类里定义的变量称其为类属性.类属性的数量不限.每个类属性均有访问控制符.本例中的访问控制符是public,表示所有的类都可以对其进行读写:
classExample.myName="
Jeff"
这样便创建了一个类ExampleClass的实例.我们可以将属性myName由Paul改为Jeff.当一个属性声明为public,便可以这样操作.如果你想让属性只能在类中使用,需要将属性改为private:
privatevarmyName:
这时执行之前的代码,会得到一个编译时错误.
接着我们看到类中名为ExampleClass的方法.
方法名与类名相同的方法被称为构造器(构造方法).
publicfunctionExampleClass()
构造器的访问控制符均是public并且每当实例化类时就被自动调用.这表示构造器中的代码将被自动执行.
类中其他的所有函数(function)都称为方法(method).
publicfunctionreturnMyName():
方法定义完后,你将发现一个冒号紧跟着一个数据类型.这是定义方法返回值的数据类型.你也可以在Flash的时间轴上这样定义方法,但这不是必须的.returnMyName()方法定义了返回值是字符串.如果你不想返回任何值,可以使用void作为返回类型:
publicfunctionreturnNothing():
void
//Donotreturnsomething
我们只需为普通方法定义返回类型即可,构造器无返回值
类,及其属性和方法,都用访问控制符,用来确定对象的访问权限.到现在我们已经看到了关键字public,表示在任何地方都可以访问.当使用public时,必须注意到可能会造成类的混乱.可以用private关键字来避免这样情况,private将使属性或方法只能在本类内进行访问.其余两个常用的访问控制符是internal和protected.internal表示同一包内可以访问.protected表示属性或方法只能由子类访问.子类是oop继承的一部分,我们稍微将解释下.
只要属性或方法不准备在类外进行访问,最好将其设定为private.每当定义属性或方法时,你都应该确定下是否要在类外进行访问.
继承
有时想创建一个类,而此类和已存在的类又很相似,而你只是想添加一个新的方法.你可以拷贝已有的类,粘贴到新类中,再添加一个新的方法.然而这样做的效率很低.这时就有继承的用武之地了.
继承是一种扩展已有类(称为父类或基类)的技术,从父类中继承的类称为子类.子类可以访问父类中所有非private的属性和方法.
假设你准备用代码来创建一个汽车和一个摩托车.你可以直接写2个类,汽车和摩托车.但你很快就会注意到这2个类的方法和属性几乎都是重复的.比如2者都可以驾驶,都有属性:
车轮数和速度.在抽象方式中,这些属性和方法都重复了,因为汽车和摩托车都是车辆.
创建父类:
车辆,汽车和摩托车都继承车辆便可以避免重复的代码.
必要时,子类可以定义与父类不同的,自己专有的属性或方法.
如:
一汽车有4个轮子并可以在相反的方向驾驶.
而摩托车有2个轮子,不能在相反的方向驾驶.
现在用2个简单类看一下继承是怎样完成的:
publicclassBasicClass
publicfunctiondoSomething():
trace("
I'
mdoingsomething"
);
publicclassSubClassextendsBasicClass
publicfunctionsaySomething():
msayingsomething"
第一个类作为父类并只有一个方法.实例化BasicClass并直接调用其方法.
varbasicClass:
BasicClass=newBasicClass();
basicClass.doSomething();
没什么特别的.由SubClass的定义我们可看到它继承了BasicClass.这样它便可以用BbsicClass的属性或方法.现在看看:
varsubClass:
SubClass=newSubClass();
subClass.doSomething();
subClass.saySomething();
subClass调用了从BasicClass继承的doSomething()方法.
不但可以从自定义的类继承,也可以继承一些内置的类.现在看一下创建Sprite的子类:
importflash.display.Sprite;
publicclassextendedSpriteextendsSprite
注意需要在包声明下面加入这句:
importflash.display.Sprite;
为了继承在当前包中没有的类,你需要声明一个引入.引入相关的包和类.本例中的Sprite类从包flash.display引入.
继承是创建新类的一种途径,以已有的类为基础-不是吗?
这将使你的代码更清晰和精炼.但如果你想改变一个父类中已存在的方法?
如果你想完全的摆脱现存类的代码,直接改父类有时不可能,同时也不是一个好方法.当你用了一个第三方的类库如Papervision3D,很难想象你会修改它.当你直接修改了一些类后,一旦更新类库的版本后你的代码就失效了.
幸运的是面向对象程序设计提供了一个解决方案.看一下我们如何在子类中修改BasicClass类的doSomething()方法.
overridepublicfunctiondoSomething():
Hi,youneedtodosomething"
我们为子类添加一个doSomething()方法.但必须明确说明此方法是覆盖了父类的同名方法.当覆盖后老方法便被替换了.在子类中依然可以调用被覆盖的父类方法.
overridepublicfunctiondoSomething():
super.doSomething();
现在在SubClass中调用doSomething()方法,将输出:
Hi,youneedtodosomething
mdoingsomething
这里简单的解释了最基础的面向对象.借此你应该明白了一些基础面向对象,并能大概看懂面向对象的书,如果想了解的更多,在线的面向对象的书籍有一大堆.
使用文档类和主应用文件
文档类是在FlashIDE中才有,主应用文件在FlexBuilder或FlashBuilder中才有.
文档类是只包含一个构造器的特殊类,当SWF文件载入时会调用它.也可以说文档类的构造器是你程序的入口.文档类必须是Sprite或MovieClip,或他们的子类.
为了简单起见,本书只使用文档类不用主应用文件,虽然他们的名字不同,但作用却是一样.
FlexBuilder和FlashBuilder获取并执行文档类的流程一样,但FlashIDE使用另一种方式.现在我们解释下FlashIDE的工作方式.
设置Flash的文档类
在Flash中,你可选择一个文档类作为你程序的入口.文档类可以是有时间轴的MovieClip的子类.将其放置到舞台作为应用的入口.虽然可以用舞台和文档类的组合来作为应用的入口,但不怎么常用.
指定文档类非常简单.打开Flash,步骤如下:
1.新建as文件,保存为DocumentClassExample.
2.新建Flash(as3)文件保存为DocumentClassExample.Fla,与as文件同一目录.
3.打开FLA文件的属性面板.在最底下的右边有Documentclass的输入框.输入文档类的类名,本例是DocumentClassExample,下图:
到此就足够了.很简单是吧?
在Flash中构造应用这些基本信息是非常重要的,不论是否是3d的应用.
现在看一下发布后将发生什么.如果以上的步骤不对的话,Flash将抛出错误5007.
5007:
AnActionScriptflemusthaveatleastoneexternallyvisibledefnition.
这是个可预知的错误.因为我们在属性面板定义文档类名却不存在相应的类.
我们只创建了一个空的文件还没任何类的定义.当Flash无法继续工作就抛出刚才的那个错误.提醒我们出现了错误.现在我们修改此类.在Flash中打开DocumentClassExample.as,加入下面的代码并保存.
publicclassDocumentClassExampleextendsSprite
publicfunctionDocumentClassExample()
Helloworld!
"
现在我们可以正常发布了.第三行我们看到此类继承了Sprite,这是必须的.构造器只输出了一行字符,发布后会在输出窗口看到这行字符.
设置FlashBuilder,FlexBuilder的文档类
虽然这是可以的,但在本书中不使用FlexBuilder或FlashBuilder来创建Papervision3D的应用.但这2个工具都可以处理ActionScript工程.
FlashBuilder或FlexBuilder中创建文档类步骤相同.使用这2个工具可以自动创建文档类.现在看一下如何创建文档类:
1.新建一个ActionScript项目.
2.将其命名为DocumentClassExample.
3.单击Next直到看到Mainapplicationfile的输入框,默认此处的值为工程名.As,本例中为DocumentClassExample.as.
下图是新建ActionScript项目向导的第2步.自动命名的文档类.
4.单机Finish就设定好了文档类.如果有多个类,可以随时在FlexNavigator(FlexBuilder)或PackageExplorer(Flashbuilder)中更新文档类.(步骤为:
在xxx.as右键选SetasDefaultApplication,文件的图标变为
即可).
5.现在完成此类并输入"
HelloWorld"
.
因为FlexBuilder和FlashBuilder为了运行你的代码必须指定一个文档类,之外不须更多的步骤.Debug方式运行你的代码,将看到trace出的字符.
Papervision3D里3D场景基础
在我们开始写Papervision3D的代码前,我们需要知道更多一些Papervision3D面的3D.接下来的这部分会让你更明白所写的那些代码.这些概念跟Papervision3D用到的类有直接关系.本章,将使用这些来完成第一个应用.我们所说的对象都是3D场景里活动的元素.让我们看一下这些对象:
场景Scene
Scene是在3d空间由3d对象组成的一个整体.就如flash里有3个轴的舞台(stage)-x,y,z.每个可视对象都可以添加到场景.如不添加到场景中就不会在出现在屏幕上.
摄影机Camera
可以想象成一个真实的相机,它在3d空间中不断的记录场景的活动.摄影机确定了查看场景的点.因为3d空间的相机不是可视对象,它不是场景的组成部分不必添加它.摄影机可以像真实的相机一样缩放和聚焦.
3d空间的相机可以做更多的事.如,在3d中对象距离相机过近或过远时将剔除此对象防止它被渲染.相机可以忽略某些在不可见区域的对象.这些都是出于性能考虑的.对象距离太远或处于相机后面,不需来记录,这时会节省很多计算的资源.
观察口Viewport
观察口是一个舞台上的sprite容器,输出相机记录下来的对象.对象介绍中,观察口好比相机的镜头.镜头是我们放在3d场景上面的窗口.
我们可以缩小这个窗口则可以只看到3d场景的一小部分,放大一些就看的多一些.观察口如现实中真实窗口一样—窗口越大看到的外面世界越大,它影响到我们究竟可以看到多少场景.
下面的图解包含了一个大的观察口,右侧是一个小而宽的观察口.黑边框画出了观察口区域.右侧的图很好的说明了观察口如何影响我们所看到的物体.
3D对象
在3d空间中的图形被称为一个3d对象,在Papervision3D中叫DisplayObject3D.可以将其想象成一个更高级的可视化对象如sprite和movieclip.不同的是DisplayObject3D有第三个轴,我们可以让其绕3轴进行旋转.
材质Material
材质是附着在对象表面上的结构.当对象没有附着材质时,它是不可见的.可以使用很多材质.如一个简单的材质:
颜色;
高级的材质可能是:
流(livestream).第四章会用到所有的材质.
渲染引擎Renderengine
渲染引擎像一个滚动的相机.只要渲染引擎开始工作,它会输出相机记录下来的信息给观察口.当停止渲染引擎时观察口不会有任何新的信息输出仅仅会看到最后的那张图像.渲染是计算机中最繁重的任务,它需要重复计算你场景内部的对象并输出他们到观察口去.
左手定则笛卡尔坐标系
Flash,Papervision3D,都使用笛卡尔坐标系.在Flash中,一个规则的可视化对象可以通过设置x,y值改变其在舞台的位置.对象依靠x,y的值与舞台左上角的关系来确定位置.x值越大对象越靠右,y值增大对象便向下移动.
Papervision3D里面的坐标系工作一致,只有2点不同之处.
●Flash使用了笛卡尔坐标系的2个轴,而Papervision3D使用了3个轴
●Papervision3D里的y轴与Flash里面的y轴相反.
在Papervision3D中,我们不但要设置可视化对象的x,y轴,还要设置其额外的轴,为了确定对象的深度.第三轴称为z轴.
在Flash中,依靠左上角的关系来摆放对象,这点是(0,0).称为中心点或原点.可想而知,Papervision3D中的原点是(0,0,0).
图中(+,-)的标志说明了坐标值相对于原点是增加还是减少.[注意]y轴与Flash2D坐标系是相反的.若准备将对象放置到屏幕的下方,需要给y轴更大的值.这是2D坐标的工作情况.上面的图解说明了Papervision3D坐标系里的y轴情况.
(注:
这样想Flash的坐标原点在屏幕的左上角,Papervision3D的坐标原点在屏幕的左下角)
创建一个基础的Papervision3D类
前面学习了基础场景的使用,和如何创建自定义类.现在我们要开始实践.
使用你顺手的工具.第一个应用我们将创建一个3D场景包含一个可绕y轴旋转的球体.球体是Papervision3D内置的一个基本体.
基本文档类
首先,看一下定义了旋转球体应用结构的文档类.
importorg.papervision3d.cameras.Camera3D;
importorg.papervision3d.objects.primitives.Sphere;
importorg.papervision3d.render.BasicRenderEngine;
importorg.papervision3d.scenes.Scene3D;
importorg.papervision3d.view.Viewport3D;
publicclassFirstApplicationextendsSprite
privatevarscene:
Scene3D;
privatevarviewport:
Viewport3D;
privatevarcamera:
Camera3D;
privatevarrenderEngine:
BasicRenderEngine;
privatevarsphere:
Sphere;
publicfunctionFirstApplication()
scene=newScene3D();
camera=newCamera3D();
sphere=newSphere();
scene.addChild(sphere);
viewport=newViewport3D();
addChild(viewport);
renderEngine=newBasicRenderEngine();
renderEngine.renderScene(scene,camera,viewport);
现在细说下,我们可以在Flash,Flexbuilder,FlashBuilder中建立一个新工程之后创建一个名为FirstApplication的文档类.不要忘记在FlexBuilder,FlashBuilder中导入Papervision3D的代码.
此前,我们了解到要把渲染结果输出到屏幕上我们需要一个场景,摄像机,观察口,有材质的3d对象,和一个渲染引擎.[注意]文档类需要继承Sprite.之前我们需要将其引入.
importorg.papervision3d.cameras.Camera3D;
importorg.papervision3d.objects.primitives.Sphere;
importorg.papervision3d.render.BasicRenderEngine;
importorg.papervision3d.scenes.S