عندما تقوم بتوصيل وحدة تحكم، فإنك تقوم بهرس الأزرار، وتحريك العصي، وسحب المشغلات... وكمطور، لا ترى أيًا من ذلك. من المؤكد أن المتصفح يلتقطها، ولكن ما لم تقم بتسجيل الأرقام في وحدة التحكم، فهي غير مرئية. هذا هو الصداع مع 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. إنهم يقومون بتجميع الأنماط في "طبقات" مرتبة حسب الأولوية، لذلك تتوقف عن محاربة الخصوصية والتخمين، "لماذا لا يظهر نمط تصحيح الأخطاء الخاص بي؟" بدلاً من ذلك، يمكنك الحفاظ على مخاوف منفصلة:
القاعدة: المظهر الأولي القياسي لوحدة التحكم.
نشط: أبرز الأزرار المضغوطة والعصي المتحركة.
تصحيح الأخطاء: تراكبات للمطورين (على سبيل المثال، القراءات الرقمية والأدلة وما إلى ذلك).
إذا أردنا تعريف الطبقات في CSS وفقًا لذلك، فسيكون لدينا:
/* من الأدنى إلى الأعلى أولوية */
قاعدة الطبقة، نشطة، مصححة؛
@قاعدة الطبقة {
/* ... */
}
@الطبقة النشطة {
/* ... */
}
@تصحيح الطبقة {
/* ... */
}
نظرًا لأن كل طبقة تتكدس بشكل متوقع، فأنت تعرف دائمًا القواعد التي تفوز. هذه القدرة على التنبؤ لا تجعل عملية تصحيح الأخطاء أسهل فحسب، بل تجعلها قابلة للإدارة في الواقع.
لقد قمنا بتغطية المشكلة (الإدخال غير المرئي والفوضوي) والنهج (مصحح أخطاء مرئي تم إنشاؤه باستخدام طبقات Cascade). سنستعرض الآن العملية خطوة بخطوة لإنشاء مصحح الأخطاء.
مفهوم المصحح
أسهل طريقة لجعل المدخلات المخفية مرئية هي مجرد رسمها على الشاشة. هذا ما يفعله مصحح الأخطاء هذا. الأزرار والمشغلات وعصا التحكم كلها مرئية.
اضغط على A: تضيء دائرة.
دفع العصا: الدائرة تنزلق حولها.
اسحب الزناد إلى منتصف الطريق: يمتلئ الشريط في منتصف الطريق.
أنت الآن لا تحدق في 0s و 1s، ولكن في الواقع تشاهد وحدة التحكم وهي تتفاعل مباشرة.
بالطبع، بمجرد أن تبدأ في تراكم الحالات مثل المعلومات الافتراضية، والضغط، ومعلومات التصحيح، وربما حتى وضع التسجيل، يبدأ CSS في أن يصبح أكبر وأكثر تعقيدًا. هذا هو المكان الذي تكون فيه الطبقات المتتالية مفيدة. فيما يلي مثال تم تجريده:
@قاعدة الطبقة {
.زر {
الخلفية: #222؛
نصف قطر الحدود: 50%؛
العرض: 40 بكسل؛
الارتفاع: 40 بكسل؛
}
}
@تصحيح الطبقة {
.زر::بعد {
المحتوى: attr(قيمة البيانات);
حجم الخط: 12 بكسل؛
اللون: #ففف؛
}
}
ترتيب الطبقة مهم: القاعدة → النشطة → التصحيح.
قاعدة توجه وحدة التحكم.
مقابض نشطة الحالات المضغوطة.
يلقي التصحيح على التراكبات.
إن تقسيم الأمر على هذا النحو يعني أنك لا تخوض حروبًا غريبة تتعلق بالخصوصية. كل طبقة لها مكانها، وأنت تعرف دائمًا ما الذي يفوز.
بنائها
دعونا نحصل على شيء ما على الشاشة أولاً. ليس من الضروري أن يبدو الأمر جيدًا - فقط يجب أن يكون موجودًا حتى يكون لدينا شيء نعمل به.
مصحح أخطاء Gamepad Cascade
أ
ب
X
<ديف>
مصحح الأخطاء غير نشط
هذه مجرد صناديق حرفيًا. ليس الأمر مثيرًا بعد، ولكنه يمنحنا مقابض يمكن استخدامها لاحقًا باستخدام CSS وJavaScript.
حسنًا، أنا أستخدم الطبقات المتتالية هنا لأنها تحافظ على تنظيم الأشياء بمجرد إضافة المزيد من الحالات. إليك تمريرة صعبة:
/* الطبقة الثانية: الحالات النشطة - تتعامل مع الأزرار المضغوطة */
@الطبقة النشطة {
.زر.نشط {
الخلفية: #0f0; /* أخضر ساطع عند الضغط عليه */
تحويل: مقياس (1.1)؛ /* تكبير الزر قليلاً */
}
.إيقاف مؤقت.نشط {
الخلفية: #0f0;
تحويل: مقياس Y (1.1)؛ /* يمتد عموديا عند الضغط عليه */
}
}
/* الطبقة الثالثة: تراكبات تصحيح الأخطاء - معلومات المطور */
@تصحيح الطبقة {
.زر::بعد {
المحتوى: attr(قيمة البيانات); /* إظهار القيمة الرقمية */
حجم الخط: 12 بكسل؛
اللون: #ففف؛
}
}
جمال هذا النهج هو أن كل طبقة لها غرض واضح. لا يمكن للطبقة الأساسية أبدًا تجاوز الطبقة النشطة، ولا يمكن للطبقة النشطة أبدًا تجاوز تصحيح الأخطاء، بغض النظر عن الخصوصية. يؤدي هذا إلى القضاء على حروب خصوصية CSS التي عادةً ما تصيب أدوات تصحيح الأخطاء.
الآن يبدو أن بعض المجموعات تجلس على خلفية داكنة. بصراحة، ليست سيئة للغاية.
إضافة جافا سكريبت
وقت جافا سكريبت. هذا هو المكان الذي تقوم فيه وحدة التحكم بشيء ما بالفعل. سنقوم ببناء هذا خطوة بخطوة.
الخطوة 1: إعداد إدارة الدولة
أولاً، نحتاج إلى متغيرات لتتبع حالة مصحح الأخطاء:
// ================================================================================
// إدارة الدولة
// ================================================================================
دع التشغيل = خطأ؛ // يتتبع ما إذا كان مصحح الأخطاء نشطًا أم لا
اسمحوا رافيد؛ // يخزن معرف requestAnimationFrame للإلغاء
تتحكم هذه المتغيرات في حلقة الرسوم المتحركة التي تقرأ بشكل مستمر مدخلات لوحة الألعاب.
الخطوة 2: احصل على مراجع DOM
بعد ذلك، نحصل على مراجع لجميع عناصر HTML التي سنقوم بتحديثها:
// ================================================================================
// مراجع عناصر DOM
// ================================================================================
يعد تخزين هذه المراجع مقدمًا أكثر كفاءة من الاستعلام عن DOM بشكل متكرر.
الخطوة 3: إضافة احتياطي لوحة المفاتيح
للاختبار بدون وحدة تحكم فعلية، سنقوم بتعيين مفاتيح لوحة المفاتيح للأزرار:
// ================================================================================
// التراجع عن لوحة المفاتيح (للاختبار بدون وحدة تحكم)
// ================================================================================
يتيح لنا ذلك اختبار واجهة المستخدم عن طريق الضغط على المفاتيح الموجودة على لوحة المفاتيح.
الخطوة 4: إنشاء حلقة التحديث الرئيسية
هنا يحدث السحر. تعمل هذه الوظيفة بشكل مستمر وتقرأ حالة لوحة الألعاب:
// ================================================================================
// حلقة تحديث لوحة الألعاب الرئيسية
// ================================================================================
وظيفة تحديثGamepad () {
// احصل على جميع لوحات الألعاب المتصلة
const gamepads = navigator.getGamepads();
إذا عادت (! لوحات الألعاب) ؛
// استخدم أول لوحة ألعاب متصلة
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 في معظم وحدات التحكم)
constpausePressed = gp.buttons[9].pressed;
pause1.classList.toggle("active",pausePressed);
pause2.classList.toggle("active",pausePressed);
// أنشئ قائمة بالأزرار التي تم الضغط عليها حاليًا لعرض الحالة
دع الضغط = []؛
gp.buttons.forEach((btn, i) => {
إذا (btn.pressed)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("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: إضافة التحكم في البدء/الإيقاف
أخيرًا، نحتاج إلى طريقة لتشغيل مصحح الأخطاء وإيقافه:
// ================================================================================
// تبديل تشغيل/إيقاف تشغيل مصحح الأخطاء
// ================================================================================
document.getElementById("toggle").addEventListener("click", () => {
تشغيل =! تشغيل؛ // اقلب حالة التشغيل
إذا (تشغيل) {
Status.textContent = "جاري تشغيل المصحح...";
updateGamepad(); // ابدأ حلقة التحديث
} آخر {
Status.textContent = "مصحح الأخطاء غير نشط";
CancelAnimationFrame(rafId); // أوقف الحلقة
}
});
نعم، اضغط على الزر وسيضيء. ادفع العصا فتتحرك. هذا كل شيء.
شيء آخر: القيم الخام. في بعض الأحيان تريد فقط رؤية الأرقام، وليس الأضواء.
في هذه المرحلة يجب أن ترى:
وحدة تحكم بسيطة على الشاشة،
الأزرار التي تتفاعل أثناء تفاعلك معها، و
قراءات تصحيح اختيارية تظهر مؤشرات الأزرار المضغوطة.
لجعل هذا الأمر أقل تجريدًا، إليك عرض توضيحي سريع لتفاعل وحدة التحكم التي تظهر على الشاشة في الوقت الفعلي:
الآن، يؤدي الضغط على "بدء التسجيل" إلى تسجيل كل شيء حتى تضغط على "إيقاف التسجيل".
2. تصدير البيانات إلى CSV/JSON
بمجرد أن يكون لدينا سجل، سنرغب في حفظه.
الخطوة 1: إنشاء مساعد التنزيل
أولاً، نحتاج إلى وظيفة مساعدة تتعامل مع تنزيلات الملفات في المتصفح:
// ================================================================================
// مساعد تنزيل الملف
// ================================================================================
وظيفة تنزيل الملف (اسم الملف، المحتوى، النوع = "نص/عادي") {
// قم بإنشاء فقاعة من المحتوى
const blob = new Blob([content], { type });
const url = URL.createObjectURL(blob);
// قم بإنشاء رابط تنزيل مؤقت وانقر فوقه
const a = document.createElement("a");
a.href = url;
a.download = اسم الملف؛
a.click();
// تنظيف عنوان URL للكائن بعد التنزيل
setTimeout(() => URL.revocObjectURL(url), 100);
}
تعمل هذه الوظيفة عن طريق إنشاء كائن ثنائي كبير الحجم (Blob) من بياناتك، وإنشاء عنوان URL مؤقت له، والنقر برمجيًا على رابط التنزيل. يضمن التنظيف عدم تسريب الذاكرة.
الخطوة 2: التعامل مع تصدير JSON
يعد JSON مثاليًا للحفاظ على بنية البيانات الكاملة:
document.getElementById("export-json").addEventListener("click", () => {
// تحقق مما إذا كان هناك أي شيء للتصدير
إذا (! الإطارات. الطول) {
console.warn("لا يوجد تسجيل متاح للتصدير.");
عودة؛
}
// أنشئ حمولة تحتوي على البيانات الوصفية والإطارات
الحمولة الثابتة = {
تم إنشاؤه في: تاريخ جديد ().toISOString ()،
إطارات
};
يحافظ تنسيق JSON على كل شيء منظمًا وقابلاً للتحليل بسهولة، مما يجعله مثاليًا للتحميل مرة أخرى إلى أدوات التطوير أو المشاركة مع زملائك في الفريق.
الخطوة 3: التعامل مع تصدير CSV
بالنسبة لصادرات CSV، نحتاج إلى تسوية البيانات الهرمية في صفوف وأعمدة:
document.getElementById("export-csv").addEventListener("click", () => {
// تحقق مما إذا كان هناك أي شيء للتصدير
إذا (! الإطارات. الطول) {
console.warn("لا يوجد تسجيل متاح للتصدير.");
عودة؛
}
يعد ملف CSV رائعًا لتحليل البيانات لأنه يفتح مباشرة في Excel أو Google Sheets، مما يتيح لك إنشاء مخططات أو تصفية البيانات أو تحديد الأنماط بشكل مرئي.
الآن بعد أن أصبحت أزرار التصدير موجودة، سترى خيارين جديدين على اللوحة: تصدير JSON وتصدير CSV. يعد JSON أمرًا رائعًا إذا كنت تريد إعادة السجل الأولي إلى أدوات التطوير الخاصة بك أو التجول في البنية. من ناحية أخرى، يتم فتح ملف CSV مباشرة في Excel أو Google Sheets حتى تتمكن من تخطيط المدخلات أو تصفيتها أو مقارنتها. يوضح الشكل التالي كيف تبدو اللوحة مع عناصر التحكم الإضافية هذه.
3. نظام اللقطات
في بعض الأحيان لا تحتاج إلى تسجيل كامل، بل مجرد "لقطة شاشة" سريعة لحالات الإدخال. هذا هو المكان الذي يساعد فيه زر التقاط لقطة.
document.getElementById("لقطة").addEventListener("click", () => {
// احصل على جميع لوحات الألعاب المتصلة
منصات const = navigator.getGamepads();
const activePads = [];
// قم بالتكرار والتقاط حالة كل لوحة ألعاب متصلة
لـ (const gp للوسادات) {
إذا استمر (!gp)؛ // تخطي الفتحات الفارغة
ActivePads.push({
المعرف: gp.id، // اسم/نموذج وحدة التحكم
الطابع الزمني: Performance.now()،
الأزرار: gp.buttons.map(b => ({
الضغط: ب. الضغط،
القيمة: ب. القيمة
})))،
المحاور: [...gp.axes]
});
}
// تحقق من العثور على أي لوحات ألعاب
إذا (!activePads.length) {
console.warn("لا توجد لوحات ألعاب متصلة من أجل اللقطة.");
تنبيه ("لم يتم اكتشاف أي وحدة تحكم!")؛
عودة؛
}
// تسجيل وإخطار المستخدم
console.log("لقطة:"، activePads);
تنبيه (تم التقاط اللقطة! تم التقاط وحدة التحكم ${activePads.length} (وحدات التحكم).);
});
تعمل اللقطات على تجميد الحالة الدقيقة لوحدة التحكم الخاصة بك في لحظة واحدة.
4. إعادة تشغيل إدخال الشبح
الآن للمتعة: إعادة تشغيل إدخال الشبح. يأخذ هذا السجل ويعيد تشغيله بشكل مرئي كما لو كان اللاعب الوهمي يستخدم وحدة التحكم.
document.getElementById("replay").addEventListener("click", () => {
// تأكد من أن لدينا تسجيلًا لإعادة تشغيله
إذا (! الإطارات. الطول) {
تنبيه ("لا يوجد تسجيل لإعادة التشغيل!")؛
عودة؛
}
// إعادة تشغيل حلقة الرسوم المتحركة
خطوة الوظيفة () {
const now = Performance.now();
const المنقضي = الآن - startTime؛
// معالجة جميع الإطارات التي كان من المفترض أن تحدث الآن
بينما (frameIndex
// تحديث واجهة المستخدم بحالات الزر المسجلة
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) => {
إذا (btn.pressed) pressed.push("Button" + i);
});
إذا (ضغط.الطول > 0) {
Status.textContent = "الشبح: " + pressed.join(", ");
}
frameIndex++;
}
// تابع الحلقة إذا كان هناك المزيد من الإطارات
إذا (frameIndex
// ابدأ الإعادة
خطوة ()؛
});
لجعل تصحيح الأخطاء أكثر عملية، أضفت إعادة تشغيل شبحية. بمجرد تسجيل الجلسة، يمكنك الضغط على إعادة التشغيل ومشاهدة واجهة المستخدم وهي تقوم بذلك، كما لو كان اللاعب الوهمي يقوم بتشغيل اللوحة. يظهر زر Replay Ghost جديد في اللوحة لهذا الغرض.
اضغط على "تسجيل"، وعبث بوحدة التحكم قليلاً، ثم توقف، ثم أعد التشغيل. واجهة المستخدم تعكس كل ما فعلته، مثل الشبح الذي يتتبع مدخلاتك.
لماذا تهتم بهذه الإضافات؟
يسهّل التسجيل/التصدير على المختبرين إظهار ما حدث بالضبط.
تتجمد اللقطات لحظة من الزمن، وهي مفيدة للغاية عندما تطارد أخطاء غريبة.
تُعد إعادة تشغيل Ghost أمرًا رائعًا للبرامج التعليمية أو عمليات التحقق من إمكانية الوصول أو مجرد مقارنة إعدادات التحكم جنبًا إلى جنب.
في هذه المرحلة، لم يعد الأمر مجرد عرض توضيحي أنيق، ولكنه شيء يمكنك تنفيذه بالفعل.
حالات الاستخدام في العالم الحقيقي
الآن لدينا مصحح الأخطاء هذا الذي يمكنه فعل الكثير. فهو يعرض الإدخال المباشر، ويسجل السجلات، ويصدرها، بل ويعيد تشغيل الأشياء. لكن السؤال الحقيقي هو: من يهتم فعلاً؟ لمن هذا مفيد؟
مطوري اللعبة
وحدات التحكم هي جزء من المهمة، ولكن تصحيحها؟ عادة ما يكون الألم. تخيل أنك تختبر مجموعة من ألعاب القتال، مثل ↓ → + punch. وبدلا من أن تصلي، تضغط عليه بنفس الطريقة مرتين، وتسجله مرة واحدة، وتعيد تشغيله. تم. أو يمكنك مبادلة سجلات JSON مع أحد زملائك في الفريق للتحقق مما إذا كان كود اللعب الجماعي الخاص بك يتفاعل بنفس الطريقة على أجهزتهم. هذا ضخم.
ممارسون إمكانية الوصول
هذا قريب إلى قلبي. لا يلعب الجميع بوحدة تحكم "قياسية". تقوم وحدات التحكم التكيفية بإصدار إشارات غريبة في بعض الأحيان. باستخدام هذه الأداة، يمكنك رؤية ما يحدث بالضبط. المعلمين والباحثين، أيا كان. يمكنهم الحصول على السجلات أو مقارنتها أو إعادة تشغيل المدخلات جنبًا إلى جنب. فجأة، تصبح الأشياء غير المرئية واضحة.
اختبار ضمان الجودة
عادةً ما يكتب القائمون على الاختبار ملاحظات مثل "لقد هرستُ الأزرار هنا وانكسرت". ليست مفيدة للغاية. الآن؟ يمكنهم التقاط المطابع الدقيقة وتصدير السجل وإرساله. لا التخمين.
المربين
إذا كنت تنشئ برامج تعليمية أو مقاطع فيديو على YouTube، فإن إعادة العرض الخفي هي أمر ذهبي. يمكنك أن تقول حرفيًا: "هذا ما فعلته بوحدة التحكم"، بينما توضح واجهة المستخدم ما يحدث. يجعل التفسيرات أكثر وضوحا.
ما وراء الألعاب
ونعم، هذا لا يتعلق فقط بالألعاب. استخدم الناس وحدات التحكم للروبوتات والمشاريع الفنية وواجهات إمكانية الوصول. نفس المشكلة في كل مرة: ما الذي يراه المتصفح بالفعل؟ مع هذا، ليس عليك أن تخمن.
الاستنتاج
لقد كان تصحيح أخطاء إدخال وحدة التحكم دائمًا بمثابة طيران أعمى. على عكس DOM أو CSS، لا يوجد مفتش مدمج للوحة الألعاب؛ إنها مجرد أرقام أولية في وحدة التحكم، يمكن فقدها بسهولة وسط الضجيج.
باستخدام بضع مئات من أسطر HTML وCSS وJavaScript، قمنا ببناء شيء مختلف:
مصحح أخطاء مرئي يجعل المدخلات غير المرئية مرئية.
نظام CSS متعدد الطبقات يحافظ على واجهة المستخدم نظيفة وقابلة للتصحيح.
مجموعة من التحسينات (التسجيل، التصدير، اللقطات، إعادة التشغيل الخفي) التي ترتقي به من أداة تجريبية إلى أداة مطور.
يوضح هذا المشروع إلى أي مدى يمكنك الذهاب من خلال مزج قوة منصة الويب مع القليل من الإبداع في CSS Cascade Layers.
الأداة التي شرحتها للتو بالكامل مفتوحة المصدر. يمكنك استنساخ GitHub repo وتجربته بنفسك.
ولكن الأهم من ذلك، يمكنك جعلها بنفسك. أضف طبقاتك الخاصة. قم ببناء منطق إعادة التشغيل الخاص بك. ادمجها مع النموذج الأولي للعبة. أو حتى استخدامه بطرق لم أتخيلها. للتدريس أو إمكانية الوصول أو تحليل البيانات.
في نهاية المطاف، لا يتعلق الأمر فقط بتصحيح أخطاء لوحات الألعاب. يتعلق الأمر بتسليط الضوء على المدخلات المخفية، ومنح المطورين الثقة للعمل مع الأجهزة التي لا يزال الويب لا يحتضنها بالكامل.
لذا، قم بتوصيل وحدة التحكم الخاصة بك، وافتح المحرر الخاص بك، وابدأ في التجربة. قد تتفاجأ بما يمكن أن يحققه متصفحك وCSS الخاص بك حقًا.