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

第42節 - LibGDX: WorldController & WorldRenderer Class

這一節我會介紹LibGDX的兩個自定類別 - WorldController & WorldRenderer,這兩個類別的主要功能是把程式碼分類,一個好的程式結構,會讓程式有更好的閱讀和維護,也可減少除錯的時間。

WorldController類別 - 這個類別用來把所有有關"更新時間",則"deltaTime"有關的程式碼放在這裡。

WorldRender類別 - 這個類別用來把其他程式碼,例如: create()方法內所產生的物件和render()方法內須要顯示在屏幕上的有關的程式碼放在這裡。

以下會用不同的例子詳細說明:

例子1 - Not Using WorldController & WorldRenderer Class

這個例子是第33節的例子2,這個例子很簡單,沒有用上WorldController和WorldRenderer類別。

以下是Class Diagram:

LibGDX: WorldController & WorldRenderer Class
  1. 把ApplicationAdapter抽象類別實作ApplicationListener介面。

  2. 把MyDemo42類別繼承ApplicationAdapter抽象類別,所有程式碼,包括以上提及的deltaTime,create()方法內所產生的物件和render()方法內須要顯示在屏幕上的有關的程式碼放在MyDemo42類別內。

LibGDX程式

DesktopLauncher.java

LibGDX: WorldController & WorldRenderer Class
  1. DesktopLauncher是PC Desktop的Starter Class,我們在DesktopLauncher內設定顯示的大小為1024 X 768 px。

LibGDX: WorldController & WorldRenderer Class
  1. 把bullet.png、hero1Atlas.pack和hero1Atlas.png儲存到Android的Assets文件夾內(/data/...)。

    把map.tmx和tileAtlas.png儲存到Android的Assets文件夾內(/map/...)。

    把bgsound1.mp3和gun1.mp3儲存到Android的Assets文件夾內(/sound/...)。

MyDemo42.java

LibGDX: WorldController & WorldRenderer Class
  1. 建立一個speed變數(float type),並設定值為150。

  2. 建立一個xPosition變數(float type)。

  3. 建立一個deltaTime變數(float type)。

  4. 設定deltaTime初始值為0.0f。

  5. 設定xPosition的初始值為-(1920/2)。

  6. Gdx.graphics.getDeltaTime()方法敢得 兩格(two frames)動畫之間的時間,再傳入deltaTime變數內。

  7. 設定sprite位置的初始值。

  8. 根據最新deltaTime的值,更新xPosition位置。

執行程式:

LibGDX: WorldController & WorldRenderer Class

例子2 - WorldController & WorldRenderer Class

例子2會把例子1加上WorldController和WorldRenderer類別。

以下是Class Diagram:

LibGDX: WorldController & WorldRenderer Class
  1. 把ApplicationAdapter抽象類別實作ApplicationListener介面。

  2. 建立WorldController類別,把有關deltaTime的程式碼放在WorldController類別內,再把WorldController物件(worldController)傅入DyDemo42_1類別內,這樣做,就可以在DyDemo42_1類別內執行worldController的方法。

  3. 建立WorldRenderer類別,把WorldController物件(worldController)傅入,再把WorldRenderer物件(worldRenderer)傅入DyDemo42_1類別內,這樣做,就可以在DyDemo42_1類別內執行worldRenderer的方法。

    注意,所有程式碼,包括以上提及create()方法內所產生的物件和render()方法內須要顯示在屏幕上的有關的程式碼放在WorldRenderer類別內。

LibGDX程式

DesktopLauncher.java

LibGDX: WorldController & WorldRenderer Class
  1. DesktopLauncher是PC Desktop的Starter Class,我們在DesktopLauncher內設定顯示的大小為1024 X 768 px。

LibGDX: WorldController & WorldRenderer Class
  1. 把bullet.png、hero1Atlas.pack和hero1Atlas.png儲存到Android的Assets文件夾內(/data/...)。

    把map.tmx和tileAtlas.png儲存到Android的Assets文件夾內(/map/...)。

    把bgsound1.mp3和gun1.mp3儲存到Android的Assets文件夾內(/sound/...)。

MyDemo42_1.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先建立兩個private的物件變數worldRenderer和worldController。

  2. 在create()方法內,建立worldRenderer和worldController物件。

  3. 在render()方法內,執行worldController.update()方法和worldRenderer()方法。

  4. 別忘記呼叫worldRenderer.dispose()方法,釋放資源。

WorldRenderer.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先建立一個private的物件變數worldController。

  2. 建立WorldRenderer類別的Constructor,把worldController傳入。

  3. 現在就可以把animationTime更改為worldController.getAnimationTime()。

  4. 把deltaTime更改為worldController.getDeltaTime()。

WorldController.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先建立兩個private的物件變數deltaTime和animationTime。

  2. 建立WorldController類別的Constructor,設定deltaTime和animationTime的初始值為0.0f。

  3. 建立一個新的update()方法,讀取deltaTime的數值,並設定deltaTime和animationTime的更新值。

  4. 建立deltaTime和animationTime的getter和setter,getter和setter可以用來傳入和讀取WorldController類別內的變數值。

    注意,我會在其他章節詳細介紹getter和setter。

執行程式:

注意,程式執行結果與例子1完全相同。

LibGDX: WorldController & WorldRenderer Class

例子3 - Use WorldController & WorldRenderer Class in Section 41

例子3會把第41節的2D platform Game加上WorldController和WorldRenderer類別。

以下是Class Diagram:

LibGDX: WorldController & WorldRenderer Class
  1. 把第41節的2D platform Game加入WorldRenderer類別和WorldController類別。

  2. 把WorldRenderer類別實作Disposable介面,這樣做,我們就必須定義dispose()方法。

  3. 把WorldRenderer類別實作InputProcessor介面,這樣做,我們就可以定義所有關於Input的方法。

  4. 把Bullet、 BackgroundSound和GunSound的物件傳入WorldRenderer類別內。

LibGDX程式

DesktopLauncher.java

LibGDX: WorldController & WorldRenderer Class
  1. DesktopLauncher是PC Desktop的Starter Class,我們在DesktopLauncher內設定顯示的大小為1024 X 768 px。

LibGDX: WorldController & WorldRenderer Class
  1. 把bullet.png、hero1Atlas.pack和hero1Atlas.png儲存到Android的Assets文件夾內(/data/...)。

    把map.tmx和tileAtlas.png儲存到Android的Assets文件夾內(/map/...)。

    把bgsound1.mp3和gun1.mp3儲存到Android的Assets文件夾內(/sound/...)。

MyDemo42_2.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先建立兩個private的物件變數worldRenderer和worldController。

  2. 在create()方法內,建立worldRenderer和worldController物件。

  3. 在render()方法內,執行worldController.update()方法和worldRenderer()方法。

  4. 別忘記呼叫worldRenderer.dispose()方法,釋放資源。

WorldRenderer.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先WorldRenderer類別,並把WorldRenderer類別實作Disposable和InputProcessor介面。

  2. 建立一個private的物件變數worldController。

  3. 建立WorldRenderer類別的Constructor,把worldController傳入。

  4. 把animationTime更改為worldController.getAnimationTime()和把deltaTime更改為worldController.getDeltaTime()。

  5. 別忘記呼叫dispose()方法,釋放資源。

WorldController.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先建立兩個private的物件變數deltaTime和animationTime。

  2. 建立WorldController類別的Constructor,設定deltaTime和animationTime的初始值為0.0f。

  3. 建立一個新的update()方法,讀取deltaTime的數值,並設定deltaTime和animationTime的更新值。

  4. 建立deltaTime和animationTime的getter和setter,getter和setter可以用來傳入和讀取WorldController類別內的變數值。

    注意,我會在其他章節詳細介紹getter和setter。

Bullet.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先在Bullet類別的Constructor內,把bulletPosition和bulletVelocityX傳入。

    bulletPosition就是主角hero1的子彈發射位置。

  2. 建立一個update()方法,把子彈的位置加上bulletVelocityX傳入的數值。

BackgroundSound.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先在BackgroundSound類別的Constructor內,把bgsound1.mp3傳入Sound物件(sound)內。

  2. 建立一個playSound()方法,用sound.loop()方法重複播放背景音樂,音量是0至1,0.5f代表設定音量為一半。

GunSound.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先在GunSound類別的Constructor內,把gun1.mp3傳入Sound物件(sound)內。

  2. 建立一個playSound()方法,用sound.play()方法播放發射子彈音效,音量是0至1,0.5f代表設定音量為一半。

    注意,發射子彈音效不須要重複播放,所以我們不用sound.loop()方法。

執行程式:

LibGDX: WorldController & WorldRenderer Class

例子4 - Use Game Class

例子4會把MyDemo42_3類別繼承Game抽象類別,這是因為Game類別內有一個setScreen()方法,它可以用來轉換畫面,例如在第16節 - LibGDX: Splash Screen用來做過埸畫面。

以下是Class Diagram:

LibGDX: WorldController & WorldRenderer Class
  1. 把MyDemo42_3類別繼承Game抽象類別。

  2. 建立一個新的LevelOneScreen類別,並實作Screen介面,再把LevelOneScreen物件(levelOneScreen)傳入到MyDemo42_3,它可以用來轉換畫面。

  3. 把WorldRenderer類別實作Disposable介面,這樣做,我們就必須定義dispose()方法。

  4. 把WorldRenderer類別實作InputProcessor介面,這樣做,我們就可以定義所有關於Input的方法。

  5. 把Bullet、 BackgroundSound和GunSound的物件傳入WorldRenderer類別內。

LibGDX程式

DesktopLauncher.java

LibGDX: WorldController & WorldRenderer Class
  1. DesktopLauncher是PC Desktop的Starter Class,我們在DesktopLauncher內設定顯示的大小為1024 X 768 px。

LibGDX: WorldController & WorldRenderer Class
  1. 把甩bullet.png、hero1Atlas.pack和hero1Atlas.png儲存到Android的Assets文件夾內(/data/...)。

    把map.tmx和tileAtlas.png儲存到Android的Assets文件夾內(/map/...)。

    把bgsound1.mp3和gun1.mp3儲存到Android的Assets文件夾內(/sound/...)。

MyDemo42_3.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先把MyDemo42_3繼承Game抽象類別。

  2. 建立一個LevelOneScreen物件(levelOneScreen)傳入到setScreen()方法內,它可以用來轉換畫面。

LevelOneScreen.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先建立三個private的物件變數game、worldRenderer和worldController。

  2. 建立LevelOneScreen類別的Constructor,把game傳入。

  3. 在show()方法內,建立worldRenderer和worldController物件。

  4. 在render()方法內,執行worldController.update()方法和worldRenderer()方法。

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

WorldRenderer.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先WorldRenderer類別,並把WorldRenderer類別實作Disposable和InputProcessor介面。

  2. 建立一個private的物件變數worldController。

  3. 建立WorldRenderer類別的Constructor,把worldController傳入。

  4. 把animationTime更改為worldController.getAnimationTime()和把deltaTime更改為worldController.getDeltaTime()。

  5. 別忘記呼叫dispose()方法,釋放資源。

WorldController.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先建立兩個private的物件變數deltaTime和animationTime。

  2. 建立WorldController類別的Constructor,設定deltaTime和animationTime的初始值為0.0f。

  3. 建立一個新的update()方法,讀取deltaTime的數值,並設定deltaTime和animationTime的更新值。

  4. 建立deltaTime和animationTime的getter和setter,getter和setter可以用來傳入和讀取WorldController類別內的變數值。

    注意,我會在其他章節詳細介紹getter和setter。

Bullet.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先在Bullet類別的Constructor內,把bulletPosition和bulletVelocityX傳入。

    bulletPosition就是主角hero1的子彈發射位置。

  2. 建立一個update()方法,把子彈的位置加上bulletVelocityX傳入的數值。

BackgroundSound.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先在BackgroundSound類別的Constructor內,把bgsound1.mp3傳入Sound物件(sound)內。

  2. 建立一個playSound()方法,用sound.loop()方法重複播放背景音樂,音量是0至1,0.5f代表設定音量為一半。

GunSound.java

LibGDX: WorldController & WorldRenderer Class
  1. 首先在GunSound類別的Constructor內,把gun1.mp3傳入Sound物件(sound)內。

  2. 建立一個playSound()方法,用sound.play()方法播放發射子彈音效,音量是0至1,0.5f代表設定音量為一半。

    注意,發射子彈音效不須要重複播放,所以我們不用sound.loop()方法。

執行程式:

注意,程式執行結果與例子3完全相同。

LibGDX: WorldController & WorldRenderer Class

為甚麼LevelOneScreen要實作Screen介面?

很簡單,因為這樣做我們就可以把我們的2D Platform Game連接到第26節 - LibGDX: Advanced Game Menu Screen (using AssetManager)上,如下圖:

以下是Class Diagram:

LibGDX: WorldController & WorldRenderer Class
  1. 第26節 - LibGDX: Advanced Game Menu Screen (using AssetManager)。

  2. 這一節,第42節 - LibGDX: WorldController & WorldRenderer Class。

以下是第42節 - LibGDX: WorldController & WorldRenderer Class程式執行的結果:

注意,程式執行結果與第41節完全相同。


Download above code and sample pictures here!