اثنين من الأزرار الحمراء ، لحام الحديد و React: كيف اتخذنا خطوة لمؤتمر تكنولوجيا المعلومات

Badoo تشارك بانتظام مع كشك في معارض مؤتمرات تكنولوجيا المعلومات. لذلك ، في كل عام ، نتوصل مع زملائنا - المهندسين والشياطين - إلى عمل شيء جيد حتى لا نشعر بالملل بين التقارير.


اسمي إيفان ، أنا مطور الواجهة الأمامية. في هذه المقالة ، مع زميلنا الليلي وعشاق DIY يوري ليلكوف ، سوف نخبرك كيف ، باستخدام زري أحمر وأحمر متحكم ورمز React و 250 كلمة لموضوع تكنولوجيا المعلومات ، صممنا اللعبة "لعبة تخمين تكنولوجيا المعلومات" وضمنا حفلة مريحة على Highload ++ و Heisenbug.



المحتويات:


المعارف التقليدية غير التقليدية
لعبة الميكانيكا والتهديف
حيوية
الواجهة
الأجهزة: اثنين من الأزرار الحمراء
يؤدي


المعارف التقليدية غير التقليدية


تتميز مؤتمرات تكنولوجيا المعلومات بجوها الخاص: فهناك الكثير من الأشخاص ، ليس من السهل جذب انتباههم والاحتفاظ بهم على أهبة الاستعداد. حتى يتمكنوا من القدوم إلينا بدقة في الفواصل الزمنية بين التقارير ، نحتاج أن نقدم لهم درسًا مثيرًا للاهتمام ولكنه غير معقد.


مستوحاة من نجاح الاسم المستعار لتقنية المعلومات للعام الماضي ، قمنا بصياغة المتطلبات التالية للعبة الجديدة:


  • يجب أن يكون متعدد المستخدمين. التواصل بين المشاركين هو المهمة الرئيسية. نحن نعلم أن الكثيرين يأتون بمفردهم ولا يبدأون دائمًا بمحادثة مع الغرباء بسهولة. يجب أن تعطي اللعبة فرصة للتحدث مع بعضهم البعض ومع مهندسي Badoo.
  • يجب أن تكون الجلسات قصيرة. يمكن أن يكون هناك من واحد إلى ثلاثة آلاف شخص في المؤتمر ، وأردنا الوصول إلى أكبر عدد ممكن من المشاركين.
  • يجب أن تكون اللعبة مذهلة. إذا لم يشارك شخص ما في اللعبة ، فدعه على الأقل يشاهدها. هذا الاهتمام يشعل ، ويساعد على فهم الجوهر ويقرر المشاركة.
  • إدارة أبسط. كما نعلم جميعا ، إذا كان هناك شيء ما يمكن أن ينكسر ، فسوف ينهار بالتأكيد.
  • بدون تسجيل ورسائل نصية!

بعد العصف الذهني والتفكير في الحلم ومحاولة إلهام ، توصلنا إلى "لعبة التخمين IT" - لعبة بسيطة مع الكلمات حول مواضيع تكنولوجيا المعلومات.



ما هو جوهر:


  • مشاركان يلعبان في وقت واحد.
  • تتمثل المهمة في الضغط على الزر بشكل أسرع من الخصم وتخمين الكلمة المشفرة التي تظهر على الشاشة.
  • مرحلتان: بسيطة ("اختصارات") ، حيث تتم كتابة الكلمات مرة أخرى إلى الأمام ، والصعبة ("تحريك") ، حيث يتم خلط جميع الأحرف في الكلمات.
  • إذا كانت الإجابة صحيحة ، يتم حساب نقطة واحدة للمستجيب. خطأ - النتيجة يذهب إلى الخصم.
  • يمكن لأولئك الذين سجلوا نقاط N على الأقل المشاركة في سحب سماعات إلغاء الضوضاء الرائعة.

يبدو أن كل شيء سهل وبسيط للغاية ، لكن الصعوبات كانت أمامنا.


لعبة الميكانيكا والتهديف



من هذه الصورة ، من الواضح تمامًا كيف تبدو العملية المستديرة:


  1. تظهر كلمة مشفرة.
  2. يبدأ الموقت لمدة 10 ثوانٍ.
  3. إذا ضغط أحد اللاعبين على الزر ، فسيتوقف هذا المؤقت ، ويبدأ الآخر بدلاً من ذلك - لمدة 3 ثوانٍ. خلال هذا الوقت ، يجب إعطاء اللاعب إجابة ، وإلا ستتم إضافة النتيجة إلى الخصم.
  4. إذا لم يضغط أحد على الزر ، فستتغير الكلمة تلقائيًا ، وتتكرر العملية بأكملها مرة أخرى.

المشكلة الرئيسية التي نواجهها هي كيفية الحفاظ على النتيجة وتسجيل اللاعبين. أردنا أن نجعل اللعبة في أسرع وقت ممكن وليس إجبار المشاركين على التسجيل في أي مكان. ولكن كان من الضروري فهم أي منهم سجل عددًا معينًا من النقاط ويمكنه الحصول على الجائزة الرئيسية.


لم نتوصل إلى ميكانيكا الحساب في المرة الأولى. فقط بعد العديد من الاختبارات ، أصبح من الواضح كيفية جعل اللعبة مريحة وبسيطة - للمشاركين والمضيفين.


أفكار فاشلة ورائعة


الفكرة رقم 1: نقطة واحدة = قطعة شوكولاتة صغيرة


لكل إجابة صحيحة ، قررنا في البداية إعطاء قطعة شوكولاتة واحدة. في النهاية ، يقوم المشارك بإحضار الشوكولاتة (أو على الأقل أغلفة الحلوى من "النقاط" التي يتم تناولها) ، وهذا كل شيء! نحن نعول على الجوائز ، ونحن ندرك الفائز.


ولكن هناك بعض النقاط.


أولاً: إنه غير مريح. اتضح أنه من المستحيل معتدلة اللعبة وحساب النقاط في وقت واحد ، وكان هناك حاجة لمساعد ثانٍ. هذا مكلف للغاية من حيث قوة ووقت اللاعبين في المنصة. ونظرا لسرعة اللعبة ، كان علي أن أقوم بإلقاء الشوكولاتة على المشاركين.


النقطة الثانية - كيفية التمييز بين بلدي الشوكولاتة والشوكولاتة الآخرين؟ يمكن للاعبين التعاون وتكدس الشوكولاتة أو أغلفة الحلوى منها. لذلك ، الدائرة لا تعمل! علاوة على ذلك ، فإن المؤتمرات تستغرق يومين ، ويمكنك جمع الشوكولاتة إلى ما لا نهاية.


النقطة الثالثة: تحتاج إلى الكثير من الشوكولاتة. فحصنا تجريبياً عدد النقاط التي سجلها اللاعب العادي ، وأدركنا أن عربة واحدة على الأقل تحتاج إلى الشوكولاته. وكان لدينا فقط عربة صغيرة.



الفكرة رقم 2: الترتيب


بينما يلعب البعض الآخر ، سوف يسجل آخرون أنفسهم في الترتيب. في هذه الحالة ، سنواجه جميع المشكلات المحتملة: الأسماء ، الأسماء ، أخطاء الكتابة ، الكتابة غير المقروءة (أو الحاجة إلى وضع شاشة كبيرة وجهاز كمبيوتر محمول آخر للإدخال) ، الإحجام عن ترك جهات اتصالك ، وأكثر من ذلك بكثير.


لذلك ، واصلنا البحث.


الفكرة رقم 3: علامات على شارات المشاركين


للتخلص من مشكلة تسجيل اللاعبين ، استخدمنا حلاً جاهزًا: شارات تم توزيعها على جميع المشاركين. هذا شيء لن يخسره أحد ، ولديه كل مشارك. قررنا أن نكتب لهم حسابًا مباشرًا. جاء المشارك إلى الحساب ، ونظر إلى الشارة ، وقام بحساب النقاط وحدد الفائز. ولكن كان هناك تأثير كبير في هذا المخطط: يمكن للاعبين "مزيفة" النتيجة النهائية على شاراتهم.


ثم تخلينا تمامًا عن فكرة تسجيل النتيجة. اسمح لأولئك الذين يكتسبون القيمة العشرية للنقاط أن يحصلوا على علامة خاصة في الشارة - ختم على شكل قلبنا - حيث انتقلوا إلى دائرة "المختارين". وبين هؤلاء المشاركين ، سنسحب الجوائز الرئيسية بشكل عشوائي. وسيظل الباقي يتلقون هدايا: ملصقاتنا وأجهزة الكمبيوتر المحمولة وحاملي البطاقات وصناع القرار.


بالطبع ، لم يشارك موظفو Badoo في الهبة.
بالطبع ، لم يشارك موظفو Badoo في الهبة.


المخطط كما يلي:


  1. يتم وضع علامة على الشارة مع علامة المشاركة: أسود للوصول إلى 20 نقطة أو الأرجواني فقط للعب. يمكن إجراء ثلاث محاولات في اليوم والحصول على ثلاث قلوب.
  2. يجتمع جميع الفائزين الذين يحملون علامات سوداء في وقت معين في المنصة ، وبمساعدة من اسطوانة اليانصيب الدافئة ، نلعب سماعات الرأس بينهم.


بعد اختبار اللعبة على الأشخاص الأحياء ، قمنا بحساب علامة العتبة: ليس من السهل تسجيل 20 نقطة في اللعبة. لكن في كل يوم من أيام Highload ++ ، كان حوالي 15 شخصًا هم الرابحون!


صحيح ، في قائمة الكلمات كان هناك عدد قليل من المصطلحات التي فهمها المطور في المقام الأول ، لذلك بالنسبة لمؤتمر Heisenbug QA ، اتفقنا على عتبة 15 نقطة. ربما دون جدوى: تبين أن الدور نصف النهائي كان أكثر من مرة ، مما يعني أن هناك فرصًا أقل للفوز بالسماعات.


ملاحظة: في المرحلة الأولية ، قررنا أنه مع وجود إجابة خاطئة ، سيفقد المشارك درجة الشوكولاته. لكن لا أحد يحب أن يتعرض للسرقة من شيء ما. "هذا هو شريط الشوكولاتة الخاص بي ، لقد ربحته!" - كان أول اختبار للعبة ساخطًا. لذلك ، كعقوبة ، بدأنا في إعطاء نقطة لمنافس.



حيوية


يجب أن تظهر كلمة التخمين مع نوع من الرسوم المتحركة. هذا يعطينا ميزتين:


  1. نوع من "الضرب" بين الكلمات. يسهل على اللاعبين التبديل من كلمة إلى أخرى إذا كان هناك أي إجراء بينهم. تذكر ألعاب القتال القديمة. بدأت كل جولة جديدة بـ "3..2..1..FIGHT!". لم أكن أرغب في عمل مؤقت آخر هنا - لدينا بالفعل بالجملة.
  2. متنوعة البصرية. حاولنا جعل اللعبة بسيطة قدر الإمكان ، ولم يكن لدينا خلفيات متحركة وتحولات بين المستويات. لم نتمكن أيضًا من استخدام الصوت ، حتى لا نتدخل مع المشاركين الآخرين في المؤتمر. لذلك ، كانت الرسوم المتحركة ضرورية.

معها ، ليس كل شيء سار بسلاسة على الفور. في الاختبارات التجريبية ، كان هناك لاعبون ماكرون لم ينتظروا نهاية الرسوم المتحركة ونقروا على الزر في وقت سابق. لتعليم الحيل ، بدأنا في منع ظهور الكلمة عند ضغط أحد اللاعبين قبل الأوان على زر. جزء من الكلمة التي لم يتح لها الوقت بعد للظهور ، في هذه الحالة ظلت مخفية وراء الشخصيات. سواء كان اللاعب يريد ذلك أم لا ، كان عليه أن يجيب. من الصعب تخمين كلمة بعدة أحرف ، لذلك حصل الخصم على نقطة.


إليك ما تبدو عليه الكلمة إذا نقرت على الزر في وقت مبكر:



اللحظة الصعبة الثانية هي مدة الرسوم المتحركة. استمرت دائمًا في نفس الوقت - 1.5 ثانية. إذا كنت "تلتقط الإيقاع" ، فيمكنك الحصول على تعليق الضغط على الزر بشكل أسرع من الخصم. لحل المشكلة ، أضفنا متغيرًا عشوائيًا يتراوح من 0 إلى 500 مللي ثانية. في هذه الحالة ، أصبح التكيف مع الإيقاع أكثر صعوبة.


الواجهة


سأخبركم قليلاً عن جزء البرنامج. إذا لم تكن مهتمًا ، فانتقل مباشرةً إلى قصة كيفية بحثنا عن الأزرار الحمراء .


تبين أن ميكانيكا اللعبة بسيطة للغاية ، ولم أكن أريد إعادة اختراع العجلة. استغرق create-react-app لجانب العميل. لكن التحدي ما زال مطلوبا.


حتى السنانير! ظهر Hooks في الأفق لفترة طويلة ، لكن تطبيقها في منتجات Badoo الرئيسية تطلب إعادة التفكير بشكل جدي في عملية التطوير. كان مشروع جانبي صغير نقطة انطلاق كبيرة لاستخدامها.


لا استرجاع! Redux شيء رائع ، ونحن نستخدمه في عملنا كل يوم. ولكن لمثل هذا التطبيق الصغير ، لم يكن هناك ما يبرر استخدام الإعادة. بالإضافة إلى ذلك ، هناك ربط جديد useContext .


 const { score, changeScore } = useContext(SessionContext); const { next } = useContext(QuestionsContext); const steps = useContext(StepsContext); 

نعم ، بدلاً من قصة عالمية ، حصلنا على ثلاثة سياقات لم تتقاطع على الإطلاق.


سجل SessionContext .
كان StepsContext مسؤولاً عن تبديل شاشات التطبيق: مقدمة ، حلقة ، خارجي ...
كل ما يتعلق بالأسئلة هو الذي يعرف كل الأسئلة: أي الأسئلة التي تمت الإجابة عليها ، وأي سؤال سيكون بعد ذلك ، ما هو المبلغ المتبقي.


مزود


يحتاج كل سياق إلى موفر يقوم بتسليم البيانات إلى المكونات النهائية. كمثال ، سوف نستخدم مزودًا بسيطًا للتسجيل.


 const increment = score => score + 1; const SessionProvider = props => { const [leftPlayerScore, changeLeftPlayerScore] = useState(0); const [rightPlayerScore, changeRightPlayerScore] = useState(0); const resetScore = useCallback(() => { changeLeftPlayerScore(0); changeRightPlayerScore(0); }, []); const changeScore = useCallback(player => { player === 'left' ? changeLeftPlayerScore(increment) : changeRightPlayerScore(increment); }, []); const score = { left: leftPlayerScore, right: rightPlayerScore }; return ( <SessionContext.Provider value={{ score, changeScore, resetScore }}> {props.children} </SessionContext.Provider> ); }; 

كما ترى من الكود ، فإننا نتتبع النقاط بشكل مستقل. هناك حالة منفصلة للاعبين "اليسار" و "الأيمن". بالإضافة إلى وظائف لإدارة الحساب: إعادة تعيين الحساب والتغيير.


واجهة برمجة تطبيقات الموفر الناتجة بسيطة للغاية. بشكل عام ، كان كل المنطق المرتبط بمزودي الخدمة بسيطًا جدًا ، لذلك لن نركز عليه.


توقيت


اتضح أن عنصر الجولة الرئيسية من اللعبة مثير للاهتمام: كانت هناك لحظات غامضة فيها. المكون هو نفسه بالنسبة لكلا الوضعين (عكس وخلط - "اختصارات" و "خلاطات").


من وصف الجولة ، من الواضح أن هناك الكثير من التفاعل مع الوقت.


أولاً ، هناك جهاز توقيت مسؤول عن مدة الكلمة على الشاشة: 10 ثوانٍ للضغط على زر. إذا لم يقم أحد بالضغط على الزر ، فستظهر الكلمة التالية تلقائيًا.


ثانياً ، جهاز توقيت يبدأ عندما ينقر أحد اللاعبين على زر. ثم لديه 3 ثوان لتخمين كلمة.


يبدو أنه لا يوجد شيء معقد في هذا ، لذلك نكتب رمزًا واضحًا على ما يبدو:


 const [time, nextTick] = useState(0); useEffect(() => { let id = setInterval(() => { nextTick(time + 1); }, 1000); return () => clearInterval(id); }, []); 

ولكن ، كما يمكنك أن تخمن ، هذا لم ينجح. إنه لم ينجح على الإطلاق!


وصل الموقت 1 وتوقف عند ذلك. الحقيقة هي أن القيمة time القديمة كانت "مغلقة" داخل وظيفة المعالج. لذلك ، مع كل علامة ، يشير setInterval إلى القيمة time من التجسيد الأول.


كان هناك حل لمشكلة استخدام دالة بدلاً من القيمة المباشرة:


 nextTick(currentTime => currentTime + 1); 

نعم ، بهذه الطريقة كان لدينا دائمًا قيمة "جديدة" للوقت. ولكن لم نتمكن من الحصول على props "الطازجة" ، على سبيل المثال.


من الواضح ، كان لا بد من اتباع نهج مختلف. وكان أضمن قرار لجعل وظيفة المعالج قابلة للتغيير. useRef له استخدام خاص useRef هوك لهذا useRef .


في أغلب الأحيان يتم استخدامه للعمل مع عناصر DOM ، ولكن هذا ليس التطبيق الوحيد. يمكننا "تذكر" أي متغير في الخاصية current وتحديثه مع كل تقديم.


 function callback() { setCount(count + 1); } useEffect(() => { savedCallback.current = callback; }); useEffect(() => { function tick() { savedCallback.current(); } let id = setInterval(tick, 1000); return () => clearInterval(id); }, []); 

هناك مقالة جيدة كتبها Dan Abramov حول العمل مع خطاطيف setInterval و React: جعل setInterval معبرًا عن React Hooks . لقد وصف تمامًا جميع المزالق وجميع مراحل التفكير في تنفيذ ربط useInterval ، والذي useInterval .


نظرًا لأن الكشك كان مفتوحًا طوال المؤتمر ، فقد كانت الجلسة المستمرة باستخدام اللعبة كبيرة جدًا. لم يتم تحديث الصفحة على الإطلاق (F5) ، لذلك كان من المهم للغاية مراقبة الذاكرة في مرحلة التطوير. كما تعلمون ، فإن التسريبات تسير جنبًا إلى جنب مع أجهزة ضبط الوقت ، وإذا كان كل هذا محنكًا مع إعادة تقديم رد الفعل ، فسيكون من السهل جدًا كتابة التعليمات البرمجية التي تستهلك ذاكرة كبيرة جدًا.


بدأ Countdown ، وأوقف ، وأعد ضبط ، وأعد تشغيل عشرات (أو ربما المئات) من المرات في جلسة لعب واحدة. حتى لا تهتم بالشيكات ، التي كان ينبغي أن تكون كثيرة ، استخدمنا "خدعة" بسيطة إلى حد ما - أضفنا عناصر أساسية لهذا المكون.


 <QuestionCountdown key={question.text} onComplete={nextQuestion} /> 

لن نتطرق إلى ذلك بالتفصيل ، فالوصف الشامل لعملية التوفيق بين رد الفعل لا يزال مع نفس دان أبراموف: رد الفعل باعتباره وقت تشغيل واجهة المستخدم .


الأجهزة: اثنين من الأزرار الحمراء


لذلك ، لقد استوفينا بالفعل بعض المتطلبات للعبة: لقد كانت متعددة اللاعبين وسريعة ومع ميكانيكا بسيطة. يبقى أن تضيف إلى الترفيه لها. ستلي القصة Yura Lilekov lilek - عشاقنا في صناعة DIY ، متحدث دائم في المجتمع ، منشئ الجناح الطائر وأجهزة أخرى تعمل بنفسك.


أردنا حقًا العثور على اثنين من الأزرار الميكانيكية الكبيرة. وللتأكد من الأحمر - كما في تلك الميم مع Agutin.


لسوء الحظ ، كان كل ما تم العثور عليه في المتاجر عبر الإنترنت إما صغير جدًا (قطره 5 سم) أو لم يكن هناك أزرار على الإطلاق. بالطبع ، كان هناك AliExpress قديم جيد ، ولكن لم يكن هناك وقت لانتظار التسليم.


نتيجة لذلك ، وجدنا الأزرار الصحيحة على موقع وكالة الإبداعية. أزرار في مكان ما في الضواحي فعل ألكساندر (على ما يبدو ، خريج كلية راديو الإلكترونيات). اتصلنا هاتفياً ، وسألنا عن المتحكم الدقيق الذي تم حياكته في الصندوق ، وطلب منا ترك الوصول إليه ، لأننا نحتاج إلى إعادة برمجته.


ألكساندر ، بعبارة ملطفة ، فوجئ بمثل هذه الأسئلة. عندما سألنا عما إذا كانت الأزرار ستقاوم ضغوط المبرمجين المتحمسين ، أكد لنا أن هذه الأزرار موجودة في ماكينات القمار في "الكونية" والتعامل مع تدفق الأطفال بشكل مثالي. واستشرافًا للمستقبل ، سأقول أن المهندسين المسخنين احتفظوا بالأزرار أيضًا (يجب تغيير البطارية فقط مرة واحدة).



تعبئة


لكن لسوء الحظ ، لم يكن للجهاز النهائي كل الصفات التي نحتاجها. وإذا كان لا يزال بإمكانك التخلص من المؤثرات الصوتية عن طريق قطع السلك على السماعة ، فإن تحديد الزر الذي تم الضغط عليه تلقائيًا لم يكن بالأمر السهل. اقترح خيارًا بسيطًا: توصيل هذا الجهاز بطريقة ما بالكمبيوتر وترجمة مكابس هذه الأزرار إلى ضغطات المفاتيح على لوحة المفاتيح.


الحل دون استخدام أي زخرفة - لأخذ لوحة مفاتيح USB القديمة وجلب بضعة أزرار بأسلاك إضافية من لوحة المفاتيح إلى الجهاز - تم رفضه على الفور باعتباره "مزرعة جماعية". وتوصيل قوة DIY.


بعد بعض المداولات ، قررنا استخدام لوحة Arduino Pro Micro استنادًا إلى متحكم ATmega32u4 لعائلة AVmel من Atmel مع الربط الضروري. في هذا المنتدى ، من بين أشياء أخرى ، يتم فصل منافذ الإدخال / الإخراج و MicroUSB. والأهم من ذلك - أن متحكم ATmega32u4 يمكن أن يعمل كجهاز HID ، أي في حالتنا ، محاكاة ضربات المفاتيح في ظل ظروف معينة.


(تم التقاط الصورة من أحد البائعين من بيت.كوم


لبرمجة وحدة التحكم هذه ، تحتاج فقط إلى سلك سلك microUSB المعتاد وبيئة تطوير Arduino IDE.


بعد تثبيت بيئة التطوير ، ستكون أبسط أمثلة التعليمات البرمجية متاحة على الفور.


على سبيل المثال ، يوجد برنامج يحاكي الكتابة على لوحة المفاتيح عند الضغط على زر (متصل بمنفذ إدخال / إخراج) هنا:


ملف-> أمثلة-> USB-> لوحة المفاتيح-> KeyboardMessage


يتحقق محاكاة ضغطات المفاتيح ببساطة شديدة:


 #include "Keyboard.h" //      void setup() { Keyboard.begin(); //   } void loop() { Keyboard.print("Test"); //   4  delay(1000); //   1  } 

قراءة حالة منفذ الإدخال هي أيضًا بلا زخرفة:


 int button_pin = 7; //  ,     void setup() { pinMode(button_pin, INPUT); //     } void loop() { if (digitalRead(button_pin)) { //   } else { //    } } 

نظرًا لأن المنفذ يتم فتحه بواسطة الجهد ، وليس بالتيار ، فإن أصغر التيارات المستحثة في الأسلاك التي تنتقل من الزر إلى المنفذ يمكن أن تعطي إيجابيات خاطئة. لذلك ، نوصي "بسحب" منافذ الإدخال بمقاومات عالية المقاومة: يتدفق التيار المستحث على الفور من خلاله إلى "الأرض" ، ويمنع حدوث فرق الجهد العالي بين المدخلات و "الأرض" ، وبالتالي ، لن يكون هناك أي سبب خاطئ. لهذه الأغراض ، يكون المقاوم 5-10 kΩ كافيًا ، وهو مرتبط بين مدخلات المتحكم الدقيق و "الأرض".


وبالتالي ، نحصل على المخطط التالي:



تتصل لوحة Arduino Pro Micro عبر microUSB بجهاز كمبيوتر محمول مع جزء البرنامج من اللعبة ، ويتصل زريان بمدخلين من اللوحة وإمدادات الطاقة العامة. أيضا ، يتم سحب هذه المدخلات اثنين على الأرض من قبل اثنين من المقاومات.


عند الضغط على أحد الأزرار ، ينتقل التيار من خرج وحدة تزويد الطاقة من خلال الزر إلى الإدخال المقابل للوحة - وبالتالي سنرى "وحدة" منطقية عند الإدخال.


في جزء البرنامج ، قررنا محاكاة ضغطات المفاتيح "السهم الأيسر" و "السهم الأيمن" ، وأيضًا تأخير 4 ثوانٍ بعد تحديد الضغط ، من أجل تجنب النقرات المتكررة من قبل المشاركين أو ثرثرة جهات الاتصال في الأزرار.


 #include <Keyboard.h> char leftKey = KEY_LEFT_ARROW; char rightKey = KEY_RIGHT_ARROW; int btn1pin = 7; int btn1value = 0; int btn2pin = 8; int btn2value = 0; void setup() { pinMode(btn1pin, INPUT); pinMode(btn2pin, INPUT); Keyboard.begin(); } void loop() { btn1value = digitalRead(btn1pin); btn2value = digitalRead(btn2pin); if (btn1value == 1 && btn2value == 1) { //    =    } else if (btn1value == 0 && btn2value == 0) { //    =    } else if (btn1value == 1) { //    =       4  Keyboard.press(leftKey); delay(100); Keyboard.releaseAll(); delay(4000); } else if (btn2value == 1) { //    =       4  Keyboard.press(rightKey); delay(100); Keyboard.releaseAll(); delay(4000); } } 

لذلك بمساعدة الأجهزة البسيطة ، قمنا بتدريس الأزرار لتحديد اللاعب الذي ينقر عليها أسرع من الخصم ، ولإشارة هذا إلى مقدم العرض.


إدارة


يدوي بالكامل وبسيط قدر الإمكان:


  • الفضاء - الكلمة التالية
  • أدخل - إظهار الكلمة الصحيحة
  • + - صواب (نقطة واحدة)
  • 0 - غير صحيح (أشر إلى الخصم)
  • التحول الأيسر - الخطوة التالية
  • التحول الصحيح - الخطوة السابقة

يؤدي


لعبت جميع المؤتمرات الأربعة أيام (اثنان على Highload ++ ، واثنان على Heisenbug) على منصة Badoo "لعبة التخمين IT" بشكل مستمر. كل آمالنا تحققت:


  • جذبت اللعبة كل من المشاركين والمتفرجين: مجموعة كاملة من الناس تجمعوا في المنصة. من الجيد بشكل خاص أن عدد المشاركين في اليوم الثاني من المؤتمرات لم يتناقص.
  • الأزرار هي الأعلى! أضف +100 إلى الإثارة. حتى لو كان المنافسان غرباء على بعضهما البعض ، تسببت اللعبة في الكثير من المشاعر.
  • عملت الفكرة التي تحمل علامات على الشارة: لا توجد صعوبة في العثور على الفائزين وجمع جهات الاتصال. طلب شخصان ترك شارتهم نظيفة ، لذلك وضعنا علامات على معصميننا (تم محوها بسهولة).
  • سلمنا 14 زوجًا من سماعات الرأس وعدة مئات من الجوائز الصغيرة. لم يبق أحد من دون هدية!


للمشاركة في اللعبة في المؤتمر ، قدمنا ​​مجموعة رائعة

صناع القرار على المغناطيس. لا أعرف ما يجب القيام به مع المهمة - تدور القرص السحري! لدينا فقط بضع صور متبقية ، حيث قمنا بتوزيع كل شيء:



لمهندسي ضمان الجودة



للمطورين


ملفات تعريف الارتباط التنبؤية
اخترعت التنبؤات نفسها (52 خيارات). تحقق مع احتمال يصل إلى 100٪.



Source: https://habr.com/ru/post/ar482028/


All Articles