第49節 - LibGDX: Blackjack Animation
這一節我會介紹LibGDX: Blackjack的動畫製作,我會介紹以下Scene2d的Class(類別):
- Stage(舞台)
- Group(組)
- Actor(演員)
- Actions(演出)
還有以下Actions類別的的addAction()方法:
- Actions類別的addAction()方法
執行結果:
以下是本節LibGDX: Blackjack Animation所有例子的執行結果:
Scene2d的關係圖
我在第16節 - LibGDX: Scene2d和Graphical User Interface (GUI)介紹過Scene2d的關係圖:

Scene2d UI的簡化圖
以下是Scene2d UI的簡化圖,與Android相似,每個Group內可包含不同的介面元件,也可包括另一個Group,不過Actor內就不能包含其他介面元件:

我會用到Scene2d的Stage(舞台), Actor(演員), Image(圖像)和Actions(演出)類別來製作LibGDX: Blackjack的動畫。
注意1: Stage是一個舞台,在舞台內可以有不同的Actor,而Image也是Actor的一種。
注意2: Actions是令一個類別,它不是在Stage類別之內,Actions類別可以用來製作不同的動畫效果,我會在這節詳細介紹。

Actions類別
另外,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()
這一節我們會用到以的Actions方法:
- addAction()
- AddListener()
- delay()
- fadeIn()
- fadeOut()
- forever()
- moveTo()
- parallel()
- rotateby()
- scaleTo()
- sequence()
sequence()和parallell()方法
以上Actions類別內有兩個方法: squence()和parallel()方法,這兩個方法會時常用到,它們主要用來控制動畫是順序或同步執行。
1. sequence() method
以下就是sequence()方法的例子,它用來控制動畫順序執行的:

- 用moveTo()方法把Image物件直線移動到目的地位置(484, 343)。
注意1: 括號的第三個數字就是時間的長度,0.5f = 0.5s,f = float。
注意2: 我們可以把sequence()內的動作在一行內表示,也可以分成幾行表示,結果是一樣的。
- 用delay()方法把時間延遲 0.5s。
- 用rotateBy()方法把Image物件在0.3s內逆時針轉動90度。
2. parallel() method
以下就是parallel()方法的例子,它用來控制動畫同步執行的:

- 用moveTo()方法把Image物件直線移動到目的地位置(484, 343)。
注意1: 括號的第三個數字就是時間的長度,0.5f = 0.5s,f = float。
注意2: 我們可以把parallel()內的動作在一行內表示,也可以分成幾行表示,結果是一樣的。
- 用delay()方法把時間延遲 0.5s,這次因為用了parallel()方法,所以變成了同步。
- 用rotateBy()方法把Image物件在0.3s內逆時針轉動90度,這次因為用了parallel()方法,所以變成了同步。
3. Combined sequence() and parallel() method
以下把sequence()和parallel()方法合併的例子:

- 用moveTo()方法把Image物件直線移動到目的地位置(484, 343)。
注意1: 括號的第三個數字就是時間的長度,0.5f = 0.5s,f = float。 - 用delay()方法把時間延遲 0.5s,這次因為用了parallel()方法,所以變成了同步。
- 用rotateBy()方法把Image物件在0.3s內逆時針轉動90度,這次因為用了sequence()方法,所以變成了順序。
Blackjack Animation例子1 - Playing Card Linear Movement
例子1會介紹Playing Card Linear Movement,則是把紙牌直線移動到目的地,結果如下圖:

- 把紙牌在原本的位置(716, 606)直線移動到目的地位置(484, 343)。
程式部分

- DesktopLauncher是PC Desktop的Starter Class,我們在DesktopLauncher內設定顯示的大小為1024 X 768 px。

- 把以上圖片(png)儲存到Android的assets文件夾內。

- 把所有圖片(png)存入Texture物件內。
- 把紙牌Texture物件存入Actor的Image物件內。
注意: Stage是一個舞台,在舞台內可以有不同的Actor,而Image也是Actor的一種。
- 建立一個Stage物件(stage)。
- 把紙牌Image物件存入Stage物件(stage)內。
- 用Image物件的addAction()方法加入moveTo()方法,這樣做就可以把紙牌在原本的位置(716, 606)直線移動到目的地位置(484, 343)。
注意1: sequence()方法是把addAction()方法內的所有動作順序執行,但這個例子裡我們只有一個moveTo()動作,所以可以忽略。
注意2: 另外除了sequence()方法外,還有parallel()方法,parallel()方法是把addAction()方法內的所有動作同步執行,但這個例子裡我們只有個moveTo()動作,所以可以忽略。
- 把背景Texture物件(bgTexture)用SpriteBatch物件(batch)在於Render()方法內顯示出來。
- 1-stage.act(); - 更新所有Actor,這個例子裡我們只有一個紙牌物件(cardImage1)。
2-stage.draw(); - 把所有Actor顯示在屏幕上,這個例子裡我們只有一個紙牌物件(cardImage1)。
Blackjack Animation例子2 - Playing Card Flip
例子2會介紹Playing Card的Flip動畫效果,結果如下圖:


- 把紙牌在原本的位置(716, 606)直線移動到目的地位置(484, 343)。
- 用scaleTo()方法把紙牌的闊度(x direction)由1改變為0。
- 用scaleTo()方法把紙牌的闊度(x direction)由0改變為1。
程式部分

- DesktopLauncher是PC Desktop的Starter Class,我們在DesktopLauncher內設定顯示的大小為1024 X 768 px。

- 把以上圖片(png)儲存到Android的assets文件夾內。

- 把所有圖片(png)存入Texture物件內。
- 把紙牌Texture物件(紙牌的正面和底面)存入Actor的Image物件內。
注意: Stage是一個舞台,在舞台內可以有不同的Actor,而Image也是Actor的一種。
- 建立一個Stage物件(stage)。
- 把紙牌Image物件存入Stage物件(stage)內。
- 用Image物件的addAction()方法:
i) 紙牌的底面(cardImage1)- 用moveTo()方法: (716, 606) to (484, 343),時間: 0.5s。
ii) 紙牌的底面(cardImage1) - 用delay()方法: 延遲時間: 0.5s。
iii) 紙牌的底面(cardImage1)- 用scaleTo()方法: 把紙牌的闊度(x direction)由1改變為0,時間: 0.1s。
iv) 紙牌的正面(cardImage2)- 用scaleTo()方法: 把紙牌的闊度(x direction)由0改變為1。
v) 紙牌的正面(cardImage2) - 用delay()方法: 延遲時間: 0.6s。
vi) 紙牌的底面(cardImage2)- 用scaleTo()方法: 把紙牌的闊度(x direction)由0改變為1,時間: 0.1s。
- 把背景Texture物件(bgTexture)用SpriteBatch物件(batch)在於Render()方法內顯示出來。
- 1-stage.act(); - 更新所有Actor,這個例子裡我們有兩個紙牌物件(cardImage1, cardImage2)。
2-stage.draw(); - 把所有Actor顯示在屏幕上,這個例子裡我們有兩個紙牌物件(cardImage1, cardImage2)。
Blackjack Animation例子3 - Glowing Button
例子3會介紹閃爍按鈕(Glowing Button)效果,當按下按鈕,動畫才會開始,結果如下圖:

- 閃爍按鈕(Glowing Button)效果。
- 把紙牌在原本的位置(716, 606)直線移動到目的地位置(484, 343)。
程式部分

- DesktopLauncher是PC Desktop的Starter Class,我們在DesktopLauncher內設定顯示的大小為1024 X 768 px。

- 把以上圖片(png)儲存到Android的assets文件夾內。
- 注意,背景圖片(table2_1024_768.png)刪除了左下角的HIT按鈕。
- 製作兩張以上HIT的按鈕,再用fadeIn()和fadeOut緩)方法就可以做出閃爍按鈕(Glowing Button)效果。

- 把所有圖片(png)存入Texture物件內。
- 把紙牌Texture物件(紙牌的正面和底面)存入Actor的Image物件內。
注意: Stage是一個舞台,在舞台內可以有不同的Actor,而Image也是Actor的一種。
- 建立一個Stage物件(stage)。
- 把按鈕Image物件存入Stage物件(stage)內。
- 用Image物件的addAction()方法:
i) HIT按鈕(buttonImage2)- 用fadeIn()方法,時間: 0.5s。
ii) HIT按鈕(buttonImage2)- 用fadeOut()方法,時間: 0.6s。
注意1: HIT按鈕(buttonImage2)是故定在HIT按鈕(buttonImage1)之上,當HIT按鈕(buttonImage2)用fadeOut()方法消失後,下面的HIT按鈕(buttonImage1)就會呈現出來,做出閃爍按鈕(Glowing Button)的效果。
注意2: forever()方法可以用來不斷重複動作。
- 用Image物件的addListener()方法,當按下按鈕,動畫才會開始:
i) 每次按下按鈕時,首先重設(Reset)Image物件的設定。
ii) 把紙牌Image物件存入Stage物件(stage)內。
iii) 紙牌的底面(cardImage1)- 用moveTo()方法: (716, 606) to (484, 343),時間: 0.5s。
iv) 紙牌的底面(cardImage1) - 同步用rotateBy()方法: 逆時針轉動90度。
v) 紙牌的底面(cardImage1) - 用delay()方法: 延遲時間: 0.5s。
vi) 紙牌的底面(cardImage1)- 用scaleTo()方法: 把紙牌的闊度(x direction)由1改變為0,時間: 0.1s。
vii) 紙牌的正面(cardImage2) - 用delay()方法: 延遲時間: 0.6s。
iv) 紙牌的正面(cardImage2)- 用scaleTo()方法: 把紙牌的闊度(x direction)由0改變為1,時間: 0.1s。 - 設定監聽動作Gdx.input.setInputProcessor(stage),把Stage物件存入。
- 把背景Texture物件(bgTexture)用SpriteBatch物件(batch)在於Render()方法內顯示出來。
- 1-stage.act(); - 更新所有Actor。
2-stage.draw(); - 把所有Actor顯示在屏幕上。
Blackjack Animation例子4 - Playing Card Shuffle
例子4會做出洗紙牌(Shuffle)效果,當按下按鈕,動畫才會開始,結果如下圖:

- 每次按下按鈕時,首先重設(Reset)Image物件的設定
- 把紙牌在原本的位置(716, 606)直線移動到目的地位置,單數在左面(484, 343),雙數在右面(584, 343)。
- 把紙牌逆時針轉動90度,再移動到中間位置。
- 把紙牌回到原本的位置(716, 606)。
程式部分

- DesktopLauncher是PC Desktop的Starter Class,我們在DesktopLauncher內設定顯示的大小為1024 X 768 px。

- 把以上圖片(png)儲存到Android的assets文件夾內。

- 建立Image物件, 用Array儲存52張牌 (0-51)。
- 把所有圖片(png)存入Texture物件內。
- 把紙牌Texture物件(紙牌的正面和底面)存入Actor的Image物件內。
注意: Stage是一個舞台,在舞台內可以有不同的Actor,而Image也是Actor的一種。
- 把紙牌Texture物件存入Image物件, 用Array儲存52張牌 (0-51)。
- 建立一個Stage物件(stage)。
- 把按鈕Image物件存入Stage物件(stage)內。
- 用Image物件的addAction()方法:
i) HIT按鈕(buttonImage2)- 用fadeIn()方法,時間: 0.5s。
ii) HIT按鈕(buttonImage2)- 用fadeOut()方法,時間: 0.6s。
注意1: HIT按鈕(buttonImage2)是故定在HIT按鈕(buttonImage1)之上,當HIT按鈕(buttonImage2)用fadeOut()方法消失後,下面的HIT按鈕(buttonImage1)就會呈現出來,做出閃爍按鈕(Glowing Button)的效果。
注意2: forever()方法可以用來不斷重複動作。
- 用Image物件的addListener()方法,當按下按鈕,動畫才會開始:
i) 每次按下按鈕時,首先重設(Reset)Image物件的設定。 - 把紙牌在原本的位置(716, 606)直線移動到目的地位置,單數在左面(484, 343),雙數在右面(584, 343)。
- 把紙牌逆時針轉動90度,再移動到中間位置。
- 把紙牌回到原本的位置(716, 606)。
- 設定監聽動作Gdx.input.setInputProcessor(stage),把Stage物件存入。
- 把背景Texture物件(bgTexture)用SpriteBatch物件(batch)在於Render()方法內顯示出來。
- 1-stage.act(); - 更新所有Actor。
2-stage.draw(); - 把所有Actor顯示在屏幕上。
注意: 這次在moveTo()方法內加入了第四個參數(pow5Out),這叫做Interpolation (Bounce, Circle, Elastic, Linear, Power, Sine等等),它是用來做出不同的動畫動作。
關於Interpolation的用法,我第50節 - LibGDX: Interpolation會在下一節,詳細介紹。
Blackjack Animation例子5 - Slide-in Message Box
例子5會做出遊戲中段插入動畫效果,當按下按鈕,動畫才會開始,結果如下圖:

- 用scaleTo()方法把以上的slidebox高度(y direction)由0改變為1,這樣做就可以做出開關的效果。
- 用moveTo()方法把以上的Image物件(lasebeam)由右至左快速移動。
- 用moveTo()方法把以上的Image物件(blackjack_text)由左至右快速移動。
程式部分

- DesktopLauncher是PC Desktop的Starter Class,我們在DesktopLauncher內設定顯示的大小為1024 X 768 px。

- 把以上圖片(png)儲存到Android的assets文件夾內。

- 把所有圖片(png)存入Texture物件內。
- 把紙牌Texture物件(紙牌的正面和底面)存入Actor的Image物件內。
注意: Stage是一個舞台,在舞台內可以有不同的Actor,而Image也是Actor的一種。
- 建立一個Stage物件(stage)。
- 把按鈕Image物件存入Stage物件(stage)內。
- 用Image物件的addAction()方法:
i) HIT按鈕(buttonImage2)- 用fadeIn()方法,時間: 0.5s。
ii) HIT按鈕(buttonImage2)- 用fadeOut()方法,時間: 0.6s。
注意1: HIT按鈕(buttonImage2)是故定在HIT按鈕(buttonImage1)之上,當HIT按鈕(buttonImage2)用fadeOut()方法消失後,下面的HIT按鈕(buttonImage1)就會呈現出來,做出閃爍按鈕(Glowing Button)的效果。
注意2: forever()方法可以用來不斷重複動作。
- 用Image物件的addListener()方法,當按下按鈕,動畫才會開始:
i) 每次按下按鈕時,首先重設(Reset)Image物件的設定。
- 在Image物件的addListener()方法內:
把slidebox, laserbeam和blackjack_text Image物件存入Stage物件(stage)內。 - 在Image物件的addListener()方法內:
i) slidebox Image物件 - 用scaleTo()方法: 把slidebox的高度(y direction)由0改變為1,時間: 0.3s。
ii) laserbeam Image物件1 - 用delay()方法: 延遲時間: 0.3s。
iii) laserbeam Image物件1 - 用moveTo()方法把以上的Image物件(lasebeam)由右至左快速移動。
iv)複製第二條laserbeam Image物件 - 用delay()方法: 延遲時間: 0.3s。
v) 第二條laserbeam Image物件 - 用moveTo()方法把以上的Image物件(lasebeam)由右至左快速移動。
vi) blackjack_text Image物件 - 用delay()方法: 延遲時間: 0.3s。
vii) 用moveTo()方法把以上的Image物件(blackjack_text)由左至右快速移動。 - 在Image物件的addListener()方法內:
i) slidebox Image物件 - 用delay()方法: 延遲時間: 2s。 - 設定監聽動作Gdx.input.setInputProcessor(stage),把Stage物件存入。
- 把背景Texture物件(bgTexture)用SpriteBatch物件(batch)在於Render()方法內顯示出來。
- 1-stage.act(); - 更新所有Actor。
2-stage.draw(); - 把所有Actor顯示在屏幕上。
ii) slidebox Image物件 - 用scaleTo()方法: 把slidebox的高度(y direction)由1改變為0,時間: 0.2s,這樣做就可以做出消失的效果。