現實中的游戲開發常常面臨兩種互相矛盾的壓力,一方面需要測試和驗證新想法,另一方面又需要快速開發並且按時交付。把腳本語言集成到游戲項目中可以提升團隊的開發效率,並且可以很好地擴展原生編譯語言的能力。Lua在游戲開發的許多基礎領域中都表現得很出色。
在游戲開發團隊中,可能有許多成員都使用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