現實中的遊戲開發常常面臨兩種互相矛盾的壓力,一方面需要測試和驗證新想法,另一方面又需要快速開發並且按時交付。把指令碼語言整合到遊戲項目中可以提升團隊的開發效率,並且可以很好地擴充原生編譯語言的能力。Lua在遊戲開發的許多基礎領域中都表現得很出色。
在遊戲Team Dev中,可能有許多成員都使用Lua來完成他們的工作。程式員負責將Lua整合到遊戲開發環境中,通常,他們會需要編寫一些Lua代碼。遊戲設計師是指令碼語言的主要使用者,因為他們和上層的遊戲設計和資料直接打交道。美術師也會經常使用Lua,進行諸如介面布局、設計和3D情境中各種模型的擺放之類的工作。
Lua是非常強大的工具,可以用來完成下面這些工作:
- 編輯遊戲的使用者介面
- 定義、儲存和管理基礎遊戲資料
- 管理即時遊戲事件
- 建立和維護開發人員友好的遊戲儲存和載入系統
- 編寫遊戲的人工智慧系統
- 建立功能原型,可以之後用高效能語言移植
1 遊戲介面
遊戲介面是玩家和你的遊戲進行互動的媒介。遊戲介面是一個遊戲最基本的部分,因為它負責所有和玩家的互動工作。因為它的重要性,所以需要能夠高品質、高效能地運行,並且能夠被測試和持續改善,以最大化地提升使用者體驗。
Lua可以讓介面設計師迅速建立所有主要的介面元素——進行介面布局、系統管理使用者輸入並且輸出遊戲資料。利用遊戲程式員開發的一部分核心的介面控制項和控制函數,介面設計師不僅能負責介面的美術觀感還能控制遊戲的互動。這不僅節省了程式員的時間,而且給了美術設計師更大的創作空間,同時還能為介面設計的測試節省出許多時間。代碼清單3.2展示了使用Lua建立文本GUI控制項的方法。
代碼清單3.2 使用Lua建立文本GUI控制項
2 管理遊戲資料
管理遊戲資料對於遊戲開發人員一直都是一種挑戰。遊戲資料定義了遊戲世界中所有對象的參數和特性,如脈衝槍升級費用、氣墊船的行駛速度等。對於資料密集型遊戲來說,開發人員常常利用試算表工具來輸入和儲存資料,然後建立解析工具將其轉換成遊戲中可以使用的格式。這種方法一般用在資料密集型遊戲中,如角色扮演類遊戲(NPC或者非遊戲玩家角色的資訊以表格結構形式儲存)或者策略類遊戲(角色單位資訊儲存在資料表中)。
Lua可以讓這個儲存系統更為簡單,它以Lua檔案作為儲存介質讓程式使用相同的資料。通過建立一個簡單的資料管理系統,變數和類型可以定義在Lua中,然後可以很容易地讀取。因為不用關心整個資料處理過程,所以遊戲設計師可以按照需要修改、增加和縮減遊戲資料,而不需要程式員的協助。因為Lua文法的特性和在指令碼中添加註釋的能力,資料檔案是易讀的。如果需要轉換工具,也非常容易開發,把Lua資料輸出到Lua檔案,然後在運行時載入。
Lua本身並沒有可以直接存取外部資料庫的能力,但可以用C++開發訪問資料庫的組件,然後再利用LuaGlue函數整合該組件來達到目的。
在代碼清單3.3中,我們可以看到如何使用Lua樣本檔案來直接儲存遊戲資料。在這個例子中,通過使用LuaGlue函數,向由核心代碼管理的資料結構中寫入資料。代碼清單3.3的輸出可參照圖3.1。
代碼清單3.3 使用Lua儲存美國總統選舉類比遊戲(《Frontrunner》)的資料
圖3.1 遊戲《Frontrunner》的,Lua資料的即時顯示
3 事件處理
通常,遊戲中的絕大部分重要的處理都是由事件驅動的,要麼是來自遊戲角色,要麼是來自遊戲中那些互動的代理。這些事件可以是簡單的,如使用者按下了<W>鍵,也可以是複雜的,如兩個遊戲實體同時來到了某個地方。
事件驅動的編程,對於熟悉了Windows開發(事件是Windows GUI操作的基礎)的使用者來說不是什麼陌生的技術。在C++精心開發的事件系統中,使用Lua來接收和處理這些事件,使用者可以在遊戲內部運行機制、進階Lua函數和使用者輸入之間建立清晰的反饋流程。一個簡單的例子是,擷取鍵盤輸入然後向Lua事件處理器發送該事件,同時將該輸入值顯示出來。這個概念將一直貫穿於本書之中——事件會返回事件類型ID和驅動事件的物體ID,參照代碼清單3.4。
代碼清單3.4 擷取按鍵事件的例子
4 儲存和讀取遊戲狀態
儲存和讀取玩家的資料是遊戲開發項目中最具有挑戰的事情之一。因為玩家有時需要暫時離開遊戲,所以需要一種儲存遊戲進度的方法。玩家還需要在某種新的嘗試和挑戰前儲存遊戲狀態,這樣萬一嘗試失敗了還可以恢複遊戲進度。同樣,在開發與測試過程中,開發人員會經常需要讀取特定的遊戲狀態來驗證遊戲功能或者確認bug是否已修複。
如果使用Lua儲存使用者的核心遊戲資料,就可以用Lua作為儲存和讀取當前遊戲狀態的系統。在Lua中,遊戲進度檔案是簡單的可執行檔Lua代碼的文字檔。程式員或者設計師可以通過進度檔案來擷取當前遊戲的狀態(也可以修改),讀取遊戲進度就和執行Lua指令碼一樣簡單。利用Lua標準的輸入/輸出函數,編寫一個函數來儲存遊戲資料到可執行檔Lua指令碼中是最直接的方法。這個系統的優點是可以讓設計師在開發過程中,根據遊戲資料的增長和刪減來編輯並修改這個函數(不需要特別的讀取函數)。在開發的最後階段,還可以利用指令碼編譯函數來為遊戲資料加密。
5 人工智慧
人工智慧(AI)在如今的遊戲中非常關鍵——玩家需要精明的、有挑戰性的對手,感覺就像真人一樣。遊戲開發人員明白真實世界的AI不是說完全模仿人如何玩和反應,而是為玩家創造這種感覺。多年來,開發人員一直在爭論電腦對手“作弊”(電腦對手可以比玩家訪問更多的遊戲資料)的優缺點。這種爭論最好用在別的時間和地方。不過,幾乎所有的開發人員都同意,比起AI類比,AI行為的玩家感知更為重要。
就開發AI判定來說,Lua是一種非常高效的工具。有許多人工智慧組件,如路徑尋找,最好留給底層語言來實現。路徑尋找(電腦控制的物體在虛擬世界中的路徑尋找)是一個資料運算量很大的工作,電腦需要反覆測試可能的路徑來尋找最短或者最直接的路徑。(路徑尋找最好整合到上層的LuaGlue函數中以便控制相關參數,但還是會在後面的章節中介紹一種Lua的實現。)另一個例子是用最大最小值方法實現的移動判定,一般被用在電腦象棋遊戲中,預測之後幾步的移動並嘗試計算出最優的移動步驟。一般來說,“能思考的函數”都需要大量的數學計算,如導航樹或者嘗試錯誤法運算最好都留給底層代碼。依賴有限的資料集合和參數的人工智慧才更適合Lua的特點。Lua的優點是設計師可以編寫簡單的模型來試錯,並快速驗證和迭代想法而不需要麻煩程式員。想要利用Lua高效率實現AI,需要很仔細地設計函數(C函數),讓Lua指令碼可以訪問和互動遊戲資料。使用Lua作為事件管理系統同樣可以讓AI設計師能應對遊戲開發中的變更,開發出靈活反應的AI系統。
在代碼清單3.5中,使用者可以看到使用Lua來評估可能的競選旅行目的地,評估的依據是這個州的選舉人票數量和這個州的支援率。
代碼清單3.5 評估虛擬美國總統候選人應該去哪個州的Lua人工智慧函數
6 快速構建原型
商業化的遊戲必須為玩家提供高效能的體驗,掉幀和處理延遲的現象在如今競爭激烈的市場中是絕不允許的。程式概要分析(Profiling)是行之有效確定效能瓶頸的方法,但必須在所有功能都開發完成並正確工作的前提下才能進行。原型開發和效能改善一般是不能同時進行的。
Lua是構建可移植的核心遊戲功能原型的不錯工具。因為Lua可以整合原生語言開發的組件,所以移植單獨的Lua函數到C++,對於其他Lua函數來說是不需要變更的。它可以讓設計師在構建原型時,如果碰到有高效能需求的函數就可以讓程式員用底層語言來實現。因為程式的演算法結構已經有了,所以C函數和LuaGlue調用都可以高效能、無縫地整合在項目中。
7 小結
在遊戲開發領域,Lua和C++是一個功能十分強大的組合。對於GUI開發、事件管理、資料儲存和擷取、遊戲進度儲存和載入以及人工智慧這些遊戲開發工作,需要能夠快速地構建原型、測試和迭代設計,而這些正是Lua所擅長的。在核心底層語言開發的項目中,頻繁的變更會導致系統的不穩定,並讓開發人員不能專註於更重要的開發工作單位。使用Lua環境分擔這些工作,可以讓設計師和程式員快速而安全地使用指令碼來設計、測試和實現遊戲功能。
-----------------------------------------------
本文節選自《Lua遊戲開發實踐指南》,原書名:Game Development with Lua,作者:Paul Schuytema & Mark Manyen,譯者:田劍。
本書是資深lua遊戲開發工程師10餘年工作經驗和智慧的結晶,lua語言創始人親自作序推薦,是lua遊戲開發領域最具實戰意義和代表性的著作之一。它不僅詳細講解了在遊戲開發中使用lua的各種技術細節、方法技巧和最佳實務,而且講解了如何使用lua作為主要工具將遊戲設計轉化為代碼實現的過程。此外,它還重點闡述了lua語言的核心要素。最重要的是,本書包含大量精心設計的案例,並附贈了完整的原始碼,可操作性極強。
豆瓣收藏:http://book.douban.com/subject/20392269/
PDF樣章下載:http://vdisk.weibo.com/s/ix8ok