ເມື່ອທ່ານສຽບຕົວຄວບຄຸມ, ທ່ານກົດປຸ່ມ, ຍ້າຍໄມ້, ດຶງຕົວກະຕຸ້ນ ... ແລະໃນຖານະນັກພັດທະນາ, ທ່ານບໍ່ເຫັນມັນໃດໆ. ຕົວທ່ອງເວັບເລືອກມັນ, ແນ່ນອນ, ແຕ່ເວັ້ນເສຍແຕ່ວ່າທ່ານກໍາລັງບັນທຶກຕົວເລກຢູ່ໃນ console, ມັນເບິ່ງບໍ່ເຫັນ. ນັ້ນແມ່ນຄວາມເຈັບຫົວກັບ Gamepad API. ມັນ​ເປັນ​ເວ​ລາ​ຫຼາຍ​ປີ​, ແລະ​ຕົວ​ຈິງ​ແລ້ວ​ມັນ​ມີ​ອໍາ​ນາດ​ຫຼາຍ​. ທ່ານ​ສາ​ມາດ​ອ່ານ​ປຸ່ມ​, ໄມ້​, ຜົນ​ກະ​ທົບ​, ການ​ເຮັດ​ວຽກ​. ແຕ່ຄົນສ່ວນໃຫຍ່ບໍ່ແຕະຕ້ອງມັນ. ເປັນຫຍັງ? ເນື່ອງຈາກວ່າບໍ່ມີຄວາມຄິດເຫັນ. ບໍ່ມີແຜງຢູ່ໃນເຄື່ອງມືນັກພັດທະນາ. ບໍ່ມີວິທີທີ່ຈະແຈ້ງທີ່ຈະຮູ້ວ່າຜູ້ຄວບຄຸມຍັງເຮັດຕາມທີ່ທ່ານຄິດຫຼືບໍ່. ມັນຮູ້ສຶກຄືກັບບິນຕາບອດ. ສິ່ງນັ້ນເຮັດໃຫ້ຂ້ອຍສາມາດສ້າງເຄື່ອງມືເລັກນ້ອຍ: Gamepad Cascade Debugger. ແທນ​ທີ່​ຈະ​ເບິ່ງ​ຜົນ​ຜະ​ລິດ console​, ທ່ານ​ຈະ​ໄດ້​ຮັບ​ການ​ສົດ​ໃສ​, ການ​ໂຕ້​ຕອບ​ຂອງ​ການ​ຄວບ​ຄຸມ​. ກົດບາງສິ່ງບາງຢ່າງແລະມັນ reacts ໃນຫນ້າຈໍ. ແລະດ້ວຍ CSS Cascade Layers, ຮູບແບບຕ່າງໆຍັງຄົງເປັນລະບຽບ, ສະນັ້ນມັນສະອາດກວ່າທີ່ຈະດີບັກ. ໃນບົດຂຽນນີ້, ຂ້ອຍຈະສະແດງໃຫ້ເຈົ້າເຫັນວ່າເປັນຫຍັງຕົວຄວບຄຸມການດີບັກຈຶ່ງເປັນຄວາມເຈັບປວດ, ວິທີທີ່ CSS ຊ່ວຍເຮັດຄວາມສະອາດມັນ, ແລະວິທີທີ່ເຈົ້າສາມາດສ້າງຕົວແກ້ບັນຫາສາຍຕາທີ່ໃຊ້ຄືນໄດ້ສໍາລັບໂຄງການຂອງເຈົ້າເອງ.

ເຖິງແມ່ນວ່າທ່ານສາມາດບັນທຶກພວກມັນທັງຫມົດ, ທ່ານຈະສິ້ນສຸດດ້ວຍ spam console ທີ່ບໍ່ສາມາດອ່ານໄດ້ຢ່າງໄວວາ. ຕົວຢ່າງ: [0,0,1,0,0,0.5,0,...] [0,0,0,0,1,0,0,...] [0,0,1,0,0,0,0,...]

ທ່ານສາມາດບອກໄດ້ວ່າກົດປຸ່ມໃດ? ບາງທີ, ແຕ່ວ່າພຽງແຕ່ຫຼັງຈາກ straining ຕາຂອງທ່ານແລະຂາດການປ້ອນຂໍ້ມູນຈໍານວນຫນ້ອຍຫນຶ່ງ. ດັ່ງນັ້ນ, ບໍ່, debugging ບໍ່ໄດ້ມາໄດ້ຢ່າງງ່າຍດາຍໃນເວລາທີ່ມັນມາກັບການອ່ານວັດສະດຸປ້ອນ. ບັນຫາທີ 3: ຂາດໂຄງສ້າງ ເຖິງແມ່ນວ່າທ່ານຈະຖິ້ມຮູບພາບໄວຮ່ວມກັນ, ຮູບແບບຕ່າງໆສາມາດສັບສົນໄດ້ໄວ. ຄ່າເລີ່ມຕົ້ນ, ການເຄື່ອນໄຫວ, ແລະສະຖານະດີບັກສາມາດທັບຊ້ອນກັນໄດ້, ແລະໂດຍບໍ່ມີໂຄງສ້າງທີ່ຊັດເຈນ, CSS ຂອງທ່ານຈະກາຍເປັນທີ່ແຕກຫັກແລະຍາກທີ່ຈະຂະຫຍາຍອອກ. CSS Cascade Layers ສາມາດຊ່ວຍໄດ້. ພວກເຂົາຈັດກຸ່ມຮູບແບບຕ່າງໆເຂົ້າໄປໃນ "ຊັ້ນ" ທີ່ຖືກຈັດລໍາດັບຄວາມສໍາຄັນ, ດັ່ງນັ້ນເຈົ້າຈຶ່ງຢຸດເຊົາການຕໍ່ສູ້ກັບຄວາມສະເພາະແລະການຄາດເດົາ, "ເປັນຫຍັງຮູບແບບການດີບັກຂອງຂ້ອຍບໍ່ສະແດງ?" ແທນທີ່ຈະ, ທ່ານຮັກສາຄວາມກັງວົນແຍກຕ່າງຫາກ:

ພື້ນຖານ: ມາດຕະຖານຂອງຜູ້ຄວບຄຸມ, ຮູບລັກສະນະເບື້ອງຕົ້ນ. ເຄື່ອນໄຫວ: ຈຸດເດັ່ນສຳລັບປຸ່ມກົດ ແລະ ໄມ້ທີ່ຖືກຍ້າຍ. Debug: ການວາງຊ້ອນກັນສໍາລັບນັກພັດທະນາ (ເຊັ່ນ: ການອ່ານຕົວເລກ, ຄໍາແນະນໍາ, ແລະອື່ນໆ).

ຖ້າພວກເຮົາກໍານົດຊັ້ນໃນ CSS ຕາມນີ້, ພວກເຮົາຈະມີ: /* ຕ່ຳ​ສຸດ​ເຖິງ​ບູ​ລິ​ມະ​ສິດ​ສູງ​ສຸດ */ @layer base, active, debug;

@layer base { /* ... */ }

@layer ເຄື່ອນໄຫວຢູ່ { /* ... */ }

@layer debug { /* ... */ }

ເນື່ອງຈາກວ່າແຕ່ລະຊັ້ນ stacks ຄາດຄະເນ, ທ່ານສະເຫມີຮູ້ວ່າກົດລະບຽບໃດຊະນະ. ການຄາດເດົານັ້ນເຮັດໃຫ້ການດີບັກບໍ່ພຽງແຕ່ງ່າຍຂຶ້ນ, ແຕ່ຕົວຈິງແລ້ວສາມາດຈັດການໄດ້. ພວກ​ເຮົາ​ໄດ້​ກວມ​ເອົາ​ບັນ​ຫາ (ເບິ່ງ​ເຫັນ​ບໍ່​ໄດ້​, ການ​ປ້ອນ​ຂໍ້​ມູນ messy​) ແລະ​ວິ​ທີ​ການ (ການ​ແກ້​ໄຂ​ການ​ແກ້​ໄຂ​ຮູບ​ພາບ​ທີ່​ສ້າງ​ດ້ວຍ Cascade Layers​)​. ຕອນນີ້ພວກເຮົາຈະຍ່າງຜ່ານຂະບວນການເທື່ອລະກ້າວເພື່ອສ້າງຕົວດີບັກ. ແນວຄວາມຄິດຂອງ Debugger ວິທີທີ່ງ່າຍທີ່ສຸດທີ່ຈະເຮັດໃຫ້ການປ້ອນຂໍ້ມູນທີ່ເຊື່ອງໄວ້ສາມາດເຫັນໄດ້ຄືພຽງແຕ່ແຕ້ມມັນຢູ່ໃນຫນ້າຈໍ. ນັ້ນແມ່ນສິ່ງທີ່ດີບັກນີ້ເຮັດ. ປຸ່ມ, ຕົວກະຕຸ້ນ, ແລະ joysticks ລ້ວນແຕ່ໄດ້ຮັບການເບິ່ງເຫັນ.

ກົດ A: ວົງມົນໄຟຂຶ້ນ. ຈູດໄມ້: ວົງມົນເລື່ອນໄປມາ. ດຶງ​ກະ​ຕຸ້ນ​ເຄິ່ງ​ຫນຶ່ງ​: ແຖບ​ເຮັດ​ໃຫ້​ເຄິ່ງ​ຫນຶ່ງ​.

ດຽວນີ້ເຈົ້າບໍ່ໄດ້ເບິ່ງ 0s ແລະ 1s, ແຕ່ຕົວຈິງແລ້ວການເບິ່ງຕົວຄວບຄຸມມີປະຕິກິລິຍາສົດໆ. ແນ່ນອນ, ເມື່ອທ່ານເລີ່ມຕົ້ນການລວບລວມຢູ່ໃນລັດຕ່າງໆເຊັ່ນຄ່າເລີ່ມຕົ້ນ, ກົດ, ຂໍ້ມູນດີບັກ, ບາງທີແມ່ນຮູບແບບການບັນທຶກ, CSS ຈະເລີ່ມມີຂະຫນາດໃຫຍ່ແລະສັບສົນຫຼາຍ. ນັ້ນແມ່ນບ່ອນທີ່ຊັ້ນ cascade ມາສະດວກ. ນີ້ແມ່ນຕົວຢ່າງທີ່ຖອດອອກໄດ້: @layer base { .ປຸ່ມ { ພື້ນຫລັງ: #222; border-radius: 50%; width: 40px; ຄວາມສູງ: 40px; } }

@layer ເຄື່ອນໄຫວຢູ່ { .button.pressed { ພື້ນຫຼັງ: #0f0; /*ສີຂຽວສົດ*/ } }

@layer debug { .ປຸ່ມ::ຫຼັງຈາກ { ເນື້ອໃນ: attr(data-value); font-size: 12px; ສີ: #ffff; } }

ລຳດັບຊັ້ນແມ່ນສຳຄັນ: ພື້ນຖານ → ເຄື່ອນໄຫວ → ດີບັກ.

ຖານ draws ຄວບຄຸມ. ການຈັດການທີ່ມີການເຄື່ອນໄຫວທີ່ກົດດັນ. debug ຖິ້ມໃສ່ overlays.

ການແຕກແຍກແບບນີ້ໝາຍຄວາມວ່າເຈົ້າບໍ່ໄດ້ຕໍ່ສູ້ກັບສົງຄາມສະເພາະທີ່ແປກປະຫຼາດ. ແຕ່ລະຊັ້ນມີສະຖານທີ່ຂອງມັນ, ແລະທ່ານສະເຫມີຮູ້ວ່າສິ່ງທີ່ຊະນະ. ການກໍ່ສ້າງມັນອອກ ໃຫ້ເອົາບາງສິ່ງບາງຢ່າງໃນຫນ້າຈໍກ່ອນ. ມັນບໍ່ຈໍາເປັນທີ່ຈະເບິ່ງດີ - ພຽງແຕ່ຕ້ອງການເພື່ອໃຫ້ພວກເຮົາມີບາງສິ່ງບາງຢ່າງທີ່ຈະເຮັດວຽກຮ່ວມກັບ.

Gamepad Cascade Debugger

A
B
X

ດີບັກເກີບໍ່ເຄື່ອນໄຫວ

ນັ້ນແມ່ນພຽງແຕ່ກ່ອງ. ຍັງບໍ່ຕື່ນເຕັ້ນເທື່ອ, ແຕ່ມັນເຮັດໃຫ້ພວກເຮົາຈັບມືໃນພາຍຫຼັງດ້ວຍ CSS ແລະ JavaScript. ຕົກລົງ, ຂ້ອຍກໍາລັງໃຊ້ຊັ້ນ cascade ຢູ່ທີ່ນີ້ເພາະວ່າມັນຈັດລະບຽບຮຽບຮ້ອຍເມື່ອທ່ານເພີ່ມລັດເພີ່ມເຕີມ. ນີ້ແມ່ນທາງຜ່ານທີ່ຫຍຸ້ງຍາກ:

/* ==================================== ການຕິດຕັ້ງຊັ້ນ CASCADE ຄໍາສັ່ງເລື່ອງ: ພື້ນຖານ → active → debug ================================================== */

/* ກໍາ​ນົດ​ລະ​ດັບ​ຊັ້ນ​ຫນ້າ */ @layer base, active, debug;

/* ຊັ້ນ 1: ຮູບແບບພື້ນຖານ - ລັກສະນະເລີ່ມຕົ້ນ */ @layer base { .ປຸ່ມ { ພື້ນຫລັງ: #333; border-radius: 50%; width: 70px; ຄວາມສູງ: 70px; ຈໍສະແດງຜົນ: flex; justify-content: ສູນ; align-items: ສູນ; }

.ຢຸດ { width: 20px; ຄວາມສູງ: 70px; ພື້ນຫລັງ: #333; ຈໍສະແດງຜົນ: inline-block; } }

/* Layer 2: Active states - handles pressed buttons */ @layer ເຄື່ອນໄຫວຢູ່ { .button.active { ພື້ນຫຼັງ: #0f0; /* ສີ​ຂຽວ​ສົດ​ໃສ​ເມື່ອ​ກົດ */ ການຫັນປ່ຽນ: ຂະໜາດ(1.1); /* ຂະຫຍາຍປຸ່ມເລັກນ້ອຍ */ }

.pause.active { ພື້ນຫຼັງ: #0f0; ການຫັນປ່ຽນ: scaleY(1.1); /* ຢຽດຕາມແນວຕັ້ງເມື່ອກົດ */ } }

/* Layer 3: Debug overlays - ຂໍ້ມູນຜູ້ພັດທະນາ */ @layer debug { .ປຸ່ມ::ຫຼັງຈາກ { ເນື້ອໃນ: attr(data-value); /* ສະ​ແດງ​ໃຫ້​ເຫັນ​ຄ່າ​ຕົວ​ເລກ */ font-size: 12px; ສີ: #ffff; } }

ຄວາມງາມຂອງວິທີການນີ້ແມ່ນວ່າແຕ່ລະຊັ້ນມີຈຸດປະສົງທີ່ຊັດເຈນ. ຊັ້ນພື້ນຖານບໍ່ສາມາດ override active ໄດ້, ແລະ active ບໍ່ສາມາດ override debug, ບໍ່ວ່າຈະເປັນສະເພາະໃດຫນຶ່ງ. ນີ້ກໍາຈັດສົງຄາມສະເພາະຂອງ CSS ທີ່ປົກກະຕິແລ້ວເຄື່ອງມືດີບັ໊ກ plague. ຕອນນີ້ເບິ່ງຄືວ່າບາງກຸ່ມກຳລັງນັ່ງຢູ່ເທິງພື້ນຫຼັງທີ່ມືດ. ດ້ວຍຄວາມຊື່ສັດ, ບໍ່ຮ້າຍແຮງເກີນໄປ.

ເພີ່ມ JavaScript ເວລາ JavaScript. ນີ້ແມ່ນບ່ອນທີ່ຕົວຄວບຄຸມຕົວຈິງເຮັດບາງສິ່ງບາງຢ່າງ. ພວກເຮົາຈະສ້າງຂັ້ນຕອນນີ້ໂດຍຂັ້ນຕອນ. ຂັ້ນຕອນທີ 1: ຕັ້ງຄ່າການຄຸ້ມຄອງລັດ ກ່ອນອື່ນ ໝົດ, ພວກເຮົາຕ້ອງການຕົວແປເພື່ອຕິດຕາມສະຖານະຂອງ debugger: // =================================== // ການຄຸ້ມຄອງລັດ // ===================================

ໃຫ້ແລ່ນ = false; // ຕິດຕາມວ່າຕົວດີບັກແມ່ນເຮັດວຽກຫຼືບໍ່ ໃຫ້ rafId; // ເກັບຮັກສາ requestAnimationFrame ID ສໍາລັບການຍົກເລີກ

ຕົວແປເຫຼົ່ານີ້ຄວບຄຸມວົງການອະນິເມຊັນທີ່ອ່ານການປ້ອນຂໍ້ມູນຂອງ gamepad ຢ່າງຕໍ່ເນື່ອງ. ຂັ້ນຕອນທີ 2: Grab DOM References ຕໍ່ໄປ, ພວກເຮົາໄດ້ຮັບການອ້າງອີງເຖິງອົງປະກອບ HTML ທັງຫມົດທີ່ພວກເຮົາຈະປັບປຸງ: // =================================== // DOM Element References // ===================================

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​ ສຳ​ລັບ​ການ​ທົດ​ສອບ​ໂດຍ​ບໍ່​ມີ​ຕົວ​ຄວບ​ຄຸມ​ທາງ​ດ້ານ​ຮ່າງ​ກາຍ, ພວກ​ເຮົາ​ຈະ​ຕັ້ງ​ປຸ່ມ​ແປ້ນ​ພິມ​ໃສ່​ປຸ່ມ​ຕ່າງໆ: // =================================== // KEYBOARD FALLBACK (ສໍາ​ລັບ​ການ​ທົດ​ສອບ​ໂດຍ​ບໍ່​ມີ​ການ​ຄວບ​ຄຸມ​) // ===================================

const keyMap = { "a": btnA, "b": btnB, "x": btnX, "p": [pause1, pause2] // ປຸ່ມ 'p' ຄວບຄຸມທັງສອງແຖບຢຸດຊົ່ວຄາວ };

ນີ້ເຮັດໃຫ້ພວກເຮົາທົດສອບ UI ໂດຍການກົດປຸ່ມເທິງແປ້ນພິມ. ຂັ້ນຕອນທີ 4: ສ້າງ Main Update Loop ນີ້ແມ່ນບ່ອນທີ່ magic ເກີດຂຶ້ນ. ຟັງຊັນນີ້ເຮັດວຽກຢ່າງຕໍ່ເນື່ອງແລະອ່ານສະຖານະ gamepad: // =================================== // MAIN GAMEPAD ອັບເດດ LOOP // ===================================

function updateGamepad() { // ເອົາ gamepads ທີ່ເຊື່ອມຕໍ່ທັງໝົດ const gamepads = navigator.getGamepads(); ຖ້າ (!gamepads) ກັບຄືນມາ;

// ໃຊ້ gamepad ທໍາອິດທີ່ເຊື່ອມຕໍ່ const gp = gamepads[0];

ຖ້າ (gp) { // ປັບປຸງປຸ່ມລັດໂດຍການສະຫຼັບຊັ້ນ "ການເຄື່ອນໄຫວ". 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("active", pausePressed); pause2.classList.toggle("active", pausePressed);

// ສ້າງບັນຊີລາຍຊື່ຂອງປຸ່ມກົດໃນປັດຈຸບັນສໍາລັບການສະແດງສະຖານະພາບ ໃຫ້ກົດ = []; gp.buttons.forEach((btn, i) => { ຖ້າ (btn.pressed)pressed.push("ປຸ່ມ " + i); });

// ປັບປຸງຂໍ້ຄວາມສະຖານະຖ້າປຸ່ມໃດຖືກກົດ ຖ້າ (pressed.length > 0) { status.textContent = "ກົດ: " + pressed.join(", "); } }

// ສືບຕໍ່ການ loop ຖ້າດີບັກກໍາລັງແລ່ນ ຖ້າ (ແລ່ນ) { 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("active"); } 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​: ເພີ່ມ​ການ​ຄວບ​ຄຸມ Start / Stop​ ສຸດທ້າຍ, ພວກເຮົາຕ້ອງການວິທີທີ່ຈະປິດ/ເປີດ debugger ໄດ້: // =================================== // ເປີດ/ປິດການດີບັກ // ===================================

document.getElementById("toggle").addEventListener("ຄລິກ", () => { ແລ່ນ = !ແລ່ນ; // ພິກສະຖານະການແລ່ນ

ຖ້າ (ແລ່ນ) { status.textContent = "Debugger ແລ່ນ..."; updateGamepad(); // ເລີ່ມການອັບເດດ loop } ອື່ນ { status.textContent = "Debugger inactive"; cancelAnimationFrame(rafId); // ຢຸດ loop ໄດ້ } });

ແລ້ວ, ກົດປຸ່ມຫນຶ່ງແລະມັນສະຫວ່າງ. ຍູ້ໄມ້ແລະມັນຍ້າຍ. ນັ້ນ​ແມ່ນ​ມັນ. ອີກອັນຫນຶ່ງ: ມູນຄ່າວັດຖຸດິບ. ບາງຄັ້ງທ່ານພຽງແຕ່ຕ້ອງການເບິ່ງຕົວເລກ, ບໍ່ແມ່ນໄຟ.

ໃນຂັ້ນຕອນນີ້, ທ່ານຄວນເບິ່ງ:

ຕົວ​ຄວບ​ຄຸມ​ໃນ​ຫນ້າ​ຈໍ​ງ່າຍ​ດາຍ​, ປຸ່ມທີ່ມີປະຕິກິລິຍາໃນຂະນະທີ່ທ່ານພົວພັນກັບພວກມັນ, ແລະ ການອ່ານການແກ້ບັນຫາທາງເລືອກທີ່ສະແດງດັດຊະນີປຸ່ມກົດ.

ເພື່ອເຮັດໃຫ້ມັນບໍ່ມີຕົວຕົນໜ້ອຍລົງ, ນີ້ແມ່ນຕົວຢ່າງໄວຂອງຕົວຄວບຄຸມໃນໜ້າຈໍທີ່ຕອບສະໜອງໃນເວລາຈິງ:

ໃນປັດຈຸບັນ, ກົດ Start Recording ບັນທຶກທຸກສິ່ງທຸກຢ່າງຈົນກ່ວາທ່ານມົນຕີຢຸດການບັນທຶກ. 2. ການສົ່ງອອກຂໍ້ມູນໄປຍັງ CSV/JSON ເມື່ອພວກເຮົາມີບັນທຶກ, ພວກເຮົາຈະຕ້ອງການບັນທຶກມັນ.

ຂັ້ນຕອນທີ 1: ສ້າງຕົວຊ່ວຍການດາວໂຫຼດ ກ່ອນອື່ນ ໝົດ, ພວກເຮົາຕ້ອງການ ໜ້າ ທີ່ຜູ້ຊ່ວຍທີ່ຈັດການກັບການດາວໂຫລດໄຟລ໌ໃນ browser: // =================================== // ໄຟລ໌ດາວໂຫຼດຜູ້ຊ່ວຍ // ===================================

function downloadFile(ຊື່ໄຟລ໌, ເນື້ອໃນ, ປະເພດ = "ຂໍ້ຄວາມ/ທຳມະດາ") { // ສ້າງ blob ຈາກເນື້ອຫາ const blob = ໃຫມ່ Blob([ເນື້ອຫາ], { ປະເພດ }); 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 Export JSON ແມ່ນດີເລີດສໍາລັບການຮັກສາໂຄງສ້າງຂໍ້ມູນຄົບຖ້ວນສົມບູນ:

// =================================== // ສົ່ງອອກເປັນ JSON // ===================================

document.getElementById("export-json").addEventListener("click", () => { // ກວດເບິ່ງວ່າມີສິ່ງໃດທີ່ຈະສົ່ງອອກ ຖ້າ (!frames.length) { console.warn("ບໍ່ມີການບັນທຶກທີ່ຈະສົ່ງອອກ."); ກັບຄືນ; }

// ສ້າງ payload ກັບ metadata ແລະກອບ const payload = { createdAt: new Date().toISOSTring(), ກອບ };

// ດາວໂຫຼດເປັນຮູບແບບ JSON ດາວໂຫລດໄຟລ໌( "gamepad-log.json", JSON.stringify(payload, null, 2), "application/json" ); });

ຮູບແບບ JSON ຮັກສາທຸກຢ່າງທີ່ມີໂຄງສ້າງ ແລະສາມາດວິເຄາະໄດ້ງ່າຍ, ເຮັດໃຫ້ມັນເຫມາະສົມສໍາລັບການໂຫຼດກັບໄປຫາເຄື່ອງມື dev ຫຼືແບ່ງປັນກັບເພື່ອນຮ່ວມທີມ. ຂັ້ນຕອນທີ 3: ຈັດການການສົ່ງອອກ CSV ສໍາລັບການສົ່ງອອກ CSV, ພວກເຮົາຈໍາເປັນຕ້ອງແປຂໍ້ມູນລໍາດັບຊັ້ນເຂົ້າໄປໃນແຖວແລະຖັນ:

//================================================== // ສົ່ງອອກເປັນ CSV // ===================================

document.getElementById("export-csv").addEventListener("click", () => { // ກວດເບິ່ງວ່າມີສິ່ງໃດທີ່ຈະສົ່ງອອກ ຖ້າ (!frames.length) { console.warn("ບໍ່ມີການບັນທຶກທີ່ຈະສົ່ງອອກ."); ກັບຄືນ; }

// ສ້າງແຖວສ່ວນຫົວ CSV (ຖັນສຳລັບເວລາ, ປຸ່ມທັງໝົດ, ທຸກແກນ) const headerButtons = frames[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 downloadFile("gamepad-log.csv", header + rows, "text/csv"); });

CSV ແມ່ນດີເລີດສໍາລັບການວິເຄາະຂໍ້ມູນເພາະວ່າມັນເປີດໂດຍກົງໃນ Excel ຫຼື Google Sheets, ຊ່ວຍໃຫ້ທ່ານສ້າງຕາຕະລາງ, ການກັ່ນຕອງຂໍ້ມູນ, ຫຼືຮູບແບບຈຸດ. ໃນປັດຈຸບັນທີ່ປຸ່ມສົ່ງອອກແມ່ນຢູ່ໃນ, ທ່ານຈະເຫັນສອງທາງເລືອກໃຫມ່ໃນກະດານ: ສົ່ງອອກ JSON ແລະສົ່ງອອກ CSV. JSON ແມ່ນດີຖ້າທ່ານຕ້ອງການຖິ້ມບັນທຶກດິບກັບຄືນສູ່ເຄື່ອງມື dev ຂອງທ່ານຫຼືຖອກໃສ່ໂຄງສ້າງ. ໃນທາງກົງກັນຂ້າມ, CSV ເປີດໂດຍກົງໃນ Excel ຫຼື Google Sheets ເພື່ອໃຫ້ທ່ານສາມາດສ້າງຕາຕະລາງ, ການກັ່ນຕອງ, ຫຼືປຽບທຽບການປ້ອນຂໍ້ມູນ. ຕົວເລກຕໍ່ໄປນີ້ສະແດງໃຫ້ເຫັນວ່າແຜງເບິ່ງຄືແນວໃດກັບການຄວບຄຸມພິເສດເຫຼົ່ານັ້ນ.

3. ລະບົບ Snapshot ບາງຄັ້ງທ່ານບໍ່ຕ້ອງການບັນທຶກເຕັມ, ພຽງແຕ່ "ຮູບຫນ້າຈໍ" ຢ່າງໄວວາຂອງສະຖານະການປ້ອນຂໍ້ມູນ. ນັ້ນແມ່ນບ່ອນທີ່ປຸ່ມ Take Snapshot ຊ່ວຍໄດ້.

ແລະ JavaScript:

// =================================== // ເອົາ SNAPSHOT // ===================================

document.getElementById("snapshot").addEventListener("ຄລິກ", () => { // ເອົາ gamepads ທີ່ເຊື່ອມຕໍ່ທັງໝົດ const pads = navigator.getGamepads(); const activePads = [];

// Loop ຜ່ານແລະເກັບກໍາສະຖານະຂອງແຕ່ລະ gamepad ທີ່ເຊື່ອມຕໍ່ ສໍາລັບ (const gp ຂອງ pads) { ຖ້າ (!gp) ສືບຕໍ່; // ຂ້າມຊ່ອງຫວ່າງ

activePads.push({ id: gp.id, // ຊື່ຕົວຄວບຄຸມ/ແບບຈໍາລອງ timestamp: performance.now(), ປຸ່ມ: gp.buttons.map(b => ({ ກົດ​ດັນ​: b.pressed​, ຄ່າ: b.value })), ແກນ: [...gp.axes] }); }

// ກວດເບິ່ງວ່າມີ gamepads ໃດ ຖ້າ (!activePads.length) { console.warn("ບໍ່ມີ gamepads ເຊື່ອມຕໍ່ສໍາລັບການ snapshot."); alert("ບໍ່ພົບຕົວຄວບຄຸມ!"); ກັບຄືນ; }

// ບັນທຶກແລະແຈ້ງຜູ້ໃຊ້ console.log("ພາບຖ່າຍ:", activePads); alert(ຖ່າຍພາບແລ້ວ! Captured ${activePads.length} controller(s)); });

Snapshots ຢຸດສະຖານະທີ່ແນ່ນອນຂອງຕົວຄວບຄຸມຂອງທ່ານໃນເວລາດຽວ. 4. Ghost Input Replay ໃນປັດຈຸບັນສໍາລັບການມ່ວນຊື່ນຫນຶ່ງ: ghost input replay. ນີ້ໃຊ້ເວລາບັນທຶກແລະຫຼິ້ນມັນກັບສາຍຕາຄືກັບວ່າຜູ້ນ phantom ກໍາລັງໃຊ້ຕົວຄວບຄຸມ.

JavaScript ສໍາລັບການຫຼິ້ນຄືນ: // =================================== // GHOST REPLAY // ===================================

document.getElementById("replay").addEventListener("click", () => { // ໃຫ້ແນ່ໃຈວ່າພວກເຮົາມີບັນທຶກເພື່ອຫຼິ້ນຄືນ ຖ້າ (!frames.length) { alert("ບໍ່ມີການບັນທຶກການຫຼິ້ນຄືນ!"); ກັບຄືນ; }

console.log("ກຳລັງເລີ່ມການຫຼິ້ນຜີຄືນ...");

// ຕິດຕາມເວລາສຳລັບການຫຼິ້ນທີ່ຊິ້ງແລ້ວ ໃຫ້ startTime = performance.now(); ໃຫ້ frameIndex = 0;

// ຣີວິວພາບເຄື່ອນໄຫວຄືນໃໝ່ ຂັ້ນຕອນການທໍາງານ () { const now = performance.now(); const elapsed = ໃນປັດຈຸບັນ - startTime;

// ປະມວນຜົນເຟຣມທັງໝົດທີ່ຄວນຈະເກີດຂຶ້ນໃນຕອນນີ້ ໃນຂະນະທີ່ (frameIndex < frames.length && frames[frameIndex].t <= ຜ່ານໄປ) { const frame = ກອບ[frameIndex];

// ອັບເດດ 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);

// ອັບເດດສະຖານະສະແດງ ໃຫ້ກົດ = []; frame.buttons.forEach((btn, i) => { if (btn.pressed) pressed.push("ປຸ່ມ" + i); }); ຖ້າ (pressed.length > 0) { status.textContent = "ຜີ: " + pressed.join(", "); }

frameIndex++; }

// ສືບຕໍ່ loop ຖ້າມີກອບເພີ່ມເຕີມ ຖ້າ (frameIndex < frames.length) { requestAnimationFrame(ຂັ້ນຕອນ); } ອື່ນ { console.log("ຫຼິ້ນຄືນສໍາເລັດ." status.textContent = "ຫຼິ້ນຄືນສໍາເລັດ"; } }

// ເລີ່ມການຫຼິ້ນຄືນ ຂັ້ນ​ຕອນ(); });

ເພື່ອເຮັດໃຫ້ການດີບັ໊ກແບບມືຫຼາຍຂື້ນ, ຂ້ອຍໄດ້ເພີ່ມການຫຼິ້ນຜີຄືນ. ເມື່ອທ່ານໄດ້ບັນທຶກເຊດຊັນ, ທ່ານສາມາດຕີ replay ແລະເບິ່ງ UI ປະຕິບັດມັນອອກ, ເກືອບຄືກັບຜູ້ນ phantom ແລ່ນ pad ໄດ້. ປຸ່ມ Replay Ghost ໃໝ່ຈະສະແດງຢູ່ໃນແຜງສໍາລັບການນີ້.

ກົດບັນທຶກ, ລົບກວນຕົວຄວບຄຸມເລັກນ້ອຍ, ຢຸດ, ຈາກນັ້ນຫຼິ້ນຄືນ. UI ພຽງແຕ່ສະທ້ອນທຸກສິ່ງທີ່ທ່ານເຮັດ, ຄືກັບຜີທີ່ຕິດຕາມຂໍ້ມູນຂອງທ່ານ. ເປັນຫຍັງຈຶ່ງເບື່ອກັບສິ່ງພິເສດເຫຼົ່ານີ້?

ການບັນທຶກ/ການສົ່ງອອກເຮັດໃຫ້ມັນງ່າຍສໍາລັບຜູ້ທົດສອບທີ່ຈະສະແດງສິ່ງທີ່ເກີດຂຶ້ນຢ່າງແທ້ຈິງ. ພາບຖ່າຍຄ້າງໄວ້ໃນເວລາສັ້ນໆ, ມີປະໂຫຍດຫຼາຍເມື່ອທ່ານກຳລັງໄລ່ແມງໄມ້ແປກໆ. Ghost replay ແມ່ນດີເລີດສໍາລັບການສອນ, ການກວດສອບການເຂົ້າເຖິງ, ຫຼືພຽງແຕ່ປຽບທຽບການຕັ້ງຄ່າການຄວບຄຸມຂ້າງຄຽງ.

ໃນຈຸດນີ້, ມັນບໍ່ແມ່ນພຽງແຕ່ຕົວຢ່າງທີ່ສະອາດອີກຕໍ່ໄປ, ແຕ່ບາງສິ່ງບາງຢ່າງທີ່ເຈົ້າສາມາດປະຕິບັດໄດ້. ກໍລະນີການນໍາໃຊ້ທີ່ແທ້ຈິງໃນໂລກ ດຽວນີ້ພວກເຮົາມີຕົວດີບັກທີ່ສາມາດເຮັດໄດ້ຫຼາຍຢ່າງ. ມັນ​ສະ​ແດງ​ໃຫ້​ເຫັນ​ການ​ປ້ອນ​ຂໍ້​ມູນ​ສົດ​, ບັນ​ທຶກ​ການ​ບັນ​ທຶກ​, ສົ່ງ​ອອກ​ໃຫ້​ເຂົາ​ເຈົ້າ​, ແລະ​ແມ້​ກະ​ທັ້ງ replays stuff​. ແຕ່ຄໍາຖາມທີ່ແທ້ຈິງແມ່ນ: ໃຜສົນໃຈແທ້ໆ? ອັນນີ້ມີປະໂຫຍດສຳລັບໃຜ? ນັກພັດທະນາເກມ ການຄວບຄຸມແມ່ນສ່ວນຫນຶ່ງຂອງວຽກ, ແຕ່ການແກ້ບັນຫາໃຫ້ເຂົາເຈົ້າ? ປົກກະຕິແລ້ວເຈັບ. ລອງນຶກພາບວ່າເຈົ້າກຳລັງທົດສອບຄອມໂບເກມຕໍ່ສູ້, ເຊັ່ນ: ↓ → + punch. ແທນ​ທີ່​ຈະ​ອະ​ທິ​ຖານ, ທ່ານ​ໄດ້​ກົດ​ມັນ​ແບບ​ດຽວ​ກັນ​ສອງ​ຄັ້ງ, ທ່ານ​ບັນ​ທຶກ​ມັນ​ຄັ້ງ​ດຽວ, ແລະ replay ມັນ. ສຳເລັດແລ້ວ. ຫຼືທ່ານປ່ຽນບັນທຶກ JSON ກັບເພື່ອນຮ່ວມທີມເພື່ອກວດເບິ່ງວ່າລະຫັດຜູ້ຫຼິ້ນຫຼາຍຄົນຂອງທ່ານມີປະຕິກິລິຍາອັນດຽວກັນຢູ່ໃນເຄື່ອງຂອງເຂົາເຈົ້າຫຼືບໍ່. ນັ້ນແມ່ນໃຫຍ່. ຜູ້ປະຕິບັດການຊ່ວຍເຂົ້າເຖິງ ອັນນີ້ຢູ່ໃກ້ກັບຫົວໃຈຂອງຂ້ອຍ. ບໍ່ແມ່ນທຸກຄົນຫຼິ້ນກັບຕົວຄວບຄຸມ "ມາດຕະຖານ". ຕົວຄວບຄຸມການປັບຕົວໄດ້ຖິ້ມສັນຍານແປກໆບາງຄັ້ງ. ດ້ວຍ​ເຄື່ອງ​ມື​ນີ້​, ທ່ານ​ສາ​ມາດ​ເບິ່ງ​ໄດ້​ຢ່າງ​ແທ້​ຈິງ​ສິ່ງ​ທີ່​ເກີດ​ຂຶ້ນ​. ຄູອາຈານ, ນັກຄົ້ນຄວ້າ, ໃຜກໍ່ຕາມ. ພວກເຂົາສາມາດຈັບບັນທຶກ, ປຽບທຽບພວກມັນ, ຫຼື replay inputs ຂ້າງຄຽງ. ທັນໃດນັ້ນ, ສິ່ງທີ່ເບິ່ງບໍ່ເຫັນຈະກາຍເປັນທີ່ຊັດເຈນ. ການທົດສອບການຮັບປະກັນຄຸນນະພາບ ປົກກະຕິແລ້ວນັກທົດສອບຈະຂຽນບັນທຶກເຊັ່ນ: "ຂ້ອຍຂັດປຸ່ມທີ່ນີ້ແລະມັນແຕກ." ບໍ່ມີປະໂຫຍດຫຼາຍ. ດຽວນີ້? ພວກ​ເຂົາ​ເຈົ້າ​ສາ​ມາດ​ເກັບ​ກໍາ​ກົດ​ທີ່​ແນ່​ນອນ​, ສົ່ງ​ອອກ​ບັນ​ທຶກ​, ແລະ​ສົ່ງ​ອອກ​. ບໍ່ມີການຄາດເດົາ. ການສຶກສາ ຖ້າເຈົ້າກຳລັງສ້າງບົດສອນ ຫຼືວິດີໂອ YouTube, ການຫຼິ້ນຜີຄືນແມ່ນເປັນຄຳ. ທ່ານສາມາດເວົ້າໄດ້ຢ່າງແທ້ຈິງວ່າ, "ນີ້ແມ່ນສິ່ງທີ່ຂ້ອຍເຮັດກັບຕົວຄວບຄຸມ," ໃນຂະນະທີ່ UI ສະແດງໃຫ້ເຫັນວ່າມັນເກີດຂຶ້ນ. ເຮັດໃຫ້ຄໍາອະທິບາຍທີ່ຊັດເຈນຂຶ້ນ. Beyond Games ແລະແມ່ນແລ້ວ, ນີ້ບໍ່ແມ່ນພຽງແຕ່ກ່ຽວກັບເກມ. ປະຊາຊົນໄດ້ໃຊ້ຕົວຄວບຄຸມສໍາລັບຫຸ່ນຍົນ, ໂຄງການສິລະປະ, ແລະການໂຕ້ຕອບການຊ່ວຍເຂົ້າເຖິງ. ບັນຫາດຽວກັນທຸກໆຄັ້ງ: ຕົວຈິງແລ້ວຕົວທ່ອງເວັບແມ່ນຫຍັງ? ດ້ວຍສິ່ງນີ້, ທ່ານບໍ່ ຈຳ ເປັນຕ້ອງຄາດເດົາ. ສະຫຼຸບ ການດີບັກການປ້ອນຂໍ້ມູນຂອງຕົວຄວບຄຸມມີຄວາມຮູ້ສຶກຄືກັບບິນຕາບອດຢູ່ສະເໝີ. ບໍ່ເຫມືອນກັບ DOM ຫຼື CSS, ບໍ່ມີຕົວກວດສອບໃນຕົວສໍາລັບ gamepads; ມັນເປັນພຽງແຕ່ຕົວເລກດິບໃນ console, ສູນເສຍໄດ້ງ່າຍໃນສິ່ງລົບກວນ. ດ້ວຍສອງສາມຮ້ອຍແຖວຂອງ HTML, CSS, ແລະ JavaScript, ພວກເຮົາໄດ້ສ້າງສິ່ງທີ່ແຕກຕ່າງກັນ:

ເຄື່ອງດີບັ໊ກທາງສາຍຕາທີ່ເຮັດໃຫ້ການປ້ອນຂໍ້ມູນເບິ່ງບໍ່ເຫັນ. ລະບົບ CSS ເປັນຊັ້ນທີ່ຮັກສາ UI ສະອາດ ແລະສາມາດແກ້ບັນຫາໄດ້. ຊຸດການປັບປຸງ (ການບັນທຶກ, ການສົ່ງອອກ, ພາບຖ່າຍ, ການຫຼິ້ນຄືນຜີ) ທີ່ຍົກລະດັບມັນຈາກການສາທິດໄປສູ່ເຄື່ອງມືນັກພັດທະນາ.

ໂຄງ​ການ​ນີ້​ສະ​ແດງ​ໃຫ້​ເຫັນ​ວ່າ​ທ່ານ​ໄປ​ໄດ້​ໄກ​ປານ​ໃດ​ໂດຍ​ການ​ປະ​ສົມ​ພະ​ລັງ​ງານ​ຂອງ​ເວ​ທີ​ເວັບ​ໄຊ​ຕ​໌​ທີ່​ມີ​ຄວາມ​ຄິດ​ສ້າງ​ສັນ​ເລັກ​ນ້ອຍ​ໃນ CSS Cascade Layers​. ເຄື່ອງມືທີ່ຂ້າພະເຈົ້າພຽງແຕ່ອະທິບາຍທັງຫມົດແມ່ນ open-source. ທ່ານສາມາດ clone repo GitHub ແລະລອງມັນດ້ວຍຕົວທ່ານເອງ. ແຕ່ສໍາຄັນກວ່ານັ້ນ, ທ່ານສາມາດເຮັດໃຫ້ມັນເປັນຂອງຕົນເອງ. ເພີ່ມຊັ້ນຂໍ້ມູນຂອງທ່ານເອງ. ສ້າງເຫດຜົນ replay ຂອງທ່ານເອງ. ປະສົມປະສານມັນກັບຕົ້ນແບບເກມຂອງທ່ານ. ຫຼືແມ້ກະທັ້ງໃຊ້ມັນໃນວິທີທີ່ຂ້ອຍບໍ່ໄດ້ຈິນຕະນາການ. ສໍາລັບການສອນ, ການເຂົ້າເຖິງ, ຫຼືການວິເຄາະຂໍ້ມູນ. ໃນຕອນທ້າຍຂອງມື້, ນີ້ບໍ່ແມ່ນພຽງແຕ່ກ່ຽວກັບການ debugging gamepads. ມັນແມ່ນກ່ຽວກັບການສ່ອງແສງໃສ່ວັດສະດຸທີ່ເຊື່ອງໄວ້, ແລະໃຫ້ນັກພັດທະນາມີຄວາມໝັ້ນໃຈໃນການເຮັດວຽກກັບຮາດແວທີ່ເວັບຍັງບໍ່ຍອມຮັບຢ່າງເຕັມທີ່. ດັ່ງນັ້ນ, ສຽບຕົວຄວບຄຸມຂອງທ່ານ, ເປີດບັນນາທິການຂອງທ່ານ, ແລະເລີ່ມທົດລອງ. ທ່ານອາດຈະຕົກຕະລຶງໃນສິ່ງທີ່ຕົວທ່ອງເວັບແລະ 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