第五章 核心製作
5.6 人物動作
圖 5.11 初期完成核心之測試畫面 圖 5.12 中期完成核心之測試畫面 cApplication 其實就是簡單的秀出一個執行視窗(一個基本的 WinMain 程式);接著在 Game_Graphics.cpp 裡頭加入 cGraphics 的功能,初始 化 Direct3D 並產生可控制環繞的 3D 場景,如圖 5.11(若沒有先備好 cInput,使用者控制的部分可以先用視窗訊息程序(PeekMessage)的功 能來觸發),只用一些簡單的幾何圖形測試。再來更進一步的擴大 Game_Graphics.cpp 的功能,增設 cVertex、cTexture、cBillboard、
cSkyBox 等類別,完成如圖 5.12 的測試。最後才去考慮 Game_Show 與 Game_Sound 兩個核心。關於 Game_Show 撥放的方法與程式碼說明,在 DirectX SDK 裡面的範例可說是相當完整,讀者可參考之,另外,裡頭 也有可以用 DirectShow 撥放.mp3 音樂檔案格式的範例;Game_Sound 撥放音樂的部分我建議先做好能撥放.WAV 檔即可,之後再擴充其他效
入.x 檔並控制其骨架,再用一類別 cObject 來繪製出.x 檔的網格 (Mesh),然後用 cAnimation 控制此.x 檔的骨架變動,以產生人物動作 效果。
建立一個 cCharacterController 類別,用以控制人物該做哪一個 動作,另外產生 sCharacter 結構,用以紀錄人物的一些數值以及狀態,
如圖 5.13 所示,裡頭包含著人物角色的定義(Def)、位置、型態(Type,
分成 PC、NPC、MONSTER)、血量(HealthPoints)、墨魂值(魔法值,
ManaPoints)、指定動作…等,其中定義(Def)是利用一個結構來實作,
裡頭包含角色的攻擊力、防禦力、速度…等,如圖 5.14,這樣使用者 可利用相同的角色定義(MCL,Modify Character Lib),產生不同的角 色實體(instance)。大部分的人物狀態定義還是借用於「2D/3D RPG 角色扮演遊戲」這本書的內容,同時這本書也附上一個角色定義編輯 器,方便編輯角色產生.mcl 檔(等到遊戲中要產生角色時讀取),如圖 5.15。一但角色定義、角色動作(如圖 5.16 中陣列所示,Idle、Walk 等名稱,必須與產生的.x 檔裡頭的動畫名稱相對應)載入之後,就可以 用 cCharacterController 從遊戲中加入人物,刪除人物,或是變更某 個人物的某一個數值,一但改變人物的一些數值,等到主程式呼叫 cCharacterController 的 Update 函式,就會產生相對應的效果,看是 要呼叫 cObject,繪製出人物的網格(Mesh),還是要減少血量表的顯 示、使人物無法移動,或是執行.x 檔中已定義的某一個動作…等。
圖 5.13 sCharacter 角色狀態結構
圖 5.14 sCharacterDefinition 角色定義結構
圖 5.15 MCL 編輯器(取自「2D/3D RPG 角色扮演遊戲」所附光碟)
圖 5.16 利用陣列儲存.x 檔中的動作名稱
另外,關於 3D 人物、場景或是物品之間的碰撞偵測,主要分成兩 種,一種是利用投射光線(線段,有限的長度)與平面(無限的二維空間) 的相交情形來決定,如圖 5.17。若有一個會移動的網格,要偵測是否 與另一個網格(移動或非移動皆可)有接觸,可以利用此移動網格的移 動方向與距離作為偵測用的投射光線,看交於另一網格的所有平面上 的交點,與移動網格的終點之間的長度,是否大於移動網格所要移動 的起始點至終點的長度,若大於則偵測出有發生碰撞,此種方法多用 於人物與場景之間的碰撞。另一種方法是上一種方法的延伸,是利用 網格資料中所紀錄的網格範圍的半徑做判定,若移動網格的位置座 標,與其投射光線交於另一網格的交點,之間的距離小於兩個網格的 半徑相加,則有發生碰撞,如圖 5.18(一個網格的範圍是一個球型)。
詳細碰撞偵測內容請參考「2D/3D RPG 角色扮演遊戲」590 頁~598 頁。
圖 5.17 投射光線與網格相交之偵測碰撞
圖 5.18 網格與網格之間的兩球形範圍之偵測碰撞
除了玩家(PC)所控制的角色以外,非玩家(NPC,包括村民、商店老 闆等)與怪物(MONSTER)的AI控制,也是探討的重點之一。NPC與MONSTER 的AI主要分成站立不動(STAND)、漫無目的遊走(WANDER)、特定路線移 動(ROUTE)、跟蹤角色(FOLLOW)、躲避角色(EVADE)等,待我一一說明。
站立不動最簡單,指定角色顯示畫面的動作為Idle(閒置動作),並且 網格座標不做任何改變;漫無目的遊走可以指定一個區域,或是不指 定也可以,然後對其x、z(在遊戲中y座標是朝向天空的,x、z代表場 景的地板平面)做亂數取數,設定顯示Walk(行走)或是Idle的動作;特 定路線移動使用設定點(RoutePoint)的方式,利用一個sRoutePoint結 構紀錄一個點的座標,然後要移動到那點的網格,在依據其座標與設 定點的距離關係,做每次呼叫Update的朝設定點座標移動Speed(角色 定義中的一個屬性-移動速度)距離,直到其座標與設定點相同為止,
且每次可設定的點不只一個;跟蹤角色則是依據TargetChar,
TargetChar會在此角色使用跟蹤角色的AI時順便設定好,然後跟蹤角 色就會在每次呼叫Update函式時,朝TargetChar方向移動些微座標;
躲避角色則是與跟蹤角色的方法相反。AI還可以更深入的研究與實 作,但不在此專題討論範圍,讀者可前往
http://www.gameres.com/Articles/articles.asp?style=f 這個網 站一窺究竟。關於人物控制的詳細作法若還有不清楚,請參考「2D/3D RPG角色扮演遊戲」706 頁~822 頁。