หัวข้อนี้จะอธิบายวิธีใช้การป้อนข้อมูลด้วยเมาส์สำหรับ Google Play Games บน PC สำหรับเกมที่โหมดการแปลอินพุตให้ประสบการณ์การใช้งานที่ไม่เหมาะสม
โดยทั่วไปผู้เล่น PC จะมีแป้นพิมพ์และเมาส์แทนหน้าจอสัมผัส คุณจึงควรพิจารณาว่าเกมของคุณรองรับการป้อนข้อมูลด้วยเมาส์หรือไม่ โดยค่าเริ่มต้น Google Play Games บน PC จะแปลงเหตุการณ์การคลิกเมาส์ซ้ายเป็นการแตะเสมือนจริงเพียงครั้งเดียว ซึ่งเรียกว่า "โหมดการแปลอินพุต"
แม้ว่าโหมดนี้จะทําให้เกมทํางานได้โดยมีการเปลี่ยนแปลงเพียงเล็กน้อย แต่ก็ไม่ได้มอบประสบการณ์การใช้งานแบบดั้งเดิมให้แก่ผู้เล่น PC เราขอแนะนําให้คุณใช้สิ่งต่อไปนี้
- สถานะวางเมาส์เหนือสำหรับเมนูตามบริบทแทนการกดการดำเนินการค้างไว้
- คลิกขวาเพื่อดูการดำเนินการอื่นๆ ที่เกิดขึ้นเมื่อกดค้างหรือในเมนูตามบริบท
- การมองด้วยเมาส์สำหรับเกมแอ็กชันมุมมองบุคคลที่หนึ่งหรือบุคคลที่สามแทนการใช้การกดและลาก
คุณต้องปิดใช้โหมดการแปลการป้อนข้อมูลเพื่อรองรับรูปแบบ UI ที่ใช้กันทั่วไปใน PC
การจัดการการป้อนข้อมูลสำหรับ Google Play Games บน PC จะเหมือนกับของ ChromeOS การเปลี่ยนแปลงที่รองรับ PC จะปรับปรุงเกมของคุณสำหรับผู้เล่น Android ทุกคนด้วย
ปิดใช้โหมดการแปลอินพุต
ในไฟล์ AndroidManifest.xml
ให้ประกาศฟีเจอร์ android.hardware.type.pc
ซึ่งหมายความว่าเกมของคุณใช้ฮาร์ดแวร์ PC และปิดใช้โหมดการแปลอินพุต นอกจากนี้ การเพิ่ม required="false"
ยังช่วยให้มั่นใจได้ว่าเกมจะยังคงติดตั้งในโทรศัพท์และแท็บเล็ตได้โดยไม่ต้องใช้เมาส์ เช่น
<manifest ...>
<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />
...
</manifest>
Google Play Games บน PC เวอร์ชันที่ใช้งานจริงจะเปลี่ยนไปใช้โหมดที่ถูกต้องเมื่อเปิดตัวเกม เมื่อทำงานในโปรแกรมจำลองของนักพัฒนาซอฟต์แวร์ คุณต้องคลิกขวาที่ไอคอนแถบงาน เลือกตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ แล้วคลิกโหมด PC(KiwiMouse) เพื่อรับอินพุตเมาส์ดิบ
หลังจากนั้น ระบบจะรายงานการเคลื่อนไหวของเมาส์ตาม View.ongenericMotionEvent โดยแหล่งที่มา SOURCE_MOUSE
ระบุว่าเป็นเหตุการณ์ของเมาส์
Kotlin
gameView.setOnGenericMotionListener { _, motionEvent -> var handled = false if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { // handle the mouse event here handled = true } handled }
Java
gameView.setOnGenericMotionListener((view, motionEvent) -> { if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { // handle the mouse event here return true; } return false; });
ดูรายละเอียดเกี่ยวกับการจัดการอินพุตเมาส์ได้ที่เอกสารประกอบของ ChromeOS
การจัดการการเคลื่อนไหวของเมาส์
หากต้องการตรวจจับการเคลื่อนไหวของเมาส์ ให้ฟังเหตุการณ์ ACTION_HOVER_ENTER
, ACTION_HOVER_EXIT
และ
ACTION_HOVER_MOVE
เหตุการณ์นี้เหมาะสําหรับตรวจจับเมื่อผู้ใช้วางเมาส์เหนือปุ่มหรือวัตถุในเกม ซึ่งจะช่วยให้คุณมีโอกาสแสดงกล่องเคล็ดลับหรือใช้สถานะการเลื่อนเมาส์เหนือเพื่อไฮไลต์สิ่งที่ผู้เล่นกําลังจะเลือก เช่น
Kotlin
gameView.setOnGenericMotionListener { _, motionEvent -> var handled = false if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { when(motionEvent.action) { MotionEvent.ACTION_HOVER_ENTER -> Log.d("MA", "Mouse entered at ${motionEvent.x}, ${motionEvent.y}") MotionEvent.ACTION_HOVER_EXIT -> Log.d("MA", "Mouse exited at ${motionEvent.x}, ${motionEvent.y}") MotionEvent.ACTION_HOVER_MOVE -> Log.d("MA", "Mouse hovered at ${motionEvent.x}, ${motionEvent.y}") } handled = true } handled }
Java
gameView.setOnGenericMotionListener((view, motionEvent) -> { if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_HOVER_ENTER: Log.d("MA", "Mouse entered at " + motionEvent.getX() + ", " + motionEvent.getY()); break; case MotionEvent.ACTION_HOVER_EXIT: Log.d("MA", "Mouse exited at " + motionEvent.getX() + ", " + motionEvent.getY()); break; case MotionEvent.ACTION_HOVER_MOVE: Log.d("MA", "Mouse hovered at " + motionEvent.getX() + ", " + motionEvent.getY()); break; } return true; } return false; });
การจัดการปุ่มเมาส์
คอมพิวเตอร์มีปุ่มเมาส์ทั้งซ้ายและขวามาอย่างยาวนานแล้ว ซึ่งทำให้องค์ประกอบแบบอินเทอร์แอกทีฟมีการดำเนินการทั้งหลักและรอง ในเกม การแตะการกระทำต่างๆ เช่น การแตะปุ่ม ควรแมปกับคลิกซ้าย ส่วนการแตะค้างไว้ควรแมปกับคลิกขวา ในเกมกลยุทธ์แบบเรียลไทม์ คุณอาจใช้การคลิกซ้ายเพื่อเลือกและคลิกขวาเพื่อย้าย เกมยิงมุมมองบุคคลที่หนึ่งอาจกำหนดการยิงหลักและรองเป็นคลิกซ้ายและขวา เกมวิ่งที่ไม่มีจุดสิ้นสุดอาจใช้การคลิกซ้ายเพื่อกระโดดและคลิกขวาเพื่อพุ่ง เรายังไม่ได้เพิ่มการรองรับเหตุการณ์การคลิกกลาง
หากต้องการจัดการการกดปุ่ม ให้ใช้ ACTION_DOWN
และ ACTION_UP
จากนั้นใช้ getActionButton
เพื่อระบุปุ่มที่เรียกใช้การดำเนินการ หรือ getButtonState
เพื่อดูสถานะของปุ่มทั้งหมด
ในตัวอย่างนี้จะใช้ enum เพื่อช่วยแสดงผลลัพธ์ของ getActionButton
Kotlin
enum class MouseButton { LEFT, RIGHT, UNKNOWN; companion object { fun fromMotionEvent(motionEvent: MotionEvent): MouseButton { return when (motionEvent.actionButton) { MotionEvent.BUTTON_PRIMARY -> LEFT MotionEvent.BUTTON_SECONDARY -> RIGHT else -> UNKNOWN } } } }
Java
enum MouseButton { LEFT, RIGHT, MIDDLE, UNKNOWN; static MouseButton fromMotionEvent(MotionEvent motionEvent) { switch (motionEvent.getActionButton()) { case MotionEvent.BUTTON_PRIMARY: return MouseButton.LEFT; case MotionEvent.BUTTON_SECONDARY: return MouseButton.RIGHT; default: return MouseButton.UNKNOWN; } } }
ในตัวอย่างนี้ ระบบจะจัดการการดําเนินการคล้ายกับเหตุการณ์การโฮเวอร์
Kotlin
// Handle the generic motion event gameView.setOnGenericMotionListener { _, motionEvent -> var handled = false if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { when (motionEvent.action) { MotionEvent.ACTION_BUTTON_PRESS -> Log.d( "MA", "${MouseButton.fromMotionEvent(motionEvent)} pressed at ${motionEvent.x}, ${motionEvent.y}" ) MotionEvent.ACTION_BUTTON_RELEASE -> Log.d( "MA", "${MouseButton.fromMotionEvent(motionEvent)} released at ${motionEvent.x}, ${motionEvent.y}" ) } handled = true } handled }
Java
gameView.setOnGenericMotionListener((view, motionEvent) -> { if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_BUTTON_PRESS: Log.d("MA", MouseButton.fromMotionEvent(motionEvent) + " pressed at " + motionEvent.getX() + ", " + motionEvent.getY()); break; case MotionEvent.ACTION_BUTTON_RELEASE: Log.d("MA", MouseButton.fromMotionEvent(motionEvent) + " released at " + motionEvent.getX() + ", " + motionEvent.getY()); break; } return true; } return false; });
จัดการการเลื่อนด้วยลูกล้อของเมาส์
เราขอแนะนำให้คุณใช้ปุ่มลูกกลิ้งของเมาส์แทนการใช้ท่าทางสัมผัสเพื่อซูม หรือแตะและลากพื้นที่เลื่อนในเกม
หากต้องการอ่านค่าของล้อเลื่อน ให้รอฟังเหตุการณ์ ACTION_SCROLL
เดลต้าเนื่องจากเฟรมสุดท้ายดึงได้โดยใช้ getAxisValue
ร่วมกับ AXIS_VSCROLL
สำหรับออฟเซ็ตแนวตั้งและ AXIS_HSCROLL
สำหรับออฟเซ็ตแนวนอน เช่น
Kotlin
gameView.setOnGenericMotionListener { _, motionEvent -> var handled = false if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { when (motionEvent.action) { MotionEvent.ACTION_SCROLL -> { val scrollX = motionEvent.getAxisValue(MotionEvent.AXIS_HSCROLL) val scrollY = motionEvent.getAxisValue(MotionEvent.AXIS_VSCROLL) Log.d("MA", "Mouse scrolled $scrollX, $scrollY") } } handled = true } handled }
Java
gameView.setOnGenericMotionListener((view, motionEvent) -> { if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_SCROLL: float scrollX = motionEvent.getAxisValue(MotionEvent.AXIS_HSCROLL); float scrollY = motionEvent.getAxisValue(MotionEvent.AXIS_VSCROLL); Log.d("MA", "Mouse scrolled " + scrollX + ", " + scrollY); break; } return true; } return false; });
บันทึกอินพุตจากเมาส์
บางเกมจำเป็นต้องควบคุมเคอร์เซอร์เมาส์อย่างเต็มรูปแบบ เช่น เกมแอ็กชันมุมมองบุคคลที่หนึ่งหรือบุคคลที่สามซึ่งจับคู่การเคลื่อนไหวของเมาส์กับการเคลื่อนไหวของกล้อง หากต้องการควบคุมเมาส์แต่เพียงผู้เดียว ให้เรียกใช้ View.requestPointerCapture()
requestPointerCapture()
จะใช้งานได้เมื่อลําดับชั้นมุมมองที่มีมุมมองของคุณมีโฟกัสเท่านั้น ด้วยเหตุนี้ คุณจึงไม่ได้รับการบันทึกตัวชี้ในการเรียกกลับ onCreate
คุณควรรอการโต้ตอบของผู้เล่นเพื่อจับเคอร์เซอร์เมาส์ เช่น เมื่อโต้ตอบกับเมนูหลัก หรือใช้การเรียกกลับ onWindowFocusChanged
เช่น
Kotlin
override fun onWindowFocusChanged(hasFocus: Boolean) { super.onWindowFocusChanged(hasFocus) if (hasFocus) { gameView.requestPointerCapture() } }
Java
@Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus) { View gameView = findViewById(R.id.game_view); gameView.requestPointerCapture(); } }
ระบบจะส่งเหตุการณ์ที่บันทึกโดย requestPointerCapture()
ไปยังมุมมองที่โฟกัสได้ซึ่งลงทะเบียนไว้ OnCapturedPointerListener
เช่น
Kotlin
gameView.focusable = View.FOCUSABLE gameView.setOnCapturedPointerListener { _, motionEvent -> Log.d("MA", "${motionEvent.x}, ${motionEvent.y}, ${motionEvent.actionButton}") true }
Java
gameView.setFocusable(true); gameView.setOnCapturedPointerListener((view, motionEvent) -> { Log.d("MA", motionEvent.getX() + ", " + motionEvent.getY() + ", " + motionEvent.getActionButton()); return true; });
หากต้องการปล่อยการจับภาพเมาส์แบบพิเศษ เช่น เพื่อให้ผู้เล่นโต้ตอบกับเมนูหยุดชั่วคราว ให้เรียกใช้ View.releasePointerCapture()