第16節 - LibGDX: Scene2d和Graphical User Interface (GUI)
這一節我會介紹LibGDX的Scene2d用法。
Scene2d是一個場景圖(Scene Graph),而場景圖是一個資料結構(Data Structure),它把不同部分以圖表形式邏輯地表示出來。
場景圖其實是一個樹形結構,常見的圖形應用程式和資料庫(Library)都在使用這種結構,比如向量(Vector)編輯工具,3D資料庫,視頻遊戲等。
為甚麼要學LibGDX的Scene2d?
我只會簡單介紹場景圖的概念,因為我們不須要用到場景圖。但是Scene2d是一個場景圖,我們要學的是Scene2d的UI,所以對場景圖有基本概念就足夠。
LibGDX Scene2d內就有我們須要用的Graphical User Interface (GUI)或User Interface (UI),在UI內就有不同的介面元件(User Interface Component or UI Component)。
注意,我會把Graphical User Interface, User Interface, User Interface Component, UI Component, Graphical Control Element, Widget等等總一叫User Interface (UI)。
我在第1節 - 簡介介紹過一個簡單應用程式可包括一些TextView, EditText和Button等介面元件,但是我們要學的是LibGDX遊戲Apps,應該不須要用到介面元件! 這是不對的,因為在Scene2d內有四個特別的類別:
- Stage(舞台)
- Group(組)
- Actor(演員)
- Actions(演出)
它們除了用來寫應用程式外,還可以把不同的圖片做出不同的動畫,用來製作LibGDX的遊戲Apps。以下是LibGDX Scene2d官方的介面元件:
Scene2d主要介面元件的關係如下圖:
甚麼是Scene Graph?
Scene2d是一個場景圖(Scene Graph),而場景圖是一個資料結構(Data Structure),它把不同部分以圖表形式邏輯地表示出來。
場景圖其實是一個樹形結構,常見的圖形應用程式和資料庫(Library)都在使用這種結構,比如向量(Vector)編輯工具,3D 庫,視頻遊戲等。
英文解釋如下:
A scene graph is a general data structure commonly used by vector-based graphics editing applications and modern computer games, which arranges the logical and often (but not necessarily) spatial representation of a graphical scene.
場景圖不單把不同部分以圖表形式邏輯地表示出來,還以圖表形式把不同部分連接起來,它們的繼承(Inheritance)和移動(Translation/Move)關係就很容易表達出來。
以下是一個簡單例子,人體的上半身(Body)包括頭(Head),左手(Left Hand)和右手(Right Hand) (下半身不討論)。
- Body是父類,也叫原點(Root Node)。
- head是Body的子類。
- Left Upper Arm是Body的子類,也是Left Lower Arm的父類。
- Left Lower Arm是Left Upper Arm的子類,也是Left Hand的父類。
- Left Hand是Left Lower Arm的子類。
- Right Upper Arm是Body的子類,也是Right Lower Arm的父類。
- Right Lower Arm是Right Upper Arm的子類,也是Right Hand的父類。
- Right Hand是Right Lower Arm的子類。
- 以上關係就可以看出如果Body移動,所有它的子類(Head, Left Upper Arm, Left Lower Arm, Left Hand, Right Upper Arm, Right Lower Arm和Rigth Hand)都會跟隨移動。
- 但Left Upper Arm移動,所有它的子類(Left Lower Arm和Left Hand)都會跟隨移動,但其他不是它的子類(Head, Right Upper Arm, Right Lower Arm和Rigth Hand)就不會移動。
所以場景圖在設計動畫或遊戲時,就十分有用。例如如果你用程式軟件寫一個模擬房屋火警的動畫,如果程式軟件支援場景圖的資料結構,這場火災就可以做出真實的焚燒效果。
User Interface (UI)
這部分我會談談User Interface (UI),除了LibGDX Scene2d外,其實大部分程式語言都有自己的UI,例如我們要學的Java, Android和LibGDX。
在UI裡當然包含許多組件(Widget),以下先介紹Java的UI:
1 - Java UI
以下是Java UI的一些實物圖:
在上圖大家可以看到,Java的介面元件類別庫有AWT(Abstract Window Toolkit)和Swing兩種,其中AWT是早期的設計,而Swing則是基於AWT基礎所設計的新視窗元件。
AWT儲存在Java的java.awt package內,而Swing則儲存在Java的javax.swing package內。
雖然AWT和Swing的工能很相似,以下列出它們一些主要的分別:
Swing、AWT和JFC的關係:
AWT和Swing的Button比較:
2 - Android UI
以下是Android UI的簡化圖,每個ViewGroup內可包含不同的介面元件,也可包括另一個ViewGroup,不過View內就不能包含其他介面元件:
以下是Android UI的一些實物圖,大家可以在於Eclipse內找到:
3 - LigGDX (Scene2d UI)
以下是Scene2d UI的簡化圖,與會Android相似,每個Group內可包含不同的介面元件,也可包括另一個Group,不過Actor內就不能包含其他介面元件:
例子1 - 開埸畫面(Splash Screen)
最後,我會介紹LibGDX遊戲開埸畫面(Splash Screen),開埸畫面通常會把遊戲的標題,公司名稱等顯示出來。
以下我會把開埸畫面做出逐漸呈現的效果(Fade in),我們可以用剛剛介紹的Scene2d UI -Stage(舞台), Actor(演員), Image(圖像)和Actions(演出)類別。
Stage是一個舞台,在舞台內可以有不同的Actor,而Image也是Actor的一種。
另外,Scene2d UI內還有一個Actions類別,這個類別內就有不同的Actions方法,這些方法可以用來把開埸畫面做出逐漸呈現的效果,以下列出LibGDX官方的Actions方法:
- addAction()
- AddListener()
- alpha()
- color()
- delay()
- fadeIn()
- fadeOut()
- forever()
- hide()
- layout()
- moveby()
- moveTo()
- moveToAligned()
- parallel()
- removeAction()
- removeActor()
- removeListener()
- repeat()
- rotateby()
- rotateTo()
- run()
- scaleBy()
- scaleTo()
- sequence()
- show()
- sizeBy()
- timeScale()
- touchable()
- visible()
以下就是SplashScreen.java的程式碼和執行結果,我會在第17節 - LibGDX: Splash Screen詳細介紹:
- 用Texture產生一個Texture物件(例如:texture)然後把圖片(splashScreen.png)傳入。
- 用Image產生一個Image物件(例如:image)然後把texture物件傳入。
- 在show()方法內,把image加入Stage舞台內,再用Stage內還有一個addAction()方法把開埸畫面做出逐漸呈現的效果。
1-Actions.alpha(0)-設定alpha=0,則把image設定為全透明。
2-Actions.fadein(0.5f)-把image做出逐漸呈現的效果。
3-Actions.delay(2)-把動作延遲2秒。
4-Actions.run()-把現時splashScreen畫面跳到menuScreen畫面。 - show()方法會設定所有動作,但尚未顯示在屏幕上,我們必須在render()方法內用輪入:
1-stage.act();-更新所有Actor。
2-stage.draw();-把所有Actor顯示在屏幕上。
以下是LibGDX-Splash Screen程式執行的結果: