หัวข้อนี้จะครอบคลุมวิธีใช้การป้อนข้อมูลด้วยเมาส์สำหรับ 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; });
บันทึกอินพุตจากเมาส์
บางเกมต้องควบคุมเคอร์เซอร์เมาส์ได้เต็มที่ เช่น ลำดับที่ 1 หรือ 3
เกมแอ็กชันแสดงการเคลื่อนที่ของเมาส์ตามการเคลื่อนที่ของกล้อง วิธีดำเนินการ
การควบคุมเมาส์แต่เพียงผู้เดียว เรียกใช้ View.requestPointerCapture()
requestPointerCapture()
จะใช้งานได้เมื่อลำดับชั้นการแสดงผลที่มี
มีโฟกัส ด้วยเหตุนี้ คุณจึงไม่ได้รับการบันทึกตัวชี้ใน
การติดต่อกลับของ onCreate
คุณควรรอให้การโต้ตอบของผู้เล่นจับภาพ
เช่น เมื่อโต้ตอบกับเมนูหลัก หรือใช้
onWindowFocusChanged
Callback เช่น
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()