Gamepad API की मदद से, रुकावटों को पार करना

मार्सिन विचारी
मार्सिन विचारी

शुरुआती जानकारी

नौसिखियों को ऐडवेंचर गेम के लिए कीबोर्ड इस्तेमाल करने दें, फल काटने के लिए कई तरह की चुभने वाली उंगलियों की मदद से, और उनके नए चमचमाते मोशन सेंसर को रखने दें, ताकि वे दिखा सकें कि वे माइकल जैक्सन की तरह डांस कर सकते हैं. (Newsflash: वे ऐसा नहीं कर सकते.) लेकिन आप अलग हैं. आप बेहतर हैं. आप तो इसमें माहिर हैं. आपके लिए, गेम की शुरुआत और आखिर में गेमपैड आपके हाथ में होता है.

लेकिन रुकिए. क्या अपने वेब ऐप्लिकेशन में गेमपैड का इस्तेमाल करना सही नहीं है? अब नहीं. आपकी मदद के लिए, सबसे नए Gamepad API का इस्तेमाल किया जा सकता है. इससे अपने कंप्यूटर से जुड़े किसी भी गेमपैड कंट्रोलर की स्थिति को पढ़ने के लिए, JavaScript का इस्तेमाल किया जा सकता है. यह डिवाइस प्रेस के हिसाब से काफ़ी ताज़ा है, क्योंकि इसे पिछले हफ़्ते Chrome 21 पर ही लॉन्च किया गया था. साथ ही, यह Firefox में भी काम करने वाला है (फ़िलहाल, यह खास बिल्ड में उपलब्ध है).

यह बहुत ही शानदार समय रहा, क्योंकि हमें हाल ही में Hurdles 2012 Google डूडल में इसका उपयोग करने का अवसर मिला है. इस लेख में, कम शब्दों में बताया जाएगा कि हमने डूडल में Gamepad API कैसे जोड़ा है और इस प्रोसेस के दौरान हमने क्या सीखा.

बाधाएं 2012 Google डूडल
Hurdles 2012 Google डूडल

गेमपैड टेस्टर

इंटरैक्टिव डूडल की शुरुआत कुछ समय के लिए होती है, लेकिन हुड के तहत ये काफ़ी जटिल होते हैं. हमने डूडल से गेमपैड कोड लिया और एक आसान गेमपैड टेस्टर को साथ में रखा. ऐसा इसलिए किया, ताकि यह दिखाना आसान हो जाए कि हम किस बारे में बात कर रहे हैं. इसका इस्तेमाल, यह देखने के लिए किया जा सकता है कि आपका यूएसबी गेमपैड ठीक से काम कर रहा है या नहीं. साथ ही, इसका काम करने का तरीका जानने के लिए, इसके हुड के नीचे देखें.

फ़िलहाल, यह सुविधा किन ब्राउज़र पर काम करती है?

ब्राउज़र सहायता

  • 21
  • 12
  • 29
  • 10.1

सोर्स

किस तरह के गेमपैड का इस्तेमाल किया जा सकता है?

आम तौर पर, आपके सिस्टम पर काम करने वाला कोई भी मॉडर्न गेमपैड, मूल रूप से काम करेगा. हमने पीसी पर अलग-अलग ऑफ़-ब्रैंड यूएसबी कंट्रोलर के कई गेमपैड की जांच की. इसके लिए, हमने डोंगल की मदद से Mac से जोड़े गए PlayStation 2 के गेमपैड की मदद से, Chrome OS नोटबुक के साथ जोड़े गए ब्लूटूथ कंट्रोलर की मदद से, अलग-अलग गेमपैड की जांच की.

गेमपैड
गेमपैड

यह उन कुछ नियंत्रकों की फ़ोटो है, जिनका इस्तेमाल हमने अपने डूडल की जांच करने के लिए किया था – "हां, मां, असल में मैं काम में यही करता हूं." अगर आपका कंट्रोलर काम नहीं करता है या कंट्रोल सही तरीके से मैप नहीं किए गए हैं, तो कृपया Chrome के लिए गड़बड़ी की शिकायत करें या Firefox पर टैप करें . (कृपया हर ब्राउज़र के बिलकुल नए वर्शन में जांच करके पक्का करें कि यह पहले से ठीक नहीं है.)

Gamepad API का पता लगाने वाली सुविधा<

Chrome में काफ़ी आसान:

var gamepadSupportAvailable = !!navigator.webkitGetGamepads || !!navigator.webkitGamepads;

फ़िलहाल, Firefox में इसका पता लगाना संभव नहीं है – सब कुछ इवेंट पर आधारित है और सभी इवेंट हैंडलर को विंडो से अटैच करना ज़रूरी है. इस वजह से, इवेंट हैंडलर का पता लगाने की एक सामान्य तकनीक काम नहीं कर रही है.

हालांकि, हमें यकीन है कि ऐसा कुछ ही समय के लिए होगा. सबसे बेहतरीन Modernizr ऐप्लिकेशन, आपको पहले से ही Gamepad API के बारे में जानकारी दे रहा है. इसलिए, हमारा सुझाव है कि मौजूदा और आने वाले समय की ज़रूरतों के हिसाब से इसका इस्तेमाल करें:

var gamepadSupportAvailable = Modernizr.gamepads;

कनेक्ट किए गए गेमपैड के बारे में पता लगाया जा रहा है

गेमपैड को कनेक्ट करने के बाद भी, यह तब तक किसी खास तरीके से खुद को नहीं दिखाता, जब तक उपयोगकर्ता उसका कोई बटन नहीं दबाता. ऐसा इसलिए है, ताकि फ़िंगरप्रिंट की सुविधा को रोका जा सके. हालांकि, यह उपयोगकर्ता अनुभव के लिए चुनौती भरा साबित होता है: आप उपयोगकर्ता से बटन दबाने या गेमपैड के खास निर्देश देने के लिए नहीं कह सकते, क्योंकि आपको नहीं पता कि वह अपना कंट्रोलर कनेक्ट कर रहा है या नहीं.

माफ़ कीजिए, एक बार आपने भी उस बाधा को पार कर लिया, लेकिन फिर भी और इंतज़ार करना होगा.

पोल

Chrome पर एपीआई लागू करने से, एक फ़ंक्शन दिखता है – navigator.webkitGetGamepads() – इसका इस्तेमाल, सिस्टम से हाल ही में प्लग इन किए गए सभी गेमपैड की सूची के साथ-साथ उनकी मौजूदा स्थिति (बटन + स्टिक) पाने के लिए भी किया जा सकता है. कनेक्ट किया गया पहला गेमपैड, कलेक्शन में पहली एंट्री के तौर पर दिखाया जाएगा. आगे भी इसी तरह.

(इस फ़ंक्शन कॉल ने हाल ही में उस कलेक्शन को बदला है जिसे सीधे ऐक्सेस किया जा सकता है – navigator.webkitGamepads[]. अगस्त 2012 की शुरुआत में, Chrome 21 में इस अरे को ऐक्सेस करना अब भी ज़रूरी है. हालांकि, फ़ंक्शन कॉल की सुविधा Chrome 22 और उसके बाद के वर्शन में काम करती है. हमारा सुझाव है कि एपीआई का इस्तेमाल करने के लिए, फ़ंक्शन कॉल को इस्तेमाल करने का सुझाव दिया जाता है. यह तरीका, इंस्टॉल किए गए सभी Chrome ब्राउज़र पर धीरे-धीरे ऐक्सेस किया जाता है.)

इस स्पेसिफ़िकेशन को लागू करने के लिए, आपको लगातार यह देखना होगा कि कनेक्ट किए गए गेमपैड की स्थिति क्या है. साथ ही, अगर ज़रूरी हो, तो इवेंट को ट्रिगर करने के बजाय, पहले वाले गेमपैड की स्थिति से इसकी तुलना करें. हम requestAnimationFrame() पर भरोसा करते हैं, ताकि सबसे बेहतर और बैटरी के लिहाज़ से पोल की सुविधा सेट अप की जा सके. हमारे डूडल पर भले ही ऐनिमेशन को सपोर्ट करने के लिए requestAnimationFrame() लूप पहले से मौजूद है, फिर भी हमने दूसरा पूरी तरह से अलग एक लूप बनाया है. इसे कोड करना बहुत आसान था और इससे परफ़ॉर्मेंस पर कोई असर नहीं पड़ना चाहिए.

टेस्टर से मिला कोड यहां दिया गया है:

/**
 * Starts a polling loop to check for gamepad state.
 */
startPolling: function() {
    // Don't accidentally start a second loop, man.
    if (!gamepadSupport.ticking) {
    gamepadSupport.ticking = true;
    gamepadSupport.tick();
    }
},

/**
 * Stops a polling loop by setting a flag which will prevent the next
 * requestAnimationFrame() from being scheduled.
 */
stopPolling: function() {
    gamepadSupport.ticking = false;
},

/**
 * A function called with each requestAnimationFrame(). Polls the gamepad
 * status and schedules another poll.
 */
tick: function() {
    gamepadSupport.pollStatus();
    gamepadSupport.scheduleNextTick();
},

scheduleNextTick: function() {
    // Only schedule the next frame if we haven't decided to stop via
    // stopPolling() before.
    if (gamepadSupport.ticking) {
    if (window.requestAnimationFrame) {
        window.requestAnimationFrame(gamepadSupport.tick);
    } else if (window.mozRequestAnimationFrame) {
        window.mozRequestAnimationFrame(gamepadSupport.tick);
    } else if (window.webkitRequestAnimationFrame) {
        window.webkitRequestAnimationFrame(gamepadSupport.tick);
    }
    // Note lack of setTimeout since all the browsers that support
    // Gamepad API are already supporting requestAnimationFrame().
    }
},

/**
 * Checks for the gamepad status. Monitors the necessary data and notices
 * the differences from previous state (buttons for Chrome/Firefox,
 * new connects/disconnects for Chrome). If differences are noticed, asks
 * to update the display accordingly. Should run as close to 60 frames per
 * second as possible.
 */
pollStatus: function() {
    // (Code goes here.)
},

अगर आपको सिर्फ़ एक गेमपैड की परवाह है, तो उसका डेटा पाना इतना आसान हो सकता है:

var gamepad = navigator.webkitGetGamepads && navigator.webkitGetGamepads()[0];

अगर आपको होशियार रहना है या एक साथ कई खिलाड़ियों की मदद करनी है, तो आपको ज़्यादा मुश्किल हालातों का सामना करने के लिए, कोड की कुछ और लाइनें जोड़नी होंगी. जैसे, दो या उससे ज़्यादा गेमपैड कनेक्ट होने पर, कुछ लाइनें बीच में डिसकनेक्ट हो जाती हैं वगैरह. इसे हल करने का तरीका जानने के लिए, हमारे टेस्टर फ़ंक्शन pollGamepads() का सोर्स कोड देखें.

इवेंट

Firefox, Gamepad API विनिर्देशों में बताए गए एक विकल्प, बेहतर तरीके का इस्तेमाल करता है. आपको पोल कराने के लिए कहने के बजाय, वह दो इवेंट दिखाता है – MozGamepadConnected और MozGamepadDisconnected – जो किसी गेमपैड के प्लग इन होने (या किसी भी बटन को दबाकर ज़्यादा सटीक रूप से, प्लग इन किए जाने और "घोषणा" करने पर) या अनप्लग करते हैं. जो गेमपैड ऑब्जेक्ट अपने आने वाले समय में दिखता रहेगा उसे इवेंट ऑब्जेक्ट के .gamepad पैरामीटर के तौर पर पास किया जाता है.

टेस्टर के सोर्स कोड से:

/**
 * React to the gamepad being connected. Today, this will only be executed
 * on Firefox.
 */
onGamepadConnect: function(event) {
    // Add the new gamepad on the list of gamepads to look after.
    gamepadSupport.gamepads.push(event.gamepad);

    // Start the polling loop to monitor button changes.
    gamepadSupport.startPolling();

    // Ask the tester to update the screen to show more gamepads.
    tester.updateGamepads(gamepadSupport.gamepads);
},

खास जानकारी

आखिर में, दोनों तरीकों के साथ काम करते हुए, टेस्टर में हमारा इनिशलाइज़ेशन फ़ंक्शन ऐसा दिखता है:

/**
 * Initialize support for Gamepad API.
 */
init: function() {
    // As of writing, it seems impossible to detect Gamepad API support
    // in Firefox, hence we need to hardcode it in the third clause.
    // (The preceding two clauses are for Chrome.)
    var gamepadSupportAvailable = !!navigator.webkitGetGamepads ||
        !!navigator.webkitGamepads ||
        (navigator.userAgent.indexOf('Firefox/') != -1);

    if (!gamepadSupportAvailable) {
    // It doesn't seem Gamepad API is available – show a message telling
    // the visitor about it.
    tester.showNotSupported();
    } else {
    // Firefox supports the connect/disconnect event, so we attach event
    // handlers to those.
    window.addEventListener('MozGamepadConnected',
                            gamepadSupport.onGamepadConnect, false);
    window.addEventListener('MozGamepadDisconnected',
                            gamepadSupport.onGamepadDisconnect, false);

    // Since Chrome only supports polling, we initiate polling loop straight
    // away. For Firefox, we will only do it if we get a connect event.
    if (!!navigator.webkitGamepads || !!navigator.webkitGetGamepads) {
        gamepadSupport.startPolling();
    }
    }
},

गेमपैड की जानकारी

सिस्टम से कनेक्ट किए गए हर गेमपैड को एक ऑब्जेक्ट के ज़रिए दिखाया जाएगा, जो कुछ इस तरह दिखेगा:

id: "PLAYSTATION(R)3 Controller (STANDARD GAMEPAD Vendor: 054c Product: 0268)"
index: 1
timestamp: 18395424738498
buttons: Array[8]
    0: 0
    1: 0
    2: 1
    3: 0
    4: 0
    5: 0
    6: 0.03291
    7: 0
axes: Array[4]
    0: -0.01176
    1: 0.01961
    2: -0.00392
    3: -0.01176

सामान्य जानकारी

ऊपर के कुछ फ़ील्ड में सामान्य मेटाडेटा दिया गया है:

  • id: गेमपैड का टेक्स्ट के तौर पर ब्यौरा
  • index: एक कंप्यूटर से जुड़े अलग-अलग गेमपैड को बताने के लिए एक पूर्णांक
  • timestamp: बटन/ऐक्सिस की स्थिति के आखिरी अपडेट का टाइमस्टैंप (फ़िलहाल, सिर्फ़ Chrome में काम करता है)

बटन और स्टिक

आज के गेमपैड बिलकुल वैसे ही नहीं हैं जैसा आपके दादाजी ने राजकुमारी को गलत किले में बचाने के लिए इस्तेमाल किया होगा. आम तौर पर, इनमें दो ऐनालॉग स्टिक के अलावा, कम से कम सोलह अलग-अलग बटन (कुछ अलग, कुछ एनालॉग होते हैं). Gamepad API आपको उन सभी बटन और ऐनालॉग स्टिक के बारे में जानकारी देगा जिन्हें ऑपरेटिंग सिस्टम ने रिपोर्ट किया है.

गेमपैड ऑब्जेक्ट में मौजूदा स्टेटस मिलने के बाद, .buttons[] से बटन को ऐक्सेस किया जा सकता है और .axes[] कलेक्शन से स्टिक होता है. यहां इनके बारे में खास जानकारी दी गई है:

गेमपैड डायग्राम
गेमपैड डायग्राम

नियम के हिसाब से ब्राउज़र को पहले सोलह बटन और चार ऐक्सिस को मैप करने के लिए कहा जाता है:

gamepad.BUTTONS = {
    FACE_1: 0, // Face (main) buttons
    FACE_2: 1,
    FACE_3: 2,
    FACE_4: 3,
    LEFT_SHOULDER: 4, // Top shoulder buttons
    RIGHT_SHOULDER: 5,
    LEFT_SHOULDER_BOTTOM: 6, // Bottom shoulder buttons
    RIGHT_SHOULDER_BOTTOM: 7,
    SELECT: 8,
    START: 9,
    LEFT_ANALOGUE_STICK: 10, // Analogue sticks (if depressible)
    RIGHT_ANALOGUE_STICK: 11,
    PAD_TOP: 12, // Directional (discrete) pad
    PAD_BOTTOM: 13,
    PAD_LEFT: 14,
    PAD_RIGHT: 15
};

gamepad.AXES = {
    LEFT_ANALOGUE_HOR: 0,
    LEFT_ANALOGUE_VERT: 1,
    RIGHT_ANALOGUE_HOR: 2,
    RIGHT_ANALOGUE_VERT: 3
};

अतिरिक्त बटन और ऐक्सिस को ऊपर दिए बटन और ऐक्सिस में जोड़ दिया जाएगा. कृपया ध्यान रखें कि न तो सोलह बटन और न ही चार ऐक्सिस हैं, न ही कोई गारंटी है – उनमें से कुछ के लिए कोई वैल्यू नहीं दी गई है.

बटन 0.0 (दबाए नहीं गए) से 1.0 (पूरी तरह से दबाया गया) तक मान ले सकते हैं. ऐक्सिस, -1.0 (पूरी तरह से बाएं या ऊपर) से 0.0 (बीच में) से 1.0 (पूरी तरह से दाएं या नीचे) तक जाते हैं.

एनालॉग या डिस्क्रीट?

असल में, हर बटन एक एनालॉग हो सकता है – उदाहरण के लिए, कंधे वाले बटनों के लिए यह कुछ आम है. इसलिए, सिर्फ़ 1.00 की संख्या से तुलना करने के बजाय, थ्रेशोल्ड सेट करना सबसे अच्छा है. (अगर एनालॉग बटन थोड़ा गंदा हो, तो क्या होगा? यह कभी भी 1.00 तक नहीं पहुंच सकता). अपने डूडल में, हम ऐसा इस तरह करते हैं:

gamepad.ANALOGUE_BUTTON_THRESHOLD = .5;

gamepad.buttonPressed_ = function(pad, buttonId) {
    return pad.buttons[buttonId] &&
            (pad.buttons[buttonId] > gamepad.ANALOGUE_BUTTON_THRESHOLD);
};

आप ऐसा ही एनालॉग स्टिक को डिजिटल जॉयस्टिक में बदलने के लिए भी कर सकते हैं. ज़रूर, डिजिटल पैड (डी-पैड) हमेशा मौजूद रहता है, लेकिन हो सकता है कि आपके गेमपैड में ऐसा न हो. इसे मैनेज करने के लिए हमारा कोड यहां दिया गया है:

gamepad.AXIS_THRESHOLD = .75;

gamepad.stickMoved_ = function(pad, axisId, negativeDirection) {
    if (typeof pad.axes[axisId] == 'undefined') {
    return false;
    } else if (negativeDirection) {
    return pad.axes[axisId] < -gamepad.AXIS_THRESHOLD;
    } else {
    return pad.axes[axisId] > gamepad.AXIS_THRESHOLD;
    }
};

बटन दबाने और चिपकाने की मूवमेंट

इवेंट

कुछ मामलों में, जैसे किसी फ़्लाइट सिम्युलेटर गेम में, स्टिक स्थिति या बटन दबाने पर लगातार जांच करना और उस पर प्रतिक्रिया देना ज़्यादा अच्छा होता है... लेकिन हर्बल्स 2012 डूडल जैसी चीज़ों के लिए? आप सोच सकते हैं: मुझे हर फ़्रेम में बटनों की जांच क्यों करनी पड़ती है? मुझे कीबोर्ड या माउस अप/डाउन जैसे इवेंट क्यों नहीं मिल रहे हैं?

अच्छी खबर यह है कि आप ऐसा कर सकते हैं. आने वाले समय में बुरी खबर है. यह नियम में है, लेकिन इसे अभी तक किसी भी ब्राउज़र में लागू नहीं किया गया है.

पोल

इस बीच, बाहर निकलने का आपका तरीका मौजूदा और पिछली स्थिति की तुलना करना है. साथ ही, कोई अंतर दिखने पर कॉल फ़ंक्शन की तुलना करनी होगी. उदाहरण के लिए:

if (buttonPressed(pad, 0) != buttonPressed(oldPad, 0)) {
    buttonEvent(0, buttonPressed(pad, 0) ? 'down' : 'up');
}
for (var i in gamepadSupport.gamepads) {
    var gamepad = gamepadSupport.gamepads[i];

    // Don't do anything if the current timestamp is the same as previous
    // one, which means that the state of the gamepad hasn't changed.
    // This is only supported by Chrome right now, so the first check
    // makes sure we're not doing anything if the timestamps are empty
    // or undefined.
    if (gamepadSupport.prevTimestamps[i] &&
        (gamepad.timestamp == gamepadSupport.prevTimestamps[i])) {
    continue;
    }
    gamepadSupport.prevTimestamps[i] = gamepad.timestamp;

    gamepadSupport.updateDisplay(i);
}

बाधाएं 2012 डूडल में कीबोर्ड-फ़र्स्ट अप्रोच

गेमपैड के बिना, हमारे आज के डूडल में कीबोर्ड इस्तेमाल करने का पसंदीदा तरीका, कीबोर्ड है. इसलिए, हमने तय किया कि गेमपैड भी इसका करीब से पालन करेगा. इसका मतलब तीन फ़ैसले थे:

  1. डूडल को सिर्फ़ तीन बटन की ज़रूरत होती है – दो बटन दौड़ने के लिए और एक कूदने के लिए – हालांकि, गेमपैड में और भी कई बटन हो सकते हैं. इसलिए, हमने सभी सोलह बटन और दो जानी-पहचानी स्टिक को उन तीन लॉजिकल फ़ंक्शन पर मैप किया, जो हमारे हिसाब से सबसे सही थे, ताकि लोग अपनी बात कर सकें: बारी-बारी से A/B बटन, कंधे के बटन को बारी-बारी से दबाकर, डी-पैड पर बाएं/दाएं बटन दबाएं या दोनों में से कुछ, दूसरों की तुलना में ज़्यादा कुशल होंगे. उदाहरण के लिए:

    newState[gamepad.STATES.LEFT] =
        gamepad.buttonPressed_(pad, gamepad.BUTTONS.PAD_LEFT) ||
        gamepad.stickMoved_(pad, gamepad.AXES.LEFT_ANALOGUE_HOR, true) ||
        gamepad.stickMoved_(pad, gamepad.AXES.RIGHT_ANALOGUE_HOR, true),
    
    newState[gamepad.STATES.PRIMARY_BUTTON] =
        gamepad.buttonPressed_(pad, gamepad.BUTTONS.FACE_1) ||
        gamepad.buttonPressed_(pad, gamepad.BUTTONS.LEFT_SHOULDER) ||
        gamepad.buttonPressed_(pad, gamepad.BUTTONS.LEFT_SHOULDER_BOTTOM) ||
        gamepad.buttonPressed_(pad, gamepad.BUTTONS.SELECT) ||
        gamepad.buttonPressed_(pad, gamepad.BUTTONS.START) ||
        gamepad.buttonPressed_(pad, gamepad.BUTTONS.LEFT_ANALOGUE_STICK),
    
  2. हमने पहले बताए गए थ्रेशोल्ड फ़ंक्शन का इस्तेमाल करके, हर एनालॉग इनपुट को अलग इनपुट के तौर पर लिया है.

  3. हमने डूडल पर गेमपैड के इनपुट को जोड़ने के बजाय उसे जोड़ने की कोशिश की. हमारा पोलिंग लूप, असल में ज़रूरी कीडाउन और कीअप इवेंट (सही keyCode के साथ) को मिलाकर उन्हें डीओएम पर भेजता है:

    // Create and dispatch a corresponding key event.
    var event = document.createEvent('Event');
    var eventName = down ? 'keydown' : 'keyup';
    event.initEvent(eventName, true, true);
    event.keyCode = gamepad.stateToKeyCodeMap_[state];
    gamepad.containerElement_.dispatchEvent(event);

दर्शकों के लिए, प्रॉडक्ट खरीदने के बारे में बस इतना ही!

सुझाव और तरकीबें

  • याद रखें कि बटन दबाने से पहले, आपके ब्राउज़र में गेमपैड नहीं दिखेगा.
  • अगर अलग-अलग ब्राउज़र में एक साथ गेमपैड का टेस्ट किया जा रहा है, तो ध्यान रखें कि उनमें से कोई एक ही ब्राउज़र को समझ सकता है. अगर आपको कोई भी इवेंट नहीं मिल रहा है, तो उन अन्य पेजों को बंद करना न भूलें जो शायद उसका इस्तेमाल कर रहे हैं. साथ ही, हमारे अनुभव से पता चलता है कि कभी-कभी ब्राउज़र, टैब बंद करने या ब्राउज़र से बाहर निकलने के बाद भी गेमपैड को "होल्ड" कर सकता है. कभी-कभी चीज़ों को ठीक करने के लिए सिस्टम को रीस्टार्ट करना ही एक तरीका होता है.
  • हमेशा की तरह, दूसरे ब्राउज़र के लिए Chrome कैनरी और ऐसे ही किसी अन्य ब्राउज़र का इस्तेमाल करें. इससे यह पक्का होता है कि आपको सबसे अच्छी तरह काम कर रहा है. अगर आपको लगता है कि पुराने वर्शन अलग तरीके से काम कर रहे हैं, तो सही तरीके से काम करें.

द फ़्यूचर

हमें उम्मीद है कि इससे इस नए एपीआई के बारे में कुछ जानकारी देने में मदद मिलेगी – यह अब भी परेशान करने वाला है, लेकिन यह पहले से ही मज़ेदार है.

एपीआई के गायब हिस्सों (जैसे इवेंट) और व्यापक ब्राउज़र सहायता के अलावा, हम आखिरकार रंबल कंट्रोल, बिल्ट-इन जाइरोस्कोप तक पहुंच वगैरह जैसी चीज़ें भी देखने की उम्मीद कर रहे हैं. और अलग-अलग तरह के गेमपैड के लिए ज़्यादा सहायता – कृपया Chrome के ख़िलाफ़ गड़बड़ी दर्ज करें और/या Firefox के ख़िलाफ़ बग फ़ाइल करें, अगर आपको कोई भी गड़बड़ी ठीक से काम कर रही है या बिलकुल भी नहीं मिलती है.

लेकिन उससे पहले, हमारे Hurdles 2012 डूडल के साथ खेलें और देखें कि गेमपैड पर यह कितना मज़ेदार है. ओह, क्या तुमने अभी यह कहा कि तुम 10.7 सेकंड से बेहतर कर सकती हो? इसे ले जाएं.

इसके बारे में और पढ़ें