يتناول هذا الموضوع كيفية إدخال الماوس في برنامج "ألعاب Google Play على الكمبيوتر" على الألعاب التي لا يوفر فيها وضع ترجمة الإدخال تجربة مثالية للّاعبين.
عادةً ما يكون لدى لاعبي الكمبيوتر لوحة مفاتيح وماوس بدلاً من شاشة تعمل باللمس، مما يجعل من المهم أن تضع في اعتبارك ما إذا كانت اللعبة تتسع لإدخال الماوس أم لا. بشكل افتراضي، يحوّل برنامج "ألعاب Google Play على الكمبيوتر" أي حدث عند النقر بزر الماوس الأيسر إلى حدث واحد حدث افتراضي يعتمد على النقر يُعرف هذا باسم "وضع ترجمة الإدخال".
على الرغم من أنّ هذا الوضع يجعل لعبتك تعمل مع إجراء بعض التغييرات، لن يؤدي إلى ذلك. ستمنح اللاعبين على الكمبيوتر تجربة متكاملة. ولإجراء ذلك، ننصحك تقوم بتنفيذ ما يلي:
- يمكنك التمرير فوق حالات قوائم السياقات بدلاً من الضغط مع الاستمرار على الإجراءات
- انقر بزر الماوس الأيمن للحصول على الإجراءات البديلة التي تحدث عند الضغط مع الاستمرار أو في سياق القائمة
- استخدم الماوس لألعاب الحركة من منظور البطل أو من خلال الصحافة حدث سحب
من أجل إتاحة أنماط واجهة المستخدم الشائعة على أجهزة الكمبيوتر، يجب إيقاف الإدخال وضع الترجمة.
تتطابق معالجة الإدخال في برنامج "ألعاب Google Play على الكمبيوتر" مع معالجة الإدخال في ChromeOS. التغييرات التي تدعم أجهزة الكمبيوتر الشخصية أيضًا تحسين لعبتك لجميع مشغّلات Android.
إيقاف وضع ترجمة الإدخال
في ملف AndroidManifest.xml
،
الإعلان عن
android.hardware.type.pc
الميزة.
يشير ذلك إلى أنّ لعبتك تستخدم أجهزة الكمبيوتر الشخصي ويتم إيقاف ترجمة الإدخال.
الحالي. بالإضافة إلى ذلك، تساعد إضافة "required="false"
" في ضمان قدرة لعبتك على
لا يزال يمكن تثبيتها على الهواتف والأجهزة اللوحية بدون ماوس. مثلاً:
<manifest ...>
<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />
...
</manifest>
يتم تبديل إصدار الإنتاج من برنامج "ألعاب Google Play على الكمبيوتر" إلى الإصدار الصحيح. عند تشغيل اللعبة. وعند تشغيلك في محاكي المطور، يلزمك النقر بزر الماوس الأيمن على رمز شريط المهام واختيار خيارات المطوّرين وضع الكمبيوتر الشخصي(KiwiMouse) لتلقي إدخالات الماوس الأولية.
بعد إجراء ذلك، يتم الإبلاغ عن حركة الماوس من خلال View.onGeneralMotionEvent باستخدام المصدر 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
للاطّلاع على حالة جميع الأزرار.
في هذا المثال، يتم استخدام تعداد للمساعدة في عرض نتيجة
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()
.