本來打算《入門第4部》講些關於貼圖的內容,但PV3D的內置對象貼圖太容易了,並且我們前兩篇文章的程序中都有涉及到了,所以今天除了講解材質的使用外,還打算做一下複習,回顧下基本的PV3D程序結構。
我發現大部分做Flash的朋友不是像我一樣從ActionScript3時代開始的,而是從Flash的動畫製作時代開始的,這些前輩都已經習慣了以時 間軸來思考程序中的變化過程,而PV3D的程序則普遍是以幀位單位來控制內容的變化,再加上AS3相對AS2也變化比較大,所以對於傳統AS2程序員和 Flash動畫製作人員,單純給一個範例代碼,還是有些不夠的。
在講材質貼圖直接,我們就先回顧下一個基本的PV3D程序結構。
首先,我們會有一個類,不管在Flash 9 CS3中還是Flex Builder的ActionScript項目中,都會有一個類做為整個Flash程序的入口。在Flash 9 CS3中,可以在底部的Flash屬性欄裡找到主類的設置選項。
我喜歡把我的主類命名為Main,其實命名位什麼都無所謂的,只要記得保持文件名和類名一致就可以 。不過記得主類一定要繼承自Sprite類。
1 2 3 4 5 6 7 8 9 10 11 | package { import flash.display.Sprite; public class Main extends Sprite { public function Main() { } } } |
上面就是我們的主類的代碼了,Main()函數是Main類的構造函數,就是說當你執行new Main();時,Flash虛擬機會調用這個函數,初始化Main類的對象(類的實例叫對象,達達是人這個類的一個實例,所以是個對象….)。所 以,Main()函數就是我們整個Flash的入口了(如果你的類叫做AA,那你的入口就是AA()請不要和C語言的Main函數混淆),這裡面的程序最 先被執行,所以我們可以在這裡面放一些初始化PV3D的代碼。下面我們就一步步初始化PV3D。
首先,PV3D的3D舞台需要一個容器,用來容納整個3D舞台。這個容器至少是Sprite類型的,因為Sprite是AS3或者說Flash9里,顯示對象的最小單位,這也是我們的主類一定要繼承自Sprite的原因,因為它需要被顯示。
我們現在定義一個容器變量_container,初始化它並把它加到主類的顯示列表裡。我習慣實例變量用小寫開頭,前面加下劃線
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package { import flash.display.Sprite; public class Main extends Sprite { private var _container :Sprite; public function Main() { // 創建3D舞台的容器 _container = new Sprite(); _container.x = 100; _container.y = 100; //將它顯示出來 addChild( _container ); } } } |
我們有了容器,現在需要一個3D舞台。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | package { import flash.display.Sprite; import org.papervision3d.scenes.MovieScene3D; public class Main extends Sprite { private var _container :Sprite; private var _scene :MovieScene3D; public function Main() { // 創建3D舞台的容器 _container = new Sprite(); _container.x = 100; _container.y = 100; //將它顯示出來 addChild( _container ); // 創建3D舞台 _scene = new MovieScene3D( _container ); } } } |
然後我們需要在舞台上放一個攝像頭,他代表我們的眼睛,他能看到的就是你看到的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | package { import flash.display.Sprite; import org.papervision3d.scenes.MovieScene3D; import org.papervision3d.cameras.Camera3D; public class Main extends Sprite { private var _container :Sprite; private var _scene :MovieScene3D; private var _camera :Camera3D; public function Main() { // 創建3D舞台的容器 _container = new Sprite(); _container.x = 100; _container.y = 100; //將它顯示出來 addChild( _container ); // 創建3D舞台 _scene = new MovieScene3D( _container ); // 創建攝像頭 _camera = new Camera3D(); _camera.z = -500; _camera.zoom = 5; //把攝像頭看到的顯示出來 _scene.renderCamera(_camera); } } } |
現在我們需要有一個3D對象,把它顯示出來我們才算成功 。PV3D的所有3D對象都是繼承自displayObject3D,就像Flash裡的Sprite一樣它是最小單位。如果學過面向對象編程,你就會知道父類型的變量可以引用子類型的對象。比如MovieClip是Sprite的子類,那底下的代碼是成立的:
1 | var temp:Sprite = new MovieClip(); |
考慮到我們程序的通用性,我們的顯示對象使用displayObject3D類型,後面初始化時候你可以把它初始化成任意displayObject3D的子類型對象。
光一個3D顯示對象還是不夠的,它需要有個「皮」,你才能看到它….所以,我們同時需要一個材質貼圖(至少需要一個,如果是立方體,就需要六個面的貼圖)。PV3D中所有材質貼圖的基類是MaterialObject3D,所以考慮到通用性…..我就不多說了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | package { import flash.display.Sprite; import org.papervision3d.scenes.MovieScene3D; import org.papervision3d.cameras.Camera3D; import org.papervision3d.core.proto.MaterialObject3D; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.objects.Sphere; public class Main extends Sprite { private var _container :Sprite; private var _scene :MovieScene3D; private var _camera :Camera3D; private var _material:MaterialObject3D; private var _displayObj:DisplayObject3D; public function Main() { // 創建3D舞台的容器 _container = new Sprite(); _container.x = 100; _container.y = 100; //將它顯示出來 addChild( _container ); // 創建3D舞台 _scene = new MovieScene3D( _container ); // 創建攝像頭 _camera = new Camera3D(); _camera.z = -500; _camera.zoom = 5; //黑色的線框材質 _material = new WireframeMaterial(0x000000); //弄個球玩玩 _displayObj = new Sphere(_material, 80, 10, 10); //把顯示對象添加到舞台 _scene.addChild(_displayObj); //把攝像頭看到的顯示出來 _scene.renderCamera(_camera); } } } |
把程序運行起來,你可以放在Flex Builder的ActionScript項目中運行,也可以在Flash裡把影片的主類設置成我們現在寫的代碼,不要說你不會Flex Builder就做不了PV3D,這和Flex一點關係都沒有的。
運行起來你應該會看到一個像這的球:
現在我們要讓球動起來。記得我之前說的嗎?PV3D主要是以幀為單位來控制變化,所以我們需要一個方法可以控制到每一幀。AS3中我們只要註冊一個 Event.ENTER_FRAME事件的監聽程序就可以監聽到每一幀開始的時刻。然後,我們可以在我們的監聽函數裡,做我們需要做的,比如計算,或著讓 顯示對象移動旋轉等。
而PV3D要求每次舞台發生變化時都要顯式的調用舞台對象的renderCamera,重新繪製,否則內容始終是不重繪的。
下面是我們的新代碼,注意加了一句調用addEventListener的代碼,和一個OnEnterFrame函數。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | package { import flash.display.Sprite; import org.papervision3d.scenes.MovieScene3D; import org.papervision3d.cameras.Camera3D; import org.papervision3d.core.proto.MaterialObject3D; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.objects.Sphere; import flash.events.Event; public class Main extends Sprite { private var _container :Sprite; private var _scene :MovieScene3D; private var _camera :Camera3D; private var _material:MaterialObject3D; private var _displayObj:DisplayObject3D; public function Main() { // 創建3D舞台的容器 _container = new Sprite(); _container.x = 100; _container.y = 100; //將它顯示出來 addChild( _container ); // 創建3D舞台 _scene = new MovieScene3D( _container ); // 創建攝像頭 _camera = new Camera3D(); _camera.z = -500; _camera.zoom = 5; //黑色的線框材質 _material = new WireframeMaterial(0x000000); //弄個球玩玩 _displayObj = new Sphere(_material, 80, 10, 10); //把顯示對象添加到舞台 _scene.addChild(_displayObj); //把攝像頭看到的顯示出來 _scene.renderCamera(_camera); this.addEventListener(Event.ENTER_FRAME, OnEnterFrame); } private function OnEnterFrame(event:Event):void{ //以Y軸為軸旋轉 _displayObj.rotationY += 5; _scene.renderCamera(_camera); } } } |
現在你就能看到球轉啊轉的樣子:
花了很大篇幅重新複習了一遍PV3D程序的基礎結構….現在可以開始講講基本的材質貼圖了。其實我們上面的程序就已用到了線框材質貼圖。除了線框材質 外,PV3D還支持顏色材質,位圖材質等,所有這些材質貼圖的類都在org.papervision3d.materials包裡。
我們給上面的程序換上一個黃色的材質貼圖看看會是什麼樣。只要把new WireframeMaterial(0×000000);改成new ColorMaterial(0xFFFF00);然後記得import org.papervision3d.materials.ColorMaterial;就OK了。
你的效果應該會和我的一樣:
再試試位圖文件材質,把new ColorMaterial(0xFFFF00);改成new BitmapFileMaterial(」texture.jpg」);這裡的」texture.jpg」是我的貼圖文件路徑,你需要根據你的需要設置, 記得這個路徑是url格式,不是文件系統路徑。
貼圖效果:
其他的貼圖我就不多說了,大家可以自己實驗看看。