เขียนเกมด้วย LibGDX :3 – Render และการรับ input
สวัสดีครับ บทความนี้เป็นบทความที่ 3 ครับ จากซีรีส์ สอน LibGDX ครับ
บทความตอนอื่นๆ ในซีรีย์ เขียนเกมด้วย 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
สำหรับบทความนี้จะมานำเสนอ วิธีการทำให้รูปภาพเคลื่อนที่ได้ และการรับ input ต่างๆ เช่นเมาท์คลิ๊ก กดคีย์บอร์ด หรือว่า ทัชสกรีนบนหน้าจอมือถือแอนดรอยส์กันครับ
ตัวอย่างนี้ผมใช้วิธีง่ายๆ คือโหลดรูปมาแสดงบนหน้าจอ จากนั้น ก็จะให้มันขยับไปทางขวา จนสุดจอ แล้วก็วนมาเริ่มต้นไป วนแบบนี้ไปเรื่อยๆครับ
ก็อบปี้รูปของท่านเอง ไปไว้ที่ project-android/assets/
หรืออยากจะโหลดรูปตัวอย่าง ก็ตามนี้ครับ
ไฟล์ image ผมใช้ไฟล์ของผมเอง ชื่อ
chai.png
Credit: Thaweepong on Behance
ตัวอย่างใช้คลาส MyGame จาก บทความที่ 2 ได้เลยครับ ข้างล่างคือคลาส MyGame เดิมครับ
จากด้านบน ผมจะเปลี่ยนให้เป็นแบบนี้
จากด้านบน ผมได้ทำการลบ BitmapFont
ออก และ Texture
ทำการโหลดรูปภาพใหม่เข้ามา โดยใช้ Gdx.files.internal("chai.png")
ซึ่งเป็น Module ของทาง LibGDX ครับ เป็นการโหลดไฟล์จาก โฟลเดอร์ AhoyBoxBox-android/assets/
นั่นเอง ส่วนเมธอด render()
ก็สั่งให้ SpriteBatch
ทำการวาดภาพอันใหม่ ที่ตำแหน่ง 0, 0 จะได้ดังนี้
ต่อไป ผมต้องการให้รูปภาพที่แสดงมันขยับไปด้านขวาของหน้าจอเรื่อยๆ ผมจะทำอย่างไร? ก็ต้องเปลี่ยนค่า ที่เมธอด render()
ตรง batch.draw(img, x, y)
นั่นเองครับ ซึ่งค่า x และ y ก็คือ ตำแหน่งของแกน x และแกน y ที่ต้องการจะให้รูปแสดง โดยนับจากมุมซ้ายล่างของรูป
อันนี้เป็นตัวอย่างตำแหน่งของรูป และแกน x, y คร่าวๆครับ ฮ่าๆ รีบทำ ภาพไม่สวย ^^
ทีนี้ เราจะให้รูปมันขยับ เราก็ต้องทำเปลี่ยนค่า x, y ไปเรื่อยๆ เพราะ render()
มันจะรันเป็น Game Loop อยู่แล้ว คือมันจะวนทำซ้ำไปเรื่อยๆ วินาทีอาจจะ 40 ครั้ง 50 ครั้ง หรือ 60 ครั้ง โดยเราจะเพิ่ม ค่า x และ y เข้าไปในเมธอด render()
ดังนี้ โดยประกาศ int x = 0; int y = 0
เป็น member variable ไว้ภายในคลาส
ทีนี้เมื่อ render()
ถูกเรียก มันก็จะ batch.draw()
ตำแหน่ง x เปลี่ยนไปทุกๆครั้ง หากลองสั่งรันโปรแกรมดู ก็จะเห็นรูปขยับกันนะครับ
Delta Time
ทีนี้มาดูทำไมถึงเป็น Gdx.graphics.getDeltaTime();
อันนี้เป็น Module ของทาง LibGDX อีกเช่นกันครับ ไว้สำหรับแสดงเวลา DeltaTime มันคือเวลา จากเฟรมล่าสุด ถึงเฟรมปัจจุบันครับ ลองจินตนาการดู ภาพการเคลื่อนไหว ปกติจะแบ่งเป็น เฟรมๆใช่มั้ยครับ เช่น เฟรม 0 - 50 เป็นภาพแสดงการก้าวเท้าขวา ทุกๆเฟรม มันก็คือการเคลื่อนไหวทีละเล็กทีละน้อย 0 - 20 อาจจะกำลังยกขา 21-50 อาจเป็นช่วงที่ขากำลังแตะพื้น DeltaTime ก็คือช่วงเวลาระหว่างเฟรมสุดท้าย กับเฟรมล่าสุด หน่วยอาจจะเป็นเสี้ยววินาที หากอยากรู้ว่า DeltaTime มีค่าเท่าไหร่ ลองเพิ่มอันนี้เข้าไปครับ
ที่ console จะได้ผลลัพธ์ประมาณนี้
จากด้านบน เห็นเวลามั้ยครับ เสี้ยววินาที หาก เราเพิ่มค่า x ทีละ 100 ลองจินตนาการดูครับ เราแทบมองไม่เห็น รูปเลยครับ เนื่องจาก มันถูกเพิ่ม 100 แค่ 8 ครั้ง มันก็สุดจอไปแล้ว โดยใช้เวลา ไม่ถึง 0.1 วินาทีด้วยซ้ำ
ตามองไม่ทัน ฉะนั้น ก็เลยต้องใช้วิธี x += 100 * ค่า deltaTime
ครับ ก็คือ เพิ่มที 1 - 2 pixel เท่านั้น ทีนี้ก็มองทันแล้ว
Show Log
Gdx.app.log()
นั้นก็คือ Module ของ LibGDX อีกแล้วครับท่าน ไว้สำหรับแสดง Log ในโปรแกรม หากเขียนแอนดรอยส์มา ก็จะคุ้นเคยกับ Log.i, Log.e
หรือบ้านๆเลย ใครใช้ System.out.prinln()
ก็เปลี่ยนมาให้ ล็อคดีกว่าครับ ^^
จริงๆ LibGDX มี Module อีกหลายตัวที่อำนวยความสะดวกให้เรานะครับ พูดแล้วจะหาว่าคุย ลองไปศึกษาเพิ่มเติมได้ที่นี่ LibGDX Module
การรับ Input
การรับ Input ทาง LibGDX ก็มี Module ที่เตรียมมาให้ครับ เช่น หากเราต้องการรู้ว่า มีการคลิกเมาท์ หรือว่ามีการแตะที่หน้าจอมือถือหรือไม่ ก็จะใช้คำสั่งนี้ครับ
ส่วนการรับ Input จากแป้นคีย์บอร์ด ก็ใช้คำสั่งนี้ เพื่อเช็คว่ามีการพิมพ์คีย์บอร์ดหรือไม่
อย่าลืม import
import com.badlogic.gdx.Input;
Note: short cut สำหรับ import Eclipse คือ Ctrl + Alt + O ส่วน Intelij IDEA มัน auto import on fly ^^
สุดท้าย ผมได้ทำการ implement ทั้งหมดข้างต้น โดยทำเป็นคล้ายๆ Flappy Bird คือ รูปจะมีการเคลื่อนที่ไปข้างหน้า (ไปด้านขวา ค่า x ค่อยๆเพิ่ม) และจะตกลงเรื่อยๆ(ค่า y ค่อยๆลด) หากคลิ๊กเมาท์หรือแตะหน้าจอ ก็จะให้รูปมันลอยขึ้น ครับ (ค่า y เพิ่มขึ้น) โค๊ดที่ได้ก็จะประมาณนี้ ลองๆนำไปเล่นกันดูนะครับ :)
โดยตัวเกม คือ เริ่มต้นสตาร์ทที่ตำแหน่ง x = 0 และ y ที่ตำแหน่งกึ่งกลางของความสูงหน้าจอ และจะตกลงเรื่อยๆ ต้องใช้เมาท์กดที่หน้าจอ หรือว่าใช้มือแตะที่หน้าจอมือถือ หากรันบนแอนดรอยส์ ก็จะทำให้รูป มีการลอยตัวขึ้นครับ ลองๆ นำไปประยุกต์ปรับใช้ หรือลองเล่นกันดูครับ หากใครมีข้อสงสัย สอบถามได้ครับ
- Authors
-
Chai Phonbopit
เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust