Երբ դուք միացնում եք կարգավորիչը, սեղմում եք կոճակները, տեղափոխում փայտիկները, քաշում ձգանները… և որպես մշակող՝ դուք դրանցից ոչ մեկը չեք տեսնում: Բրաուզերը, իհարկե, վերցնում է այն, բայց եթե դուք թվեր չեք գրանցում վահանակում, այն անտեսանելի է: Դա գլխացավանք է Gamepad API-ի հետ: Այն գոյություն ունի տարիներ շարունակ և իրականում բավականին հզոր է: Դուք կարող եք կարդալ կոճակները, փայտերը, ձգանները, աշխատանքները: Բայց շատերը չեն դիպչում դրան: Ինչո՞ւ։ Որովհետև հետադարձ կապ չկա: Մշակողի գործիքներում վահանակ չկա: Չկա հստակ միջոց՝ իմանալու, թե արդյոք վերահսկիչն անում է այն, ինչ դուք մտածում եք: Զգում է կույր թռչել: Դա ինձ բավականաչափ հուզեց՝ ստեղծելու փոքրիկ գործիք՝ Gamepad Cascade Debugger: Վահանակի ելքին նայելու փոխարեն դուք ստանում եք կարգավորիչի ուղիղ, ինտերակտիվ տեսարան: Սեղմեք ինչ-որ բան և այն արձագանքում է էկրանին: Իսկ CSS Cascade Layers-ի դեպքում ոճերը մնում են կազմակերպված, ուստի վրիպազերծելը ավելի մաքուր է: Այս գրառման մեջ ես ձեզ ցույց կտամ, թե ինչու է վրիպազերծման կարգավորիչները այդքան ցավոտ, ինչպես է CSS-ն օգնում մաքրել այն և ինչպես կարող եք ստեղծել բազմակի օգտագործման վիզուալ կարգաբերիչ ձեր սեփական նախագծերի համար:

Նույնիսկ եթե դուք կարողանաք գրանցել դրանք բոլորին, դուք արագ կհայտնվեք անընթեռնելի վահանակի սպամի հետ: Օրինակ. [0,0,1,0,0,0.5,0,...] [0,0,0,0,1,0,0,...] [0,0,1,0,0,0,0,...]

Կարո՞ղ եք ասել, թե ինչ կոճակ է սեղմվել: Գուցե, բայց միայն այն բանից հետո, երբ լարում եք ձեր աչքերը և բացակայում եք մի քանի մուտքեր: Այսպիսով, ոչ, վրիպազերծումը հեշտ չի լինում, երբ խոսքը վերաբերում է մուտքերի ընթերցմանը: Խնդիր 3. Կառուցվածքի բացակայություն Նույնիսկ եթե դուք հավաքում եք արագ վիզուալիզատոր, ոճերը կարող են արագ խառնաշփոթ լինել: Կանխադրված, ակտիվ և վրիպազերծման վիճակները կարող են համընկնել, և առանց հստակ կառուցվածքի, ձեր CSS-ը դառնում է փխրուն և դժվար է երկարացնել: CSS Cascade Layers-ը կարող է օգնել: Նրանք խմբավորում են ոճերը «շերտերի», որոնք դասավորված են ըստ առաջնահերթության, այնպես որ դուք դադարում եք պայքարել կոնկրետության հետ և կռահել՝ «Ինչո՞ւ չի ցուցադրվում վրիպազերծման իմ ոճը»: Փոխարենը, դուք պահպանում եք առանձին մտահոգություններ.

Հիմք՝ վերահսկիչի ստանդարտ, սկզբնական տեսք: Ակտիվ. սեղմված կոճակների և շարժված ձողիկների կարևորագույն կետերը: Վրիպազերծում. ծածկույթներ մշակողների համար (օրինակ՝ թվային ընթերցումներ, ուղեցույցներ և այլն):

Եթե մենք CSS-ում շերտեր սահմանեինք ըստ դրա, կունենայինք. /* ամենացածրից բարձր առաջնահերթություն */ @layer base, ակտիվ, կարգաբերում;

@շերտի հիմք { /* ... */ }

@շերտ ակտիվ { /* ... */ }

@շերտի վրիպազերծում { /* ... */ }

Քանի որ յուրաքանչյուր շերտ կուտակվում է կանխատեսելիորեն, դուք միշտ գիտեք, թե որ կանոններն են հաղթում: Այդ կանխատեսելիությունը դարձնում է վրիպազերծումը ոչ միայն հեշտ, այլ իրականում կառավարելի: Մենք լուսաբանել ենք խնդիրը (անտեսանելի, խառնաշփոթ մուտքագրում) և մոտեցումը (տեսողական վրիպազերծիչ, որը կառուցվել է Կասկադի շերտերով): Այժմ մենք քայլ առ քայլ կանցնենք վրիպազերծիչը կառուցելու համար: Debugger-ի հայեցակարգը Թաքնված մուտքագրումը տեսանելի դարձնելու ամենահեշտ ձևը պարզապես այն էկրանին նկարելն է: Դա այն է, ինչ անում է այս վրիպազերծիչը: Կոճակները, ձգանները և ջոյստիկները բոլորն էլ տեսողական տեսք են ստանում:

Սեղմեք A: Շրջանակը լուսավորվում է: Հպեք փայտը. շրջանը սահում է շուրջը: Ձգանը կիսով չափ քաշեք. բարը կիսով չափ լցվում է:

Այժմ դուք չեք նայում 0-ին և 1-ին, այլ իրականում դիտում եք վերահսկիչի արձագանքը ուղիղ եթերում: Իհարկե, երբ դուք սկսում եք կուտակել վիճակներ, ինչպիսիք են լռելյայն, սեղմված, վրիպազերծման տեղեկատվությունը, գուցե նույնիսկ ձայնագրման ռեժիմը, CSS-ը սկսում է ավելի մեծ և բարդ դառնալ: Այստեղ կասկադային շերտերը հարմար են: Ահա մի հանված օրինակ. @շերտի հիմք { .կոճակ { ֆոն՝ #222; սահման-շառավիղ` 50%; լայնությունը՝ 40px; բարձրությունը՝ 40px; } }

@շերտ ակտիվ { .button.սեղմված { ֆոն՝ #0f0; /* վառ կանաչ */ } }

@շերտի վրիպազերծում { .կոճակ::հետո { բովանդակություն՝ attr (տվյալների արժեք); տառաչափը՝ 12px; գույնը՝ #fff; } }

Շերտերի կարգը կարևոր է՝ հիմք → ակտիվ → վրիպազերծում։

բազան նկարում է կարգավորիչը: ակտիվ բռնակներ սեղմված վիճակներ: վրիպազերծումը նետում է ծածկույթների վրա:

Այսպես կոտրելը նշանակում է, որ դուք չեք պայքարում տարօրինակ հատուկ պատերազմների մեջ: Յուրաքանչյուր շերտ ունի իր տեղը, և դուք միշտ գիտեք, թե ինչ է հաղթում: Կառուցելով այն Եկեք նախ ինչ-որ բան տեսնենք էկրանին: Այն պետք չէ լավ տեսք ունենալ, պարզապես պետք է գոյություն ունենա, որպեսզի մենք ինչ-որ բան ունենանք աշխատելու:

Gamepad Cascade Debugger

Ա
Բ
X

Վրիպազերծիչն անգործուն է

Դա բառացիորեն պարզապես տուփեր են: Դեռևս հետաքրքիր չէ, բայց այն մեզ հնարավորություն է տալիս ավելի ուշ օգտագործել CSS-ի և JavaScript-ի միջոցով: Լավ, ես այստեղ օգտագործում եմ կասկադային շերտեր, քանի որ այն պահում է իրերը կազմակերպված, երբ ավելացնեք ավելի շատ վիճակներ: Ահա կոպիտ անցում.

/* ==================================== ԿԱՍԿԱԴԻ ՇԵՐՏԵՐԻ ԿԱՐԳԱՎՈՐՈՒՄԸ Կարևոր է պատվերը՝ բազա → ակտիվ → վրիպազերծում =================================== */

/* Նախապես սահմանեք շերտերի կարգը */ @layer base, ակտիվ, կարգաբերում;

/* Շերտ 1. Հիմնական ոճեր - լռելյայն տեսք */ @շերտի հիմք { .կոճակ { ֆոն՝ #333; սահման-շառավիղ` 50%; լայնությունը՝ 70px; բարձրությունը՝ 70px; ցուցադրում: flex; հիմնավորում-բովանդակություն՝ կենտրոն; align-իրեր՝ կենտրոն; }

.դադար { լայնությունը՝ 20px; բարձրությունը՝ 70px; ֆոն՝ #333; ցուցադրում: inline-block; } }

/* Շերտ 2. Ակտիվ վիճակներ - կարգավորում է սեղմված կոճակները */ @շերտ ակտիվ { .button.active { ֆոն՝ #0f0; /* Վառ կանաչ, երբ սեղմված է */ փոխակերպում՝ մասշտաբ (1.1); /* Մի փոքր մեծացնում է կոճակը */ }

.pause.active { ֆոն՝ #0f0; փոխակերպում՝ scaleY (1.1); /* Ձգվում է ուղղահայաց սեղմելիս */ } }

/* Շերտ 3. վրիպազերծել ծածկույթները - մշակողի տեղեկություններ */ @շերտի վրիպազերծում { .կոճակ::հետո { բովանդակություն՝ attr (տվյալների արժեք); /* Ցույց է տալիս թվային արժեքը */ տառաչափը՝ 12px; գույնը՝ #fff; } }

Այս մոտեցման գեղեցկությունն այն է, որ յուրաքանչյուր շերտ ունի հստակ նպատակ: Հիմնական շերտը երբեք չի կարող անտեսել ակտիվը, իսկ ակտիվը երբեք չի կարող վերացնել վրիպազերծումը, անկախ կոնկրետությունից: Սա վերացնում է CSS-ի առանձնահատկությունների պատերազմները, որոնք սովորաբար պատուհասում են վրիպազերծման գործիքներին: Այժմ թվում է, թե որոշ կլաստերներ նստած են մուգ ֆոնի վրա: Անկեղծ ասած, այնքան էլ վատ չէ:

JavaScript-ի ավելացում JavaScript ժամանակ. Սա այն վայրն է, որտեղ վերահսկիչը իրականում ինչ-որ բան է անում: Մենք սա կկառուցենք քայլ առ քայլ: Քայլ 1. Ստեղծեք պետական կառավարում Նախ, մեզ անհրաժեշտ են փոփոխականներ՝ վրիպազերծողի վիճակին հետևելու համար. // ==================================== // ՊԵՏԱԿԱՆ ԿԱՌԱՎԱՐՈՒՄ // ====================================

թող վազում = կեղծ; // Հետևում է, թե արդյոք վրիպազերծիչը ակտիվ է թող rafId; // Պահպանում է requestAnimationFrame ID-ն չեղարկման համար

Այս փոփոխականները կառավարում են անիմացիոն օղակը, որն անընդհատ կարդում է խաղային վահանակի մուտքագրումը: Քայլ 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 («կարգավիճակ»);

Այս տեղեկանքները առջևում պահելն ավելի արդյունավետ է, քան DOM-ում բազմիցս հարցումներ կատարելը: Քայլ 3. Ավելացնել ստեղնաշարի հետադարձ կապ Առանց ֆիզիկական կարգավորիչի փորձարկման համար մենք ստեղնաշարի ստեղները կնշենք կոճակներին. // ==================================== // KEYBOARD FALLBACK (առանց կարգավորիչի փորձարկման համար) // ====================================

const keyMap = { «a»: btnA, «b»: btnB, «x»: btnX, «p»: [դադար1, դադար2] // «p» ստեղնը կառավարում է դադարի երկու տողերը };

Սա թույլ է տալիս մեզ փորձարկել միջերեսը՝ սեղմելով ստեղնաշարի ստեղները: Քայլ 4. Ստեղծեք հիմնական թարմացման հանգույցը Ահա թե որտեղ է տեղի ունենում կախարդանքը. Այս ֆունկցիան անընդհատ աշխատում է և կարդում է խաղային պահոցի վիճակը. // ==================================== // ՀԻՄՆԱԿԱՆ GAMEPAD UPDATE LOOP // ====================================

ֆունկցիա updateGamepad() { // Ստացեք բոլոր միացված խաղային վահանակները const gamepads = navigator.getGamepads(); եթե (!gamepads) վերադառնան;

// Օգտագործեք առաջին միացված gamepad-ը const gp = gamepads[0];

եթե (gp) { // Թարմացնել կոճակի վիճակները՝ միացնելով «ակտիվ» դասը btnA.classList.toggle («ակտիվ», gp.buttons[0].սեղմված); btnB.classList.toggle («ակտիվ», gp.buttons[1].սեղմված); btnX.classList.toggle («ակտիվ», gp.buttons[2].սեղմված);

// Կարգավորել դադար կոճակը (կոճակի ինդեքսը 9-ը կարգավորիչների մեծ մասում) const pausePressed = gp.buttons[9].սեղմված; pause1.classList.toggle("ակտիվ", pausePressed); pause2.classList.toggle ("ակտիվ", pausePressed);

// Ստեղծեք ներկայումս սեղմված կոճակների ցանկ՝ կարգավիճակի ցուցադրման համար թող սեղմված = []; gp.buttons.forEach((btn, i) => { եթե (btn.սեղմված)pressed.push ("Button" + i); });

// Թարմացրեք կարգավիճակի տեքստը, եթե որևէ կոճակ սեղմված է եթե (սեղմված. երկարություն > 0) { status.textContent = "Սեղմված է. " + pressed.join(", "); } }

// Շարունակեք հանգույցը, եթե վրիպազերծիչը աշխատում է եթե (վազում) { rafId = requestAnimationFrame (updateGamepad); } }

classList.toggle() մեթոդը ավելացնում կամ հեռացնում է ակտիվ դասը՝ հիմնվելով կոճակի սեղմման վրա, ինչը գործարկում է մեր CSS շերտի ոճերը։ Քայլ 5. Կառավարեք ստեղնաշարի իրադարձությունները Միջոցառումների այս ունկնդիրները ստիպում են ստեղնաշարի հետընտրական աշխատանքը. // ==================================== // ՍՏԵՂՆԱՏԱՐԻ ՄԻՋՈՑԱՌՈՒՄՆԵՐԻ ՀԱՆԴԻՊՈՒՄՆԵՐ // ====================================

document.addEventListener("keydown", (e) => { if (keyMap[e.key]) { // Կառավարել մեկ կամ մի քանի տարրեր if (Array.isArray(keyMap[e.key])) { keyMap[e.key].forEach (el => el.classList.add ("ակտիվ")); } ուրիշ { keyMap[e.key].classList.add(«ակտիվ»); } status.textContent = "Ստեղնը սեղմված է. " + e.key.toUpperCase(); } });

document.addEventListener("keyup", (e) => { if (keyMap[e.key]) { // Հեռացնել ակտիվ վիճակը, երբ բանալին բաց է if (Array.isArray(keyMap[e.key])) { keyMap[e.key].forEach (el => el.classList.remove ("ակտիվ")); } ուրիշ { keyMap[e.key].classList.remove(«ակտիվ»); } status.textContent = "Բանալին թողարկվեց. " + e.key.toUpperCase(); } });

Քայլ 6. Ավելացնել Start/Stop Control Վերջապես, մեզ անհրաժեշտ է մի միջոց՝ վրիպազերծիչը միացնելու և անջատելու համար. // ==================================== // ՄԻԱՑՆԵԼ/ԱՆՋԱՏԵԼ ՎՈՒՂԵՐԱՓՈԽՄԱՆԸ // ====================================

document.getElementById("toggle").addEventListener("click", () => { վազում = !վազում; // Շրջեք գործարկման վիճակը

եթե (վազում) { status.textContent = "Վրիպազերծիչն աշխատում է..."; updateGamepad(); // Սկսեք թարմացման հանգույցը } ուրիշ { status.textContent = «Վրիպազերծիչն ակտիվ չէ»; cancelAnimationFrame (rafId); // Դադարեցրեք հանգույցը } });

Այսպիսով, այո, սեղմեք կոճակը և այն փայլում է: Հրել փայտիկը, և այն շարժվում է: Ահա և վերջ։ Եվս մեկ բան՝ հում արժեքներ։ Երբեմն դուք պարզապես ցանկանում եք տեսնել թվեր, ոչ թե լույսեր:

Այս փուլում դուք պետք է տեսնեք.

Պարզ էկրանի վերահսկիչ, Կոճակներ, որոնք արձագանքում են, երբ դուք շփվում եք նրանց հետ, և Ընտրովի վրիպազերծման ընթերցում, որը ցույց է տալիս սեղմված կոճակի ինդեքսները:

Սա ավելի քիչ վերացական դարձնելու համար, ահա էկրանին կարգավորիչի արագ ցուցադրումը, որն արձագանքում է իրական ժամանակում.

Այժմ, սեղմելով «Սկսել ձայնագրումը», ամեն ինչ գրանցվում է, մինչև սեղմեք «Դադարեցնել ձայնագրումը»: 2. Տվյալների արտահանում CSV/JSON Երբ մենք գրանցամատյան ունենանք, մենք կցանկանանք պահպանել այն:

Քայլ 1. Ստեղծեք Ներբեռնման օգնականը Նախ, մեզ անհրաժեշտ է օգնական գործառույթ, որը կարգավորում է բրաուզերում ֆայլերի ներբեռնումը. // ==================================== // Ֆայլի ներբեռնման օգնական // ====================================

ֆունկցիա ներբեռնելՖայլ (ֆայլի անվանում, բովանդակություն, տեսակ = «տեքստ/պարզ») { // Բովանդակությունից բլոբ ստեղծեք const blob = new Blob ([բովանդակություն], {type }); const url = URL.createObjectURL(blob);

// Ստեղծեք ներբեռնման ժամանակավոր հղում և սեղմեք այն const a = document.createElement ("a"); a.href = url; a.download = ֆայլի անուն; a.click();

// Մաքրել օբյեկտի URL-ը ներբեռնումից հետո setTimeout (() => URL.revokeObjectURL(url), 100); }

Այս ֆունկցիան աշխատում է ձեր տվյալներից Blob (երկուական մեծ օբյեկտ) ստեղծելով, դրա համար ժամանակավոր URL ստեղծելով և ծրագրային կերպով սեղմելով ներբեռնման հղումը: Մաքրումը երաշխավորում է, որ մենք հիշողությունից չենք արտահոսում: Քայլ 2. Կառավարեք JSON արտահանումը JSON-ը կատարյալ է տվյալների ամբողջական կառուցվածքը պահպանելու համար.

// ==================================== // ԱՐՏԱՀԱՆՈՒՄ ՈՐՊԵՍ JSON // ====================================

document.getElementById("export-json").addEventListener("click", () => { // Ստուգեք, արդյոք արտահանելու բան կա if (!frames.length) { console.warn («Արտահանման համար հասանելի ձայնագրություն չկա»); վերադարձ; }

// Ստեղծեք օգտակար բեռ մետատվյալներով և շրջանակներով Const ծանրաբեռնվածություն = { createAt: new Date().toISOSstring(), շրջանակներ };

// Ներբեռնեք որպես ձևաչափված JSON ներբեռնել ֆայլ ( «gamepad-log.json», JSON.stringify (payload, null, 2), «հավելված/json» ); });

JSON ձևաչափը պահպանում է ամեն ինչ կառուցվածքային և հեշտությամբ վերլուծելի՝ դարձնելով այն իդեալական մշակող գործիքներում նորից բեռնելու կամ թիմակիցների հետ կիսվելու համար: Քայլ 3. Կառավարեք CSV արտահանումը CSV արտահանման համար մենք պետք է հարթեցնենք հիերարխիկ տվյալները տողերի և սյունակների մեջ.

//=================================== // ԱՐՏԱՀԱՆՈՒՄ AS CSV // ====================================

document.getElementById("export-csv").addEventListener("click", () => { // Ստուգեք, արդյոք արտահանելու բան կա if (!frames.length) { console.warn («Արտահանման համար հասանելի ձայնագրություն չկա»); վերադարձ; }

// Կառուցեք CSV վերնագրի տող (սյունակներ՝ ժամանակի դրոշմակնիքի, բոլոր կոճակների, բոլոր առանցքների համար) const headerButtons = frames[0].buttons.map((_, i) => btn${i}); const headerAxes = frames[0].axes.map((_, i) => առանցք${i}); const header = ["t", ...headerButtons, ...headerAxes].join(",") + "\n";

// Կառուցեք CSV տվյալների տողեր const rows = frames.map(f => { const btnVals = f.buttons.map(b => b.value); return [f.t, ...btnVals, ...f.axes].join(","); }).միանալ("\n");

// Ներբեռնեք որպես CSV downloadFile («gamepad-log.csv», վերնագիր + տողեր, «տեքստ/csv»); });

CSV-ը փայլուն է տվյալների վերլուծության համար, քանի որ այն բացվում է անմիջապես Excel-ում կամ Google Sheets-ում՝ թույլ տալով ստեղծել գծապատկերներ, զտել տվյալները կամ տեսողականորեն նկատել նախշերը: Այժմ, երբ արտահանման կոճակները միացված են, վահանակի վրա կտեսնեք երկու նոր տարբերակ՝ Արտահանել JSON և Արտահանել CSV: JSON-ը լավ է, եթե ցանկանում եք չմշակված գրանցամատյանը հետ նետել ձեր մշակող գործիքների մեջ կամ շրջել կառուցվածքը: Մյուս կողմից, CSV-ը բացվում է անմիջապես Excel-ի կամ Google Sheets-ի մեջ, որպեսզի կարողանաք գծապատկերում, զտել կամ համեմատել մուտքերը: Հետևյալ նկարը ցույց է տալիս, թե ինչ տեսք ունի վահանակը այդ լրացուցիչ կառավարիչների հետ:

3. Snapshot System Երբեմն ձեզ հարկավոր չէ ամբողջական ձայնագրություն, պարզապես մուտքագրման վիճակների արագ «սքրինշոթ»: Ահա թե որտեղ է օգնում Take Snapshot կոճակը:

Իսկ JavaScript-ը.

// ==================================== // TAKE SNAPSHOT // ====================================

document.getElementById("snapshot").addEventListener("click", () => { // Ստացեք բոլոր միացված խաղային վահանակները const բարձիկներ = navigator.getGamepads(); const activePads = [];

// Անցեք և ֆիքսեք յուրաքանչյուր միացված gamepad-ի վիճակը for (const gp of pads) { եթե (!gp) շարունակվի; // Բաց թողնել դատարկ անցքերը

activePads.push({ id՝ gp.id, // Կարգավորիչի անունը/մոդելը ժամադրոշմ՝ performance.now(), կոճակներ՝ gp.buttons.map(b => ({ սեղմված՝ բ.սեղմված, արժեք՝ բ.արժեք })), axes՝ [...gp.axes] }); }

// Ստուգեք, արդյոք գտնվել են խաղային վահանակներ if (!activePads.length) { console.warn («Պատկերի համար միացված խաղադաշտեր չկան»); alert («Կարգավորիչ չի հայտնաբերվել»); վերադարձ; }

// Մուտք գործեք և տեղեկացրեք օգտվողին console.log ("Snapshot:", activePads); alert(Պատկերն արված է: Գրված է ${activePads.length} կարգավորիչ(ներ):); });

Snapshots-ը սառեցնում է ձեր կարգավորիչի ճշգրիտ վիճակը ժամանակի ընթացքում: 4. Ghost Input Replay Հիմա զվարճալի մեկի համար. ուրվականների մուտքագրման կրկնություն: Սա վերցնում է գրանցամատյան և այն տեսողականորեն ցուցադրում է, կարծես ֆանտոմ նվագարկիչը օգտագործում է վերահսկիչը:

JavaScript վերարտադրման համար. // ==================================== // GHOST REPLAY // ====================================

document.getElementById("replay").addEventListener("click", () => { // Համոզվեք, որ մենք ունենք ձայնագրություն վերարտադրելու համար if (!frames.length) { alert («Ձայնագրություն չկա վերարտադրելու համար»); վերադարձ; }

console.log ("Starting ghost replay...");

// Հետևեք համաժամացված նվագարկման ժամանակին թող startTime = performance.now(); թող frameIndex = 0;

// Կրկնել անիմացիոն հանգույց ֆունկցիայի քայլ() { const now = performance.now(); const elapsed = now - startTime;

// Մշակել բոլոր շրջանակները, որոնք մինչ այժմ պետք է հայտնվեին while (frameIndex < frames.length && frames[frameIndex].t <= անցած) { const շրջանակ = շրջանակներ[frameIndex];

// Թարմացրեք UI-ը ձայնագրված կոճակի վիճակներով btnA.classList.toggle(«ակտիվ», շրջանակ.կոճակներ[0].սեղմված); btnB.classList.toggle(«ակտիվ», շրջանակ.կոճակներ[1].սեղմված); btnX.classList.toggle («ակտիվ», շրջանակ.կոճակներ[2].սեղմված);

// Թարմացնել կարգավիճակի ցուցադրումը թող սեղմված = []; frame.buttons.forEach((btn, i) => { if (btn.pressed) pressed.push("Button" + i); }); եթե (սեղմված. երկարություն > 0) { status.textContent = "Ghost: " + pressed.join(", "); }

frameIndex++; }

// Շարունակեք հանգույցը, եթե ավելի շատ շրջանակներ կան if (frameIndex < frames.length) { requestAnimationFrame (քայլ); } ուրիշ { console.log ("Replayավարտված»); status.textContent = «Վերականգնումն ավարտված է»; } }

// Սկսեք կրկնությունը քայլ (); });

Վրիպազերծումը մի փոքր ավելի գործնական դարձնելու համար ես ավելացրեցի ուրվականների կրկնությունը: Նիստը ձայնագրելուց հետո կարող եք սեղմել «Replay» և դիտել, թե ինչպես է ինտերֆեյսը ցուցադրում այն, գրեթե այնպես, ինչպես ֆանտոմային նվագարկիչը վարում է պահոցը: Դրա համար վահանակում հայտնվում է Replay Ghost-ի նոր կոճակ:

Կտտացրեք Record, մի փոքր խառնվեք կարգավորիչի հետ, կանգ առեք, ապա նորից նվագարկեք: UI-ն ուղղակի արձագանքում է այն ամենին, ինչ դուք արել եք, ինչպես ուրվականը, որը հետևում է ձեր մուտքերին: Ինչու՞ անհանգստանալ այս հավելյալներից:

Ձայնագրումը/արտահանումը հեշտացնում է փորձարկողների համար ճշգրիտ ցույց տալ, թե ինչ է տեղի ունեցել: Պատկերները մի պահ սառչում են, ինչը շատ օգտակար է, երբ հետապնդում եք տարօրինակ վրիպակներ: Ghost replay-ը հիանալի է ձեռնարկների, մատչելիության ստուգումների կամ պարզապես կողք կողքի կառավարման կարգավորումները համեմատելու համար:

Այս պահին դա այլևս պարզապես կոկիկ ցուցադրություն չէ, այլ մի բան, որը դուք կարող եք իրականում գործի դնել: Իրական աշխարհի օգտագործման դեպքեր Այժմ մենք ունենք այս կարգաբերիչը, որը կարող է շատ բան անել: Այն ցույց է տալիս կենդանի մուտքագրում, գրանցում է տեղեկամատյանները, արտահանում դրանք և նույնիսկ վերարտադրում իրերը: Բայց իրական հարցն այն է, թե իրականում ո՞ւմ է դա հետաքրքրում: Ու՞մ համար է սա օգտակար: Խաղի ծրագրավորողներ Կարգավորիչները աշխատանքի մի մասն են, բայց վրիպազերծե՞լ դրանք: Սովորաբար ցավ: Պատկերացրեք, որ դուք փորձարկում եք մարտական ​​խաղի կոմբինացիա, օրինակ՝ ↓ → + դակիչ: Աղոթելու փոխարեն երկու անգամ սեղմել ես նույն կերպ, մեկ անգամ ձայնագրել և նորից նվագարկել։ Կատարված է: Կամ դուք փոխանակում եք JSON տեղեկամատյանները թիմակցի հետ՝ ստուգելու համար, թե արդյոք ձեր բազմախաղացող կոդը նույնն է արձագանքում նրանց ապարատին: Դա հսկայական է: Մատչելիության պրակտիկանտներ Այս մեկն ինձ հոգեհարազատ է. Ոչ բոլորն են խաղում «ստանդարտ» կարգավորիչով: Հարմարվողական կարգավորիչները երբեմն տարօրինակ ազդանշաններ են նետում: Այս գործիքի միջոցով դուք կարող եք ճշգրիտ տեսնել, թե ինչ է տեղի ունենում: Ուսուցիչներ, հետազոտողներ, ովքեր էլ որ լինեն: Նրանք կարող են բռնել տեղեկամատյանները, համեմատել դրանք կամ վերարտադրել մուտքերը կողք կողքի: Հանկարծ ակնհայտ է դառնում անտեսանելի իրերը։ Որակի ապահովման փորձարկում Փորձարկողները սովորաբար գրում են նշումներ, ինչպիսիք են «Ես այստեղ կոճակները տրորեցի, և այն կոտրվեց»: Ոչ շատ օգտակար: Հիմա? Նրանք կարող են գրավել ճշգրիտ մամլիչները, արտահանել տեղեկամատյանը և ուղարկել այն: Ոչ մի գուշակություն: Դաստիարակներ Եթե դուք ձեռնարկներ կամ YouTube-ի տեսանյութեր եք պատրաստում, ապա ուրվականների վերարտադրումը ոսկե է: Դուք կարող եք բառացիորեն ասել, «Ահա, թե ինչ եմ ես արել վերահսկիչի հետ», մինչդեռ UI-ն ցույց է տալիս, որ դա տեղի է ունենում: Բացատրությունները ավելի պարզ է դարձնում: Խաղերից այն կողմ Եվ այո, սա միայն խաղերի մասին չէ: Մարդիկ օգտագործել են կարգավորիչներ ռոբոտների, արվեստի նախագծերի և հասանելիության ինտերֆեյսների համար: Ամեն անգամ նույն խնդիրը. ի՞նչ է իրականում տեսնում զննարկիչը: Դրանով դուք պետք չէ գուշակել. Եզրակացություն Կարգավորիչի մուտքագրման վրիպազերծումը միշտ զգացել է որպես կույր թռչող: Ի տարբերություն DOM-ի կամ CSS-ի, խաղային վահանակների համար ներկառուցված տեսուչ չկա. դա պարզապես հում թվեր են վահանակում, որոնք հեշտությամբ կորչում են աղմուկի մեջ: HTML, CSS և JavaScript-ի մի քանի հարյուր տողով մենք տարբեր բան ենք կառուցել.

Տեսողական վրիպազերծիչ, որը տեսանելի է դարձնում անտեսանելի մուտքերը: Շերտավոր CSS համակարգ, որը պահպանում է UI-ը մաքուր և կարգաբերելի: Բարելավումների մի շարք (ձայնագրում, արտահանում, նկարներ, ուրվականների վերարտադրում), որոնք այն դարձնում են ցուցադրականից մինչև մշակողի գործիք:

Այս նախագիծը ցույց է տալիս, թե որքան հեռու կարող եք գնալ՝ խառնելով Վեբ պլատֆորմի հզորությունը CSS Cascade Layers-ում մի փոքր ստեղծագործականության հետ: Գործիքը, որը ես պարզապես բացատրեցի ամբողջությամբ, բաց կոդով է: Դուք կարող եք կլոնավորել 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