جدول المحتويات:

اردوينو - بلاط البيانو: 16 خطوة (بالصور)
اردوينو - بلاط البيانو: 16 خطوة (بالصور)

فيديو: اردوينو - بلاط البيانو: 16 خطوة (بالصور)

فيديو: اردوينو - بلاط البيانو: 16 خطوة (بالصور)
فيديو: لوحة إنارة درج سلم بيانو تشطيب خطوة بخطوة للمبتدئين 2024, يوليو
Anonim
اردوينو - بلاط البيانو
اردوينو - بلاط البيانو

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

للبدء ، ستحتاج إلى جميع الأجزاء ، وهي كالتالي! 1x Arduino Uno r3 (42 دولارًا)

2x LCD Keypad Shield (19 دولارًا لكل منهما)

أزرار 5x

مقاومات 5x 220Ω

28x الأسلاك

حسنًا ، بمجرد حصولك على جميع الأجزاء ، حان الوقت للبدء!

الخطوة 1: الأسلاك

الأسلاك
الأسلاك
الأسلاك
الأسلاك
الأسلاك
الأسلاك

ابدأ بتوصيل أسلاك اردوينو وأصدقائك كما هو موضح في الرسم التخطيطي ،

تأكد من ربط الأزرار بالطريقة الصحيحة ، مع وجود فتحات A0-4 على الجانب الأرضي من قضبان الأزرار ، أو سيعتقد اردوينو بدلاً من ذلك أن الأزرار يتم الضغط عليها باستمرار بدلاً من الضغط فقط.

الخطوة الثانية: بيانات الإقرار

يجب أن تذهب جميع التعليمات البرمجية هنا قبل الإعداد الباطل والحلقة الفارغة ، وذلك لأن كل هذه المتغيرات والكائنات تُستخدم في العديد من الوظائف التي سنقوم بإعدادها.

ابدأ بوضع:

#يشمل

في الجزء العلوي من التعليمات البرمجية ، هذا هو إخبار اردوينو باستخدام مكتبة "LiquidCrystal.h" والوظائف التي تشكل جزءًا منها.

الخطوة التالية هي تحديد الدبابيس التي نستخدمها لأزرارنا عن طريق وضع هذا الرمز أسفل # تضمين:

# تعريف btnEnter A0 # تعريف btn1 15 # تعريف btn2 16 # تعريف btn3 17 # تعريف btn4 18

نحدد المصطلحين btnEnter و btn1 إلى btn 4 لتسهيل قراءة الكود أو تغييره إذا لزم الأمر. هذا يعني أنه عندما نكتب btn1 ، فإن اردوينو سيعرف أننا في الواقع نعني الزر 15. على الرغم من أننا نطلق على المنافذ 15 و 16 و 17 و 18 ، فقد تم تصنيفها على arduino كـ A1 A2 A3 و A4 ، وذلك لأن إنها منافذ تستخدم خصيصًا للمدخلات التناظرية ، على الرغم من أننا نستخدمها فقط للمدخلات الرقمية.

بعد ذلك ، سنقوم بإنشاء الكائنات التي ستتحكم في شاشات الكريستال السائل. للقيام بذلك ضع هذا الرمز أسفل تعريفاتنا

LiquidCrystal lcdLeft (8 ، 9 ، 12 ، 10 ، 11 ، 13) ؛ LiquidCrystal lcdRight (2 ، 3 ، 4 ، 5 ، 6 ، 7) ؛

ما يفعله هذا هو إخبار اردوينو أنه عندما نسمي lcdLeft أو lcdRight فإننا نشير إلى كائن LiquidCrystal. تخبر الأرقام الموجودة في الأقواس المرفقة اردوينو عن المنافذ التي يجب أن يستخدمها الكائن لإرسال رسائل إلى شاشة LCD عندما نستخدم وظائفها.

نحتاج الآن إلى إعلان المتغيرات عن طريق وضع الجزء التالي من الكود أسفل تعريفات الكائن:

// هذه المتغيرات هي خيارات يمكنك تغييرها - أرقام أعلى = تسريع أسرع للعبة intGameSpeedEasy = 10 ؛ int intGameSpeedMedium = 25 ؛ int intGameSpeedHard = 80 ؛

// إعداد المتغيرات لـ gameboolean bolPlay ؛ // يتتبع إذا كان اللاعب intScore ؛ // يتتبع درجة اللاعب intDiff ؛ // مجرد شيء تقريبي لمعرفة مدى صعوبة اللعبة // إعداد متغيرات لمدخلات intEnter ؛ // يتتبع إذا ضغط المستخدم على زر الإدخال intInput ؛ // يتتبع الأزرار التي يضغط عليها المستخدم BolTilePressed ؛ // تأكد من أن اللاعب لا يضغط بطريق الخطأ على الزر 5x ويفقد // إعداد المتغيرات لـ turn intTick ؛ // يحسب ما يصل إلى ملي (لكل حلقة) حتى intDelay int intDelay ؛ // وقت انتظار البرنامج حتى المنعطف التالي بالمللي intGameSpeed ؛ // abit of debug options boolean bolSerialBoard؛ // عندما تكون صحيحة ستطبع اللوحة في الشاشة التسلسلية

نعلن عن متغير من خلال ذكر نوع البيانات ثم اسم المتغير ، على سبيل المثال. int thisIsAnInteger

يمكن أن تحتوي المتغيرات المنطقية ، مثل bolSerialBoard و bolPlay على قيمة واحدة فقط من قيمتين ، صواب أو خطأ.

يمكن أن يأخذ المتغير الصحيح (int) مثل intScore و intInput الأعداد الصحيحة كقيم ، مثل 1 أو 5 أو 100.

بعض أنواع البيانات البارزة الأخرى التي لا نستخدمها هنا هي سلسلة ، وهي جزء من النص ، وقيمة عائمة ، وهي رقم عشري.

يتم استخدام كل متغير من المتغيرات هنا في عدة أماكن مختلفة بواسطة البرنامج ، وهنا ملخص لما يفعله كل متغير

يخبر bolPlay البرنامج ما إذا كان يجب عرض القائمة أو إذا كان يجب تشغيل اللعبة الفعلية.

يتتبع intScore نتيجة اللاعب عندما يضرب المربعات ،

يتم استخدام intDiff في القائمة الرئيسية لإخبار البرنامج عن جزء النص المطلوب طباعته على شاشات LCD ،

يستخدم intEnter لإخبار البرنامج إذا تم الضغط على زر الإدخال (أقصى اليسار) ،

يستخدم intInput لإخبار البرنامج بالضغط على الأزرار الأربعة الأخرى.

يستخدم bolTilePressed للتأكد من أن البرنامج لا يقرأ إلا عند الضغط على الزر وليس عند الضغط عليه.

يتم استخدام intGameSpeed و intGameSpeedEasy و intGameSpeedMedium و intGameSpeedHard للتحكم في السرعة التي يجب أن تسرع بها اللعبة بناءً على الصعوبة التي يتم تحديدها.

يتم استخدام intTick و intDelay لإيقاف البرنامج عن تحريك اللوحة في كل مرة يتكرر فيها.

يتم استخدام bolSerialBoard للسماح لك بجعل البرنامج يرسل اللوحة إلى شاشة اردوينو التسلسلية كسلسلة من الأرقام لأغراض الاختبار.

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

// إعداد لعبة مصفوفة arrGame [16] [4] = {{0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0 ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0 ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0}} ؛

المصفوفة هي مصفوفة يمكن استدعاء أي نقطة عليها للرياضيات أو تغييرها.

يجب أن تبدو التعليمات البرمجية الخاصة بك الآن مثل هذا ؛

// include libraries # include

// هذه المتغيرات هي خيارات يمكنك تغييرها - أرقام أعلى = تسريع اللعبة بشكل أسرع

int intGameSpeedEasy = 10 ؛ int intGameSpeedMedium = 25 ؛ int intGameSpeedHard = 80 ؛

// تحديد دبابيس

# تعريف btnEnter A0 # تعريف btn1 15 # تعريف btn2 16 # تعريف btn3 17 # تعريف btn4 18

// إنشاء كائنات LCD (n ، ~ ، n ، ~ ، ~ ، n)

LiquidCrystal lcdLeft (8 ، 9 ، 12 ، 10 ، 11 ، 13) ؛ LiquidCrystal LCDRight (2 ، 3 ، 4 ، 5 ، 6 ، 7) ؛

// إعداد مجموعة ألعاب

int arrGame [16] [4] = {{0، 0، 0، 0}، {0، 0، 0، 0}، {0، 0، 0، 0}، {0، 0، 0، 0}، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0 ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0 ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0}} ؛

// إعداد المتغيرات للعبة

بولبلاي منطقي. // يتتبع إذا كان اللاعب intScore ؛ // يتتبع درجة اللاعب intDiff ؛ // مجرد شيء جمالي لمعرفة مدى صعوبة اللعبة

// إعداد المتغيرات للإدخال

intEnter int // يتتبع إذا ضغط المستخدم على زر الإدخال intInput ؛ // يتتبع الأزرار التي يضغط عليها المستخدم BolTilePressed ؛ // تأكد من أن اللاعب لا يضغط بطريق الخطأ على الزر 5x ويخسر

// إعداد المتغيرات للدوران

intTick intTick // يحسب ما يصل إلى ملي (لكل حلقة) حتى intDelay int intDelay ؛ // وقت انتظار البرنامج حتى المنعطف التالي بالمللي intGameSpeed ؛

// القليل من خيارات التصحيح

bolSerialBoard منطقية. // عندما تكون صحيحة ستطبع اللوحة في الشاشة التسلسلية

الخطوة 3: وظيفة الإعداد

حلقة الإعداد هي وظيفة يقرأها اردوينو مرة واحدة فقط عند بدء تشغيلها في البداية.

في حلقة الإعداد ، نقوم فقط بتعيين قيم عدد قليل من متغيراتنا لأنه بدلاً من تعيينها قيمة عند التصريح عنها ، فإننا نقوم بذلك هنا.

ابدأ بوضع هذا الرمز في إعداد الفراغ الخاص بك.

bolPlay = خطأ ؛ intScore = 0 ؛ intTick = 0 ؛ intDelay = 1000 ؛ intDiff = 1 ؛ intGameSpeed = intGameSpeedMedium ،

كل سطر يقوم فقط بتعيين متغير إلى قيمة.

تم ضبط bolPlay على false حتى لا تبدأ اللعبة باللعب.

تم تعيين intScore على 0 ، لأنه من الطبيعي أن نتيجتك تبدأ من 0.

يبدأ intTick عند 0 لأن البرنامج لا يحسب أي شيء حاليًا.

تم تعيين intDelay على 1000 لأن هذا هو المعدل الذي يبدأ به البلاط.

intDiff هو مجرد شيء زاهد بحيث يعرف البرنامج ما يكتب لصعوبة اللعبة.

تم تعيين intGameSpeed على أي قيمة intGameSpeedMedium ، مما يعني أنه تم ضبطه على مستوى الصعوبة المتوسط.

بعد ذلك ، ضع هذا الرمز في Void Setup أسفل الكود الذي أدخلته للتو.

lcdLeft.begin (16 ، 2) ؛ lcdRight.begin (16 ، 2) ؛

Serial.begin (9600) ؛

يخبر هذا اردوينو ببدء الاتصال بالكمبيوتر من خلال الشاشة التسلسلية (مرئية بالنقر فوق الزر الموجود في الجزء العلوي الأيمن من اردوينو IDE).

يجب أن يبدو إعداد الفراغ الخاص بك الآن شيئًا كهذا!

إعداد باطل () {Serial.begin (9600) ؛ // بدء العرض التسلسلي // إعداد المتغيرات bolPlay = false ؛ intScore = 0 ؛ intTick = 0 ؛ intDelay = 1000 ؛ intDiff = 1 ؛ intGameSpeed = intGameSpeedMedium ، // start lcd's lcdLeft.begin (16، 2) ؛ lcdRight.begin (16 ، 2) ؛ }

الخطوة 4: وظيفة الحلقة

يتم تشغيل وظيفة الحلقة بواسطة اردوينو كل تكرار لاردوينو.

انسخ الكود التالي إلى Void Loop الخاص بك.

حلقة باطلة () {إدخال () ؛ // تحقق من تشغيل الإدخال إذا (bolPlay == true) {if (intTick> = intDelay) {// تحقق لمعرفة ما إذا كان يجب أن تلعب اللعبة دورًا أو تستمر في انتظار Serial.println ("~~~~~~~ ~~ ") ؛ // طباعة للدلالة على أن اللوحة تتحرك على // writeSerial () ؛ // إذا تم تمكين الخيار ، فاكتب اللوحة في أزرار تسلسليةGame () ؛ // تحقق من مدخلات اللاعب playBoard () ؛ // حرك اللوحة وأضف بلاطة جديدة clearLcd () ؛ // قم بتنظيف شاشات LCD قبل رسم drawBoard () ؛ // ارسم اللوحة على قاع شاشة LCDCheck () ؛ intTick = 0 ؛ // reset intTick} else {keysGame () ؛ // تحقق من مدخلات المشغل clearLcd () ؛ // قم بتنظيف شاشات LCD قبل رسم drawBoard () ؛ // ارسم اللوحة على intTick في شاشة LCD = intTick + intGameSpeed ؛ // add to tick}} else {clearLcd ()؛ // تنظيف شاشات الكريستال السائل قبل رسم العنوان () ؛ // عرض أزرار معلومات العنوان والنتيجة // قراءة مدخلات اللاعب clearBoard () ؛ // ضمان المجلس بالكامل = 0} تأخير (10) ؛ // تأخير اردوينو لحظة قصيرة}

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

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

يقرأ الإدخال الأزرار التي ضغط عليها المستخدم.

الأزرار تتحكم اللعبة في ما تفعله الأزرار عندما تكون في اللعبة ، وليس في القائمة

يضيف playBoard بلاطة جديدة إلى اللوحة ، ثم ينقل كل شيء في اللوحة لأسفل مسافة واحدة

يقوم clearLCD بتنظيف شاشات LCD للتأكد من عدم ترك أي أشباح خلف البلاط

يمر drawBoard عبر arrGame ويطبعها على شاشات LCD

تقوم clearBoard بمسح لعبة arrGame بالكامل عندما لا تكون اللعبة قيد التشغيل

bottomCheck يتحقق من الجزء السفلي من لعبة arrGame لحالة الفشل

يعرض العنوان عنوان اللعبة ومعلومات النتيجة عندما تكون على القائمة

تتحكم قائمة الأزرار في ما تفعله إدخالات المستخدم عندما تكون في القائمة.

gameOver هي وظيفة أخرى ، على الرغم من عدم تسميتها هنا حيث يتم استدعاؤها بدلاً من ذلك في الجزء السفلي من وظائف check و buttonGame.

الخطوة 5: وظيفة ClearLCD

لإنشاء دالة نبدأ بإضافة هذا إلى الكود

دالة باطلة اسم () {

}

يمكن أن تكون "functionName" أي شيء ، طالما أنها غير موجودة بالفعل.

انسخ هذا الرمز إلى برنامجك:

void clearLcd () {for (int i = 0؛ i <= 15؛ i ++) {for (int ii = 0؛ ii <= 1؛ ii ++) {lcdLeft.setCursor (i، ii)؛ lcdLeft.write ("") ؛ lcdRight.setCursor (i، ii) ؛ lcdRight.write ("") ؛ }}}

هذا يمر عبر المصفوفة بأكملها باستخدام حلقتين معدودتين لتصفح كل نقطة على شاشات LCD وكتابة مسافة.

بدون إعادة التعيين إلى أي شيء ، ستحافظ شاشات LCD على ما تمت كتابته مسبقًا

الخطوة 6: وظيفة DrawBoard

انسخ هذا الرمز في برنامجك

void drawBoard () {for (int i = 1؛ i <= 15؛ i ++) {// ارسم collums 1 و 2 على شاشة LCD اليسرى // إذا كانت اللوحة = 0 اكتب شيئًا ، = 1 اكتب "#" ، = 2 اكتب "@" lcdLeft.setCursor (i، 1) ؛ // ضبط على العمود الأول (أقصى اليسار) إذا (arrGame [0] == 1) {lcdLeft.write ("#")؛} إذا (arrGame [0] == 2) {lcdLeft.write ("@")؛} lcdLeft.setCursor (i، 0)؛ // ضبط على العمود الثاني (يسار الوسط) إذا (arrGame [1] == 1) {lcdLeft.write ("#")؛} إذا (arrGame [1] == 2) {lcdLeft.write ("@")؛} lcdRight.setCursor (i، 1)؛ // ضبط على العمود الثالث (يمين الوسط) إذا (arrGame [2] == 1) {lcdRight.write ("#")؛} if (arrGame [2] == 2) {lcdRight.write ("@")؛} lcdRight.setCursor (i، 0)؛ // ضبط على العمود الرابع (أقصى اليمين) إذا (arrGame [3] == 1) {lcdRight.write ("#")؛} if (arrGame [3] == 2) {lcdRight.اكتب("@")؛} } }

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

الخطوة 7: وظيفة PlayBoard

انسخ هذا الرمز في برنامجك.

void playBoard () {for (int i = 0؛ i <= 3؛ i ++) {arrGame [0] = 0؛} // مسح الصف العلوي arrGame [0] [عشوائي (0، 4)] = 1 ؛ // عيّن نقطة عشوائية في الصف العلوي لتكون بلاطة لـ (int i = 15 ؛ i> = 1 ؛ i -) {// العمل من أسفل اللوحة إلى الأعلى لـ (int ii = 0 ؛ ii <= 3؛ ii ++) {// لكل مجموعة arrGame [ii] = arrGame [i - 1] [ii] ؛ }}}

يبدأ هذا الرمز بمسح الصف العلوي بالكامل إلى 0 ، أو بدون مربع ، ثم يقوم بتعيين مربع عشوائي واحد ليكون 1 ، وغير مضروب.

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

الخطوة 8: وظيفة ClearBoard

انسخ هذا الرمز في برنامجك.

void clearBoard () {// إعادة تعيين قيم التجزئة والتأخير intTick = 0 ؛ intDelay = 1000 ؛ // انتقل إلى اللوحة وقم بتعيين كل شيء على 0 من أجل (int i = 0؛ i <= 15؛ i ++) {for (int ii = 0؛ ii <= 3؛ ii ++) {arrGame [ii] = 0 ؛ }}}

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

يقوم الكود أيضًا بإعادة تعيين قيم intDelay و intTick.

الخطوة 9: وظيفة العنوان

انسخ الكود التالي إلى برنامجك

عنوان باطل () {// اكتب العنوان على شاشة LCD ومساحة للنقاط lcdRight.setCursor (0 ، 0) ؛ lcdRight.write ("Piano Tiles") ؛ lcdRight.setCursor (0 ، 1) ؛ lcdRight.write ("الدرجة:") ؛ // تحويل النتيجة إلى سلسلة أحرف strScore [3] ؛ sprintf (strScore، "٪ d"، intScore) ؛ // عرض النتيجة على شاشة LCD LCDRight.write (strScore) ؛ // إضافة الأمر lcdRight.setCursor (10، 1) diffictuly؛ إذا (intDiff == 0) {lcdRight.write ("سهل") ؛ } if (intDiff == 1) {lcdRight.write ("Medium")؛ } if (intDiff == 2) {lcdRight.write ("Hard") ؛ } // اضغط قليلاً من التعليمات lcdLeft.setCursor (0، 0) ؛ lcdLeft.write ("اضغط Enter") ؛ lcdLeft.setCursor (0 ، 1) ؛ lcdLeft.write ("لتبدأ!") ؛ }

يكتب هذا الرمز عنوان اللعبة والنتيجة على شاشات LCD ، ويقوم بذلك عن طريق إخبار شاشة LCD بمكان بدء الكتابة باستخدام LCD.setCursor ثم كتابة السلسلة في LCD.write.

يتم أيضًا إنشاء متغير جديد هنا ، strScore ، يتم استخدامه لتحويل intScore إلى سلسلة أو نوع بيانات char باستخدام وظيفة sprintf.

يتم استخدام intDiff أيضًا هنا ، بناءً على قيمه ، فإنه يطبع خيارات الصعوبة المختلفة.

الخطوة 10: وظيفة قائمة الأزرار

أدخل الكود التالي في برنامجك

أزرار باطلةMenu () {// عند الضغط على مفتاح الإدخال ، ابدأ اللعبة وأعد ضبط قيمة النتيجة إذا (intEnter == 1) {bolPlay = true ؛ intScore = 0 ؛ لعب المجلس()؛ drawBoard () ؛ } // عند الضغط على الزر 3 ، قم بتشغيل خيار التصحيح لطباعة اللوحة بالتسلسل if (intInput == 3) {if (bolSerialBoard == false) {Serial.println ("Serial Board Active") ؛ bolSerialBoard = صحيح ؛ } else {Serial.println ("Serial Board Disabled")؛ bolSerialBoard = خطأ ؛ }} // اضبط سرعة اللعبة على صعوبة سهلة إذا (intInput == 0) {Serial.print ("Game set to easy (")؛ Serial.print (intGameSpeedEasy)؛ Serial.println ("تسريع مللي ثانية)") ؛ intDiff = 0 ؛ intGameSpeed = intGameSpeedEasy ، } // اضبط سرعة اللعبة على مستوى صعوبة متوسطة إذا (intInput == 1) {Serial.print ("تعيين اللعبة إلى متوسط (") ؛ Serial.print (intGameSpeedMedium) ؛ Serial.println ("تسريع مللي ثانية)") ؛ intDiff = 1 ؛ intGameSpeed = intGameSpeedMedium ، } // اضبط سرعة اللعبة على الصعوبة الصعبة إذا (intInput == 2) {Serial.print ("ضبط اللعبة على الثابت (") ؛ Serial.print (intGameSpeedHard) ؛ Serial.println ("تسريع مللي ثانية)") ؛ intDiff = 2 ؛ intGameSpeed = intGameSpeedHard ، }}

يتم تشغيل هذا الكود فقط عندما تكون bolPlay مساوية للخطأ في الحلقة الفارغة

إذا تم ضبط intEnter على 1 ، فهذا يعني أنه تم الضغط على زر الإدخال ، وإذا تم الضغط عليه ، فسيقوم البرنامج بضبط bolPlay على true وتبدأ اللعبة.

ثم يقرأ البرنامج ما يساوي intInput. إذا كانت تساوي 0 ، فسيتم الضغط على الزر الأول من اليسار ، صعودًا إلى اليمين حتى 3. إذا كانت intInput تساوي 4 ، فلن يتم الضغط على أي زر.

إذا تم الضغط على الأزرار 0-2 ، فستغير اللعبة مستوى الصعوبة ، وتضبط أيضًا قيمة سرعة اللعبة ، مما يعني أنها ستسارع بشكل أسرع.

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

الخطوة 11: وظيفة ButtonsGame

انسخ الكود التالي إلى برنامجك

أزرار باطلة لعبة () {if (intInput! = 4) {// إذا تم الضغط على زر إذا (bolTilePressed == false) {// فقط إذا كان bolTilePressed إجراء زناد خاطئ لفحص الزر ، فاضغط على bolTilePressed = true ؛ // ثم اضبط bolTilePressed على true للتأكد من أنه لم يتم تشغيله بشكل مفاجئ مرة أخرى int intLowestTile = 0 ؛ // ليتم ضبطها على البلاط الذي يحتوي على أقل تجانب intCheckedTile = 15 ؛ // لتتبع المربعات التي تم فحصها أثناء (intLowestTile == 0) {// طالما لم يتم تعيينها على أي شيء تحقق من المربعات لـ (int i = 0 ؛ i 100) {// طالما int التأخير ليس أقل من 100 intDelay = intDelay - 20 ؛ // أخذ قيمة منه}} else {Serial.println ("تم الضغط على الزر الخطأ") ؛ انتهت اللعبة()؛ // انتهت اللعبة بخلاف ذلك}}}}}

يتم تشغيل الكود فقط عندما يكون bolPlay مساويًا لـ true في الفراغ Loop.

مثل الأزرار القائمة على أساس قيمة intInput تتحقق لمعرفة ما إذا كان اللاعب قد اصطدم بلوح أو فقده.

يقوم بذلك عن طريق الانتقال من خلال لعبة arrGame من الأسفل إلى الأعلى باستخدام حلقة while للبحث عن أي صف هو الأدنى مع بلاطة غير مضطربة. ثم يتحقق لمعرفة ما إذا كانت البقعة في هذا الصف المقابل للزر الذي تم الضغط عليه عبارة عن بلاطة غير مضرة أم لا ، إذا لم يتم ضربها ، فستضبطها على مساوية 2 بدلاً من 1 ، مما يعني أنها ستظهر على أنها @ ، وإلا فإنها ستطلق اللعبة الوظيفة التي لم نخلقها بعد.

تستخدم هذه الوظيفة أيضًا متغير bolTilePressed عن طريق ضبطه على "true" عند الضغط على الزر والخطأ عند عدم الضغط على أي زر. هذا لضمان عدم فقد المستخدم للعبة عن طريق الخطأ لأن البرنامج اعتقد أنه ضغط على الزر عدة مرات عند الضغط عليه.

الخطوة 12: وظيفة GameOver

انسخ الكود التالي إلى برنامجك

void gameOver () {Serial.println ("انتهت اللعبة!") ؛ Serial.print ("كانت نتيجتك:") ؛ Serial.println (intScore) ؛ Serial.print ("سرعتك كانت:") ؛ Serial.println (intDelay) ؛ bolPlay = خطأ ؛ }

يتم تشغيل هذا إما من خلال وظائف checkBottom أو الأزرار

يقوم أيضًا بطباعة رسالة في الشاشة التسلسلية لتسجيل المستخدمين وتم إضافة مربعات السرعة بالمللي ثانية.

الخطوة 13: وظيفة الإدخال

انسخ الكود التالي إلى برنامجك.

إدخال باطل () {intEnter = digitalRead (btnEnter) ؛ // read enter // اقرأ أيًا من المدخلات الأخرى ، أو إذا لم يتم تعيين أي من المدخلات الأخرى على 4 if (digitalRead (btn1) == HIGH) {intInput = 0 ؛} else {if (digitalRead (btn2) == HIGH) {intInput = 1؛} else {if (digitalRead (btn3) == HIGH) {intInput = 2؛} else {if (digitalRead (btn4) == HIGH) {intInput = 3؛} else {intInput = 4 ؛ }}}} // serial print the inputs if (intEnter == 1) {Serial.println ("Enter Pressed!")؛} if (intInput! = 4) {Serial.print ("Button Press:")؛ Serial.println (intInput) ؛ } else {// إذا لم يتم الضغط على زر إعادة تعيين bolTilePressed bolTilePressed = false؛ }}

يستخدم هذا الرمز مع الأزرار اللعبة والأزرار وظائف القائمة. استنادًا إلى الأزرار التي ضغط عليها المستخدم ، فإنه يحدد قيمة intInput ، أو إذا لم يتم الضغط على أي زر ، فإنه يضبط intInput على يساوي 4.

إذا لم يتم الضغط على أي زر ، فهذا هو المكان الذي يتم فيه إعادة ضبط bolTilePressed لوظيفة الأزرار Game.

يقوم أيضًا بطباعة رسالة إلى الشاشة التسلسلية التي يتم الضغط على الزر عليها.

الخطوة 14: وظيفة BottomCheck

انسخ الكود التالي إلى برنامجك.

void bottomCheck () {for (int i = 0؛ i <= 3؛ i ++) {// للأعمدة الأربعة إذا (arrGame [15] == 1) {// إذا كانت القطعة في الجزء السفلي من المسلسل.println ("تجانب في الأسفل") ؛ arrGame [15] = 2 ؛ drawBoard () ؛ تأخير (400) ؛ arrGame [15] = 1 ؛ drawBoard () ؛ تأخير (400) ؛ arrGame [15] = 2 ؛ drawBoard () ؛ تأخير (400) ؛ arrGame [15] = 1 ؛ drawBoard () ؛ تأخير (400) ؛ انتهت اللعبة()؛ }}}

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

الخطوة 15: وظيفة WriteSerial

انسخ الكود التالي إلى برنامجك

void writeSerial () {if (bolSerialBoard == true) {for (int i = 0؛ i <= 15؛ i ++) {for (int ii = 0؛ ii <= 3؛ ii ++) {Serial.print (arrGame [ii]) ؛ Serial.print ("،") ؛ } Serial.println ("") ؛ }}}

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

الخطوة 16: الإكمال

انتهاء!
انتهاء!

يجب ألا تكون جميع التعليمات البرمجية الخاصة بك كاملة وتبدو مثل هذا!

/ * * الاسم - بلاط البيانو ؛ Arduino * By - دومينيك مارولي * التاريخ - 11 / *

/ تشمل المكتبات

#يشمل

// هذه المتغيرات هي خيارات يمكنك تغييرها - أرقام أعلى = تسريع اللعبة بشكل أسرع

int intGameSpeedEasy = 10 ؛ int intGameSpeedMedium = 25 ؛ int intGameSpeedHard = 80 ؛

// تحديد دبابيس

# تعريف btnEnter A0 # تعريف btn1 15 # تعريف btn2 16 # تعريف btn3 17 # تعريف btn4 18

// إنشاء كائنات LCD (n ، ~ ، n ، ~ ، ~ ، n)

LiquidCrystal lcdLeft (8 ، 9 ، 12 ، 10 ، 11 ، 13) ؛ LiquidCrystal LCDRight (2 ، 3 ، 4 ، 5 ، 6 ، 7) ؛

// إعداد مجموعة ألعاب

int arrGame [16] [4] = {{0، 0، 0، 0}، {0، 0، 0، 0}، {0، 0، 0، 0}، {0، 0، 0، 0}، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0 ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0 ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0} ، {0 ، 0 ، 0 ، 0}} ؛

// إعداد المتغيرات للعبة

بولبلاي منطقي. // يتتبع إذا كان اللاعب intScore ؛ // يتتبع درجة اللاعب intDiff ؛ // مجرد شيء جمالي لمعرفة مدى صعوبة اللعبة

// إعداد المتغيرات للإدخال

intEnter int // يتتبع إذا ضغط المستخدم على زر الإدخال intInput ؛ // يتتبع الأزرار التي يضغط عليها المستخدم BolTilePressed ؛ // تأكد من أن اللاعب لا يضغط بطريق الخطأ على الزر 5x ويخسر

// إعداد المتغيرات للدوران

intTick intTick // يحسب ما يصل إلى ملي (لكل حلقة) حتى intDelay int intDelay ؛ // وقت انتظار البرنامج حتى المنعطف التالي بالمللي intGameSpeed ؛

// القليل من خيارات التصحيح

bolSerialBoard منطقية. // عندما تكون صحيحة ستطبع اللوحة في الشاشة التسلسلية

// الإعداد الذي سيتم تشغيله مرة واحدة

إعداد باطل () {Serial.begin (9600) ؛ // بدء العرض التسلسلي // إعداد المتغيرات bolPlay = false ؛ intScore = 0 ؛ intTick = 0 ؛ intDelay = 1000 ؛ intDiff = 1 ؛ intGameSpeed = intGameSpeedMedium ، // start lcd's lcdLeft.begin (16، 2) ؛ lcdRight.begin (16 ، 2) ؛ }

// الحلقة التي سيتم تشغيلها كل 10 مللي ثانية

حلقة باطلة () {إدخال () ؛ // تحقق من تشغيل الإدخال إذا (bolPlay == true) {if (intTick> = intDelay) {// تحقق لمعرفة ما إذا كان يجب أن تلعب اللعبة دورًا أو تستمر في انتظار Serial.println ("~~~~~~~ ~~ ") ؛ // طباعة للدلالة على أن اللوحة تتحرك على // writeSerial () ؛ // إذا تم تمكين الخيار ، فاكتب اللوحة في أزرار تسلسليةGame () ؛ // تحقق من مدخلات اللاعب playBoard () ؛ // حرك اللوحة وأضف بلاطة جديدة clearLcd () ؛ // قم بتنظيف شاشات LCD قبل رسم drawBoard () ؛ // ارسم اللوحة على قاع شاشة LCDCheck () ؛ intTick = 0 ؛ // reset intTick} else {keysGame () ؛ // تحقق من مدخلات المشغل clearLcd () ؛ // قم بتنظيف شاشات LCD قبل رسم drawBoard () ؛ // ارسم اللوحة على intTick في شاشة LCD = intTick + intGameSpeed ؛ // add to tick}} else {clearLcd ()؛ // تنظيف شاشات الكريستال السائل قبل رسم العنوان () ؛ // عرض أزرار معلومات العنوان والنتيجة // قراءة مدخلات اللاعب clearBoard () ؛ // ضمان المجلس بالكامل = 0} تأخير (10) ؛ // تأخير اردوينو لحظة قصيرة}

// ينظف شاشات الكريستال السائل ، لذلك لا تترك أي خلايا غير مخترقة هناك

void clearLcd () {for (int i = 0؛ i <= 15؛ i ++) {for (int ii = 0؛ ii <= 1؛ ii ++) {lcdLeft.setCursor (i، ii)؛ lcdLeft.write ("") ؛ lcdRight.setCursor (i، ii) ؛ lcdRight.write ("") ؛ }}}

// يرسم اللوحة على شاشات الكريستال السائل

void drawBoard () {for (int i = 1؛ i <= 15؛ i ++) {// ارسم collums 1 و 2 على شاشة LCD اليسرى // إذا كانت اللوحة = 0 اكتب شيئًا ، = 1 اكتب "#" ، = 2 اكتب "@" lcdLeft.setCursor (i، 1) ؛ // ضبط على العمود الأول (أقصى اليسار) إذا (arrGame [0] == 1) {lcdLeft.write ("#")؛} إذا (arrGame [0] == 2) {lcdLeft.write ("@")؛} lcdLeft.setCursor (i، 0)؛ // ضبط على العمود الثاني (يسار الوسط) إذا (arrGame [1] == 1) {lcdLeft.write ("#")؛} إذا (arrGame [1] == 2) {lcdLeft.write ("@")؛} lcdRight.setCursor (i، 1)؛ // ضبط على العمود الثالث (يمين الوسط) إذا (arrGame [2] == 1) {lcdRight.write ("#")؛} if (arrGame [2] == 2) {lcdRight.write ("@")؛} lcdRight.setCursor (i، 0)؛ // ضبط على العمود الرابع (أقصى اليمين) إذا (arrGame [3] == 1) {lcdRight.write ("#")؛} if (arrGame [3] == 2) {lcdRight.اكتب("@")؛} } }

// يحرك اللوحة لأسفل ويضع قيمة عشوائية لتكون بلاطة

void playBoard () {for (int i = 0؛ i <= 3؛ i ++) {arrGame [0] = 0؛} // مسح الصف العلوي arrGame [0] [عشوائي (0، 4)] = 1 ؛ // عيّن نقطة عشوائية في الصف العلوي لتكون بلاطة لـ (int i = 15 ؛ i> = 1 ؛ i -) {// العمل من أسفل اللوحة إلى الأعلى لـ (int ii = 0 ؛ ii <= 3؛ ii ++) {// لكل مجموعة arrGame [ii] = arrGame [i - 1] [ii] ؛ }}}

// يعين اللوحة بأكملها على 0 ويعيد تعيين المتغيرات على اللعبة المسبقة

void clearBoard () {// إعادة تعيين قيم التجزئة والتأخير intTick = 0 ؛ intDelay = 1000 ؛ // انتقل إلى اللوحة وقم بتعيين كل شيء على 0 من أجل (int i = 0؛ i <= 15؛ i ++) {for (int ii = 0؛ ii <= 3؛ ii ++) {arrGame [ii] = 0 ؛ }}}

// يعرض القائمة الرئيسية على شاشات الكريستال السائل

عنوان باطل () {// اكتب العنوان على شاشة LCD ومساحة للنقاط lcdRight.setCursor (0 ، 0) ؛ lcdRight.write ("Piano Tiles") ؛ lcdRight.setCursor (0 ، 1) ؛ lcdRight.write ("الدرجة:") ؛ // تحويل النتيجة إلى سلسلة أحرف strScore [3] ؛ sprintf (strScore، "٪ d"، intScore) ؛ // عرض النتيجة على شاشة LCD LCDRight.write (strScore) ؛ // إضافة الأمر lcdRight.setCursor (10، 1) diffictuly؛ إذا (intDiff == 0) {lcdRight.write ("سهل") ؛ } if (intDiff == 1) {lcdRight.write ("Medium")؛ } if (intDiff == 2) {lcdRight.write ("Hard") ؛ } // اضغط قليلاً من التعليمات lcdLeft.setCursor (0، 0) ؛ lcdLeft.write ("اضغط Enter") ؛ lcdLeft.setCursor (0 ، 1) ؛ lcdLeft.write ("لتبدأ!") ؛ }

// يتحقق من الأزرار وماذا يفعل لهم أثناء الخروج من اللعبة

أزرار باطلةMenu () {// عند الضغط على مفتاح الإدخال ، ابدأ اللعبة وأعد ضبط قيمة النتيجة إذا (intEnter == 1) {bolPlay = true ؛ intScore = 0 ؛ لعب المجلس()؛ drawBoard () ؛ } // عند الضغط على الزر 3 ، قم بتشغيل خيار التصحيح لطباعة اللوحة بالتسلسل if (intInput == 3) {if (bolSerialBoard == false) {Serial.println ("Serial Board Active") ؛ bolSerialBoard = صحيح ؛ } else {Serial.println ("Serial Board Disabled")؛ bolSerialBoard = خطأ ؛ }} // اضبط سرعة اللعبة على صعوبة سهلة إذا (intInput == 0) {Serial.print ("Game set to easy (")؛ Serial.print (intGameSpeedEasy)؛ Serial.println ("تسريع مللي ثانية)") ؛ intDiff = 0 ؛ intGameSpeed = intGameSpeedEasy ، } // اضبط سرعة اللعبة على مستوى صعوبة متوسطة إذا (intInput == 1) {Serial.print ("تعيين اللعبة إلى متوسط (") ؛ Serial.print (intGameSpeedMedium) ؛ Serial.println ("تسريع مللي ثانية)") ؛ intDiff = 1 ؛ intGameSpeed = intGameSpeedMedium ، } // اضبط سرعة اللعبة على الصعوبة الصعبة إذا (intInput == 2) {Serial.print ("ضبط اللعبة على الثابت (") ؛ Serial.print (intGameSpeedHard) ؛ Serial.println ("تسريع مللي ثانية)") ؛ intDiff = 2 ؛ intGameSpeed = intGameSpeedHard ، }}

// يتحقق من الأزرار وماذا يفعل لهم أثناء اللعب

أزرار باطلة لعبة () {if (intInput! = 4) {// إذا تم الضغط على زر إذا (bolTilePressed == false) {// فقط إذا كان bolTilePressed إجراء زناد خاطئ لفحص الزر ، فاضغط على bolTilePressed = true ؛ // ثم اضبط bolTilePressed على true للتأكد من أنه لم يتم تشغيله بشكل مفاجئ مرة أخرى int intLowestTile = 0 ؛ // ليتم ضبطها على البلاط الذي يحتوي على أقل تجانب intCheckedTile = 15 ؛ // لتتبع المربعات التي تم فحصها أثناء (intLowestTile == 0) {// طالما لم يتم ضبطها على أي شيء تحقق من المربعات لـ (int i = 0 ؛ i 100) {// طالما int التأخير ليس أقل من 100 intDelay = intDelay - 20 ؛ // أخذ قيمة منه}} else {Serial.println ("تم الضغط على الزر الخطأ") ؛ انتهت اللعبة()؛ // انتهت اللعبة بخلاف ذلك}}}}}

لعبة باطلة

Serial.println ("انتهت اللعبة!") ؛ Serial.print ("كانت نتيجتك:") ؛ Serial.println (intScore) ؛ Serial.print ("سرعتك كانت:") ؛ Serial.println (intDelay) ؛ bolPlay = خطأ ؛ }

// يتحقق من مدخلات اللاعب

إدخال باطل () {intEnter = digitalRead (btnEnter) ؛ // read enter // اقرأ أيًا من المدخلات الأخرى ، أو إذا لم يتم تعيين أي من المدخلات الأخرى على 4 if (digitalRead (btn1) == HIGH) {intInput = 0 ؛} else {if (digitalRead (btn2) == HIGH) {intInput = 1؛} else {if (digitalRead (btn3) == HIGH) {intInput = 2؛} else {if (digitalRead (btn4) == HIGH) {intInput = 3؛} else {intInput = 4 ؛ }}}} // serial print the inputs if (intEnter == 1) {Serial.println ("Enter Pressed!")؛} if (intInput! = 4) {Serial.print ("Button Press:")؛ Serial.println (intInput) ؛ } else {// إذا لم يتم الضغط على زر إعادة تعيين bolTilePressed bolTilePressed = false؛ }}

// يتحقق من الجزء السفلي من اللوحة بحثًا عن الفشل

void bottomCheck () {for (int i = 0؛ i <= 3؛ i ++) {// للأعمدة الأربعة إذا (arrGame [15] == 1) {// إذا كانت القطعة في الجزء السفلي من المسلسل.println ("تجانب في الأسفل") ؛ arrGame [15] = 2 ؛ drawBoard () ؛ تأخير (400) ؛ arrGame [15] = 1 ؛ drawBoard () ؛ تأخير (400) ؛ arrGame [15] = 2 ؛ drawBoard () ؛ تأخير (400) ؛ arrGame [15] = 1 ؛ drawBoard () ؛ تأخير (400) ؛ انتهت اللعبة()؛ }}}

// يطبع اللوحة في الشاشة التسلسلية إذا كانت bolSerialBoard صحيحة

void writeSerial () {if (bolSerialBoard == true) {for (int i = 0؛ i <= 15؛ i ++) {for (int ii = 0؛ ii <= 3؛ ii ++) {Serial.print (arrGame [ii]) ؛ Serial.print ("،") ؛ } Serial.println ("") ؛ }}}

بمجرد إدخال كل الكود ، قم بتحميله على اردوينو الخاص بك واستمتع!

موصى به: