เขียนเกมด้วย LibGDX 6 – Simple Game ภาคพิเศษ
กลับมาพบกับซีรีย์เขียนเกมด้วย LibGDX กันต่อครับ บทความนี้เป็นบทความที่ 6 แล้วครับ จะมาพูดต่อ จากบทความที่แล้ว คือ เขียนเกมด้วย LibGDX #5 – Simple Game ตอนจบ โดยในบทความนี้จะทำการเพิ่มหน้า เมนู และระบบต่างๆที่ทำให้เกมดูสมจริงขึ้นครับ
บทความตอนอื่นๆ ในซีรีย์ เขียนเกมด้วย LibGDX ติดตามอ่านได้ตามลิงค์ข้างล่างเลยครับ
- เขียนเกมด้วย libGDX #1 – สร้างโปรเจ็ค
- เขียนเกมด้วย LibGDX #2 – Hello World
- เขียนเกมด้วย LibGDX #3 – Render และการรับ input
- เขียนเกมด้วย LibGDX #4 – Simple Game ภาคแรก
- เขียนเกมด้วย LibGDX #5 – Simple Game ภาคจบ
- เขียนเกมด้วย LibGDX #6 – Simple Game ภาคพิเศษ
- เขียนเกมด้วย LibGDX #7 - Simple Game - scene2d.ui
- เขียนเกมด้วย LibGDX #8 - Simple Game - Actor
เริ่มกันเลยครับ มาพูดถึงคลาสในเกมของเราก่อนดีกว่า เริ่มจาก
The Screen interface
Screens ถือเป็นพื้นฐานของทุกๆเกมส์เลยก็ว่าได้ครับ Screens
นั้นมีเมธอดให้เลือกใช้จาก ออปเจ็ค ApplicationListener
รวมถึงเมธอด show
และ hide
ที่จะถูกเรียกเมื่อเวลาโฟกัสและไม่ได้โฟกัสหน้าจอ
The Game Class
abstract คลาส Game นั้น implement ApplicationListener
สำหรับใช้เป็น helper เมธอด สำหรับจัดการการเรนเดอร์ต่างๆของหน้าจอครับ
ทั้งออปเจ็ค Screen และ Game ใช้สำหรับเป็นโครงสร้างพื้นฐานสำหรับเขียนเกมครับ เราจะมาเริ่มโดยการสร้างออปเจ็ค Game กันครับ จากบทความเก่า คลาส Drop
ของเรา ทีแรกจะ implements ApplicationListener
ใช่มั้ย มาอันนี้เราจะให้ทำการ extends Game
ครับ ซึ่งออปเจ็คเกมนั้นก็ implements ApplicationListener
มาอีกทีครับ เวลาเรา extends เราก็ไม่จำเป้นต้อง implement ทุกเมธอดครับ สนใจเฉพาะ create
, render
และ dispose
เราเริ่มต้นด้วยการสร้างแอพพลิเคชัน โดยสร้างออปเจ็ค SpriteBatch
และ BitmapFont
ใหม่ (มันอาจจะเป็นตัวอย่างที่ไม่ดีนัก หากพูดถึงกฎเรื่อง DRY Don’t Repeat Yourself. ออปเจ็ค SpriteBatch
ใช้สำหรับเรนเดอร์ออปเจ็คบนหน้าจอ เช่น Texture ส่วน BitmapFont
ใช้สำหรับเรนเดอร์ข้อความบนหน้าจอครับ โดยใช้ร่วมกับ SpriteBatch
ถัดมา เราทำการสร้าง Screen ของเกมครับ โดยใช้คลาส MainMenuScreen
จะใช้เป็นหน้าจอเมนูตอนเริ่มเข้าสู่เกม โดยรับคลาส Drop เป็น parameter ครับ (คลาส MainMenuScreen ยังไม่ได้สร้างนะครับ หากว่าตอนนี้มี error ก็ปล่อยไปก่อน)
อย่าลืมเรียก
super.render()
ในเมธอดrender
ที่เรา implement คลาส Game มาด้วยนะครับ ไม่อย่างนั้น Screen ที่เราทำการสร้างตรงเมธอดcreate()
จะไม่เรนเดอร์อะไรออกมาเลย
สุดท้าย อย่าลืมเมธอด dispose()
ครับ อ่านเพิ่มเติม การจัดการ Assets
The Main Menu
มาถึงการสร้างคลาส MainMenuScreen แล้วครับ โดยทำการ implement Screen ก่อนเลยครับ
จากโค๊ดด้านบน เราได้สร้าง constructor สำหรับคลาส MainMenuScreen
ที่ implements อินเตอร์เฟส Screen. อินเตอร์เฟส Screen นั้นไม่มีเมธอด create()
มาให้นะครับ นั่นจึงเป็นเหตุผลว่าทำไมเราต้องสร้าง Constructor ของเราขึ้นเอง สำหรับ constructor เราก็รับออปเจ็ค Drop
เข้ามาครับ ตัวที่ส่งมาจากคลาส Drop
ตรงเมธอด create#setScreen
ถัดมาทำการ override เมธอด render
ครับ หากยังจำโค๊ดจากบทความเก่าได้ เมธอด render
ของ ApplicationListener
จะไม่มี parameter เลย ขณะที่ เมธอด render
อันนี้รับ parameter เป็น float ครับ ซึ่งก็คือ deltaTime เราไม่ต้องไปใช้ Gdx.graphics.getDeltaTime()
แล้ว
โค๊ดด้านบน สังเกตที่ SpriteBatch
และ BitmapFont
เราไม่ได้สร้างออปเจ็คมันขึ้นมา แต่เราใช้อ้อปเจ็คทั้งสองที่ได้สร้างจากคลาส Game
สำหรับ game.font.draw(SpriteBatch, String, float, float)
คือเมธอดที่ใช้สำหรับแสดงข้อความบทหน้าจอ สำหรับฟ้อนพื้นฐานที่มีมาให้คือฟ้อน Arial ครับ
ถัดมาก็ทำการเช็คว่ามีการแตะที่หน้าจอหรือไม่ ถ้ามี ก็ให้ setScreen คือเปลี่ยนหน้าจอ ไปที่หน้าจอ GameScreen ครับ โดยส่งอ็อปเจ็ค game ไปเป็น parameter ด้วย ครับ (ลองนึกถึง เวลาเข้าเกมมาครับ หน้าแรก จะโชว์หน้าจอนี้ แล้วเมื่อผู้เล่นทำการแตะหน้าจอ ก็จะไปหน้าจอเล่นเกมครับ)
หน้าตาที่ได้ก็จะได้ประมาณนี้
The Game Screen
มาถึง Game Screen บ้างครับหลังจากที่ทำหน้า Menu เสร็จไปแล้ว ตัว GameScreen อันนี้จะเป็นหน้าจอหลักที่ไว้สำหรับเล่นเกมเลยครับ โค๊ดส่วนใหญ่ก็เหมือน บทความที่แล้วครับ ต่างกันที่ GameScreen
จะทำการ implements Screen
แล้วรับออปเจ็ค Game เป็น parameter ในขณะที่โค๊ดเก่า เราสร้างคลาส Drop
โดย implements ApplicationListener
โค๊ดด้านบนนั้น 95% นั้นเหมือนกับโค๊ดจากคลาส Drop
ในบทความที่แล้ว ต่างกันที่เราใช้ constructor แทนที่เมธอด create()
ของ ApplicationListener
แล้วก็ส่งค่าออปเจ็ค Drop
เหมือนอย่างคลาส MainMenuScreen
สุดท้ายก็ทำการเล่นเสียงเพลง เมื่อหน้า GameScreen
นี้แสดง
รวมถึงได้เพิ่มข้อความที่มุมุซ้ายบนของหน้าจอเกม เพื่อเก็บบันทึกว่าเก็บเม็ดฝนไปกี่เม็ดแล้ว
เอาละ สุดท้ายตัวเกมก็เสร็จเรียบร้อยแล้วครับ ตอนนี้ถ้าได้อ่านมาถึงบทความนี้ เชื่อว่าหลายๆคนต้องพอรู้พื้นฐาน LibGDX รวมถึงรู้ ในเรื่องอินเตอร์เฟซ Screen , abstract คลาส Game และ Game State ต่างๆมากขึ้นครับ
สำหรับหน้าจอตัวอย่างเกมก็จะได้แบบนี้ ลองนำโค๊ดที่ได้ไปปรับใช้ แล้วลองเรียนรู้ ลองเล่นกันดูนะครับ การเรียนโปรแกรมมิ่งที่ดีที่สุด ไม่ใช่การอ่านหรือทำตาม Tutorial ครับ แต่มันคือการทดลอง ลองผิดลองถูกกับมันครับ
โค๊ดทั้งหมด
Drop.java
GameScreen.java
MainMenuScreen.java
Reference :
- Authors
-
Chai Phonbopit
เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust