جدول المحتويات:
- الخطوة 1: اعتبارات تصميم الصورة الكبيرة
- الخطوة 2: بروتوكول الإشارة: لغة بسيطة لاتصالات الشبكة
- الخطوة 3: نريد التحكم في إجراءات الجهاز بناءً على حالته الحالية
- الخطوة 4: نريد الرد على مدخلات المستخدم
- الخطوة 5: نريد تهيئة قيم البيانات في ذاكرة الأجهزة عند بدء تشغيل الجهاز
- الخطوة 6: نريد عرض الرسوم المتحركة والرسومات باستخدام شاشة 5 X 5 LED
- الخطوة 7: نريد نقل البيانات لاسلكيًا باستخدام راديو الجهاز
- الخطوة 8: نريد الاستماع إلى البيانات واستلامها عبر راديو الجهاز ومعالجتها وفقًا لذلك
- الخطوة 9: جهاز الجذر: نريد أن نكون قادرين على تحديد إشارة
- الخطوة 10: لقد انتهينا
فيديو: التنافس على الشبكة: لعبة بزمن انتقال منخفض لـ BBC Micro: بت: 10 خطوات (بالصور)
2024 مؤلف: John Day | [email protected]. آخر تعديل: 2024-01-30 07:38
في هذا البرنامج التعليمي ، سأشرح كيفية تنفيذ لعبة أساسية متعددة اللاعبين على BBC micro: bit بالميزات التالية:
- واجهة بسيطة
- زمن انتقال منخفض بين ضغطات الأزرار وتحديثات الشاشة
- عدد مرن من المشاركين
- تحكم سهل باللعبة باستخدام جهاز تحكم عن بعد رئيسي ("جذر")
اللعبة هي في الأساس محاكاة للسياسة. يبدأ جميع اللاعبين في اللعب دون تعيين أي فريق ، باستثناء لاعبين اثنين. تم تعيين أحد هؤلاء اللاعبين إلى الفريق أ ، والآخر مخصص للفريق ب.
الهدف من اللعبة لكل لاعب أن يكون في الفريق مع غالبية اللاعبين في الوقت الذي يتم فيه تحويل الجميع.
يوضح الرسم البياني أعلاه آلة حالة محدودة ، أي مواصفات الحالات التي يمكن أن يكون فيها الجهاز والانتقالات بين تلك الحالات.
يمكن اعتبار الحالة على أنها المجموعة الحالية من البيانات التي تصف ذاكرة الجهاز منذ تشغيله. بناءً على هذه البيانات ، قد يقوم الجهاز بتنفيذ إجراءات معينة أو يتفاعل بشكل مختلف مع إدخال المستخدم.
الانتقال هو شرط منطقي يؤدي ، عندما يكون صحيحًا ، إلى تغيير الجهاز لحالته. يمكن أن يكون الانتقال من دولة إلى أي دولة أخرى. قد يكون للدولة انتقالات متعددة.
يحدد الرسم البياني أعلاه الحالات التالية:
- غير معين
- استمع إلى A
- استمع إلى B
- فريق أ
- فريق ب
قد يكون الجهاز الذي يقوم بتشغيل رمز اللعبة في أي من هذه الولايات الخمس ، ولكن في حالة واحدة فقط في كل مرة ، وهذه الحالات الخمس فقط.
سأفترض طوال الدليل أنك تستخدم محرر MakeCode من Microsoft ، والذي يمكن العثور عليه على:
يمكن الاطلاع على التنفيذ الكامل للعبة هنا:
makecode.microbit.org/_CvRMtheLbRR3 ("microbit-demo-user" هو اسم المشروع)
ويمكن الاطلاع على تنفيذ وحدة تحكم الشبكة الرئيسية ("الجذر") هنا:
makecode.microbit.org/_1kKE6TRc9TgE ("microbit-demo-root" هو اسم المشروع)
سأشير إلى هذه الأمثلة خلال البرنامج التعليمي الخاص بي.
الخطوة 1: اعتبارات تصميم الصورة الكبيرة
قبل أن نكتب أي رمز ، نحتاج إلى التفكير في الشكل الذي نريد أن يبدو عليه منتجنا النهائي. بمعنى آخر ما هي متطلبات التطبيق؟ ما الذي يجب أن يخبر الكود الخاص بنا الجهاز بفعله عند الانتهاء؟ لقد قسمت وظائف التطبيق الرئيسي إلى ست فئات ، يمكن اعتبار كل فئة من منظور تصميم مختلف.
- نريد التحكم في تصرفات الجهاز بناءً على حالته الحالية
- نريد أن يتفاعل الجهاز مع مدخلات المستخدم
- قد نرغب في عرض الرسوم المتحركة والرسومات باستخدام شاشة LED مقاس 5 × 5
- نريد تهيئة قيم البيانات في ذاكرة الأجهزة عند بدء تشغيل الجهاز
- نريد نقل البيانات لاسلكيًا باستخدام راديو الجهاز
- نريد الاستماع إلى البيانات واستلامها عبر راديو الجهاز ومعالجتها وفقًا لذلك
اسمح لي أن أخوض في مزيد من التفاصيل حول كل منها.
1. نريد التحكم في تصرفات الجهاز بناءً على حالته الحالية
مثل معظم البرامج الأخرى ، يحدث تنفيذ التعليمات المحددة بواسطة الكود سطرًا واحدًا في كل مرة. نريد لجهازنا تنفيذ تعليمات معينة بناءً على حالته الداخلية ، كما هو موضح في الرسم التخطيطي في الجزء العلوي من هذا البرنامج التعليمي. يمكننا كتابة سلسلة من الشروط بعد كل كتلة من الكود الذي يجب أن يقوم بفحص الجهاز ، ولكن هذا النهج يمكن أن يصبح فوضويًا بسرعة كبيرة ، لذلك سنستخدم بدلاً من ذلك حلقة لا نهائية تتحقق ببساطة من متغير واحد ، وبناءً على هذا المتغير أو ينفذ مجموعة معينة من التعليمات أو لا يفعل شيئًا على الإطلاق. سيتم تحديد هذا المتغير من خلال اللاحقة "_state" في كل من تطبيق المستخدم الخاص بنا وتطبيق الجذر الخاص بنا.
2. نريد أن يتفاعل الجهاز مع مدخلات المستخدم
على الرغم من التنفيذ الطبيعي للشفرة التي تحدث بالتتابع ، أي سطر واحد في كل مرة ، نحتاج إلى أن يتفاعل جهازنا مع ضغطات الأزرار بينما تحدد حلقة الحالة الرئيسية ما يجب أن يفعله الجهاز في أي لحظة. لهذا الغرض ، يمتلك الجهاز القدرة على إرسال إشارات إلى برامج المستوى الأدنى التي تتفاعل مع الأجهزة ، مما يؤدي إلى تشغيل ما يسمى بالحدث. يمكننا كتابة رمز يخبر الجهاز بفعل شيء ما عندما يكتشف نوعًا معينًا من الأحداث.
3. نريد عرض الرسوم المتحركة والرسومات باستخدام شاشة 5 × 5 LED
يبدو أن آلية القيام بذلك بسيطة ، لكن الكتلة تعرض صورة تضيف تأخيرًا خفيًا قدره 400 مللي ثانية. نظرًا لأننا نريد أن يستمر جهازنا في تنفيذ حلقة الحالة الخاصة به بأقل قدر ممكن من التأخير ، فسنحتاج إلى تحرير كود جافا سكريبت لتقليل التأخير.
4. نريد تهيئة قيم البيانات في ذاكرة الأجهزة عند بدء تشغيل الجهاز
قبل أن يقوم الجهاز بأي شيء ، يحتاج التطبيق إلى تحميل بياناته في الذاكرة. يتضمن هذا المتغيرات الثابتة المسماة لسهولة قراءة الكود ، والمتغيرات التي تحتوي على صور ، والتي قد تكون جزءًا من الرسوم المتحركة ، ومتغيرات العداد التي يجب أن تبدأ عند 0 لتعمل بشكل صحيح. سننتهي بقائمة طويلة من أسماء المتغيرات والقيم المخصصة لها حديثًا. كخيار نمط شخصي ، سأشير إلى القيم الثابتة ، أي القيم التي لن أحتاج إلى تغييرها أبدًا ، باستخدام ALL_CAPS. سأقوم أيضًا ببدء معرفات المتغيرات الرئيسية باسم فئة يشير إلى نوع من الكائن أو النوع الذي يقع ضمنه المعرف. هذا في محاولة لتسهيل متابعة الكود. لن أستخدم أبدًا اسمًا متغيرًا مثل "item" أو "x" بسبب الغموض الذي ينشأ عند محاولة فك الشفرة.
5. نريد نقل البيانات لاسلكيًا باستخدام راديو الجهاز
هذه في الواقع مهمة بسيطة إلى حد ما عند استخدام لغة كتل MakeCode. نقوم ببساطة بتعيين جميع الأجهزة على نفس مجموعة الراديو في وقت التمهيد ثم عندما نريد إرسال إشارة ، يمكننا تمرير رقم واحد إلى مجموعة "رقم إرسال الراديو" المقدمة إلينا. من المهم أن يعمل المرسل والمستقبل على نفس مجموعة الراديو ، لأنه إذا لم يكن الأمر كذلك ، فسيتم الإرسال أو الاستقبال على ترددات مختلفة ، ولن ينجح الاتصال.
6. نريد الاستماع إلى البيانات واستقبالها عبر راديو الجهاز ومعالجتها وفقًا لذلك
مع الأخذ في الاعتبار نفس الاعتبارات مثل العنصر السابق ، سنستمع للإرسالات الواردة بنفس الطريقة التي نستمع بها لإدخال المستخدم: باستخدام معالج الأحداث. سنقوم بكتابة كتلة من التعليمات البرمجية التي ستفحص أي إشارات واردة ونتحقق مما إذا كان سيتم اتخاذ أي إجراء دون الإخلال بحلقة الحالة الرئيسية.
بالإضافة إلى ذلك ، يجب أن نفكر بإيجاز في تصميم تطبيق الجذر الأبسط بكثير ، وهو برنامج يسمح للجهاز بالتحكم في الشبكة بالكامل. لن أقضي الكثير من الوقت في هذا لأنه أبسط بكثير من التصميم أعلاه ومعظمه مجرد تكرار. لقد قسمت وظائف الجذور إلى ثلاث فئات.
- نريد أن نكون قادرين على تحديد إشارة
- نريد أن نكون قادرين على إرسال إشارة
-
1. نريد أن نكون قادرين على تحديد إشارة
يمكن القيام بذلك ببساطة عن طريق وجود زر يتكرر عبر الإشارات الممكنة. نظرًا لوجود ثلاثة فقط ، فإن هذا النهج سيكون كافيًا. في الوقت نفسه ، يمكن أن يكون لدينا حلقة تعيد عرض الإشارة المحددة باستمرار ، مما يسمح للمستخدم بالضغط على زر ورؤية الإشارة المحددة تظهر على شاشة LED مع زمن انتقال ضئيل للغاية.
2. نريد أن نكون قادرين على نقل إشارة
نظرًا لوجود زرين ، يمكننا تخصيص أحدهما للاختيار والآخر للتأكيد. مثل تطبيق المستخدم ، نقوم ببساطة بإرسال الإشارة عبر الشبكة كرقم. لا توجد معلومات أخرى مطلوبة.
سأتحدث أكثر عن بروتوكول الإشارة البسيط في القسم التالي.
الخطوة 2: بروتوكول الإشارة: لغة بسيطة لاتصالات الشبكة
يمكن اعتبار الإشارات التالية مجموعة من جميع الكلمات الممكنة التي يمكن للأجهزة استخدامها للتحدث مع بعضها البعض. نظرًا لأن الشبكة بسيطة جدًا ، فلا يوجد الكثير مما يمكن قوله ، وبالتالي يمكننا تمثيل هذه الإشارات الثلاث بقيم عدد صحيح بسيط.
0. إعادة تعيين
- المعرف في الكود: SIG-R
- قيمة عدد صحيح: 0
- الغرض: أخبر جميع الأجهزة الموجودة داخل النطاق بإسقاط ما يفعلونه والتصرف كما لو تم تمهيدهم للتو. إذا وصلت هذه الإشارة إلى كل جهاز على الشبكة ، فسيتم إعادة تعيين الشبكة بالكامل ويمكن للمستخدمين بدء لعبة جديدة. لا يمكن بث هذه الإشارة إلا بواسطة جهاز جذر.
1. التحويل أ
- المعرف في الكود: SIG-A
- قيمة عدد صحيح: 1
- الغرض: أخبر أي جهاز موجود في الحالة LISTEN_A ، بمجرد تلقيه إشارة التحويل ، للتبديل إلى الحالة TEAM_A.
2. التحويل ب
- المعرف في الكود: SIG-B
- قيمة عدد صحيح: 2
- الغرض: أخبر أي جهاز في الحالة LISTEN_B ، بمجرد تلقيه إشارة التحويل ، للتبديل إلى الحالة TEAM_B.
الخطوة 3: نريد التحكم في إجراءات الجهاز بناءً على حالته الحالية
أخيرًا ، يمكننا البدء في كتابة التعليمات البرمجية.
أولاً ، افتح مشروعًا جديدًا في Make Code
- قم بإنشاء وظيفة جديدة. اتصلت بحلقة الألغام لأن هذه هي الحلقة الأساسية للتطبيق
- أضف كتلة حلقة تتكرر إلى أجل غير مسمى. لقد استخدمت while (true) لأن الصواب الحرفي لن يكون خاطئًا أبدًا ، وبالتالي لن يخرج تدفق التحكم في التطبيق من الحلقة أبدًا
- أضف ما يكفي من كتل if-else للتحقق مما إذا كان الجهاز في أي من حالاته الخمس الممكنة
- قم بإنشاء متغير للاحتفاظ بحالة الجهاز الحالية
-
أنشئ متغيرات لتمثيل كل حالة من الحالات الخمس المحتملة
ملاحظة: من المقبول ألا تحتوي هذه المتغيرات على أي قيم مخصصة حتى الآن. سوف نصل إلى ذلك. في هذه المرحلة ، من المهم أن نكتب رمزًا نظيفًا وسهل القراءة
- قم بتغيير كل شرط في كتل if-else لمقارنة الحالة الحالية بإحدى الحالات الممكنة
- في الجزء السفلي من كتل if-else ، أضف وقفة مؤقتًا لعدد من المللي ثانية ، وأنشئ متغيرًا للاحتفاظ بهذا الرقم. سنقوم بتهيئته لاحقًا. تأكد من أن المتغير له اسم وصفي ، مثل التجزئة أو ضربات القلب. نظرًا لأن هذه هي الحلقة الأساسية للجهاز ، فإن هذا الإيقاف المؤقت سيحدد السرعة التي ينفذ بها الجهاز الحلقة الرئيسية ، لذا فهي قيمة مهمة جدًا ، ومن المهم جدًا أن يكون رقمًا سحريًا بدون اسم.
ملاحظة: لا تقلق بشأن المربعات الرمادية في الصورة الثالثة. سأصل إلى هؤلاء لاحقًا.
الخطوة 4: نريد الرد على مدخلات المستخدم
الآن ، نريد إخبار الجهاز بكيفية التعامل مع ضغطات الأزرار. قد يكون فكر المرء أولاً هو ببساطة استخدام كتل "عند الضغط على الزر" في فئة الإدخال ، لكننا نرغب في المزيد من التحكم الدقيق من ذلك. سنستخدم كتلة "on event from (X) with value (Y)" من فئة التحكم ضمن القسم المتقدم ، لأننا متقدمون في هذا البرنامج التعليمي.
-
إنشاء أربع مجموعات "في حدث من …".
- يجب أن يتحقق اثنان من هؤلاء من مصدر الحدث "MICROBIT_ID_BUTTON_A"
- يجب أن يتحقق اثنان من هؤلاء من مصدر الحدث "MICROBIT_ID_BUTTON_B"
-
من بين الحدثين اللذين يستهدفان كل زر:
- يجب على المرء التحقق من الحدث من النوع "MICROBIT_BUTTON_EVT_UP"
- يجب على المرء التحقق من الحدث من النوع "MICROBIT_BUTTON_EVT_DOWN"
- ملاحظة: هذه الخيارات في جميع الأحرف الكبيرة عبارة عن تسميات مستخدمة في المستوى الأدنى لرمز micro: bit. إنها ببساطة عناصر نائبة يتم استبدالها لاحقًا بأعداد صحيحة عندما يتم تجميع الكود إلى ملف ثنائي قابل للتنفيذ. من الأسهل على البشر استخدام هذه التسميات بدلاً من البحث عن العدد الصحيح الذي يجب إدخاله ، على الرغم من أن كلاهما يعمل بنفس الطريقة.
-
اخترت ، كمسألة أسلوب ، أن يكون لكل من "حدث من …" استدعاء حظر وظيفة تصف الحدث المرتفع. على الرغم من أنه ليس ضروريًا تمامًا ، إلا أن هذا في رأيي يحسن إمكانية القراءة. إذا رغب المرء في القيام بذلك ، فيمكنه وضع رمز معالجة الحدث داخل كتلة "on event from…" نفسها.
ملاحظة: تسمى كتلة التعليمات البرمجية التي تتعامل مع استجابة الجهاز لحدث ما بشكل بديهي بـ "معالج الحدث"
- أضف ، في كل معالج حدث ، نفس بنية if-else المستخدمة لتقسيم تدفق التحكم بناءً على حالة الجهاز مثل الهيكل في حلقة الحالة الرئيسية.
-
أضف كتل المهام التي تعدل حالة الجهاز كما هو محدد في مخطط الحالة الخاص بنا
- نعلم أنه عندما يكون الجهاز في حالة "غير محدد" ، يجب أن يتفاعل الجهاز مع الزر "أ" الذي يتم الضغط عليه من خلال الانتقال إلى الحالة LISTEN_A ، والضغط على الزر B بالانتقال إلى الحالة LISTEN_B
- نعلم أيضًا أنه عندما يكون الجهاز في الحالة LISTEN_A أو LISTEN_B ، يجب أن يتفاعل الجهاز مع الزر A الذي تم تحريره والزر B ، على التوالي ، من خلال الانتقال مرة أخرى إلى الحالة UNASSIGNED.
-
أخيرًا ، نعلم أنه عندما يكون الجهاز في حالة TEAM_A أو TEAM_B ، يجب أن يتفاعل الجهاز مع الزر A المضغوط والزر B الذي يتم الضغط عليه عن طريق بث SIG_A وبث SIG_B على التوالي.
ليس من الضروري في هذه المرحلة ملء تفاصيل إشارات البث. سنصل إلى ذلك لاحقا. المهم هو أننا نوجه هذه الوظائف لاستخدام الكود الذي سنكتبه من خلال تسمية كتلة الإجراءات هذه ، مثل بث الإشارة SIG_A ، والذي يصف ما يجب القيام به في تلك المرحلة
الخطوة 5: نريد تهيئة قيم البيانات في ذاكرة الأجهزة عند بدء تشغيل الجهاز
في هذه المرحلة ، استخدمنا الكثير من المتغيرات (أسماء البيانات) ، لكننا لم نقم فعليًا بتعيين قيم لهذه الأسماء. نريد أن يقوم الجهاز بتحميل قيم كل هذه المتغيرات في الذاكرة عند بدء التشغيل ، لذلك نضع التهيئة لهذه المتغيرات في كتلة "عند البدء".
هذه هي القيم التي يجب أن نهيئها:
-
ثوابت الإشارة حسب بروتوكول الإشارة. يجب أن تكون القيم:
- SIG_R = 0
- SIG_A = 1
- SIG_B = 2
- ملاحظة: لقد سبقت هذه الثوابت بـ "EnumSignals" للإشارة إلى أن هذه المتغيرات يجب أن تتصرف كما لو كانت جزءًا من نوع تم تعداده يسمى الإشارات. هذه هي الطريقة التي يمكن بها تنفيذ هذه المتغيرات في لغات البرمجة الأخرى. تعريف الأنواع التي تم تعدادها وشرحها خارج نطاق البرنامج التعليمي الخاص بي. يمكن للمرء أن جوجل إذا رغبوا في ذلك. هذه البادئات هي ببساطة اختيارات أسلوبية وليست ضرورية على الإطلاق للتشغيل السليم للبرنامج.
-
ثوابت الحالة ، والتي يمكن أن تكون عشوائية طالما كانت لها قيمة. لقد قمت باختيار نمط لاستخدام الأعداد الصحيحة تصاعديًا من 0 ، مثل:
- غير محدد = 0
- LISTEN_A = 1
- LISTEN_B = 2
- TEAM_A = 3
- TEAM_B = 4
- ملاحظة: لقد اتخذت نفس قرار النمط فيما يتعلق بالبادئات لهذه المتغيرات أيضًا. بالإضافة إلى ذلك ، سأذكر أن كل شيء عن هذه التخصيصات ، القيم والترتيب ، تعسفي تمامًا. لا يهم حتى أن تكون هذه القيم متسقة من جهاز لآخر ، لأنها تُستخدم داخليًا فقط وليس للاتصال عبر الشبكة. كل ما يهم هو أن المتغيرات لها قيمة ويمكن مقارنتها ببعضها البعض لمعرفة ما إذا كانت متكافئة أم لا.
- لسهولة القراءة ، ثابت يسمى BOOT_STATE وقم بتعيينه على UNASSIGNED. هذا يجعل حقيقة أننا نعيد التعيين إلى حالة التمهيد ، بدلاً من حالة أكثر تعسفية ، أكثر وضوحًا عندما يتلقى الجهاز إشارة إعادة تعيين ، والتي سننفذها لاحقًا.
-
ثوابت الرسوم المتحركة ، تُستخدم في الخطوة التالية لإنشاء رسوم متحركة تسمح بمقاطعة زمن انتقال منخفض للغاية عبر إدخال المستخدم. لم نستخدمها حتى الآن ، ولكن بالتأكيد سيتم شرحها واستخدامها في القسم التالي. يجب أن يكون معنى بعض هؤلاء بديهيًا بسبب أسمائهم.
- TICKS_PER_FRAME_LOADING_ANIMATION = 50
- MS_PER_DEVICE_TICK = 10
- MS_PER_FRAME_BROADCAST_ANIMATION = 500
- MICROSECONDS_PER_MILLISECOND = 1000
- NUMBER_OF_FRAMES_IN_LOADING_ANIMATION = 4
-
متغير آخر للرسوم المتحركة ، هذه المرة عداد بالتأكيد ليس ثابتًا. مثل معظم العدادات ، نقوم بتهيئته إلى 0
iTickLoadingAnimation = 0
-
قم بإنشاء سلسلتين من المتغيرات لتثبيت إطارات الرسوم المتحركة. الأولى ، التي أسميها "تحميل الرسوم المتحركة" ، يجب أن تحتوي على أربع صور (والتي ربما تكون قد خمنت من خلال التهيئة الثابتة الأخيرة) ، والثانية ، والتي أسميها "بث الرسوم المتحركة" ، والتي يجب أن تحتوي على ثلاث صور. أوصي بتسمية المتغيرات لتتوافق مع إطارات الرسوم المتحركة ، على سبيل المثال ringAnimation0 ، ringAnimation1 …
قم بإنشاء نفس قيم الصورة كما فعلت أو قم بإنشاء المزيد من الصور الأصلية والأكثر برودة
- أخيرًا وليس آخرًا ، يجب علينا ضبط مجموعة الراديو للجهاز على 0 باستخدام كتلة "مجموعة أجهزة الراديو (X)"
- اختياريًا ، اكتب الرسالة "اكتمال التهيئة" إلى الإخراج التسلسلي لإخبار المستخدم أن كل شيء سار على ما يرام.
- الآن بعد أن انتهينا من إعداد الجهاز ، يمكننا استدعاء وظيفة حلقة الحالة الخاصة بنا.
الخطوة 6: نريد عرض الرسوم المتحركة والرسومات باستخدام شاشة 5 X 5 LED
والآن عن شيء مختلف تماما.
نريد عرض بعض الرسوم المتحركة وبعض الأحرف ، لكننا لا نريد مقاطعة حلقة الحالة الرئيسية. لسوء الحظ ، فإن الكتل التي تعرض الصور والسلاسل النصية لها تأخير يبلغ 400 مللي ثانية بشكل افتراضي. لا توجد طريقة لتغيير هذا بدون تحرير تمثيل جافا سكريبت للكود. لذا ، هذا ما سنفعله.
- قم بإنشاء وظيفة لكل صورة. سيسمح هذا للمرء باستخدام كتلة واحدة لعرض الصورة بدلاً من تحرير جافا سكريبت في كل مرة. في هذا البرنامج المحدد ، لا يتم استخدام أي صورة أكثر من مرة ، ولكن ما زلت أعتقد أن هذا النمط يجعل الكود أسهل في القراءة.
- إضافة ، في كل وظيفة جديدة ، كتلة "إظهار الصورة (X) عند الإزاحة 0" مع استبدال اسم متغير الصورة المقابل (X)
-
إضافة ، في حلقة الحالة الرئيسية. كتل "إظهار السلسلة (X)" لكل كتلة بالإضافة إلى الكتلة التي تتعامل مع الحالة "غير محدد". أضف حرفًا لعرضه للجهاز للإشارة إلى حالاته المختلفة. هذا ما فعلته:
- LISTEN_A: "أ"
- LISTEN_B: "ب"
- TEAM_A: "أ"
-
TEAM_B: "ب"
بالنسبة إلى الحالة غير المحددة ، قم بإجراء مكالمة إلى وظيفة ستعمل على تحديث الرسوم المتحركة للتحميل. سنقوم بملء تفاصيل هذه الوظيفة أدناه
- قم بالتبديل إلى وضع جافا سكريبت.
- ابحث عن كل استدعاء لـ X.showImage (0) و basic.showString (X)
-
قم بتغيير كل واحدة إما إلى X.showImage (0 ، 0) أو basic.showString (X ، 0)
- ستؤدي إضافة هذه الوسيطة الإضافية إلى تعيين التأخير بعد الإجراء على 0. بشكل افتراضي ، يتم ترك هذا الأمر ، وسيتوقف الجهاز مؤقتًا لمدة 400 مللي ثانية بعد تنفيذ كل من هذه الكتل.
- الآن ، لدينا آلية شبه خالية من الكمون لعرض صورنا في كتل الرسوم المتحركة الخاصة بنا ، والتي يمكننا الآن إنشاؤها
أولاً ، سنبني وظيفة بث الرسوم المتحركة البسيطة نسبيًا. إنه أبسط لأننا لا نريد أن يكون المستخدم قادرًا على فعل أي شيء حتى تكتمل الوظيفة ، وذلك لمنعه من إرسال بريد عشوائي على وظيفة البث. لتحقيق ذلك ، يمكننا ببساطة الحفاظ على تدفق التحكم مقيدًا بالكتلة حتى تكتمل الوظيفة ، وهو السلوك القياسي.
- قم بإنشاء وظيفة تعرض بث الرسوم المتحركة.
- داخل تلك الكتلة ، أضف ثلاث استدعاءات وظيفية ، واحدة لكل إطار من الرسم المتحرك ، بالترتيب الذي ينبغي عرضها به
-
أضف كتلة "wait (us) (X)" بعد كل مكالمة إلى وظيفة عرض الصور.
ملاحظة: هذه الكتلة ، من قسم التحكم المتقدم ، ستذهب إلى أبعد من "الإيقاف المؤقت (مللي ثانية)" من حيث أنها ستجمد المعالج تمامًا حتى انقضاء الوقت المحدد. عند استخدام كتلة الإيقاف المؤقت ، من الممكن أن يؤدي الجهاز مهام أخرى خلف الكواليس. هذا مستحيل مع كتلة الانتظار
- استبدل (X) بـ (MS_PER_FRAME_BROADCAST_ANIMATION x MICROSECONDS_PER_MILLISECOND)
- يجب أن تعمل الرسوم المتحركة الآن بشكل صحيح
ثانيًا ، سنقوم ببناء آلية عرض الرسوم المتحركة للتحميل. الفكرة من وراء ذلك هي تحديث شاشة LED في فترة زمنية محددة ، والتي نحددها في المتغير MS_PER_DEVICE_TICK. هذه القيمة ، طول علامة الجهاز ، هي عدد المللي ثانية التي يتوقف فيها الجهاز مؤقتًا بعد إكمال كل تكرار لحلقة الحالة. نظرًا لأن هذه القيمة صغيرة بما يكفي ، يمكننا تحديث العرض مرة واحدة خلال كل تكرار لحلقة العرض وسيظهر للمستخدم أن الرسوم المتحركة تتقدم بسلاسة ، وعندما تتغير الحالة ، سيكون هناك زمن انتقال ضئيل للغاية بين مدخلات المستخدم يتم تحديث العرض. من خلال عد العلامات ، وهو ما نقوم به باستخدام متغير iTickLoadingAnimation ، يمكننا عرض الإطار المناسب للرسوم المتحركة.
- قم بإنشاء وظيفة من شأنها تحديث الرسوم المتحركة للتحميل
-
أضف شرطًا للتحقق مما إذا كان عداد التجزئة قد وصل إلى قيمته القصوى. سيكون هذا الشرط صحيحًا إذا كانت قيمة عداد التجزئة أكبر من عدد الإطارات في حركة التحميل مضروبًا في عدد العلامات لعرض كل إطار
إذا كانت الحالة صحيحة ، فقم بإعادة تعيين iTickLoadingAnimation إلى 0
-
أضف كتلة من شروط if-else. سيحدد هذا إطار الرسم المتحرك الذي سيتم عرضه.
لكل إطار من الرسم المتحرك ، إذا كان عداد التجزئة أقل من عدد العلامات في كل حركة مضروبة في رقم إطار الرسم المتحرك (بدءًا من 1) ، ثم اعرض هذا الإطار ، وإلا تحقق مما إذا كان الإطار التالي هو الإطار المطلوب لا تكن مشاغبا
- في الجزء السفلي من الكتلة ، قم بزيادة iTickLoadingAnimation
- يجب أن تعمل الرسوم المتحركة الآن بشكل صحيح
ملاحظة: يتم إنشاء جميع الكتل الرمادية التي تظهر في المثال الخاص بي عندما يقوم أحدهم بتحرير تمثيل جافا سكريبت للكتلة. هذا يعني ببساطة أن الكتلة تمثل كود جافا سكريبت لا يمكن تمثيله باستخدام مجموعة الكتل القياسية ويجب تحريرها في شكل نصي.
الخطوة 7: نريد نقل البيانات لاسلكيًا باستخدام راديو الجهاز
هذه الخطوة أقصر بكثير من السابقة. في الواقع ، ربما تكون أقصر خطوة في هذا البرنامج التعليمي بأكمله.
تذكر أنه عندما قمنا ببرمجة استجابة الجهاز لإدخال المستخدم ، كان لدي كتلتان في لقطة الشاشة لم يتم شرحهما في هذا القسم. كانت هذه مكالمات لوظائف ترسل إشارات عبر الراديو. اكثر تحديدا:
-
عند الضغط على الزر A:
-
إذا كان الجهاز في حالة TEAM_A:
إشارة البث SIG_A
-
-
عند الضغط على الزر B:
-
إذا كان الجهاز في حالة TEAM_B
إشارة البث SIG_B
-
قم بإنشاء هذه الوظائف إذا لم تكن موجودة بالفعل.
في كل وظيفة:
- استدعاء وظيفة بث الرسوم المتحركة. سيؤدي هذا إلى منع حدوث أي شيء آخر حتى اكتماله ، والذي سيكون في MS_PER_FRAME_BROADCAST_ANIMATION * 3 = 1.5 ثانية. يتم ضرب الثابت في ثلاثة لأن هناك ثلاثة إطارات في الرسم المتحرك. هذا أمر تعسفي ويمكن إضافة المزيد إذا كانت الترقية الجمالية كبيرة بدرجة كافية. الغرض الثاني من هذه الرسوم المتحركة هو منع المستخدم من إرسال بريد عشوائي إلى وظيفة البث.
- أضف كتلة "رقم الإرسال اللاسلكي (X)" ، حيث يوجد ثابت الإشارة المذكور في اسم الوظيفة
هذا كل ما يحتاجه المرء للبث عبر الراديو.
الخطوة 8: نريد الاستماع إلى البيانات واستلامها عبر راديو الجهاز ومعالجتها وفقًا لذلك
هذه هي الخطوة الأخيرة لإنشاء التطبيق الرئيسي.
سنخبر الجهاز بكيفية معالجة إشارات الراديو الواردة. أولاً ، سيقوم جهازنا بتسمية الإشارة المستلمة. بعد ذلك ، بناءً على قيمة تلك الإشارة ، ستقرر الإجراء الذي يجب اتخاذه ، إن وجد.
أولا:
- قم بإنشاء كتلة من التعليمات البرمجية تبدأ بكتلة "على الراديو المستلم (X)".
- اختياريًا ، قم بتعيين تلك القيمة المستلمة إلى متغير آخر باسم وصفي أكثر.
- قم باستدعاء الوظيفة التي ستقوم بمعالجة الإشارة
ثانيًا ، في وظيفة معالجة الإشارة:
- قم بإنشاء كتلة من عبارات if-else التي تتحكم في تدفق الفرع بناءً على قيمة الإشارة.
-
إذا كانت الإشارة SIG_R
اضبط حالة الجهاز على BOOT_STATE (لهذا أنشأنا هذا الثابت سابقًا)
- إذا كانت الإشارة SIG_A وكانت الحالة الحالية LISTEN_A
اضبط حالة الجهاز على TEAM_A
-
إذا كانت الإشارة SIG_B وكانت الحالة الحالية LISTEN_B
اضبط حالة الجهاز على TEAM_B
هذا كل شيء. تم الانتهاء من التطبيق.
الخطوة 9: جهاز الجذر: نريد أن نكون قادرين على تحديد إشارة
الآن ، سنكتب تطبيقًا بسيطًا لجهاز "جذر" ، أي جهاز يتحكم في الشبكة.
سيحتاج هذا الجهاز لأداء وظيفتين:
- نريد السماح للمستخدم بتحديد إحدى إشاراتنا
- نريد السماح للمستخدم ببث الإشارة
نظرًا لأن مواصفات هذا التطبيق هي مجموعة فرعية من السابق ، سأقدم نظرة عامة ولكني لن أخوض في الكثير من التفاصيل كما فعلت من قبل. الصورة أعلاه تحتوي على الكود الكامل لهذا التطبيق.
للسماح للمستخدم بتحديد إشارة:
-
تهيئة 5 متغيرات في كتلة "عند البدء":
- الإشارات الثلاث (0 ، 1 ، 2)
- عدد الإشارات (3)
- متغير للاحتفاظ بالإشارة المحددة حاليًا (تم ضبطها مبدئيًا على الإشارة الأولى ، 0)
-
تعامل مع الضغط على الزر A:
- قم بزيادة الإشارة المحددة
-
تحقق مما إذا كانت الإشارة المحددة أكبر من أو تساوي عدد الإشارات
إذا كان الأمر كذلك ، فاضبط الإشارة المحددة على 0
- بعد حظر عند البدء ، قم بتشغيل حلقة "إلى الأبد" تعرض قيمة الإشارة المحددة الحالية بدون تأخير
للسماح للمستخدم ببث إشارة
- اضبط مجموعة الراديو على 0 في كتلة "عند البدء"
-
تعامل مع الضغط على الزر B:
بث الإشارة المحددة باستخدام كتلة "رقم الإرسال اللاسلكي (X)"
هذا كل شيء. تطبيق عقدة الجذر بسيط للغاية.
الخطوة 10: لقد انتهينا
أعلاه صورة للأجهزة التي تقوم بتشغيل التطبيق. يقوم الاثنان الموجودان على اليمين بتشغيل تطبيق "المستخدم" الرئيسي ، بينما يقوم التطبيق الموجود على اليسار بتشغيل تطبيق "الجذر".
لقد عرضت هذه اللعبة في CS Connections 2018 ، وهو مؤتمر صيفي لمدة أسبوع لمعلمي المدارس المتوسطة والثانوية حول تعليم علوم الكمبيوتر. أعطيت حوالي 40 جهازًا للمعلمين وشرحت القواعد. وجد معظمهم أن اللعبة مسلية ، ووجد الكثيرون أنها مربكة حتى اكتشفوا كيفية اللعب. كانت المظاهرة قصيرة ، لكننا وجدنا أن اللعبة ممتعة بين جمهور متنوع إلى حد ما.
يمكن العثور على مزيد من المعلومات حول CS Connections 2018 هنا.
موصى به:
بث مباشر للفيديو عالي الدقة 4G / 5G من طائرة بدون طيار DJI في زمن انتقال منخفض [3 خطوات]: 3 خطوات
بث مباشر للفيديو عالي الدقة 4G / 5G من DJI Drone في زمن انتقال منخفض [3 خطوات]: سيساعدك الدليل التالي في الحصول على دفق فيديو مباشر بجودة HD من أي طائرة بدون طيار DJI تقريبًا. بمساعدة تطبيق FlytOS Mobile App وتطبيق الويب FlytNow ، يمكنك بدء دفق الفيديو من الطائرة بدون طيار
حظر الإعلانات على مستوى الشبكة باستخدام Raspberry Pi الخاص بك: 4 خطوات
حظر الإعلانات على مستوى الشبكة باستخدام Raspberry Pi الخاص بك: تمتع بتجربة ويب أنظف وأسرع وحظر الإعلانات المزعجة في شبكتك المنزلية بالكامل باستخدام Pi-hole و Raspberry Pi
كيفية إعداد Pi-Hole على Raspberry Pi ، أداة حظر الإعلانات على مستوى الشبكة !!: 25 خطوة
كيفية إعداد Pi-Hole على Raspberry Pi ، أداة حظر الإعلانات على مستوى الشبكة !!: بالنسبة لهذا المشروع ، ستحتاج إلى: Raspberry Pi قادر على الاتصال بالإنترنت وبطاقة Micro SD تعمل على لوحة مفاتيح Raspbian LiteA (لإعداد SSH) ثانية الجهاز (للوصول إلى بوابة الويب) معرفة أساسية بـ UNIX بالإضافة إلى التنقل عبر الواجهة على
جهاز مراقبة جودة الهواء IoT منخفض التكلفة يعتمد على RaspberryPi 4: 15 خطوات (مع صور)
مراقب جودة هواء إنترنت الأشياء منخفض التكلفة استنادًا إلى RaspberryPi 4: تتمتع سانتياغو ، تشيلي خلال حالة الطوارئ البيئية الشتوية بامتياز العيش في واحدة من أجمل البلدان في العالم ، ولكن لسوء الحظ ، ليس كل الورود. تشيلي خلال فصل الشتاء تعاني كثيرًا من تلوث الهواء ، وماي
اصنع لعبة Micro Micro: bit Hovercraft معًا: 6 خطوات (بالصور)
اصنعوا Cool Micro: bit Hovercraft معًا: في معظم الأوقات ، لا يمكن للسيارات التي نصنعها إلا أن تعمل على سطح الأرض. اليوم سنقوم بإنشاء حوامة ، تعمل في الماء وعلى الأرض ، أو حتى في الهواء. نستخدم محركين لتفجير الهواء تحتها لدعم الحوامة