綁定帳號登入

Android 台灣中文網

打印 上一主題 下一主題

[教程] Flash 3D -- 使用 Papervision 3D (PV3D)

[複製連結] 查看: 2644|回覆: 0|好評: 0
跳轉到指定樓層
樓主
timlin1 | 收聽TA | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
發表於 2020-8-4 09:53

馬上加入Android 台灣中文網,立即免費下載應用遊戲。

您需要 登錄 才可以下載或查看,沒有帳號?註冊

x
Flash 3D -- 使用 Papervision 3D (PV3D)

首先,要先說明的是,Flash Player 中,並沒有 3D engine,所以要做到 3D 效果的效能與功能上,並不像 3D MAX 或 Maya 那些專業的 3D 軟體一樣。Flash 的 3D 是透過一些好心人士以 ActionScript 語言,自行開發一些 3D 的 Library 給其他開發者使用,所以不同人開發的 Library 都有其各自的 3D 概念,想要使用 Flash 3D 的人就必須選擇一套 Library 並學習其開發觀念與使用方法。近期比較常聽到有人使用的 Flash 3D Library / Engine 有 Papervision 3D (PV3D) 與 Sandy 3D,以下我將以 PV3D 做介紹。

預備知識

1.讀者一定要具備有物件導向程式(OOP)的開發經驗,因為好心人士都是以 OOP 的方式來開發各自的 Library,所以想要使用的話,至少開發者要知道如何在 Flash / Flex 中使用別人寫好的 *.as 與類別。

2.不同的 3D Library 可能是以不同版本的 ActionScript 所開發而成的,以 PV3D 來說,也有區分 ActionScript 2 與 ActionScript 3,若是開發者要使用 ActionScript 3 的版本,就必須對該版本的 ActionScript 語法有基本認識,因應不同版本的 ActionScript,也就必須使用不同版本的開發工具才行,譬如 AS3 就至少要使用 Flash 9 或 Flex 2 / 3 以上的開發工具才行。

3.對 (Sub)Version Control 版本控制軟體有基礎的認識,因為大部分的 Library 都仍在開發階段,不斷改版的過程中,Library 的版本號碼不斷在改變,Library 的開發者也大都有使用版本控制軟體來管理自己的產品,所以想要使用這些 Library 的開發者大多需要使用相關的工具來取得最新版本的 Library 開放原始碼,作者本身比較慣用 TortoiseSVN (http://tortoisesvn.net/) 來做檔案下載的工作,若讀者有需要的話 TortoiseSVN 也提供了版本控管的 Server 程式,可用來管理自己的專案。

取得資源

1.Adobe Flex Builder 3 Public Beta 3,因為作者將使用 PV3D 的 AS3 的版本來開發,所以需要使用 Flash 9 或 Flex 2 / 3 以上的工具,手邊沒有這些工具的讀者可以上 Adobe Labs 網站取得 90 天試用版,到以下網址可以取得:http://labs.adobe.com/technologies/flex/flexbuilder3/

2.PV3D 的 Library 可以透過 TortoiseSVN 從 Google Code 下載最新版本,URL 為 http://papervision3d.googlecode.com/svn/trunk/,作者寫此文章時的最新版本為 392 版。若是對於 SVN 的方式不熟悉的讀者也可直接到 Google Code 下載已經打包好的 *.zip 檔,網址為:http://code.google.com/p/papervision3d/,此刻可下載到的版本為 1.5 版,可能會有讀者對此版本有些疑問,這跟 SVN 上的版本號碼看似使用不同的編號原則,我們可將 1.5 版的 *.zip 解開後,檢視 srcorgpapervision3dPapervision3D.as 的檔案內容可以發現以下這段敘述:

/**
* Enables version to be retrieved at runtime or when reviewing a decompiled swf.
*/
static public var VERSION :String = "Beta RC1.1";

/**
* Enables version date to be retrieved at runtime or when reviewing a decompiled swf.
*/
static public var DATE :String = "18.06.07";

若是從 SVN 取得的 392 版,則可在 as3        runksrcorgpapervision3dPapervision3D.as 看到以下這段敘述:

/**
* Enables version to be retrieved at runtime or when reviewing a decompiled swf.
*/
static public var VERSION :String = "Beta 1.7";

/**
* Enables version date to be retrieved at runtime or when reviewing a decompiled swf.
*/
static public var DATE :String = "20.08.07";

先不論其版號的命名原則是否有正確的在執行,以上也只是幫助讀者做一個參考罷了,最重要的是開發者必須了解 PV3D 仍是個正在開發中的專案,所以若是自己在研究開發的過程中遇到任何問題的話,在討論區詢問討教時,一定要把使用的 PV3D 版本也考慮進來,或許在其他版本的 Library 上就不會有相同的問題,這樣一來就看是要等 PV3D 的開發者自己改好,還是讀者要佛心一點幫它改。

使用PV3D的範例

PV3D 提供了許多範例,可以在 as3        runkexamples 資料夾中找到 34 個範例資料夾,若是採用 AS2 的版本的話,則在 as2        runkexamples 資料夾中也有 5 個範例,相對 AS3 來說範例數較少。以 AS3 版本的範例來說,若是在範例資料夾中看到 *.fla 檔案的話,那就表示此範例需使用 Flash 9 來開啟,若是在範例資料夾中沒有 *.fla,取而代之的是 src 資料夾的話,那就表示這個範例是以 Flex 所開發的,進而依據 src 資料夾中是否有 *.mxml 來得知是 Flex 的哪種專案型態。

以下,作者將以 Flex Builder 3 使用 as3        runkexamplesAS3OnlyFocus 範例做說明:

1.在 Flex Builder 3 中,建立一個 ActionScript Project,project name 可以任意決定,假設取作 "AS3OnlyFocus",然後 Main source folder 可自行新增一個 src 資料夾來使用,並且需要額外將 PV3D Library 的原始檔加到 Additional source folders,譬如作者是將 D:PV3D@GoogleCodeas3        runksrc 加入,這樣一來才能運用到 PV3D Library 中的類別,然後便可完成建立新專案的動作。


                               
登錄/註冊後可看大圖


2.在新建立的專案中,在 src 資料夾上點選滑鼠右鍵,透過 Import 功能,可選擇 General > File System,然後從 PV3D 的 AS3OnlyFocus 範例資料夾中便可匯入該範例原始檔,譬如作者是匯入 D:PV3D@GoogleCodeas3        runkexamplesAS3OnlyFocussrc 到此新專案的 src 資料夾下。

3.匯入完成後,在 src 資料夾下除了原本空空不做事情的 AS3OnlyFocus.as 之外,還有剛匯入的 main.as,我們可以將 main.as 設定為執行時的主程式,Set as Default Application,如下圖所示。


                               
登錄/註冊後可看大圖


4.執行 main.as 後,Flex Builder 會新開一個瀏覽器來執行編譯後放在 C:Documents and Settings{登入帳號}My DocumentsFlex Builder 3AS3OnlyFocusin-debug 資料夾下的 main.html,執行結果如下圖所示,讀者可以使用 W, A, S, D 來控制車輛的前後左右移動,並可移動滑鼠決定 Camera 的角度。


                               
登錄/註冊後可看大圖



研究原始碼

1.回到原始碼來看,從 main.as 看起,在main.as 中,它 import 了 org.papervision3d.examples.FocusApp,並且在 main() 中最關鍵的事情就是建立了一個 FocusApp 類別的物件 focusApp,並將一個新的 Sprite 類別的物件 paperCanvas 當作參數代入。這裡的語義是要提供一個 Sprite ( 不熟悉 Sprite 的讀者可以想像是一個 MovieClip ) 給 FocusApp 類別,作為日後開始繪製 3D 元素 ( DisplayObject3D 類別 ) 的 Container,所有的 3D 元素與 Camera ( Camera 其實也是一種 3D 元素,其繼承關係為 DisplayObject3D > CameraObject3D > Camera ) 都是繪製在這個 Sprite 中。

2.因此大部分的程式都是寫在 FocusApp 類別中,不熟悉如何在 Flex Builder ( 或 Eclipse 開發平台 ) 中快速找到其他類別原始檔的讀者,可以在 C:Documents and Settings{登入帳號}My DocumentsFlex Builder 3AS3OnlyFocussrcorgpapervision3dexamples 找到 FocusApp.as 這個檔案。

以下是程式碼的閱讀順序:

38列,建構子 FocusApp() 會將代入的唯一參數,也就是 Sprite 類別的物件,儲存起來日後備用。然後進行 init() 初始化的工作。

47~49列,設定 Stage 的 Event.ENTER_FRAME、KeyboardEvent.KEY_DOWN、KeyboardEvent.KEY_UP 事件處理函式,onEnterFrame 函式將會不斷更新畫面來重新計算 3D 物件彼此的關係,並且依照不同的角度來處理貼圖效果,keyDownHandler 與 keyUpHandler 則是監聽 W, A, S, D 按鍵事件,並改變幾個變數值,用以決定後續在重繪時的動畫該如何呈現。

51列,進入 setupScene() 進行一些基礎設定。

56列,將之前儲存的 Sprite 當作參數,建立一個 Scene3D 類別的物件 scene,表示 PV3D 將會以此 Sprite 當作 Container 來繪製內容。

59~63列,建立一個 Camera3D 類別的 camera 物件,並設定他在 3D 空間中的 x, y, z 座標值,以及給予一些基本屬性來影響畫面縮放時所呈現的大小倍數比例。這裡可以先注意一點,此刻建立的 Camera3D 尚未與方才所建立的 Scene3D 做結合,所以 Scene3D 內的 3D 物件此刻仍不知要從何種角度來呈現。

66列,在 Scene3D 中,可以透過 addChild() 新增 DisplayObject3D 到此容器中 (Scene3D 繼承自 DisplayObjectContainer3D,可容納多個 DisplayObject3D ),並以 "rootNode" 命名之。PV3D 現在有提供的一些繼承自 DisplayObject3D 的類別都放在 D:PV3D@GoogleCodeas3        runksrcorgpapervision3dobjects 下,包含一些常用的矩形、圓柱、球體,甚至是紙飛機,還有一個最棒的 Collada 類別。關於 Collada 的相關說明可以自行上 google 或是 wikipedia (http://en.wikipedia.org/wiki/COLLADA) 查看,簡單來說就是將 3D 模型以一種 XML 資料的方式來呈現,這種叫做 Collada 的 XML 中包含了 3D 模型的點線面資料,還有像是貼圖是用哪種顏色或外部圖檔都有定義。而 PV3D 中的 Collada 類別便是用來解析這份 XML 資料並轉換成可被 Flash ActionScript 操控的 PV3D 的 DisplayObject3D 物件。Collada 類別的建構子需要一個參數,可提供 *.dae 檔案位置當作參數,而此 *.dae 的 XML 檔案,便是由其他 3D 建模軟體所匯出而成。

若有興趣,讀者可自行將汽車開到 camera 前面,便可發現這個汽車的 3D 模型,都是 "面" 所構成,並且只有貼外層的圖,請參考下圖畫面中,底盤與車子內部是沒有貼圖的,這方面是開發者的實際需求而定,不過想當然貼圖越少、節點越少、型狀結構越不複雜的話,PV3D 運算的速度也就越快囉。


                               
登錄/註冊後可看大圖



70列,在剛剛所建立的 scene 下的 rootNode 下,再加入一個新的 DisplayObject3D,這次加入的是 Plane 類別的 DisplayObject3D,目的是希望製作一個地面的效果,這樣一來等下車子在移動時,才能看出與地面的互動感覺,才能感覺車子有在動,不然車子在黑漆漆的空間中移動,沒有背景的相對搭配的話,是看不出移動的效果的。Plane 類別的建構子需要提供貼圖用的素材,這裡僅使用了純色 ( ColorMaterial 類別 ) 的貼圖效果,PV3D 提供了多種貼圖材質,可在 D:PV3D@GoogleCodeas3        runksrcorgpapervision3dmaterials 資料夾中找到,諸如外部圖檔、MovieClip、影片、BitmapData都可以被當成是貼圖的素材,也可選用 InteractiveXXXXXX 開頭的類別來製作具有使用者互動的貼圖材質。

73~74列,因為新加入的 Plane 類別所產生的 [ 面 ] 物件,在 3D 空間中預設的擺放角度,並不如我們所希望的與地面平行,所以要對此 DisplayObject3D 的三軸做一些 rotation,以及改變其座標位置。到此,一個 PV3D 的基本空間設定就差不多成型了。

3.接著,我們來看到剛剛事先定義好的三個事件傾聽函式,keyDownHandler 與 keyUpHandler 不用特別說明,在此僅看 onEnterFrame 中是如何不斷重繪畫面的部份。

79~80列,依照 Sprite 中的 mouseX, mouseY 滑鼠座標,來決定 camera 物件的 z, y 座標,在三度空間中,x 是左右,y 是上下,z 是裡外,不過我這裡形容的上下左右並不是絕對感覺,這只是當 camera 的鏡頭是面對三度空間的原點座標 (0, 0, 0) 的時候才是這種感覺,若是鏡頭不是對著圓點,而是對著空間中的其他位置的話,那麼被看到的 DisplayObject3D 的 x, y, z 座標位移就有可能不見得給讀者一種 "你以為" 的方向移動。總之,開發者腦袋中要有一個假想的三度空間,並且知道每個 DisplayObject3D 包括 Camera 的 "座標位置" 與 "本體的旋轉角度" 與 "面向的角度" 等等。

83列,在 DisplayObjectContainer3D 類別中可以透過 getChildByName() 取得指定名稱的 DisplayObject3D,rootNode 是被加到 scene 中的一個 Collada 類別物件,Collada 的繼承關係是 DisplayObjectContainer3D > DisplayObject3D > Collada,也就是說每個 DisplayObject3D 都是 DisplayObjectContainer3D,都可以透過 addChild() 新增 DisplayObject3D 到自己這個容器中,也都可以透過 getChildByName() 取得已經加入的 DisplayObject3D。

86列,若是找不到指定名稱的 DisplayObject3D 的話,則回傳結果將會是null。

88~95列,找到當作地面的 DisplayObject3D,DisplayObject3D 可以透過 hitTestObject() 來判斷自己是否與另一個 DisplayObject3D 有接觸。若是汽車與地面有接觸到的話,則會將地面 plane 這個 DisplayObject3D 的 material 屬性所代表的材質,改變其 fillColor 屬性進行填色的動作。

98列,進入 driveCar(),136~175列,針對先前按鈕事件所改變的變數值,來計算出汽車要移動時所需的一些速度數據。

101列,進入 updateCar(),111~127列,取得汽車的前後輪胎,根據速度決定輪胎的旋轉效果,特別要注意的是,因為前輪才會根據左右方向作左右旋轉,所以在 3D 模型的結構上也比後輪多了一層。129~133列,可以依照方向與速度來改變整部汽車的本體旋轉角度,以及針對面向的角度所前進的距離。

105列,在這之前,Scene3D 與 Camera3D 仍無任何結合,以上所做的任何 DisplayObject3D 的座標或旋轉角度的改變,都僅是改變其基本屬性,但是對於讀者會如何看到這個 Flash 所呈現出來的效果,仍要等到 Camera3D 是從何種位置與角度去拍攝出此 Scene3D 三度空間而定,SceneObject3D 類別可透過 renderCamera() 接受用某個 CameraObject3D 類別的物件,來計算出在這個 Scene3D 空間中所有 DisplayObject3D 所要呈現的位置、角度、以致於要貼哪一面的材質。所以直到這時,scene 的內容才會以 camera 的視角來表現在 pv3dSprite 這個 Sprite 上。


[結語]

使用 PV3D 的基本觀念就是,提供一個 Sprite / MovieClip 給 PV3D 引擎作繪圖之用,在 PV3D 的程式中,就是看如何將調整與組合 Scene3D 中的各種 DisplayObject3D 類別物件,並且依照使用者互動來調整各物件的座標、旋轉角度、面向角度,因為 Camera3D 也是繼承自 DisplayObject3D,所以調整其角度與座標的方法也都一樣,最後就是在 3D 資料異動後記得重新讓 Scene3D 的內容透過 Camera3D 的視角來呈現到 Sprite 上即可。

有了基本 PV3D 的架構與觀念後,即使讀者希望使用 Flash 9 搭配 PV3D 的 AS3 版本,或是以 Flash 8 搭配 PV3D 的 AS2 版本,都是可以的。想當然使用 AS3 會因為 Flash Player 中的 AVM 版本的關係,本質上就會比使用 AS2 的版本在效能上要來得好一些,加上未來 Adobe 將會在 Flash Player 中強化甚至加入這方面的增強功能,所以建議讀者可以從 AS3 切入會比較好,但若是僅想要在舊有的技術或軟體環境下使用 PV3D 的話,當然也都是可以的,只不過若是不幸遇上某些只有 AS2 版本才有的問題時,可能在網路上討論就比較難得到共鳴了 (不是故意嚇大家!)。

覺得在入口網站看到的廣告動畫已經很無趣了嗎?覺得空有一些 3D 的創意但是技術上又覺得 Flash 好像做不到嗎?那就趕緊請你們家的美術與程式設計師聯手打造一個 Papervision 3D 的應用吧!

[關於作者]

邦邦,通過 Flash MX 2004 Developer 認證、Flash MX 2004 Developer 認證講師、Flash Lite 1.1 認證講師等,現服務於 Qisda 佳世達科技。



「用Android 就來APK.TW」,快來加入粉絲吧!
Android 台灣中文網(APK.TW)

評分

參與人數 1碎鑽 +1 幫助 +1 收起 理由
jia4568tw + 1 + 1 非常讃

查看全部評分

收藏收藏1 分享分享 分享專題
用Android 就來Android 台灣中文網(https://apk.tw)
回覆

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則