जेव्हा तुम्ही कंट्रोलर प्लग इन करता, तेव्हा तुम्ही बटणे मॅश करता, स्टिक्स हलवता, ट्रिगर्स खेचता… आणि डेव्हलपर म्हणून तुम्हाला यापैकी काहीही दिसत नाही. ब्राउझर ते उचलत आहे, नक्कीच, परंतु जोपर्यंत तुम्ही कन्सोलमध्ये नंबर लॉग करत नाही तोपर्यंत ते अदृश्य आहे. गेमपॅड API सह डोकेदुखी आहे. हे वर्षानुवर्षे चालत आले आहे, आणि ते खरोखर खूप शक्तिशाली आहे. तुम्ही बटणे, काठ्या, ट्रिगर, कामे वाचू शकता. परंतु बहुतेक लोक त्यास स्पर्श करत नाहीत. का? कारण कोणताही अभिप्राय नाही. विकसक साधनांमध्ये कोणतेही पॅनेल नाही. कंट्रोलर तुम्हाला जे वाटते ते करत आहे की नाही हे जाणून घेण्याचा कोणताही स्पष्ट मार्ग नाही. आंधळा उडतोय असे वाटते. त्यामुळं मला एक लहान साधन तयार करण्यासाठी पुरेसा बग दिला: गेमपॅड कॅस्केड डीबगर. कन्सोल आउटपुटकडे टक लावून पाहण्याऐवजी, तुम्हाला कंट्रोलरचे थेट, परस्परसंवादी दृश्य मिळेल. काहीतरी दाबा आणि ते स्क्रीनवर प्रतिक्रिया देते. आणि CSS कॅस्केड स्तरांसह, शैली व्यवस्थित राहतात, त्यामुळे डीबग करणे अधिक स्वच्छ आहे. या पोस्टमध्ये, मी तुम्हाला दाखवतो की डीबगिंग कंट्रोलर्स इतके वेदनादायक का आहेत, CSS ते साफ करण्यास कशी मदत करते आणि तुम्ही तुमच्या स्वतःच्या प्रकल्पांसाठी पुन्हा वापरता येण्याजोगे व्हिज्युअल डीबगर कसे तयार करू शकता.

जरी तुम्ही ते सर्व लॉग करू शकत असाल, तरीही तुम्हाला न वाचता येणारा कन्सोल स्पॅम त्वरीत मिळेल. उदाहरणार्थ: [०,०,१,०,०,०.५,०,...] [०,०,०,०,१,०,०,...] [०,०,१,०,०,०,०,...]

कोणते बटण दाबले होते ते सांगता येईल का? कदाचित, परंतु केवळ आपले डोळे ताणल्यानंतर आणि काही इनपुट गमावल्यानंतर. तर, नाही, इनपुट वाचण्याच्या बाबतीत डीबगिंग सहज येत नाही. समस्या 3: संरचनेचा अभाव जरी तुम्ही एक द्रुत व्हिज्युअलायझर एकत्र फेकले तरीही, शैली लवकर गोंधळात टाकू शकतात. डीफॉल्ट, सक्रिय आणि डीबग स्थिती ओव्हरलॅप होऊ शकतात आणि स्पष्ट संरचनेशिवाय, तुमची CSS ठिसूळ आणि वाढवणे कठीण होते. CSS कॅस्केड स्तर मदत करू शकतात. ते प्राधान्यक्रमानुसार क्रमबद्ध केलेल्या "थर" मध्ये शैलींचे गट करतात, त्यामुळे तुम्ही विशिष्टतेशी लढा देणे थांबवता आणि "माझी डीबग शैली का दिसत नाही?" त्याऐवजी, तुम्ही स्वतंत्र चिंता राखता:

बेस: कंट्रोलरचे मानक, प्रारंभिक स्वरूप. सक्रिय: दाबलेली बटणे आणि हलवलेल्या काड्यांसाठी हायलाइट. डीबग: डेव्हलपरसाठी आच्छादन (उदा. अंकीय वाचन, मार्गदर्शक आणि असेच).

जर आम्ही यानुसार सीएसएसमध्ये स्तर परिभाषित केले तर आमच्याकडे असेल: /* सर्वात कमी ते सर्वोच्च प्राधान्य */ @layer बेस, सक्रिय, डीबग;

@लेयर बेस { /* ... */ }

@layer सक्रिय { /* ... */ }

@layer डीबग { /* ... */ }

प्रत्येक लेयर अंदाजानुसार स्टॅक करत असल्यामुळे, कोणते नियम जिंकतात हे तुम्हाला नेहमी माहीत असते. त्या अंदाजामुळे डीबग करणे सोपे नाही तर प्रत्यक्षात व्यवस्थापित करता येते. आम्ही समस्या (अदृश्य, गोंधळलेले इनपुट) आणि दृष्टिकोन (कॅस्केड लेयर्ससह तयार केलेला व्हिज्युअल डीबगर) कव्हर केला आहे. आता आम्ही डीबगर तयार करण्यासाठी चरण-दर-चरण प्रक्रियेतून जाऊ. डीबगर संकल्पना लपविलेले इनपुट दृश्यमान करण्याचा सर्वात सोपा मार्ग म्हणजे तो फक्त स्क्रीनवर काढणे. हा डीबगर तेच करतो. बटणे, ट्रिगर आणि जॉयस्टिक्स या सर्वांना दृश्यमान मिळते.

A दाबा: एक वर्तुळ उजळते. काठी हलवा: वर्तुळ आजूबाजूला सरकते. ट्रिगर अर्ध्यावर खेचा: बार अर्ध्यावर भरतो.

आता तुम्ही 0s आणि 1s कडे पाहत नाही, पण प्रत्यक्षात कंट्रोलरची थेट प्रतिक्रिया पाहत आहात. अर्थात, एकदा तुम्ही डीफॉल्ट, दाबलेली, डीबग माहिती, कदाचित रेकॉर्डिंग मोड यांसारख्या स्थितींवर जमा करणे सुरू केले की, CSS मोठे आणि अधिक जटिल होऊ लागते. तिथेच कॅस्केड लेयर्स कामी येतात. येथे एक स्ट्रिप-डाउन उदाहरण आहे: @लेयर बेस { .बटण { पार्श्वभूमी: #222; सीमा-त्रिज्या: 50%; रुंदी: 40px; उंची: 40px; } }

@layer सक्रिय { .button.pressed { पार्श्वभूमी: #0f0; /* चमकदार हिरवा */ } }

@layer डीबग { .button:: नंतर { सामग्री: attr(डेटा-मूल्य); फॉन्ट-आकार: 12px; रंग: #fff; } }

लेयर ऑर्डर महत्त्वाची आहे: बेस → सक्रिय → डीबग.

बेस कंट्रोलर काढतो. सक्रिय हँडल दाबलेल्या स्थिती. आच्छादनांवर डीबग थ्रो.

अशा प्रकारे तोडणे म्हणजे आपण विचित्र विशिष्टतेची युद्धे लढत नाही आहात. प्रत्येक लेयरला त्याचे स्थान असते आणि आपल्याला नेहमी माहित असते की काय जिंकते. बिल्डिंग इट आउट प्रथम स्क्रीनवर काहीतरी मिळवूया. हे चांगले दिसण्याची आवश्यकता नाही - फक्त अस्तित्वात असणे आवश्यक आहे म्हणून आमच्याकडे कार्य करण्यासाठी काहीतरी आहे.

गेमपॅड कॅस्केड डीबगर

A
B
X

डीबगर निष्क्रिय

ते अक्षरशः फक्त बॉक्स आहेत. अद्याप रोमांचक नाही, परंतु ते आम्हाला CSS आणि JavaScript सह नंतर हस्तगत करण्यासाठी हँडल देते. ठीक आहे, मी येथे कॅस्केड लेयर्स वापरत आहे कारण एकदा तुम्ही आणखी राज्ये जोडली की ती सामग्री व्यवस्थित ठेवते. येथे एक उग्र पास आहे:

/* ===================================== कॅस्केड लेयर्स सेटअप ऑर्डर महत्त्वाची: बेस → सक्रिय → डीबग ======================================*/

/* लेयर ऑर्डर अगोदर परिभाषित करा */ @layer बेस, सक्रिय, डीबग;

/* स्तर 1: बेस शैली - डीफॉल्ट देखावा */ @लेयर बेस { .बटण { पार्श्वभूमी: #333; सीमा-त्रिज्या: 50%; रुंदी: 70px; उंची: 70px; डिस्प्ले: फ्लेक्स; justify-content: केंद्र; align-items: केंद्र; }

.विराम द्या { रुंदी: 20px; उंची: 70px; पार्श्वभूमी: #333; प्रदर्शन: इनलाइन-ब्लॉक; } }

/* स्तर 2: सक्रिय स्थिती - दाबलेली बटणे हाताळते */ @layer सक्रिय { .button.active { पार्श्वभूमी: #0f0; /* दाबल्यावर चमकदार हिरवा*/ रूपांतर: स्केल(1.1); /* बटण थोडे मोठे करते */ }

.pause.active { पार्श्वभूमी: #0f0; ट्रान्सफॉर्म: स्केलवाय(1.1); /* दाबल्यावर अनुलंब ताणतो */ } }

/* स्तर 3: डीबग आच्छादन - विकसक माहिती */ @layer डीबग { .button:: नंतर { सामग्री: attr(डेटा-मूल्य); /* अंकीय मूल्य दाखवते */ फॉन्ट-आकार: 12px; रंग: #fff; } }

या दृष्टिकोनाचे सौंदर्य हे आहे की प्रत्येक स्तराचा एक स्पष्ट हेतू आहे. बेस लेयर कधीही सक्रिय ओव्हरराइड करू शकत नाही आणि सक्रिय कधीही डीबग ओव्हरराइड करू शकत नाही, विशिष्टतेकडे दुर्लक्ष करून. हे CSS विशिष्टता युद्धे काढून टाकते जे सहसा डीबगिंग साधनांना त्रास देतात. आता असे दिसते की काही क्लस्टर गडद पार्श्वभूमीवर बसले आहेत. प्रामाणिकपणे, खूप वाईट नाही.

JavaScript जोडत आहे JavaScript वेळ. येथेच नियंत्रक प्रत्यक्षात काहीतरी करतो. आम्ही हे चरण-दर-चरण तयार करू. पायरी 1: राज्य व्यवस्थापन सेट करा प्रथम, डीबगरच्या स्थितीचा मागोवा घेण्यासाठी आम्हाला व्हेरिएबल्सची आवश्यकता आहे: // ==================================== // राज्य व्यवस्थापन // ====================================

चालू द्या = खोटे; // डीबगर सक्रिय आहे की नाही याचा मागोवा घेतो rafId द्या; // रद्द करण्यासाठी विनंती ॲनिमेशनफ्रेम आयडी संग्रहित करते

हे व्हेरिएबल्स ॲनिमेशन लूप नियंत्रित करतात जे गेमपॅड इनपुट सतत वाचतात. पायरी 2: DOM संदर्भ मिळवा पुढे, आम्ही अपडेट करत असलेल्या सर्व HTML घटकांचे संदर्भ मिळतात: // ==================================== // डोम एलिमेंट संदर्भ // ====================================

const btnA = document.getElementById("btn-a"); const btnB = document.getElementById("btn-b"); const btnX = document.getElementById("btn-x"); const pause1 = document.getElementById("pause1"); const pause2 = document.getElementById("pause2"); const status = document.getElementById("status");

DOM ला वारंवार क्वेरी करण्यापेक्षा हे संदर्भ समोर साठवणे अधिक कार्यक्षम आहे. पायरी 3: कीबोर्ड फॉलबॅक जोडा भौतिक नियंत्रकाशिवाय चाचणीसाठी, आम्ही बटणांवर कीबोर्ड की मॅप करू: // ==================================== // कीबोर्ड फॉलबॅक (कंट्रोलरशिवाय चाचणीसाठी) // ====================================

const keyMap = { "a": btnA, "b": btnB, "x": btnX, "p": [pause1, pause2] // 'p' की दोन्ही पॉज बार नियंत्रित करते };

हे आम्हाला कीबोर्डवरील की दाबून UI ची चाचणी करू देते. पायरी 4: मुख्य अपडेट लूप तयार करा जादू कुठे होते ते येथे आहे. हे कार्य सतत चालते आणि गेमपॅड स्थिती वाचते: // ==================================== // मुख्य गेमपॅड अपडेट लूप // ====================================

फंक्शन अपडेट गेमपॅड() { // सर्व कनेक्ट केलेले गेमपॅड मिळवा const gamepads = navigator.getGamepads(); जर (!gamepads) परत आले;

// प्रथम कनेक्ट केलेले गेमपॅड वापरा const gp = gamepads[0];

जर (जीपी) { // "सक्रिय" वर्ग टॉगल करून बटण स्थिती अद्यतनित करा btnA.classList.toggle("active", gp.buttons[0].pressed); btnB.classList.toggle("active", gp.buttons[1].pressed); btnX.classList.toggle("active", gp.buttons[2].pressed);

// पॉज बटण हँडल करा (बहुतेक नियंत्रकांवर बटण इंडेक्स 9) const pausePressed = gp.buttons[9].pressed; pause1.classList.toggle("सक्रिय", विराम दाबला); pause2.classList.toggle("सक्रिय", विराम दाबला);

// स्थिती प्रदर्शनासाठी सध्या दाबलेल्या बटणांची सूची तयार करा let pressed = []; gp.buttons.forEach((btn, i) => { जर (btn. दाबले)pressed.push("बटण" + i); });

// कोणतीही बटणे दाबल्यास स्थिती मजकूर अद्यतनित करा जर (दाबले. लांबी > 0) { status.textContent = "दाबले: " + pressed.join(", "); } }

// डीबगर चालू असल्यास लूप सुरू ठेवा जर (धावत) { rafId = requestAnimationFrame(UpdateGamepad); } }

classList.toggle() पद्धत बटण दाबले आहे की नाही यावर आधारित सक्रिय वर्ग जोडते किंवा काढून टाकते, जे आमच्या CSS स्तर शैलीला ट्रिगर करते. पायरी 5: कीबोर्ड इव्हेंट हाताळा हे इव्हेंट श्रोते कीबोर्ड फॉलबॅक कार्य करतात: // ==================================== // कीबोर्ड इव्हेंट हँडलर // ====================================

document.addEventListener("keydown", (e) => { जर (keyMap[e.key]) { // एकल किंवा एकाधिक घटक हाताळा जर (Array.isArray(keyMap[e.key])) { keyMap[e.key].forEach(el => el.classList.add("active")); } इतर { keyMap[e.key].classList.add("सक्रिय"); } status.textContent = "की दाबली: " + e.key.toUpperCase(); } });

document.addEventListener("keyup", (e) => { जर (keyMap[e.key]) { // की रिलीझ झाल्यावर सक्रिय स्थिती काढा जर (Array.isArray(keyMap[e.key])) { keyMap[e.key].forEach(el => el.classList.remove("active")); } इतर { keyMap[e.key].classList.remove("active"); } status.textContent = "की जारी केली: " + e.key.toUpperCase(); } });

पायरी 6: स्टार्ट/स्टॉप कंट्रोल जोडा शेवटी, आम्हाला डीबगर चालू आणि बंद करण्याचा मार्ग आवश्यक आहे: // ==================================== // टॉगल डीबगर चालू/बंद करा // ====================================

document.getElementById("टॉगल").addEventListener("क्लिक", () => { धावणे = !धावणे; // चालू स्थिती फ्लिप करा

जर (धावत) { status.textContent = "डीबगर चालू आहे..."; अपडेट गेमपॅड(); // अपडेट लूप सुरू करा } इतर { status.textContent = "डीबगर निष्क्रिय"; ॲनिमेशन फ्रेम (rafId) रद्द करा; // लूप थांबवा } });

तर होय, एक बटण दाबा आणि ते चमकते. काठी दाबा आणि ती हलते. तेच आहे. आणखी एक गोष्ट: कच्ची मूल्ये. काहीवेळा आपल्याला फक्त संख्या पहायची असतात, दिवे नव्हे.

या टप्प्यावर, आपण हे पहावे:

एक साधा ऑन-स्क्रीन कंट्रोलर, तुम्ही त्यांच्याशी संवाद साधताना प्रतिक्रिया देणारी बटणे आणि दाबलेले बटण निर्देशांक दर्शवणारे पर्यायी डीबग रीडआउट.

हे कमी अमूर्त करण्यासाठी, रिअल टाइममध्ये प्रतिक्रिया देणाऱ्या ऑन-स्क्रीन कंट्रोलरचा एक द्रुत डेमो येथे आहे:

आता, स्टार्ट रेकॉर्डिंग दाबल्याने तुम्ही रेकॉर्डिंग थांबवा दाबेपर्यंत सर्वकाही लॉग होते. 2. CSV/JSON वर डेटा निर्यात करणे एकदा आमच्याकडे लॉग आला की, आम्ही ते जतन करू इच्छितो.

पायरी 1: डाउनलोड मदतनीस तयार करा प्रथम, आम्हाला ब्राउझरमध्ये फाइल डाउनलोड हाताळणारे हेल्पर फंक्शन आवश्यक आहे: // ==================================== // फाइल डाउनलोड मदतनीस // ====================================

फंक्शन डाउनलोडफाइल(फाइलनाव, सामग्री, प्रकार = "मजकूर/साधा") { // सामग्रीमधून ब्लॉब तयार करा const blob = नवीन ब्लॉब([सामग्री], { प्रकार }); const url = URL.createObjectURL(blob);

// तात्पुरती डाउनलोड लिंक तयार करा आणि त्यावर क्लिक करा const a = document.createElement("a"); a.href = url; a.download = फाइलनाव; a.click();

// डाउनलोड केल्यानंतर ऑब्जेक्ट URL साफ करा setTimeout(() => URL.revokeObjectURL(url), 100); }

हे फंक्शन तुमच्या डेटामधून ब्लॉब (बायनरी लार्ज ऑब्जेक्ट) तयार करून, त्यासाठी तात्पुरती URL तयार करून आणि प्रोग्रामॅटिकली डाउनलोड लिंकवर क्लिक करून कार्य करते. साफसफाई हे सुनिश्चित करते की आम्ही मेमरी लीक करत नाही. पायरी 2: JSON निर्यात हाताळा JSON संपूर्ण डेटा संरचना जतन करण्यासाठी योग्य आहे:

// ==================================== // JSON म्हणून निर्यात करा // ====================================

document.getElementById("export-json").addEventListener("क्लिक", () => { // निर्यात करण्यासाठी काही आहे का ते तपासा जर (!frames.length) { console.warn("निर्यात करण्यासाठी कोणतेही रेकॉर्डिंग उपलब्ध नाही."); परत }

// मेटाडेटा आणि फ्रेम्ससह पेलोड तयार करा const पेलोड = { येथे निर्मित: नवीन तारीख().toISOSstring(), फ्रेम };

// स्वरूपित JSON म्हणून डाउनलोड करा फाइल डाउनलोड करा( "gamepad-log.json", JSON.stringify(पेलोड, शून्य, 2), "अनुप्रयोग/json" ); });

JSON फॉरमॅट सर्वकाही संरचित आणि सहजपणे पार्स करण्यायोग्य ठेवते, dev टूल्समध्ये परत लोड करण्यासाठी किंवा टीममेटसह शेअर करण्यासाठी ते आदर्श बनवते. पायरी 3: CSV निर्यात हाताळा CSV निर्यातीसाठी, आम्हाला श्रेणीबद्ध डेटा पंक्ती आणि स्तंभांमध्ये सपाट करणे आवश्यक आहे:

//==================================== // CSV म्हणून निर्यात करा // ====================================

document.getElementById("export-csv").addEventListener("क्लिक", () => { // निर्यात करण्यासाठी काही आहे का ते तपासा जर (!frames.length) { console.warn("निर्यात करण्यासाठी कोणतेही रेकॉर्डिंग उपलब्ध नाही."); परत }

// CSV शीर्षलेख पंक्ती तयार करा (टाइमस्टॅम्पसाठी स्तंभ, सर्व बटणे, सर्व अक्ष) const headerButtons = फ्रेम्स[0].buttons.map((_, i) => btn${i}); const headerAxes = frames[0].axes.map((_, i) => axis${i}); const header = ["t", ...headerButtons, ...headerAxes].join(",") + "\n";

// CSV डेटा पंक्ती तयार करा const rows = frames.map(f => { const btnVals = f.buttons.map(b => b.value); परत करा [f.t, ...btnVals, ...f.axes].join(","); }).सामील व्हा("\n");

// CSV म्हणून डाउनलोड करा डाउनलोड फाइल("gamepad-log.csv", शीर्षलेख + पंक्ती, "text/csv"); });

CSV डेटा विश्लेषणासाठी उत्कृष्ट आहे कारण ते थेट Excel किंवा Google Sheets मध्ये उघडते, ज्यामुळे तुम्हाला चार्ट, डेटा फिल्टर किंवा स्पॉट पॅटर्न दृश्यमानपणे तयार करता येतात. आता निर्यात बटणे आत आहेत, तुम्हाला पॅनेलवर दोन नवीन पर्याय दिसतील: निर्यात JSON आणि CSV निर्यात करा. जर तुम्हाला कच्चा लॉग परत तुमच्या dev टूल्समध्ये टाकायचा असेल किंवा स्ट्रक्चरभोवती पोक करायचा असेल तर JSON छान आहे. दुसरीकडे, CSV, थेट Excel किंवा Google Sheets मध्ये उघडते जेणेकरून तुम्ही चार्ट, फिल्टर किंवा इनपुटची तुलना करू शकता. खालील आकृती त्या अतिरिक्त नियंत्रणांसह पॅनेल कसे दिसते ते दर्शवते.

3. स्नॅपशॉट सिस्टम काहीवेळा आपल्याला संपूर्ण रेकॉर्डिंगची आवश्यकता नसते, फक्त इनपुट स्थितींचा एक द्रुत "स्क्रीनशॉट" असतो. तिथेच स्नॅपशॉट घ्या बटण मदत करते.

आणि JavaScript:

// ==================================== // स्नॅपशॉट घ्या // ====================================

document.getElementById("snapshot").addEventListener("क्लिक", () => { // सर्व कनेक्ट केलेले गेमपॅड मिळवा const pads = navigator.getGamepads(); const activePads = [];

// प्रत्येक कनेक्ट केलेल्या गेमपॅडची स्थिती लूप करा आणि कॅप्चर करा साठी (पॅडचा जीपी) { (!gp) सुरू ठेवल्यास; // रिक्त स्लॉट वगळा

activePads.push({ id: gp.id, // कंट्रोलरचे नाव/मॉडेल टाइमस्टॅम्प: performance.now(), बटणे: gp.buttons.map(b => ({ दाबलेले: b.pressed, मूल्य: b.value })), अक्ष: [...gp.axes] }); }

// कोणतेही गेमपॅड आढळले आहेत का ते तपासा जर (!activePads.length) { console.warn("स्नॅपशॉटसाठी कोणतेही गेमपॅड कनेक्ट केलेले नाहीत."); इशारा ("कोणताही नियंत्रक आढळला नाही!"); परत }

// लॉग इन करा आणि वापरकर्त्याला सूचित करा console.log("स्नॅपशॉट:", सक्रियपॅड); इशारा(स्नॅपशॉट घेतला! ${activePads.length} कंट्रोलर(s).) कॅप्चर केले; });

स्नॅपशॉट्स एका क्षणी तुमच्या कंट्रोलरची अचूक स्थिती गोठवतात. 4. घोस्ट इनपुट रीप्ले आता गंमतीसाठी: भूत इनपुट रीप्ले. हे एक लॉग घेते आणि एखाद्या फँटम प्लेअरने कंट्रोलर वापरल्याप्रमाणे ते दृश्यमानपणे प्ले करते.

रिप्लेसाठी JavaScript: // ==================================== // GHOST रीप्ले // ====================================

document.getElementById("रीप्ले").addEventListener("क्लिक", () => { // आमच्याकडे पुन्हा प्ले करण्यासाठी रेकॉर्डिंग असल्याची खात्री करा जर (!frames.length) { इशारा("पुन्हा प्ले करण्यासाठी कोणतेही रेकॉर्डिंग नाही!"); परत }

console.log("भूत रीप्ले सुरू करत आहे...");

// समक्रमित प्लेबॅकसाठी ट्रॅक टाइमिंग startTime = performance.now(); फ्रेमइंडेक्स = 0 द्या;

// ॲनिमेशन लूप रीप्ले करा कार्य चरण() { const now = performance.now(); const elapsed = आता - startTime;

// आत्तापर्यंत आलेल्या सर्व फ्रेम्सवर प्रक्रिया करा असताना (frameIndex < frames.length && frames[frameIndex].t <= गेलं) { const फ्रेम = फ्रेम्स[फ्रेमइंडेक्स];

// रेकॉर्ड केलेल्या बटणाच्या स्थितीसह UI अपडेट करा btnA.classList.toggle("active", frame.buttons[0].pressed); btnB.classList.toggle("active", frame.buttons[1].pressed); btnX.classList.toggle("active", frame.buttons[2].pressed);

// स्थिती प्रदर्शन अद्यतनित करा let pressed = []; frame.buttons.forEach((btn, i) => { जर (btn.pressed) pressed.push("Button" + i); }); जर (दाबले. लांबी > 0) { status.textContent = "भूत: " + pressed.join(", "); }

फ्रेमइंडेक्स++; }

// अधिक फ्रेम्स असल्यास लूप सुरू ठेवा जर (frameIndex < frames.length) { विनंती ॲनिमेशनफ्रेम(चरण); } इतर { console.log("रीप्लेसमाप्त."); status.textContent = "पुन्हा प्ले पूर्ण"; } }

// रीप्ले सुरू करा पाऊल(); });

डीबगिंग थोडे अधिक हँड-ऑन करण्यासाठी, मी एक भूत रीप्ले जोडला. एकदा तुम्ही सेशन रेकॉर्ड केल्यावर, तुम्ही रिप्ले दाबू शकता आणि UI ची क्रिया पाहू शकता, जसे की फँटम प्लेयर पॅड चालवत आहे. यासाठी पॅनेलमध्ये नवीन रिप्ले घोस्ट बटण दिसेल.

रेकॉर्ड दाबा, कंट्रोलरशी थोडासा गोंधळ करा, थांबा, नंतर पुन्हा प्ले करा. UI फक्त तुम्ही केलेल्या प्रत्येक गोष्टीचा प्रतिध्वनी करतो, जसे तुमच्या इनपुटचे अनुसरण करणारे भूत. या अवांतरांचा त्रास का?

रेकॉर्डिंग/निर्यात केल्याने परीक्षकांना नेमके काय झाले हे दाखवणे सोपे होते. स्नॅपशॉट वेळेत एक क्षण गोठवतात, जेव्हा तुम्ही विचित्र बग्सचा पाठलाग करत असाल तेव्हा खूप उपयुक्त. ट्यूटोरियल, प्रवेशयोग्यता तपासणी किंवा नियंत्रण सेटअप्सची शेजारी तुलना करण्यासाठी घोस्ट रीप्ले उत्तम आहे.

या क्षणी, तो आता फक्त एक नीटनेटका डेमो नाही, परंतु आपण प्रत्यक्षात कार्य करू शकता असे काहीतरी आहे. वास्तविक-जागतिक वापर प्रकरणे आता आम्हाला हा डीबगर मिळाला आहे जो बरेच काही करू शकतो. हे लाइव्ह इनपुट दाखवते, नोंदी नोंदवते, निर्यात करते आणि सामग्री रीप्ले करते. पण खरा प्रश्न आहे: कोणाला काळजी आहे? हे कोणासाठी उपयुक्त आहे? गेम डेव्हलपर्स नियंत्रक हे कामाचा भाग आहेत, परंतु त्यांना डीबग करणे? सहसा एक वेदना. कल्पना करा की तुम्ही फाइटिंग गेम कॉम्बोची चाचणी करत आहात, जसे की ↓ → + पंच. प्रार्थना करण्याऐवजी, तुम्ही ते त्याच प्रकारे दोनदा दाबले, तुम्ही ते एकदा रेकॉर्ड करा आणि ते पुन्हा प्ले करा. झाले. किंवा तुमचा मल्टीप्लेअर कोड त्यांच्या मशीनवर सारखीच प्रतिक्रिया देतो का हे तपासण्यासाठी तुम्ही टीममेटसह JSON लॉग स्वॅप करता. ते प्रचंड आहे. प्रवेशयोग्यता अभ्यासक हे माझ्या हृदयाच्या जवळ आहे. प्रत्येकजण "मानक" नियंत्रकासह खेळत नाही. अनुकूली नियंत्रक कधीकधी विचित्र सिग्नल फेकतात. या साधनाद्वारे, आपण नेमके काय घडत आहे ते पाहू शकता. शिक्षक, संशोधक, कोणीही असो. ते लॉग पकडू शकतात, त्यांची तुलना करू शकतात किंवा शेजारी-शेजारी इनपुट पुन्हा प्ले करू शकतात. अचानक, अदृश्य सामग्री स्पष्ट होते. गुणवत्ता हमी चाचणी परीक्षक सहसा "मी येथे बटणे मॅश केली आणि ती फुटली" सारख्या नोट्स लिहितात. फार उपयुक्त नाही. आता? ते अचूक प्रेस कॅप्चर करू शकतात, लॉग एक्सपोर्ट करू शकतात आणि ते पाठवू शकतात. अंदाज नाही. शिक्षक तुम्ही ट्यूटोरियल किंवा यूट्यूब व्हिडीओ बनवत असाल तर, घोस्ट रीप्ले सोनेरी आहे. तुम्ही शब्दशः म्हणू शकता, "मी कंट्रोलरसह काय केले ते येथे आहे," तर UI हे घडत असल्याचे दाखवते. स्पष्टीकरण अधिक स्पष्ट करते. खेळांच्या पलीकडे आणि हो, हे फक्त खेळांबद्दल नाही. लोकांनी रोबोट्स, कला प्रकल्प आणि प्रवेशयोग्यता इंटरफेससाठी नियंत्रक वापरले आहेत. प्रत्येक वेळी समान समस्या: ब्राउझर प्रत्यक्षात काय पाहत आहे? यासह, आपल्याला अंदाज लावण्याची गरज नाही. निष्कर्ष कंट्रोलर इनपुट डीबग करणे नेहमीच आंधळे उडण्यासारखे वाटले आहे. DOM किंवा CSS च्या विपरीत, गेमपॅडसाठी अंगभूत निरीक्षक नाही; हे कन्सोलमधील फक्त कच्चे क्रमांक आहेत, आवाजात सहज गमावले जातात. HTML, CSS आणि JavaScript च्या काही शंभर ओळींसह, आम्ही काहीतरी वेगळे तयार केले:

एक व्हिज्युअल डीबगर जो अदृश्य इनपुट दृश्यमान करतो. एक स्तरित CSS प्रणाली जी UI स्वच्छ आणि डीबग करण्यायोग्य ठेवते. सुधारणांचा एक संच (रेकॉर्डिंग, एक्सपोर्टिंग, स्नॅपशॉट्स, घोस्ट रीप्ले) जो डेमो वरून डेव्हलपर टूलवर वाढवतो.

वेब प्लॅटफॉर्मची शक्ती CSS कॅस्केड लेयर्समध्ये थोडी सर्जनशीलता मिसळून तुम्ही किती पुढे जाऊ शकता हे हा प्रकल्प दाखवतो. मी नुकतेच स्पष्ट केलेले साधन हे ओपन सोर्स आहे. तुम्ही GitHub रेपो क्लोन करू शकता आणि स्वतःसाठी प्रयत्न करू शकता. पण महत्त्वाचे म्हणजे तुम्ही ते स्वतःचे बनवू शकता. आपले स्वतःचे स्तर जोडा. तुमचे स्वतःचे रीप्ले लॉजिक तयार करा. ते तुमच्या गेम प्रोटोटाइपसह समाकलित करा. किंवा मी कल्पनाही केली नसलेल्या मार्गांनी ते वापरा. शिक्षण, प्रवेशयोग्यता किंवा डेटा विश्लेषणासाठी. दिवसाच्या शेवटी, हे फक्त गेमपॅड डीबग करण्याबद्दल नाही. हे लपविलेल्या इनपुटवर प्रकाश टाकण्याबद्दल आहे आणि विकसकांना हार्डवेअरसह कार्य करण्याचा आत्मविश्वास देण्याबद्दल आहे जे वेब अद्याप पूर्णपणे स्वीकारत नाही. म्हणून, तुमचा कंट्रोलर प्लग इन करा, तुमचा संपादक उघडा आणि प्रयोग सुरू करा. तुमचा ब्राउझर आणि तुमचा CSS खरोखर काय साध्य करू शकतात याबद्दल तुम्हाला आश्चर्य वाटेल.

You May Also Like

Enjoyed This Article?

Get weekly tips on growing your audience and monetizing your content — straight to your inbox.

No spam. Join 138,000+ creators. Unsubscribe anytime.

Create Your Free Bio Page

Join 138,000+ creators on Seemless.

Get Started Free