Major Softwares

  INDEX PAGE

  1. 簡介
  2. Java, Android和LibGDX好書推介
  3. Java, Android和LibGDX要學的知識
  4. 用Windows寫Java程式
  5. 用Eclipse寫Java程式
  6. 用Eclipse寫Android程式
  7. 用Eclipse寫LibGDX程式
  8. Standard Java Naming Conventions
  9. System.out.println()的用法和意思
  10. Where is main() method in Android?

LibGDX - Splash & Menu Screen

  1. LibGDX: World, Texture, Background, Camera, Viewport, Screen & OpenGL
  2. LibGDX: Texture, TextureRegion, SpriteBatch & Sprite
  3. UML(Unified Modeling Language): Class Diagram
  4. Type Casting, Upcasting & Downcasting
  5. @Override的用法和意思
  6. LibGDX: Scene2d & Graphical User Interface(GUI)
  7. LibGDX: Splash Screen
  8. LibGDX: Texture Packer
  9. LibGDX: BitmapFonts, JSON & Skin
  10. Android: R.java File
  11. Android: onClick事件的5種實現方式
  12. LibGDX: Game Menu Screen
  13. LibGDX: Advanced Game Menu Screen (using Abstract Screen)
  14. LibGDX: Disposable Interface
  15. Java & LibGDX: super keyword
  16. LibGDX: Advanced Game Menu Screen (using AssetManager)
  17. Java: Array, Arrays, List, ArrayList & LibGDX: Array
  18. LibGDX: File I/O (Preferences)
  19. LibGDX: Game Level Selection Screen
  20. LibGDX: Advanced Game Level Selection Screen (using AssetManager)

LibGDX - Tiled 2D Platform Game

  1. LibGDX: Lifecylce (Render() Method)
  2. LibGDX: Delta Time
  3. LibGDX: Animation & Spritesheet
  4. LibGDX: Keyboard, Mouse & Touch Screen Control
  5. Input Control (Polling VS Event Driven Input)
  6. LibGDX: Tiled (Background and Foreground)
  7. LibGDX: Jumping Action
  8. LibGDX: Tiled (Collision Detection)
  9. LibGDX: Tiled (Bullet Class)
  10. LibGDX: Audio (Sound & Music)
  11. LibGDX: Tiled (Scrollable Background with Camera & HUD)
  12. LibGDX: WorldController & WorldRenderer Class

LibGDX/Java - Card Game No.1 - Blackjack

  1. LibGDX: Install & Setup Android Studio IDE
  2. LibGDX: Use Android Studio to Run Java Hello World
  3. LibGDX: Use Android Studio to Run LibGDX Hello World
  4. Adobe Illustrator: Basic Components Part 1
  5. Adobe Illustrator: Basic Components Part 2
  6. Adobe Illustrator: BlackJack Table & Cards
  7. LibGDX: Blackjack Animation
  8. LibGDX: Interpolation
  9. Java: toString() Method
  10. Java: Blackjack Shuffle Methods
  11. LibGDX: Blackjack Shuffle Method
  12. Java: Blackjack Card Game

LibGDX - Others

  1. Making and Displaying App Icon
  2. LibGDX: Displaying Traditional and Simplified Chinese Characters
  3. LibGDX: Handling Different Screen Resolutions

Unity Game Engine & C#

  1. Visual Studio: C# Hello World
  2. Unity: C# Hello World
  3. Unity: Handling Different Screen Resolutions
  4. Unity: Life Cycle
  5. Unity: StartCoroutine, StopCoroutine, IEnumerator & Yield
  6. Unity: Splash Screen
  7. Unity: Fonts, Traditional and Simplified Chinese Characters
  8. Unity: GameObject, Class Object, new & Instantiate
  9. Unity: Start Screen with Glowing Animated Button
  10. Unity: C# Get & Set Modifier
  11. Unity: Delegates & Events
  12. Unity: File I/O, Read & Write Text File & PlayerPrefs
  13. Unity: Game Level Selection Screen
  14. Unity: Game Menu Screen & ScreenManager
  15. Unity: Encrypt and Decrypt Text File
  16. Unity: Options Menu Screen
  17. Unity: Convert Numbers Image to Custom Font

Unity - Card Game No.1 - Blackjack

  1. Unity: Blackjack Card Game - Part 1 (Full Game)
  2. Unity: Blackjack Card Game - Part 2
  3. Unity: Blackjack Card Game - Part 3
  4. Unity: Blackjack Card Game - Part 4
  5. Unity: Blackjack Card Game - Part 5
  6. Unity: Blackjack Card Game - Part 6
  7. Unity: Blackjack Card Game - Part 7

以下是預告-Coming soon!


Secret Weapon No.1

  1. Unity: Card Game No.2

Advanced Programming

  1. Unity: GPS Programming
  2. Unity: User Login System
  3. Unity: Augmented Reality (AR)

Secret Weapon No.2

  1. Unity: GPS & AR Application

第23節 - LibGDX: Advanced Game Menu Screen (using Abstract Screen)

這一節我會介紹用一個AbstractScreen抽象類別重寫Game Menu Screen。

AbstractScreen Class

我在第22節 - LibGDX: Game Menu Screen介紹過Game Menu Screen的內容,大部分的Screen類別(例如:LevelScreen, OptiosScreen, CreditsScreen等等)都有很多相同的部份,我們可以建立一個抽象類別(Abstract Class)叫AbstractScreen,它可以把畫面相同部分放在AbstractScreen類別內,這樣做就可以簡化程式,如下圖:

LibGDX-Abstract Screen
  1. Start Screen, Options Screen, Credits Screen和Facebook Link都是Class,Meun Screen是Class,所以它們的關係是Association。因為畫面可以向前或向後,所以是Bi-directional(雙向)。
  2. 因為Start Screen, Options Screen, Credits Screen和Facebook Link都須要是Screen類別,它們須要實作Sceen介面。

甚麼是抽象類別(Abstract Class)?

當您定義類別時,可以僅宣告方法名稱而不實作當中的內容,這樣的方法稱之為抽象方法(Abstract Class),如果一個類別中包括了抽象方法,則該類別稱之為抽象類別(Abstract Class)。

Abstract class的特徵:

  1. Abstract Method只需要宣告, 不需要實作。
  2. 使用關鍵字 abstract 宣告的類別 (class) 並不能夠被實體化 (Instantiated) ,也就是說不能用 Abstract 的類別建立物件 (Object) ,但 abstract 類別可當成父類別 (Superclass) 給子類別 (Subclass) 繼承 (Inherit) 。
  3. 繼承Abstract Class的子類別必須實作父類別的Abstract Method, 否則這子類別還是個Abstract Class。
  4. Abstract Class除了可以包括抽象方法外,也可以包括普通的方法。
  5. 另外注意,Abstract Class也可以不包括抽象方法,只包括普通的方法。

    沒有抽象方法的Abstract Class和一般普通類別有甚麼分別?
    以上提及過,最主要是Abstract Class不能建立物件,但普通類別可以建立物件。如果你覺得一個類別只是供給Subclass使用,而不須要獨立使用,我們就可以使用Abstract Class(注意,我們將要設計的AbstractScreen抽象類別就是不須要獨立使用的好例子,它只供給LevelScreen, OptionsScreen, CreditsScreen和FacebookScreen使用)。

以下用Java程式舉例說明:

Java - 例子1

例子1是一個簡單的抽象類別。

LibGDX-Abstract Screen
  1. 建立一個抽象父類別(Parent),再在抽象父類別內建立一個抽象方法methodP1()。
  2. 建立一個子類別(Son),再在子類別內實作methodP1()方法。
  3. 執行結果。

Java - 例子2

例子2把抽象方法methodP1()刪除,就成為我曾經提及的沒有抽象方法的Abstract Class

LibGDX-Abstract Screen
  1. 建立一個抽象父類別(Parent),再在抽象父類別內建立一個普通方法methodP1()。
  2. 建立一個子類別(Son),再在子類別內覆寫methodP1()方法和執行super.methodP1()方法。
  3. 執行結果。

Java - 例子3

例子3和例子2相似,Parent類別是一個普通類別,所以可以建立Parent物件(p)。

LibGDX-Abstract Screen
  1. 建立一個父類別(Parent),再在父類別內建立一個普通方法methodP1()。
  2. 建立一個子類別(Son),再在子類別內覆寫methodP1()方法和執行super.methodP1()方法。
  3. 執行結果。

以下例子就是嘗試在抽象父類別(Parent)內建立Parent物件(p),程式就會顯示錯誤:

LibGDX-Abstract Screen
  1. 建立一個抽象父類別(Parent),再在抽象父類別內建立一個普通方法methodP1()。
  2. 建立一個子類別(Son),再在子類別內覆寫methodP1()方法和執行super.methodP1()方法。
  3. 執行結果。
  4. 在抽象父類別(Parent)內建立Parent物件(p),程式就會顯示錯誤。

建立AbstractScreen抽象類別

原本的LevelScreen.java

首先,我們看看LevelScreen、OptionsScreen和CreditsScreen程式,它們都有相同的部分,我們就可以把相同的部分放在AbstractScreen.java內,下圖為LevelScreen程式,紅色地方為相同部分:

LibGDX-Abstract Screen


AbstractScreen.java

以下是AbstractScreen.java程式,我們把LevelScreen、OptionsScreen和CreditsScreen相同的部分放在AbstractScreen內:

LibGDX-Abstract Screen
  1. 注意,我加入了一個getSkin()方法,它用來把mainmenu.json和mainmenu.pack傅入,這樣做除了AbstractScreen內可以呼叫getSkin()外,在LevelScreen內就可以呼叫super.getSkin()。

新的LevelScreen.java

大家可以看到以下的LevelScreen.java程式就簡潔很多了:

LibGDX-Abstract Screen
  1. 把LevelScreen類別繼承AbstractScreen抽象類別。
  2. 在show()方法內除了呼叫super.show()外,再執行只有LevelScreen類別獨有的部分。
  3. 在render()方法內呼叫super.render(),把所有Actor顯示在屏幕上。
  4. 在hide()方法內呼叫super.hide(),則執行AbstractScreen抽象類別內的hide()方法。

    注意,Screen介面的dispose()方法和Game類別的dispose()方法不同,根據LibGDX官方文件解釋,Screen介面的dispose()方法是不會自動執行,所以我們必須在畫面轉換時在hide()執行dispose()方法,我會在第24節 - LibGDX: Disposable Interface詳細介紹。

  5. 在dispose()方法內呼叫super.dispose(),則執行AbstractScreen抽象類別內的dispose()方法。

用AbstractScreen抽象類別重寫Game Menu Screen

以下詳細介紹用AbstractScreen抽象類別重寫Game Menu Screen的每一個類別程式:

DesktopLauncher.java

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

MyDemo23.java

LibGDX-Abstract Screen
  1. 在MyDemo23.java內把MyDemo23 extends Game。
    在Game類別內,create()是未定義內容,所以在MyDemo23 class內必須定義內容。
    定義create()方法,在create()方法內用setScreen()方法把畫面跳到splashScreen。

SplashScreen.java

我在第17節 - LibGDX: Splash Screen介紹過Splash Screen的製作,Splash Screen跳到Game Menu Screen,再按不同按鈕跳到不同的畫面。

LibGDX-Abstract Screen
  1. 用Texture產生一個Texture物件(例如:texture)然後把圖片(splashScreen.png)傳入。
    用Image產生一個Image物件(例如:splashImage)然後把texture物件傳入。

  2. 在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畫面。

  3. show()方法會設定所有動作,但尚未顯示在屏幕上,我們必須在render()方法內用輪入:

    1-stage.act();-更新所有Actor。
    2-stage.draw();-把所有Actor顯示在屏幕上。

  4. 注意,Screen介面的dispose()方法和Game類別的dispose()方法不同,根據LibGDX官方文件解釋,Screen介面的dispose()方法是不會自動執行,所以我們必須在畫面轉換時在hide()執行dispose()方法,我會在第24節 - LibGDX: Disposable Interface詳細介紹。

  5. 最後別忘記把在dispose()方法內輸入texture.dispose();和stage.dispose()。

MainScreen.java

我們會用第17節的MenuScreen.java檔案再加入"Button Click"事件處理。

  1. Button "Start"會把畫面跳到Level Screen。
  2. Button "Options"會把畫面跳到Options Screen。
  3. Button "Credits"會把畫面跳到Credits Screen。
  4. Button "Share Facebook"會把畫面跳到Facebook網頁。

以下列出MenuScreen.java的操作原理:

LibGDX-Abstract Screen
  1. 設定所有Member Variables。
  2. 建立Skin物件(skin),把mainmenu.json和mainmenu.pack傳入。
  3. 建立Image物件(bg),把skin和bg圖片傳入。
    再建立Button物件(startbutton, optionsbutton, creditsbutton和facebookbutton),把skin和(startButton, optionsButton, creditsButton和facebookButton)圖片傳入。
  4. 設定它們的位置。
  5. 用介面元件的addListener()方法監聽"Click"事件。
    注意,facebookbutton按鈕會把畫面跳到一個預設的網站,我用www.hkprogram.com作例子。
  6. 用介面元件的addActor()方法把所有Image物件和Button物件傳入stage內。
  7. 用setInputProcessor()方法把stage傳入,再設定touch和key input事件。
  8. show()方法會設定所有動作,但尚未顯示在屏幕上,我們必須在render()方法內用輪入:

    1-stage.act();-更新所有Actor。
    2-stage.draw();-把所有Actor顯示在屏幕上。

  9. 注意,Screen介面的dispose()方法和Game類別的dispose()方法不同,根據LibGDX官方文件解釋,Screen介面的dispose()方法是不會自動執行,所以我們必須在畫面轉換時在hide()執行dispose()方法,我會在第24節 - LibGDX: Disposable Interface詳細介紹。

  10. 最後別忘記把在dispose()方法內輸入skin.dispose();和stage.dispose()。

AbstractScreen.java

以下是AbstractScreen.java程式:

LibGDX-Abstract Screen
  1. 把AbstractScreen抽象類別實作Screen介面。
  2. 設定所有Member Variables。
  3. 建立一個getSkin()方法,它用來把mainmenu.json和mainmenu.pack傅入,這樣做除了AbstractScreen內可以呼叫getSkin()外,在LevelScreen、OptionsScreen和CreditsScreen類別內就可以呼叫super.getSkin()。
  4. 建立MenuScreen物件(menuScreen)。
  5. 建立Button物件(backButton),把getSkin()和backbutton圖片傳入。
  6. 設定它們的位置和用介面元件的addListener()方法監聽"Click"事件。
  7. 用setInputProcessor()方法把stage傳入,再設定touch和key input事件。
  8. show()方法會設定所有動作,但尚未顯示在屏幕上,我們必須在render()方法內用輪入:

    1-stage.act();-更新所有Actor。
    2-stage.draw();-把所有Actor顯示在屏幕上。

  9. 注意,Screen介面的dispose()方法和Game類別的dispose()方法不同,根據LibGDX官方文件解釋,Screen介面的dispose()方法是不會自動執行,所以我們必須在畫面轉換時在hide()執行dispose()方法,我會在第24節 - LibGDX: Disposable Interface詳細介紹。

  10. 最後別忘記把在dispose()方法內輸入skin.dispose();和stage.dispose()。

LevelScreen.java

以下是LevelScreen.java程式,把LevelScreen類別繼承AbstractScreen抽象類別:

LibGDX-Abstract Screen
  1. 把LevelScreen類別繼承AbstractScreen抽象類別。
  2. 在show()方法內除了呼叫super.show()外,再執行只有LevelScreen類別獨有的部分。
  3. 在render()方法內呼叫super.render(),把所有Actor顯示在屏幕上。
  4. 在hide()方法內呼叫super.hide(),則執行AbstractScreen抽象類別內的hide()方法。

    注意,Screen介面的dispose()方法和Game類別的dispose()方法不同,根據LibGDX官方文件解釋,Screen介面的dispose()方法是不會自動執行,所以我們必須在畫面轉換時在hide()執行dispose()方法,我會在第24節 - LibGDX: Disposable Interface詳細介紹。

  5. 在dispose()方法內呼叫super.dispose(),則執行AbstractScreen抽象類別內的dispose()方法。

OptionsScreen.java

以下是OptionsScreen.java程式,把OptionsScreen類別繼承AbstractScreen抽象類別:

LibGDX-Abstract Screen
  1. 把OptionsScreen類別繼承AbstractScreen抽象類別。
  2. 在show()方法內除了呼叫super.show()外,再執行只有LevelScreen類別獨有的部分。
  3. 在render()方法內呼叫super.render(),把所有Actor顯示在屏幕上。
  4. 在hide()方法內呼叫super.hide(),則執行AbstractScreen抽象類別內的hide()方法。

    注意,Screen介面的dispose()方法和Game類別的dispose()方法不同,根據LibGDX官方文件解釋,Screen介面的dispose()方法是不會自動執行,所以我們必須在畫面轉換時在hide()執行dispose()方法,我會在第24節 - LibGDX: Disposable Interface詳細介紹。

  5. 在dispose()方法內呼叫super.dispose(),則執行AbstractScreen抽象類別內的dispose()方法。

CrdeditsScreen.java

以下是CreditsScreen.java程式,把CreditsScreen類別繼承AbstractScreen抽象類別:

LibGDX-Abstract Screen
  1. 把CreditsScreen類別繼承AbstractScreen抽象類別。
  2. 在show()方法內除了呼叫super.show()外,再執行只有LevelScreen類別獨有的部分。
  3. 在render()方法內呼叫super.render(),把所有Actor顯示在屏幕上。
  4. 在hide()方法內呼叫super.hide(),則執行AbstractScreen抽象類別內的hide()方法。

    注意,Screen介面的dispose()方法和Game類別的dispose()方法不同,根據LibGDX官方文件解釋,Screen介面的dispose()方法是不會自動執行,所以我們必須在畫面轉換時在hide()執行dispose()方法,我會在第24節 - LibGDX: Disposable Interface詳細介紹。

  5. 在dispose()方法內呼叫super.dispose(),則執行AbstractScreen抽象類別內的dispose()方法。

FacebookScreen.java

以下是FacebookScreen.java程式,把FacebookScreen類別繼承AbstractScreen抽象類別。

注意,FacebookScreen類別內其實與LevelScreen,OptionsScreen和CreditsScreen類別沒有相同的地方,但為了把所有Screen類別系一 說明,所以才把FacebookScreen類別也繼承AbstractScreen抽象類別。

LibGDX-Abstract Screen
  1. 把FacebookScreen類別繼承AbstractScreen抽象類別。
  2. 在render()方法內,用batch.draw(),把texture傳入和設定顯示位置,最後顯示在屏幕上。
  3. 注意,Screen介面的dispose()方法和Game類別的dispose()方法不同,根據LibGDX官方文件解釋,Screen介面的dispose()方法是不會自動執行,所以我們必須在畫面轉換時在hide()執行dispose()方法,我會在第24節 - LibGDX: Disposable Interface詳細介紹。
  4. 最後別忘記把在dispose()方法內輸入texture.dispose();和batch.dispose()。

執行結果:

以下是LibGDX-Advanced Game Menu Screen (Using Abstract Screen)程式執行的結果:



Download above code and sample pictures here!