第19節 - LibGDX: Bitmap Fonts, JSON & Skin
這一節我會介紹Bitmap Fonts, JSON和Skin。簡單來說Bitmap Fonts就是在屏幕上顯示文字,JSON就是一個文字檔案,把Texture Packer的圖片和Bitmap Fonts的文字加入特效設定,再顯示在屏幕上,就好像製作網頁的CSS(Cascading Style Sheets )一樣。而Skin就是把JSON文字檔案傳入,再套在不同的UI components(例如:Button)上。
以下是Texture Packer, Bitmap Font, JSON和Skin用在LibGDX的關係圖:

1 - Texture Packer
我在第18節 - LibGDX: Texture Packer介紹過,Texture Packer把不同的圖片儲存在一個.png檔案上,再傳到GPU作其他程式處理,這樣做就會大大減少記憶體的資源。
以下例子就把兩個Button圖片(button1.png和button2.png)用Texture Packer軟件產生兩個檔案(button.png和button.pack):

2 - Bitmap Font
Bitmap Font的原理和Texture Packer很相似,Bitmap Font把一種字體的A至Z和其他字符儲存在一個.png檔案上,再傳到GPU作其他程式處理,這樣做也是為了減少記憶體的資源。
以下例子就把Google Font-Carter One內的A至Z和其他字符用Hiero軟件產生兩個檔案(carterone.png和carterone.fnt):

- carterone.png把Carter One字體的A至Z和其他字符儲存在carterone.png檔案內。
- carterone.fnt是一個文字檔案,它把carterone.png檔案內的A至Z和其他字符的資料記錄下來。
3 - JSON
JSON全名是JavaScript Object Notation,它是一個以純文字檔案去儲存和傳送簡單結構資料,是一種輕量級的數據交換語言(Extensible Markup Language, XML),你可以透過特定的格式去儲存任何資料(字串,數字,陣列,物件),也可以透過物件或陣列來傳送較複雜的資料。它的用途十分廣闊,在這裡我只會針對LibGDX而論。
以下就是LibGDX預設uiskin.json文字檔的內容:

- 第1段設定Bitmap Font的預設字體(default-font)和字體路徑。
- 第2段設定不同顏色(Color)。
- 第3至第15段設定不同介面元件的特性。我會已TextButton介面元件作詳細介紹。
注意,如果我們只須要用到uiskin.json文件內的幾個特性,我們可以簡略內容,如下圖:

- 第1段設定Bitmap Font的預設字體(default-font)和字體路徑。
- 第2段設定不同顏色(Color)。
- 第3段設定不同介面元件的特性。我會已TextButton介面元件作詳細介紹。
4 - Skin類別, TextButton類別, Stage類別和SpriteBatch類別
以下是Skin類別, TextButton類別, Stage類別和SpriteBatch類別的關係:

- 首先我們建立一個Skin物件(skin),skin可把JSON檔案傳入,例如:簡化的JSON檔案(uiskin-simple.json)。
- 建立一個TextButton物件(button),我們可以把以下三個引數傳入:
- 顯示文字內容,例如: "Click me"。
- 傳入skin,則是間接傳入了JSON檔案內容,亦則是間接傳入了Texture Packer圖片和Bitmap Font字體。
- 傳入default,則是把JSON檔案內的default設定傳入button。
- 建立一個Stage物件(stage),用stage.addActor()方法把button傳入。
注意,button也是Actor物件。 - 最後,建立一個SpriteBatch物件(batch),它用來把stage設定好的圖像(圖片和文字)顯示在屏幕上。
Google Fonts - Carter One
以下介紹如何把我們喜歡的字體下載,我會已Google Fonts - Carter One作解釋:

1.&2. 在以上Google網站,下載Google Fonts - Carter One

1.&2. 按"下載"按鈕

1.&2. 下載Zip File和按"儲存"按鈕

1. 把Zip File解壓,會得到一個CarterOne.ttf檔案。

1. 把CarterOne.ttf檔案儲存到"C:\Windows\Fonts"內,任何Windows軟件內就會多了Carter One的字體。
Bitmap Font - Hiero
以下介紹如何把Carter One字體製作成Bitmap Font,我會已Hiero軟件作解釋:

1. 在以上LibGDX官方網站下載Hiero.jar。

- 按Hiero.jar開啟Hiero軟件。
- 在Hiero內選擇Carter One的字體。

1., 2.&3. 設定Background顏色為灰色,再按"OK"按鈕。

1.至6. 設定outline顏色為綠色,可以在"RGB"設定內輸入Color Code為"358E15"。

1.&2. 把Carter One字體儲存成Bitmap Font檔案。

1. Bitmap Font檔案: carterone.png和carteron.fnt就會產生。

- carterone.png把Carter One字體的A至Z和其他字符儲存在carterone.png檔案內。
- carterone.fnt是一個文字檔案,它把carterone.png檔案內的A至Z和其他字符的資料記錄下來。
LibGDX - Default Files
LibGDX預設了五個可用檔案:
Bitmap Font:
- default.fnt
- default.png
Texture Packer:
- uiskin.atlas
- uiskin.png
JSON:
- uiskin.json

以上五個檔案可以在LibGDX的網站下載,如下圖:

- LibGDX的預設Bitmap Font檔案(default.fnt和default.png)。
- LibGDX的預設Texture Packer和JSON檔案(uiskin.atlas, uiskin.png和uiskin.json)。
注意,LibGDX的預設檔案是".atlas",而用Texture Packer產生的檔案是".pack",兩種也可以接受。
以下是這五個檔案用在LibGDX時的關係:

- LibGDX的預設Bitmap Font檔案(default.fnt和default.png)。
- LibGDX的預設Texture Packer檔案(uiskin.atlas和uiskin.png)。
- LibGDX的預設JSON檔案(uiskin.json)。
在uiskin.json檔案內主要包括三個部分: Bitmap Font, Color和14種UI Components。 - 建立一個Skin物件(skin),skin可把JSON檔案傳入,例如: 簡化的JSON檔案(button.json)。
- 建立一個TextButton物件(button),把skin傳入。
- 建立一個Stage物件(stage),用stage.addActor()方法把button傳入。
- 最後,建立一個SpriteBatch物件(batch),它用來把stage設定好的圖像(圖片和文字)顯示在屏幕上。
以下就是LibGDX的預設JSON檔案(uiskin.json),在uiskin.json檔案內主要包括三個部分:Bitmap Font, Color和14種UI Components。

LibGDX - Create Your Own Files
如果我們希望用自己的宇字體和圖片,我們可以建立自己的Bitmap Font, Texture Packer和JSON檔案。
我們自建的五個檔案:
Bitmap Font:
- carterone.fnt
- carterone.png
Texture Packer:
- button.pack
- button.png
JSON:
- button.json

以下是這五個檔案用在LibGDX時的關係:

- 我們自建的Bitmap Font檔案(carterone.fnt和carterone.png)。
- 我們自建的Texture Packer檔案(button.pack和button.png)。
- 我們自建的JSON檔案(button.json)。
在button.json檔案內也包括三個主要部分: Bitmap Font, Color和1種UI Components(TextButton)。 - 建立一個Skin物件(skin),skin可把JSON檔案傳入,例如: 簡化的JSON檔案(button.json)。
- 建立一個TextButton物件(button),把skin傳入。
- 建立一個Stage物件(stage),用stage.addActor()方法把button傳入。
- 最後,建立一個SpriteBatch物件(batch),它用來把stage設定好的圖像(圖片和文字)顯示在屏幕上。
以下就是我們自建的JSON檔案(button.json),在button.json檔案內也包括三個主要部分:Bitmap Font, Color和1種UI Components(TextButton)。

- 第1段設定Bitmap Font的預設字體(default-font)和字體路徑。
- 第2段設定不同顏色(Color)。
- 第3段設定不同介面元件的特性。我會已TextButton介面元件作詳細介紹。
例子1
第1個例子不須要用Bitmap Font, Texture Packer和JSON檔案,只用SpriteBatch物件(sprite)顯示字串在屏幕上。

1.&2. DesktopLauncher是PC Desktop的Starter Class,我們在DesktopLauncher內設定顯示的大小為500x700px。

- 在MyDemo19.java內建立有關的Member Variables。
- 在create()方法內建立一個BitmpaFont物件(font1),再設定顏色為黑色。
- 顯示"Hello World"字串在屏幕上,字串的位置為(200,350)。
- 最後別忘記把在dispose()方法內輸入batch.dispose()和font1.dispose()。
執行程式,結果如下圖:

例子2
第2個例子只會用到Bitmap Font的Carter One字體,不須要用Texture Packer和JSON檔案,再用SpriteBatch物件(sprite)顯示字串在屏幕上。

- 在Android的assets內建立"fonts"文件夾,複製carterone.fnt和carterone.png到文件夾。
- DesktopLauncher是PC Desktop的Starter Class,我們在DesktopLauncher內設定顯示的大小為500x700px。

- 在MyDemo19.java內建立有關的Member Variables。
- 在create()方法內建立一個BitmpaFont物件(font1),再設定顏色為黑色。
再建立一個BitmpaFont物件(font2),把carterone.fnt和carterone.png傳入。 - 顯示"Hello World"字串在屏幕上,字串的位置為(200,350)。
顯示"START"字串在屏幕上,字串的位置為(200,450)。 - 最後別忘記把在dispose()方法內輸入batch.dispose(), font1.dispose()和font2.dispose()。
執行程式,結果如下圖:

例子3
第3個例子會用LibGDX預設的5個檔案:
- default.fnt
- default.png
- uiskin.atlas--->uiskin-simple.atlas
- uiskin.png--->uiskin-simple.png
- uiskin.json--->uiskin-simple.json
注意1,我會示範更改LibGDX預設的uiskin.atlas檔案,只留下須要的部分。
注意2,更改完uiskin.atlas的內容後,如果須要改名(例如: 把uiskin.altas改為uiskin-simple.altas),其他檔案最好一同改名:
- uiskin.atlas--->uiskin-simple.atlas
- uiskin.png--->uiskin-simple.png
- uiskin.json--->uiskin-simple.json
注意3,除了以上檔案名外,uiskin-simple.altas內的uiskin.png也要改為uiskin-simple.png,如下圖:

1.&2. 在uiskin-simple.altas內的uiskin.png也要改為uiskin-simple.png

- 在Android的assets內建立"fonts"文件夾,複製default.fnt和default.png到文件夾。
在Android的assets內建立"data"文件夾,複製uiskin-simple.atlas, uiskin-simple.png和uiskin-simple.json到文件夾。 - DesktopLauncher是PC Desktop的Starter Class,我們在DesktopLauncher內設定顯示的大小為500x700px。

- 在MyDemo19_2.java內建立有關的Member Variables。
- 在create()方法內建立一個Skin物件(skin),再把uiskin-simple.json傳入。
- 再建立一個TextButton物件(button),我們可以把以下三個引數傳入:
1-顯示文字內容""Click me"。
2-傳入skin,則是間接傳入了JSON檔案內容,亦則是間接傳入了Texture Packer圖片和Bitmap Font字體。
3-傳入default,則是把JSON檔案內的default設定傳入button。 - 設定button的大小為200x20px。
注意1,我們是用LibGDX的預設uiskin-simple.atlas檔案,在這檔案的TextButton內,當按下按鈕,圖片會用default-round-down; Mouse放開時,圖片會用default-round。
注意2,圖片default-round-down和default-round的大小不是固定的,我們可以用以下設定button的大小。:
1-button.setwidth();
2-button.setheight();
設定button的左下角位置為(-100,-10)px。 - 用button介面元件的button.addListener()方法監聽Mouse按下按鈕時要作出的動作。
在這例子裡,當Mouse按下按鈕時,button元件上的字串就會由"Click me"轉為"Go to Next Screen"。
注意,我會在第21節 - Android: onClick事件的5種實現方式介紹有關Click Listener的用法。 - 建立一個Stage物件(stage),用stage.addActor()方法把button傳入。
再把stage傳入Gdx.input.setInputProcessor()方法內,這方法可以設定Mouse, Keyboard或Touchpad等輸入裝置。 - 建立一個SpriteBatch物件(batch),它用來把stage設定好的圖像(圖片和文字)顯示在屏幕上。
- 最後別忘記把在dispose()方法內輸入batch.dispose(), stage.dispose()和skin.dispose()。
以下解釋LibGDX預設的按鈕圖片,當按下按鈕時,圖片會用default-round-down(紅色); Mouse放開時,圖片會用default-round(灰色)。


執行程式,結果如下圖:

用Mouse按一下按鈕,結果如下圖:

例子4
例子4會用我們自建的5個檔案:
- carterone.fnt
- carterone.png
- button.pack
- button.png
- button.json

- 在Android的assets內建立"fonts"文件夾,複製carterone.fnt和carterone.png到文件夾。
在Android的assets內建立"data"文件夾,複製button.pack, button.png和button.json到文件夾。 - DesktopLauncher是PC Desktop的Starter Class,我們在DesktopLauncher內設定顯示的大小為459x600px。

- 在MyDemo19_3.java內建立有關的Member Variables。
- 在create()方法內建立一個Skin物件(skin),再把button.json和button.pack傳入。
- 再建立一個TextButton物件(button),我們可以把以下三個引數傳入:
- 顯示文字內容"Start"。
- 傳入skin,則是間接傳入了JSON檔案內容,亦則是間接傳入了Texture Packer圖片和Bitmap Font字體。
- 傳入carterone,則是把JSON檔案內的carterone設定傳入button。
- 用button介面元件的button.addListener()方法監聽Mouse按下按鈕時要作出的動作。
在這例子裡當Mouse按下按鈕時,button元件上的字串是"Start",Mouse放開時,button元件上的字串會保持在"Start"。
注意,我會在第21節 - Android: onClick事件的5種實現方式介紹有關Click Listener的用法。 - 建立一個Stage物件(stage),用stage.addActor()方法把button傳入。
再把stage傳入Gdx.input.setInputProcessor()方法內,這方法可以設定Mouse, Keyboard或Touchpad等輸入裝置。 - 建立一個SpriteBatch物件(batch),它用來把stage設定好的圖像(圖片和文字)顯示在屏幕上。
- 最後別忘記把在dispose()方法內輸入batch.dispose(), stage.dispose()和skin.dispose()。
執行程式,結果如下圖:

用Mouse按一下按鈕,結果如下圖:
