تعرَّف على كيفية استخدام واجهة برمجة التطبيقات Gamepad API لتحسين ألعاب الويب.
إنّ مفاجأة Chrome المخفية في الصفحة بلا اتصال بالإنترنت هي من أسوأ الأسرار التي تم الاحتفاظ بها في التاريخ ([citation needed]
،
ولكن تم تقديم هذا الادعاء لتأثيره الدرامي). عند الضغط على مفتاح مسافة أو النقر على الديناصور على الأجهزة الجوّالة، ستصبح الصفحة المتوفّرة بلا إنترنت لعبة آركيد قابلة للّعب. قد تكون على علم بأنّك لن تضطر إلى قطع الاتصال بالإنترنت عند شعورك باللعب: في Chrome، يمكنك الانتقال إلى about://dino
أو التصفّح إلى about://network-error/-106
إذا كنت محترفًا. هل لديك فكرة عن عدد مستخدمي لعبة الديناصور في Chrome؟ يتم تشغيل لعبة الديناصور في Chrome 270 مليون مرة كل شهر.
هناك حقيقة أخرى قد لا تكون على دراية بها، وهي أنّه في وضع "ألعاب الأركيد"، يمكنك تشغيل اللعبة باستخدام جهاز تحكّم. تمت إضافة ميزة استخدام وحدة التحكّم في الألعاب قبل عام تقريبًا، ويعود تاريخ كتابة هذه المقالة إلى وقت تنفيذ التغيير الذي أجراه Reilly Grant. كما ترى، أصبحت اللعبة مفتوحة المصدر تمامًا مثل بقية مشروع Chromium. في هذه المشاركة، أريد أن أعرض لك كيفية استخدام واجهة برمجة التطبيقات Gamepad API.
استخدام Gamepad API
رصد الميزات وتوافق المتصفّح
تتوافق واجهة برمجة التطبيقات Gamepad API مع المتصفحات المتوافقة مع الأجهزة الجوّالة بشكل عام على كلٍّ من أجهزة الكمبيوتر والأجهزة الجوّالة. يمكنك معرفة ما إذا كانت واجهة برمجة التطبيقات Gamepad API متوافقة باستخدام المقتطف التالي:
if ('getGamepads' in navigator) {
// The API is supported!
}
كيفية تمثيل المتصفّح لجهاز تحكّم في الألعاب
يمثّل المتصفّح لوحات الألعاب على شكل عناصر Gamepad
. تتضمّن السمة Gamepad
السمات التالية:
id
: سلسلة تعريف لوحة الألعاب تحدد هذه السلسلة العلامة التجارية أو نمط جهاز لوحة الألعاب المتصل.displayId
: تشير هذه السمة إلىVRDisplay.displayId
الخاص بخدمةVRDisplay
ذات الصلة (إذا كان ذلك منطبقًا).index
: فهرس لوحة الألعاب في أداة التنقّل.connected
: يشير إلى ما إذا كان جهاز التحكّم في الألعاب لا يزال متصلاً بالنظام.hand
: تعداد يحدِّد اليد التي تُمسك بها وحدة التحكّم أو التي يُرجّح حملها بهtimestamp
: آخر مرة تم فيها تعديل بيانات جهاز التحكّم في الألعاب هذاmapping
: تعيين الأزرار والمحاور المستخدَم لهذا الجهاز، إما"standard"
أو"xr-standard"
.-
pose
: عنصرGamepadPose
يمثّل معلومات الوضع المرتبطة بجهاز تحكّم في WebVR axes
: صفيف من القيم لجميع محاور لوحة الألعاب، تم تسويته خطيًا ضمن النطاق-1.0
–1.0
buttons
: مصفوفة من حالات الأزرار لجميع أزرار لوحة الألعاب
يُرجى العِلم أنّ الأزرار يمكن أن تكون رقمية (عند الضغط عليها أو غير مضغوطة) أو عادية (مثلاً، مضغوطة بنسبة 78%). لهذا السبب،
يتم تسجيل الأزرار كعناصر GamepadButton
، مع السمات التالية:
pressed
: حالة الضغط على الزر (true
إذا تم الضغط على الزر، وfalse
إذا لم يتم الضغط عليه:)touched
: حالة الزر عند لمسه إذا كان الزر قادرًا على رصد اللمس، تكون قيمة هذه السمةtrue
إذا تم لمس الزر، وfalse
في غير ذلك.-
value
: بالنسبة إلى الأزرار التي تحتوي على أداة استشعار تمثيلية، تمثّل هذه السمة مقدار الضغط على الزر، ويتم تسويتها خطيًا ضمن النطاق من0.0
إلى1.0
. -
hapticActuators
: صفيف يحتوي على عناصرGamepadHapticActuator
، يمثّل كلّ منها جهازًا للّمس التحفيزي متوفّرًا في جهاز التحكّم.
هناك عنصر إضافي قد تواجهه، استنادًا إلى المتصفّح ووحدة التحكّم في الألعاب التي تستخدمها، وهو
سمة vibrationActuator
. تسمح هذه اللعبة بنوعَين من تأثيرات أصوات المزمار:
- التأثير المزدوج للاهتزاز: تأثير الملاحظات اللمسية الناتج عن محرّكَين غريبَي الشكل للكتلة الدوّارة، أحدهما في كل مقبض من مقبضَي ذراع التحكّم.
- التأثير في الزناد: تأثير الملاحظات اللمسية الناتج عن محرّكين مستقلّين، مع محرّك واحد في كل من أدوات التنشيط في لوحة الألعاب.
تشتمل النظرة العامة للرسم البياني مباشرةً على المواصفات على طريقة التخطيط وترتيب الأزرار والمحاور في لوحة الألعاب العامة.
إشعار عند توصيل جهاز تحكّم في الألعاب
لمعرفة متى يتم توصيل جهاز تحكم ألعاب، انتظِر حدث gamepadconnected
الذي يتم تشغيله على العنصر
window
. عندما يربط المستخدم جهاز تحكّم في الألعاب، وهو ما يمكن أن يحدث إما باستخدام USB أو عبر البلوتوث، يتم تنشيط GamepadEvent
مع وضع تفاصيل لوحة الألعاب في خاصية gamepad
بشكل مناسب.
في ما يلي مثال من وحدة تحكّم في جهاز Xbox 360 كانت لديّ (نعم، أحبّ
الألعاب القديمة).
window.addEventListener('gamepadconnected', (event) => {
console.log('✅ 🎮 A gamepad was connected:', event.gamepad);
/*
gamepad: Gamepad
axes: (4) [0, 0, 0, 0]
buttons: (17) [GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton]
connected: true
id: "Xbox 360 Controller (STANDARD GAMEPAD Vendor: 045e Product: 028e)"
index: 0
mapping: "standard"
timestamp: 6563054.284999998
vibrationActuator: GamepadHapticActuator {type: "dual-rumble"}
*/
});
إشعار عند انقطاع اتصال جهاز تحكّم في الألعاب
يتم تلقّي إشعارات بشأن انقطاع الاتصال بوحدة التحكّم في الألعاب بالطريقة نفسها التي يتم بها رصد عمليات الاتصال.
ينتظر التطبيق هذه المرة الاستماع إلى حدث gamepaddisconnected
. يُرجى ملاحظة أنّه في المثال التالي، أصبح connected
هو false
عند فصل وحدة تحكّم Xbox 360.
window.addEventListener('gamepaddisconnected', (event) => {
console.log('❌ 🎮 A gamepad was disconnected:', event.gamepad);
/*
gamepad: Gamepad
axes: (4) [0, 0, 0, 0]
buttons: (17) [GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton]
connected: false
id: "Xbox 360 Controller (STANDARD GAMEPAD Vendor: 045e Product: 028e)"
index: 0
mapping: "standard"
timestamp: 6563054.284999998
vibrationActuator: null
*/
});
لوحة الألعاب في حلقة لعبتك
يبدأ الحصول على جهاز تحكم في الألعاب من خلال طلب navigator.getGamepads()
، الذي يعرض صفيفًا
يحتوي على Gamepad
عنصرًا. تحتوي المصفوفة في Chrome دائمًا على طول ثابت من أربعة عناصر. إذا لم يتم ربط أربعة أجهزة تحكم في الألعاب أو أقل، قد يكون العنصر null
فقط. تأكّد دائمًا من فحص كل عناصر المصفوفة واعلم أنّ لوحات الألعاب "تتذكر" الخانة الخاصة بها وقد لا تكون متوفّرة دائمًا في أوّل خانة متاحة.
// When no gamepads are connected:
navigator.getGamepads();
// (4) [null, null, null, null]
إذا كان هناك جهاز تحكم ألعاب واحد أو عدة أجهزة متصلة، ولكن navigator.getGamepads()
لا يزال يُبلغ عن null
جهاز،
قد تحتاج إلى "تنشيط" كل جهاز تحكم ألعاب من خلال الضغط على أي من أزراره. يمكنك بعد ذلك استطلاع حالات لوحة الألعاب في
حلقة الألعاب كما هو موضح في التعليمة البرمجية التالية.
const pollGamepads = () => {
// Always call `navigator.getGamepads()` inside of
// the game loop, not outside.
const gamepads = navigator.getGamepads();
for (const gamepad of gamepads) {
// Disregard empty slots.
if (!gamepad) {
continue;
}
// Process the gamepad state.
console.log(gamepad);
}
// Call yourself upon the next animation frame.
// (Typically this happens every 60 times per second.)
window.requestAnimationFrame(pollGamepads);
};
// Kick off the initial game loop iteration.
pollGamepads();
مشغّل الاهتزاز
تعرض السمة vibrationActuator
كائن GamepadHapticActuator
، يتجاوب مع تكوين المحرّكات أو المشغِّلات الأخرى التي يمكنها استخدام قوة لأغراض التجاوب الحسّي. يمكن تشغيل التأثيرات باللمس من خلال طلب الرقم Gamepad.vibrationActuator.playEffect()
. نوعا التأثير الوحيدان
الصالحان هما 'dual-rumble'
و'trigger-rumble'
.
تأثيرات الاهتزاز المتوافقة
if (gamepad.vibrationActuator.effects.includes('trigger-rumble')) {
// Trigger rumble supported.
} else if (gamepad.vibrationActuator.effects.includes('dual-rumble')) {
// Dual rumble supported.
} else {
// Rumble effects aren't supported.
}
ميزة الارتجاج المزدوج
يصف مصطلح "الاهتزاز المزدوج" إعدادًا لمسيًا باستخدام محرك اهتزاز دوار بكتلة غير مركزية في كل مقبض من أذرع وحدة تحكّم ألعاب عادية. في هذه الحالة، يمكن لأي من المحرّكين أن يتسبب في اهتزاز لوحة الألعاب بالكامل. الكتلتان غير متساويتين حتى يمكن دمج تأثيرات كل منهما لإنشاء تأثيرات لمسية أكثر تعقيدًا. يتم تحديد تأثيرات الهجوم المزدوج من خلال أربع معلمات:
-
duration
: لضبط مدة تأثير الاهتزاز بالملي ثانية -
startDelay
: لضبط مدة الانتظار إلى أن يبدأ الاهتزاز. -
strongMagnitude
وweakMagnitude
: اضبط مستويات شدة الاهتزاز للمحركات ذات الكتلة الدوّارة المتغيّرة الأوزان والأحجام، مع تسويتها على النطاق0.0
–1.0
.
// This assumes a `Gamepad` as the value of the `gamepad` variable.
const dualRumble = (gamepad, delay = 0, duration = 100, weak = 1.0, strong = 1.0) => {
if (!('vibrationActuator' in gamepad)) {
return;
}
gamepad.vibrationActuator.playEffect('dual-rumble', {
// Start delay in ms.
startDelay: delay,
// Duration in ms.
duration: duration,
// The magnitude of the weak actuator (between 0 and 1).
weakMagnitude: weak,
// The magnitude of the strong actuator (between 0 and 1).
strongMagnitude: strong,
});
};
بدء الاهتزاز
التأثير الهزّي للزناد هو تأثير الملاحظات اللمسية الذي ينشئه محرّكان مستقلان، مع محرّك واحد في كل من زنادَي لوحة الألعاب.
// This assumes a `Gamepad` as the value of the `gamepad` variable.
const triggerRumble = (gamepad, delay = 0, duration = 100, weak = 1.0, strong = 1.0) => {
if (!('vibrationActuator' in gamepad)) {
return;
}
// Feature detection.
if (!('effects' in gamepad.vibrationActuator) || !gamepad.vibrationActuator.effects.includes('trigger-rumble')) {
return;
}
gamepad.vibrationActuator.playEffect('trigger-rumble', {
// Duration in ms.
duration: duration,
// The left trigger (between 0 and 1).
leftTrigger: leftTrigger,
// The right trigger (between 0 and 1).
rightTrigger: rightTrigger,
});
};
الدمج مع سياسة الأذونات
تحدِّد مواصفات Gamepad API
ميزة تخضع للرقابة بموجب السياسة يتم تحديدها باستخدام السلسلة"gamepad"
. القيمة التلقائية allowlist
هي "self"
. تحدّد سياسة الأذونات للمستند
ما إذا كان يُسمح لأي محتوى في ذلك المستند بالوصول إلى navigator.getGamepads()
. في حال إيقافه في
أي مستند، لن يُسمح لأي محتوى في المستند باستخدام navigator.getGamepads()
، ولن يتم إعلامه بحدثَي gamepadconnected
وgamepaddisconnected
.
<iframe src="index.html" allow="gamepad"></iframe>
عرض توضيحي
تم تضمين عرض توضيحي لمختبِر لوحة الألعاب في المثال التالي. يتوفّر رمز المصدر على Glitch. جرِّب العرض الترويجي من خلال توصيل جهاز تحكّم في الألعاب باستخدام USB أو البلوتوث والضغط على أي من أزراره أو تحريك أي من محاوره.
ميزة إضافية: تشغيل لعبة الديناصور في Chrome على web.dev
يمكنك تشغيل ديناصور Chrome باستخدام وحدة التحكّم في الألعاب على
هذا الموقع الإلكتروني. يتوفّر رمز المصدر على GitHub.
يمكنك الاطّلاع على طريقة تنفيذ الاستطلاعات في لوحة الألعاب في
trex-runner.js
والتعرّف على طريقة محاكاتها للضغطات على المفاتيح.
لكي يعمل الإصدار التجريبي من وحدة تحكّم لعبة الديناصور في Chrome، أزلنا لعبة الديناصور في Chrome من مشروع Chromium الأساسي (من خلال تعديل جهد سابق من إعداد أرنيل بالاني)، ووضعناها على موقع إلكتروني مستقل، ووسّعنا تنفيذ واجهة برمجة التطبيقات الحالية لوحدة التحكّم في الألعاب من خلال إضافة تأثيرات الانحناء والاهتزاز، واخترعنا وضعًا للعرض على الشاشة الكاملة، وساهم مههول ساتارديكار في تنفيذ وضع الوضع الداكن. نتمنى لك تجربة لعب ممتعة.
روابط مفيدة
الشكر والتقدير
راجع هذا المستند فرانسوا بافوي و جو ميديل. تم تعديل مواصفات Gamepad API بواسطة كل من ستيف أغوستون وجيمس هولير ومات رينولدز. محرّرو المواصفات السابقون هم براندون جونز وسكوت غراهام و تيد ميلشاريك. يُعدّل براندون جونز مواصفات إضافات لوحات الألعاب. الصورة الرئيسية من تصميم "لورا تورنت بويج".