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

第26節 - LibGDX: Advanced Game Menu Screen (using AssetManager)

這一節我會介紹LibGDX的AssetManager,資產管理員(AssetManager)是用來管理資產/素材(assets) 。

遊戲程式用上大量資源, 圖像和聲音效果會佔用大量的記憶體。而libgdx內有很多類別就須要在生命週期結束時手動處理把記憶體資源釋放。 否則會導致嚴重的記憶體洩漏(Memory Leaks)。

大家在前幾節會發現,如果要把一張圖片顯示在屏幕上,LibGDX的生命週期主要經過create()、 resize()、render() 、pause()和resume()和dispose()方法,當程式結束時,圖片就要在dispose()方法內進行銷毀,把記憶體資源釋放,如下圖:

LibGDX AssetManager
  1. 但是如果每一個類別都要管理自己的素材,不是一個有效率的做法,所以就要用上AssetManager管理我們的素材,LibGDX的AssetManager就提供資源加載(Loading Resouces)方案。

AssetManager的特點和好處

  1. 加載大部分資源使用異步(Asynchronously)的方式,這樣就能在加載的同時執行其他程式,例如Loading Progress Bar,我會在其他章節詳細介紹Progress Bar。

  2. 所有Assets用上了Reference Counted,當A和B都依賴C素材的時候,C只有在A,B都銷毀了才會銷毀。這也意味著即使一個資源加載(Loading Resouces)了很多次,在記憶體中只有一份,我們詳細介紹Reference Count。

  3. 使用一個地方管理所有素材。

  4. 可以實現素材的緩存。

LibGDX官方解釋

  1. Loading of most resources is done asynchronously, so you can display a rea​​ctive loading screen while things load.

  2. Assets are reference counted. If two assets A and B both depend on another asset C, C won't be disposed until A and B have been disposed. This also means that if you load an asset multiple times, it will actually be shared and only take up memory once!

  3. A single place to store all your assets.

  4. Allows to transparently implement things like caches

Assets Class Diagram

這一次我們建立一個Assets類別,它會用到LibGDX預設的AssetManager類別,我們把Assets類別加到第23節 - LibGDX: Advanced Game Menu Screen (Using Abstract Screen)的Class Diagram上,如下圖:

LibGDX AssetManager
  1. MyDemo26是Class,Assets是Class(傳入MyDemo26內用),所以它們的關係是Association。

Reference Counting

Reference Counting(引用計數)是計算機編程語言中的一種內存管理技術,是指將資源(可以是對象、內存或磁盤空間等等)的被引用次數保存起來,當被引用次數變為零時就將其釋放的過程。使用引用計數技術可以實現自動資源管理的目的。同時引用計數還可以指使用引用計數技術回收未使用資源的垃圾回收算法。

在計算機科學中,Garbage Collection(垃圾回收)是一種自動的記憶體管理機制。當一個電腦上的動態記憶體不再需要時,就應該予以釋放,以讓出記憶體,這種記憶體資源管理,稱為垃圾回收Garbage Collection。垃圾回收器可以讓程式員減輕許多負擔,也減少程式員犯錯的機會。

In computer science, reference counting is a technique of storing the number of references, pointers, or handles to a resource such as an object, block of memory, disk space or other resource. It may also refer, more specifically, to a garbage collection algorithm that uses these reference counts to deallocate objects which are no longer referenced.

As a collection algorithm, reference counting tracks, for each object, a count of the number of references to it held by other objects. If an object's reference count reaches zero, the object has become inaccessible, and can be destroyed.

Assets Reference VS Reference Variables

LibGDX AssetManager

Assets Reference和Reference Variables都是代表某類別物件的Reference,但它們有些不同,texture1和 texture2 是Texture Class的Reference Variables,而Assets Reference是指某個Asset(例如:splashscreen.png)所產生的Reference,不同References會共享一個記憶體位址。

texture1 & texture2 are reference variables of Texture Class。
Assets Reference is the reference of an Asset (e.g. splashscreen.png) which is loaded in a memory address, Different references will be shared the same memory.

例子

以下會用幾個簡單例子說明Java Reference Variables和LibGDX Assets Reference的分別。

注意,Java程式語言是沒有預設Reference Counting功能的。

Java Reference Variables - 例子1

例子1建立一個A類別物件new A()和Reference Varaible(a)。

LibGDX AssetManager

Java Reference Variables - 例子2

例子2建立一個A類別物件new A()和Reference Varaible(a),再建立一個類別物件new B()和Reference Varaible(b)。

LibGDX AssetManager

Java Reference Variables - 例子3

例子3建立一個A類別物件new A()和Reference Varaible(a),再建立一個Reference Varaible(b)指向A類別物件new A()。

LibGDX AssetManager

LibGDX Assets Reference Counting - 例子1

LibGDX的AssetManager類別預設有Reference Counting功能,所以我們建立的Assets類別(Assets.java)內也是用到AssetManager類別,所以當我們在任何地方呼叫Assets.load()方法,它都有Reference Counting功能的。

LibGDX AssetManager


建立一個臨時的AssetsTest.java類別作測試。

LibGDX AssetManager
  1. 建立load()方法,在load()方法內執行manager.load()方法。

  2. 建立unload()方法,在unload()方法內執行manager.unload()方法。

建立一個臨時的MyDemo26_1.java類別作測試。

LibGDX AssetManager
  1. 呼叫AssetsTest.load();,完成後呼叫AssetsTest.manager.finishLoading();這樣做就會產生第一個Assets Reference,所以Reference Counting=1。

  2. 把texture1和texture2設定到splashscreen.png上, texture1和texture2是Texture Class的Reference Variables。

  3. 用LibGDX AssetManager類別預設的getReferenceCount()方法把現時Reference Counting數目顯示在屏幕上。

執行結果。

LibGDX AssetManager
  1. Asset (splashscreen.png)的Reference Counting=1。

LibGDX Assets Reference Counting - 例子2

LibGDX AssetManager


建立一個臨時的MyDemo26_1.java類別作測試。

LibGDX AssetManager
  1. 呼叫AssetsTest.load();,完成後呼叫AssetsTest.manager.finishLoading();這樣做就會產生第一個Assets Reference,所以Reference Counting=1。

    把texture1和texture2設定到splashscreen.png上, texture1和texture2是Texture Class的Reference Variables。

    用LibGDX AssetManager類別預設的getReferenceCount()方法把現時Reference Counting數目顯示在屏幕上。

  2. 重複步驟1,所以Reference Counting=2。

執行結果。

LibGDX AssetManager
  1. Asset (splashscreen.png)的Reference Counting=2。

LibGDX Assets Reference Counting - 例子3

LibGDX AssetManager


建立一個臨時的MyDemo26_1.java類別作測試。

LibGDX AssetManager
  1. 呼叫AssetsTest.load();,完成後呼叫AssetsTest.manager.finishLoading();這樣做就會產生第一個Assets Reference,所以Reference Counting=1。

    把texture1和texture2設定到splashscreen.png上, texture1和texture2是Texture Class的Reference Variables。

    用LibGDX AssetManager類別預設的getReferenceCount()方法把現時Reference Counting數目顯示在屏幕上。

  2. 重複步驟1,所以Reference Counting=2。

  3. 呼叫AssetsTest.unload();,其中一個Assets Reference就會進行銷毀,所以Reference Counting=1。

執行結果。

LibGDX AssetManager
  1. Asset (splashscreen.png)的Reference Counting回復=1。

Assets Class 內容

我會建立一個Assets類別,它會用到LibGDX預設的AssetManager類別,在LibGDX官方的AssetManager.java內可以看到以下主要的幾個方法,我會一一介紹:

LibGDX AssetManager
  1. load()方法就是用來加載Assets(素材),例如:Textures、 BitmapFonts、Music和Sound等等 。

  2. finishLoading()方法才真正代表加載完畢,單純呼叫load()方法只是安排了排隊執行程式,而沒有真正加載Assets(素材)。

  3. dispose()方法實現了Disposable介面(interface),凡是實現了Disposable介面,都應該在程序結束時對該類進行銷毀。

  4. update()方法回傳一個boolean值(true or false),如果用update()方法就不須要用finishLoading()方法,兩者選一。

    finishLoading()方法會用同步(Synchronous)執行,則是它會在一條隊裡加載Assets,直到加載完畢才繼續其他程式。

    而update()方法會用異步(Asynchronous)執行,就好像兩條並行的隊,加載Assets的任務就交給第二條隊(真正叫Thread),所以在第二條隊加載Assets時,我們就可以用update()方法回傳一個boolean值(true or false),如果值是false,則是加載Assets尚未完成,我們可以爭取時間,執行其他程式,例如顯示Progress Bar, 50% Loading....等等。

  5. getProgress()方法就是用來顯示加載Assets的進度,回傳0至1的值(再x100得到0至100),我們可以用來顯示Progress Bar, 50% Loading....等等,我會在本節詳細介紹。

  6. unload()方法就是用來把以上介紹的Reference Count數值減少一,則是如果我們呼叫一次Assets.load()方法,Reference Count=1,如果再呼叫第二次Assets.load()方法,Reference Count=2,Assets就不能進行銷毀,直至Reference Count回復1才能進行銷毀。

Assets Class 簡單版

以下是Assets Class的簡單版,我們只用到:

1. load();
2. finishLoading();
3. dispose();

LibGDX AssetManager

以下是實際例子:

LibGDX AssetManager
  1. load()方法用來加載Assets mainmenu.pack。

  2. finishLoading()方法代表加載完畢,單純呼叫load()方法只是安排了排隊執行程式,而沒有真正加載Assets mainmenu.pack。

  3. dispose()方法實現了Disposable介面(interface),凡是實現了Disposable介面,都應該在程序結束時對該類進行銷毀。

Assets Class 進階版

以下是Assets Class的進階版,我們只用到:

1. load();
4. update();
5. getProgress();
3. dipose();

LibGDX AssetManager

以下是實際例子:

LibGDX AssetManager
  1. load()方法用來加載Assets mainmenu.pack。

  2. update()方法回傳一個boolean值(true or false),如果用update()方法就不須要用finishLoading()方法,兩者選一。

    update()方法會用異步(Asynchronous)執行,就好像兩條並行的隊,加載Assets的任務就交給第二條隊(真正叫Thread),所以在第二條隊加載Assets時,我們就可以用update()方法回傳一個boolean值(true or false),如果值是false,則是加載Assets尚未完成,我們可以爭取時間,執行其他程式,例如顯示Progress Bar, 50% Loading....等等。

    getProgress()方法就是用來顯示加載Assets的進度,回傳0至1的值(再x100得到0至100),我們可以用來顯示Progress Bar, 50% Loading....等等,我會在本節詳細介紹。

  3. dispose()方法實現了Disposable介面(interface),凡是實現了Disposable介面,都應該在程序結束時對該類進行銷毀。

Assets Class 進階版 - 測試1

LibGDX AssetManager
  1. 假設我們只呼叫一個Asset,例如呼叫一次manager.load();。

  2. Testing: 0.0% 代表0%未完成,則100%完成。

Assets Class 進階版 - 測試2

LibGDX AssetManager
  1. 假設我們只呼叫兩個Asset,例如呼叫兩次manager.load();。

  2. Testing: 50.0% 代表50%未完成,則50%完成。

Assets Class 進階版 - 測試3

LibGDX AssetManager
  1. 假設我們只呼叫三個Asset,例如呼叫三次manager.load();。
  2. Testing: 33.33333% 代表33.33333%未完成,則66.66666%完成。

Assets Class 進階版 - Progress Bar/Loading Bar

我們可以用update()方法,在boolean值是false時,則是加載Assets尚未完成,用getProgress()方法顯示Progress Bar, 50% Loading....等等,以下是Progress Bar的例子,我會在其他章節詳細介紹:

LibGDX AssetManager


第22節 - LibGDX: Game Menu Screen

第22節 - LibGDX: Game Menu Screen沒有用到AbstractScreen類別和AssetManger類別,如下圖:

LibGDX AssetManager
  1. SplashScreen類別須要加載一次splashscreen.png。

  2. 所有MenuScreen、LevelScreen、 OptinsScreen和CreditsScreen類別都獨立加載一次mainmenu.pack,總數四次。

  3. FacebookScreen類別須要加載一次facebookscreen.png。

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

第23節 - LibGDX: Advanced Game Menu Screen (Using Abstract Screen)只用到AbstractScreen類別,沒有用到AssetManger類別,如下圖:

LibGDX AssetManager
  1. SplashScreen類別須要加載一次splashscreen.png。

  2. MenuScreen類別須要加載一次mainmenu.pack。

  3. 我們新增一個AbstractScreen抽象類別,把LevelScreen、 OptinsScreen和CreditsScreen類別的mainmenu.pack搬到AbstractScreen抽象類別上執行。

    注意,我們只是把skin程式搬到AbstractScreen抽象類別上執行,但當LevelScreen、 OptinsScreen或CreditsScreen類別加載mainmenu.pack時,其實它們也是獨立加載一次mainmenu.pack(用getSkin()方法),所以總數也是四次,AbstractScreen抽象類別只把相同部分放在一起或設立大家須要執行的抽象方法。

  4. FacebookScreen類別須要加載一次facebookscreen.png。

第26節 - LibGDX: Advanced Game Menu Screen (Using AssetManager)

第26節 - LibGDX: Advanced Game Menu Screen (Using AssetManager)用到AbstractScreen類別和AssetManger類別,如下圖:

LibGDX AssetManager
  1. 我們新增一個Assets類別,在Assets類別內我們加入一個LibGDX的話AssetManger類別再用static load()方法加載mainmenu.pack一次。

    注意1,我們新增一個Assets類別,把AbstractScreen抽象類別的mainmenu.pack搬到Assets類別上執行。

    注意2,用static load()則是代表load()是一個類別方法(不是成員方法),所以我們就可以在程式的任何位置呼叫Assets.load();

    注意3,我們可以在程式的任何位置呼叫Assets.manager.get()方法傳取mainmenu.pack,用幾多次Assets.manager.get()傳取mainmenu.pack,加載次數都只是一次。

  2. SplashScreen類別須要加載一次splashscreen.png。

  3. MenuScreen類別須要加載一次mainmenu.pack。

  4. FacebookScreen類別須要加載一次facebookscreen.png。

用AssetManager類別重寫Game Menu Screen

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

注意,我們以下的Game Menu Screen程式只會用上一次Assets.load();,所以Reference Count=1,不須要用到Assets.unload();。

Assets Resources

LibGDX AssetManager
  1. 建立文件夾fonts,把carterone.fnt和carterone.png傳入assets/fonts/內。

  2. 把mainmenu.pack,mainmenu.png,mainmenu2.png,mainmenu3.png,mainmenu.json和splashscreen.png傳入assets/內。

  3. 在MyDemo26-core/src/com.hkprogram.mydemo26/內建立所有.java程式檔案。

DesktopLauncher.java

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

Assets.java

以下是Assets.java程式:

LibGDX AssetManager
  1. 建立一個類別成員(static AssetManger manager)和一個static Skin menuSkin,這樣做,我們可以在程式的任何位置呼叫Assets.manager.xxx();方法或是Assets.menuSkin。

  2. load()方法就是用來加載mainmenu.pack 。

  3. 我們再新增一個類別方法static setMenuSkin(),把mainmenu.json和mainmenu.pack傳入menuSkin物件上,這樣做,我們可以在程式的任何位置呼叫Assets.setMenuSkin();方法,就可再呼叫Assets.menuSkin當時skin物件用。

  4. update()方法回傳一個boolean值(true or false),如果用update()方法就不須要用finishLoading()方法,兩者選一。

    finishLoading()方法會用同步(Synchronous)執行,則是它會在一條隊裡加載Assets,直到加載完畢才繼續其他程式。

    而update()方法會用異步(Asynchronous)執行,就好像兩條並行的隊,加載Assets的任務就交給第二條隊(真正叫Thread),所以在第二條隊加載Assets時,我們就可以用update()方法回傳一個boolean值(true or false),如果值是false,則是加載Assets尚未完成,我們可以爭取時間,執行其他程式,例如顯示Progress Bar, 50% Loading....等等。

  5. dispose()方法實現了Disposable介面(interface),凡是實現了Disposable介面,都應該在程序結束時對該類進行銷毀。

MyDemo26.java

以下是MyDemo26.java程式:

LibGDX AssetManager
  1. 在MyDemo26.java內把MyDemo26 extends Game。

    呼叫Assets.load()方法,再呼叫Assets.manager.finishLoading()方法。

  2. 最後別忘記把在dispose()方法內輸入super.dispose();和Assets.dispose();。

SplashScreen.java

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

LibGDX AssetManager
  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. 我們運用Assets.update()方法回傳一個boolean值(true or false),如果值是false,則是加載Assets尚未完成,我們可以爭取時間,執行Assets.setMenuSkin();設定menuSkin。

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

  6. 最後別忘記把在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 AssetManager
  1. 設定所有Member Variables。

  2. 把Skin物件(skin)刪除。

  3. 把所有Skin物件(skin)改為Assets.menuSkin。
    建立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 AssetManager
  1. 把AbstractScreen抽象類別實作Screen介面。

  2. 設定所有Member Variables,把Skin物件(skin)刪除。

  3. 刪除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()方法內輸入stage.dispose();,但刪除skin.dispose();。

LevelScreen.java

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

LibGDX AssetManager
  1. 把LevelScreen類別繼承AbstractScreen抽象類別。

  2. 在show()方法內除了呼叫super.show()外,再執行只有LevelScreen類別獨有的部分,注意把Skin物件(skin)改為Assets.menuSkin。

  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 AssetManager
  1. 把OptionsScreen類別繼承AbstractScreen抽象類別。

  2. 在show()方法內除了呼叫super.show()外,再執行只有LevelScreen類別獨有的部分,注意把Skin物件(skin)改為Assets.menuSkin。

  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()方法。

CreditsScreen.java

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

LibGDX AssetManager
  1. 把CreditsScreen類別繼承AbstractScreen抽象類別。

  2. 在show()方法內除了呼叫super.show()外,再執行只有LevelScreen類別獨有的部分,注意把Skin物件(skin)改為Assets.menuSkin。

  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 AssetManager
  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!