Gamepad API का इस्तेमाल करके, अपने वेब गेम को बेहतर बनाने का तरीका जानें.
Chrome के ऑफ़लाइन पेज पर मौजूद ईस्टर एग, इतिहास के सबसे खराब तरीके से छिपाए गए रहस्यों में से एक है ([citation needed],
लेकिन यह दावा नाटकीय असर के लिए किया गया है). अगर आपने space बटन दबाया है या मोबाइल डिवाइसों पर डायनासोर पर टैप किया है, तो ऑफ़लाइन पेज एक आर्केड गेम में बदल जाता है. आपको शायद पता हो कि इस गेम को खेलने के लिए, आपको ऑफ़लाइन होने की ज़रूरत नहीं है. Chrome में, about://dino पर जाकर इस गेम को खेला जा सकता है. इसके अलावा, अगर आपको गेमिंग पसंद है, तो about://network-error/-106 पर जाएं. लेकिन क्या आपको पता है कि
हर महीने 27 करोड़ Chrome Dino गेम खेले जाते हैं?
एक और बात जो शायद आपको न पता हो और जो आपके लिए ज़्यादा काम की हो सकती है, वह यह है कि आर्केड मोड में गेमपैड का इस्तेमाल करके गेम खेला जा सकता है. गेमपैड की सुविधा को करीब एक साल पहले जोड़ा गया था. इस बारे में, राइली ग्रांट ने एक कमिट में बताया था. जैसा कि आप देख सकते हैं, Chromium प्रोजेक्ट के बाकी हिस्सों की तरह ही यह गेम भी पूरी तरह से ओपन सोर्स है. इस पोस्ट में, हम आपको Gamepad API इस्तेमाल करने का तरीका बताएंगे.
Gamepad API का इस्तेमाल करना
सुविधा की पहचान और ब्राउज़र के साथ काम करना
Gamepad API, डेस्कटॉप और मोबाइल, दोनों पर ब्राउज़र के साथ काम करता है. इस स्निपेट का इस्तेमाल करके, यह पता लगाया जा सकता है कि Gamepad API काम करता है या नहीं:
if ('getGamepads' in navigator) {
// The API is supported!
}
ब्राउज़र, गेमपैड को कैसे दिखाता है
ब्राउज़र, गेमपैड को Gamepad ऑब्जेक्ट के तौर पर दिखाता है. Gamepad में ये प्रॉपर्टी होती हैं:
id: गेमपैड के लिए आइडेंटिफ़िकेशन स्ट्रिंग. यह स्ट्रिंग, कनेक्ट किए गए गेमपैड डिवाइस के ब्रैंड या स्टाइल की पहचान करती है.displayId: जुड़े हुएVRDisplayकाVRDisplay.displayId(अगर ज़रूरी हो).index: नेविगेटर में गेमपैड का इंडेक्स.connected: इससे पता चलता है कि गेमपैड अब भी सिस्टम से कनेक्ट है या नहीं.hand: यह एक enum है, जिससे पता चलता है कि कंट्रोलर को किस हाथ में पकड़ा गया है या किस हाथ में पकड़े जाने की संभावना सबसे ज़्यादा है.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 प्रॉपर्टी. इससे दो तरह के रंबल इफ़ेक्ट मिलते हैं:
- ड्यूअल-रंबल: यह हैप्टिक फ़ीडबैक इफ़ेक्ट, दो एक्सेंट्रिक रोटेटिंग मास ऐक्चुएटर से जनरेट होता है. इनमें से एक ऐक्चुएटर, गेमपैड की हर ग्रिप में होता है.
- ट्रिगर-रंबल: यह हैप्टिक फ़ीडबैक इफ़ेक्ट, दो अलग-अलग मोटर से जनरेट होता है. इनमें से एक मोटर, गेमपैड के हर ट्रिगर में मौजूद होती है.
यहां दी गई खास जानकारी, सीधे तौर पर स्पेसिफ़िकेशन से ली गई है. इसमें सामान्य गेमपैड पर बटन और ऐक्सिस की मैपिंग और उनकी व्यवस्था दिखाई गई है.
गेमपैड कनेक्ट होने पर सूचना
गेमपैड कनेक्ट होने पर, window ऑब्जेक्ट पर ट्रिगर होने वाले gamepadconnected इवेंट को सुनें. जब उपयोगकर्ता किसी गेमपैड को कनेक्ट करता है, तो यूएसबी या ब्लूटूथ का इस्तेमाल करके,
एक 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 इवेंट को मॉनिटर करता है. ध्यान दें कि इस उदाहरण में, Xbox 360 कंट्रोलर को अनप्लग करने पर, connected अब false हो गया है.
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>
डेमो
यहां दिए गए उदाहरण में, गेमपैड टेस्टर का डेमो एम्बेड किया गया है. सोर्स कोड GitHub पर उपलब्ध है. यूएसबी या ब्लूटूथ का इस्तेमाल करके गेमपैड को कनेक्ट करें और उसका कोई भी बटन दबाकर या उसके किसी भी ऐक्सिस को मूव करके डेमो आज़माएं.
बोनस: web.dev पर Chrome Dino गेम खेलें
इस साइट पर, गेमपैड की मदद से Chrome dino खेला जा सकता है. सोर्स कोड GitHub पर उपलब्ध है.
trex-runner.js में गेमपैड पोलिंग को लागू करने का तरीका देखें और ध्यान दें कि यह बटन दबाने की नकल कैसे करता है.
Chrome dino गेमपैड डेमो के काम करने के लिए, मैंने Chrome dino गेम को Chromium के मुख्य प्रोजेक्ट से अलग कर दिया है. इसके लिए, मैंने Arnelle Ballane की पिछली कोशिश को अपडेट किया है. साथ ही, इसे एक अलग साइट पर रखा है. इसके अलावा, मैंने डकिंग और वाइब्रेशन इफ़ेक्ट जोड़कर, मौजूदा गेमपैड एपीआई को बेहतर बनाया है. साथ ही, फ़ुल स्क्रीन मोड बनाया है. इसके अलावा, मेहुल सतरदेकर ने गहरे रंग वाले मोड को लागू करने में मदद की है. गेमिंग का आनंद लें!
काम के लिंक
Acknowledgements
इस दस्तावेज़ की समीक्षा François Beaufort और Joe Medley ने की है. Gamepad API की खास जानकारी में बदलाव स्टीव अगोस्टन, जेम्स हॉलियर, और मैट रेनॉल्ड्स ने किया है. स्पेसिफ़िकेशन के पूर्व संपादक ब्रैंडन जोन्स, स्कॉट ग्राहम, और टेड मिएल्ज़ारेक हैं. Gamepad Extensions spec को ब्रैंडन जोन्स ने एडिट किया है.