使用Lua實做GUI系統的遊戲例項

2021-05-28 06:34:38 字數 4079 閱讀 2807

在這篇文章裡,將以國外乙個非常著名的休閒遊戲diner dash 2的例項,探討 lua 的應用功能之一:gui 系統。自前篇「scripting系統概論與lua簡介」對 lua 的what(是什麼)why(為什麼使用)有了初步的認識之後,接下來的重點就是了解 lua 的how(如何使用)

在進入 how 的主題之前,先補充一下where(在何處使用)的概念。lua 的能力十分強大,似乎無所不能,可以完成任何的任務與功能。但是就實際應用層面的考量來說,哪些功能與系統才是真正適合使用 lua 的部分呢?又要如何區分 c++ 語言與 lua 語言所能達成的任務呢?

以兩者擅長處理的事項來分類:

複雜的運算與低階的底層核心,適合使用 c++;而因應設計需求,經常會變動的各種功能系統,例如使用者介面、人工智慧、遊戲邏輯等等就適合使用 lua 來完成。另外,有安全性考量的功能層面,也應該使用 c++ 撰寫比較合適。

diner dash 2這款遊戲中的圖形化使用者介面,也就是常聽到的gui(或簡稱為ui)系統,都是以 lua 進行開發設計的。首先,需要了解一點基本的 gui 開發概念。在乙個完整的 gui 系統中,需要許多的基本元件,例如常見的按鈕 (button)、文字 (text)、圖片 (picture)、編輯輸入 (edit)、進度條 (progress bar) 等等,這些物件稱為介面元件 (ui widget);藉由這些基礎的元件,就能夠組合出遊戲中所使用的各種 ui。而將個別的元件集合起來形成乙個群組的容器,常稱做框架 (frame) 或圖層 (layer)。最後,在架構頂層做為上述這些 ui widget 的管理者,包含住一至多個 frame,負責高階功能與介面的元件,則稱做視窗 (window) 或是對話盒 (dialog)。

一般常見的 gui 系統實做方法,是在 c++ 中將各個元件封裝成 class,例如 ctext、cbutton、cpicture 等等,加上 cframe 與 cdialog 類別,分別負責各自的功能,然後再以這些類別建立出來的物件,組合成乙個乙個的完整介面。這樣的實做方法,在物件導向程式的領域中是很直覺的設計模式,但是也存在著不少缺點;像是每個元件都需要存在個別獨立的 class,而若要修改或新增元件的功能,即使只是很微小的部分,也必須在 c++ 中撰寫完畢後,重新建置整個程式專案完成後才能夠使用。另外,在處理資料的讀取程式中,也會有相當瑣碎且重複性極高的修改步驟;只要更動了資料的讀取順序或資料型態,同樣非得經過重新建置的程式不可。

lua,可以讓一切變得不同。以下,開始進入遊戲的例項說明:(閱讀以下內容,需具備基本的 lua 程式設計能力)

先來看一段使用 lua 製作 text 元件的簡短程式碼:

view plain

copy to clipboard

print?

text  

;  

上述這段程式碼,即定義出乙個 text 文字項元件的種種規格;如註解所示,這個元件使用 dialogtitlefont 這個字型,在指定的位置處顯示出 gdialogtable.title 變數的內容。而 dialogtitlefont 這個字型,定義在其他的程式碼中:

view plain

copy to clipboard

print?

dialogtitlefont = ;  

standardfont = "fonts/mercurius.mvec"

; -- 字型使用的實體檔案

bordercolor = color(30, 42, 102, 255); -- 顏色

由以上的程式碼片段可以了解,ui 元件的建構,是利用 lua function 能夠接受 table 結構做為函式引數的強大特徵,將所需的引數傳入 function 中進行處理。如果是沒有特別指定的引數,就直接使用預設值去建立,能夠毫不費力地建構出 default parameters 的功能,使得 ui 元件的建構方式變得非常具有彈性與可擴充性。

再來看乙個製作 button 元件的例子:

view plain

copy to clipboard

print?

button  

;  standardbuttongraphics = ;  

在 standardbuttongraphics 這個 table 裡,定義了 button 在 normal、pushed、disabled 三個狀態下顯示的圖片。接下來的 type 變數,指定這個 button 的型態是一般常見的 push button 型別;其他還包括了 radio button 與 check button 型別。而 command 變數,是使用者按下 button 時所需執行的程式,也就是去呼叫 popmodal() 這個函式。除了一般按下 button 所觸發的執行程式之外,也能夠很輕易地實做出滑鼠進入 button 範圍的 function,或是 button 切換至其他狀態下所應該觸發的 function。其他的各種元件也以同樣的方法製作,就能夠迅速而便利地建立起一組 ui 元件與完整的使用者介面。

依照以上 standardfont、standardbuttongraphics 與 bordercolor 變數的定義方法,可以將所有 ui 相關的格式設定,以及與實體檔案相關的變數,全部定義在另外的 lua 檔案中,便於集中管理、修改與使用。其中的程式碼片段如下:

view plain

copy to clipboard

print?

-- file: style.lua

-- 字型的實體檔案

standardfont = "fonts/mercurius.mvec"

;  -- 定義各種顏色

blackcolor = color(0, 0, 0, 255);  

bluecolor = color(16, 225, 226, 255);  

yellowcolor = color(255, 255, 0, 255);  

-- 標準按鈕用的圖片

standardbuttongraphics = ;  

-- 小型按鈕用的圖片

smallbuttongraphics = ;  

-- 大型按鈕用的圖片

largebuttongraphics = ;  

最後,以遊戲中的乙個 lua 檔案為例,列出建構起乙個 dialog 所需的完整程式碼:

view plain

copy to clipboard

print?

-- file: ok.lua

require( "scripts/style.lua"

);  

makedialog  

,  text  

;  text  

;  },  

}  

以上這段 lua 程式碼,製作出由乙個 bitmap、乙個 button 以及兩個 text 元件所組成的 dialog 介面。撰寫完成後,在遊戲中看到這個 dialog 所呈現出來的結構,如圖所示:

以上文章所提的內容,其實只佔了整個 gui 系統其中一半的部分:資料描述。也就是將 lua 當成一種data description language,用來儲存與讀取遊戲所需的資料。藉由 lua 的強大威力,能夠讓開發者輕易地進行各種資料寫入與讀取的動作,完全不必費力撰寫繁複瑣碎的 parse 或 serialize 程式。

資料處理的部分是一半,而另一半是與功能相關的部分,也就是真正在內部進行gui 相關行為處理的程式。將資料傳入 text()、button()、picture() 這些函式中之後,裡面到底做了些什麼?如何建構 gui 系統的資料結構?如何和原來的 c++ 端主程式相結合?如何傳遞滑鼠與鍵盤的輸入訊息?如何真正畫出這些 ui?

下篇待續。

遊戲中使用LUA指令碼語言的簡介

我們知道指令碼語言是解除硬編碼,防止重編譯的利器,可以這樣說,任何大型遊戲都有自己的指令碼系統。想要做出一款精品遊戲,指令碼語言也是我們需要掌握和運用的。較流行的指令碼語言有python,lua,ruby等。lua有著輕量,高效,介面乾淨等特點,學起來很快,風靡全球的 魔獸爭霸3 冰封王座 就是採用...

遊戲中使用LUA指令碼語言的簡介

我們知道指令碼語言是解除硬編碼,防止重編譯的利器,可以這樣說,任何大型遊戲都有自己的指令碼系統。想要做出一款精品遊戲,指令碼語言也是我們需要掌握和運用的。較流行的指令碼語言有python,lua,ruby等。lua有著輕量,高效,介面乾淨等特點,學起來很快,風靡全球的 魔獸爭霸3 冰封王座 就是採用...

使用cocos2dx的lua指令碼寫遊戲邏輯

原文 luascript conf lua global lua include lua logic hxgameboardlogic lua hxgameicon lua hxgamescene lua hxmainmenuscene lua logic lua main lua util aud...