在這篇文章裡,將以國外乙個非常著名的休閒遊戲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...