تشغيل لعبة الديناصور في Chrome باستخدام لوحة الألعاب

تعرَّف على طريقة استخدام واجهة برمجة التطبيقات Gamepad API للارتقاء بألعاب الويب إلى مستوى أعلى.

تُعد المفاجأة المخفية في الصفحات غير المتصلة بالإنترنت أحد أسوأ الأسرار في التاريخ ([citation needed]، ولكن ادّعى أنّ هذا التأثير كبير. إذا ضغطت على مفتاح المسافة، أو على الجهاز الجوّال الأجهزة، انقر على الديناصور، فستصبح صفحة وضع عدم الاتصال لعبة آركيد قابلة للّعب. قد تدرك أن لست مضطرًا إلى قطع الاتصال بالإنترنت عندما تشعر بالرغبة في اللعب: في Chrome، يمكنك التنقل إلى about://dino، أو انتقل إلى about://network-error/-106 للمهتمين. لكن هل تعلم لأن هناك هل يتم تشغيل 270 مليون لعبة الديناصور في Chrome كل شهر؟

صفحة Chrome غير متصلة بالإنترنت تعرض لعبة الديناصور في Chrome
اضغط على مفتاح المسافة لبدء اللعب.

هناك حقيقة أخرى يمكن القول إن من المفيد معرفتها وقد لا تكون على دراية بها وهي أنه في وضع الألعاب الكلاسيكية، يمكنك تشغيل اللعبة باستخدام جهاز تحكّم في الألعاب. تمّت إضافة إمكانية استخدام لوحة الألعاب قبل عام تقريبًا من وقت هذه الكتابة في الالتزام بحلول Reilly Grant. فكما ترى، ستتغير اللعبة تمامًا مثل بقية مشروع Chromium بالكامل البرامج مفتوحة المصدر. ضِمن أودّ أن أوضح لك طريقة استخدام واجهة برمجة تطبيقات Gamepad.

استخدام 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.01.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 الأساسي (تحديث الجهد السابق من قبل Arnella Ballane)، ووضعتها في موقع مستقل، ووسّعت نطاق تنفيذ واجهة برمجة تطبيقات حالية في Gamepad من خلال إضافة تأثيرات الاهتزاز والاهتزاز، تم إنشاء وضع ملء الشاشة ، وساهم Mehul Satardekar في الوضع الداكن التنفيذ. نتمنّى لك تجربة لعب ممتعة.

شكر وتقدير

تمت مراجعة هذا المستند من قِبل فرانسوا بوفورت جو ميدلي يتم تعديل مواصفات Gamepad API بواسطة ستيف أغوستون، جيمس هولير مات رينولدز يعد محررو المواصفات السابقة Brandon Jones وسكوت غراهام تيد ميلتشارك يتم تعديل مواصفات إضافات لوحة الألعاب بواسطة براندون جونز. صورة رئيسية من تصميم "لورا تورنت بويغ"