
جدول المحتويات:
2025 مؤلف: John Day | [email protected]. آخر تعديل: 2025-01-23 12:53


في هذا البرنامج التعليمي سننظر في كيفية استخدام الصور النقطية باستخدام مكتبة Adafruit_GFX.c كنوع من النقوش المتحركة في اللعبة. إن أبسط لعبة يمكن أن نفكر فيها هي لعبة تغيير حارة التمرير الجانبي ، وفي النهاية قرر مختبِر النسخة التجريبية ومساعد المبرمج لدينا "Reckless Racer" كاسم ، لأنه من المتهور جدًا القيادة في الطريق الخطأ على الطريق السريع !!.
تصميم دائرتنا موجود في الصور المدرجة أعلاه وهو مفصل في مشروعنا / البرنامج التعليمي الأخير هنا Snake Instructables الذي يصف كيفية عمل الدائرة.
سوف نطلب
Adafruit_GFX
Paint.net
Arduino IDE windowslinux
ويرجى إلقاء نظرة على برنامج Snake التعليمي لبقية المعدات.
اللوازم
لعبة الثعبان
الخطوة 1: تثبيت Paint.net



نحن نستخدم paint.net لأن البرنامج مجاني ، لذا يمكنك تنزيل برنامج Paint. Net هنا.
لتثبيت paint.net ، انقر نقرًا مزدوجًا فوق البرنامج الذي تم تنزيله وأجب بشكل إيجابي كالتالي ، نعم ، حسنًا ، أوافق وستعطيك الصور أعلاه إرشادات.
الخطوة الثانية: رسم شاشة بسيطة



عندما تكون في موقع paint.net ، قم بإنشاء صورة جديدة بالنقر فوق ملف ثم جديد ، واضبط حجم الصورة على 1260x620 (انظر الصورة الأولى) انقر فوق موافق عندما يكون لديك صفحة جديدة ، ارسم شاشة البداية باستخدام لونين فقط أبيض وأسود باستخدام قلم الرصاص أداة (صورة 2) ،
عندما تقوم برسم (أو لصق) صورة شاشة البداية الخاصة بك ، انقر فوق الصورة ثم قم بتغيير حجمها (الصورة 4) ، في النافذة المنبثقة ، قم بتغيير الحجم من 1260 × 620 إلى 126 × 62 (2 بكسل أصغر من شاشتك) (صورة 5) انقر فوق موافق.
انقر بعد ذلك على قائمة ملف ثم احفظ باسم (صورة 6).
عندما تظهر النافذة المنبثقة في القائمة المنسدلة لنوع الملف ، حدد BMP (صورة نقطية). (صورة 7) ، اكتب اسم ملف وانقر فوق حفظ ، عندما تظهر النافذة المنبثقة ، اضبط التردد على 0 واضبط على 8 بت ، انقر فوق موافق (صورة 8)).
الخطوة 3: تحويل BMP إلى ملف C Bitmap




نحتاج الآن إلى تحويل صورتنا إلى تنسيق يمكن لـ arduino فهمه ، فهناك الكثير من الأدوات المتاحة للقيام بذلك ، ولكن "go to" الخاص بي ، ضع أداة تحويل الصور النقطية لموقع الويب marlin …
marlinfw.org/tools/u8glib/converter.html
لذلك نبدأ هذا القسم باستخدام الرابط أعلاه لفتح الموقع الموضح في صورة 1
انقر فوق اختيار ملف وحدد الصورة النقطية التي قمت بإنشائها مسبقًا (صورة 2)
سيقوم محول الصور النقطية من marlin بتحويل صورتك تلقائيًا إلى رمز c ، انقر نقرًا مزدوجًا فوق الرمز الذي يجب أن يبرز الرمز ، ثم انقر بزر الماوس الأيمن وانقر فوق نسخ (pic3)
التالي نقوم بإنشاء انقر بزر الماوس الأيمن وإنشاء مستند نصي جديد (صورة 4)
انقر نقرًا مزدوجًا فوق المستند الجديد ، عند الفتح ، انقر بزر الماوس الأيمن والصق الرمز (صورة 5)
بعد ذلك ، يتعين علينا إضافة السطر بالقرب من الجزء العلوي من الكود # تضمين هذا يسمح لنا بحفظ بيانات الصورة النقطية في ذاكرة الفلاش على اردوينو ، ثم نعيد تسمية # تعريف العرض والارتفاع والاسم إلى شيء أسهل في الاستخدام. في الموافقة المسبقة عن علم 6
نعيد تسميتها من الأحرف التي تم إنشاؤها عشوائيًا ونقوم بإعادة تسميتها إلى المثال الذي تحته خط أدناه
#define LOGOWIDTH
# تعريف الشعار
const char LOGOPIC غير الموقعة PROGMEM
بعد ذلك ، انقر فوق ملف ثم احفظ باسم ، واحفظ الملف باسم logo.c ، وأغلق المفكرة ، وانقر بزر الماوس الأيمن على logo.c وانقر فوق نسخ.
الخطوة 4: عرض الشعار باستخدام DrawBitmap



الآن نقوم بتحميل arduino IDE وننشئ رسمًا جديدًا ونحفظه باسم logoexample.ino ، بعد ذلك كغش في arduino ID انقر فوق قائمة الملف ثم احفظ باسم ، ارجع إلى مجلد المشروع انقر بزر الماوس الأيمن والصقه في ملف.c (pic2) ثم انقر فوق "إلغاء الأمر" ، وهذا يوفر عليك التصفح للوصول إلى المجلد للصقه في الملف.
اكتب الكود التالي في arduino IDE أو قم بتنزيل ino.
(نوصي بالكتابة بدلاً من النسخ واللصق أو استخدام الملفات الموجودة أدناه ، إنها أفضل طريقة للتعلم)
#include / * سيختلف هذا حسب المكان الذي تخزن فيه
عادةً ما يكون ino في المجلد C: / Users / ~ username / Documents / Arduino / project ~ name
وهذه هي الطريقة التي نربط بها بالصورة النقطية الخاصة بنا * /
#يشمل
#يشمل
uint8_t bmpX ، bmpY = 0 ؛ / * حجز ذاكرة لأعداد صحيحة 2 × 8 بت ، نحتاج فقط إلى عدد 8 بت
نظرًا لأن القيمة لا تزيد أبدًا عن 128 (بكسل) ، لذا يمكننا توفير مساحة باستخدام 8 بت ints (والتي لها قيمة قصوى تبلغ 255) * /
الإعداد باطل()
{تأخير (100) ؛ // امنح العرض وما إلى ذلك وقتًا لتشغيل العرض. begin (SSD1306_SWITCHCAPVCC، 0x3C) ؛ // هذا لتهيئة شاشة العرض. // ابدأ بشاشة فارغة}
/ * يرجى ملاحظة أنه ليس عليك كتابة هذه التعليقات فيها للرجوع إليها …………..
الأمر الذي سنركز عليه هو display.drawBitmap ، هذا ما يرسم شاشة البداية. (bmpX ، هي قيمة المحور X على الشاشة حيث ستكون نقطة الربط X في الصورة النقطية و bmpX و bmpY هي القيم التي نهتم بها لإنشاء حركة (bmpY ، هي قيمة المحور Y على الشاشة حيث تكون نقطة الارتساء Y) نقطة الصورة النقطية هي أننا نحصل على أسماء المراجع كما حددناها في logo.c (LOGOPIC ، هو اسم الصورة النقطية في # included file logo.c (LOGOWIDTH ، هو عدد وحدات البكسل المتقاطعة (X) لرسم الصورة النقطية من نقطة الربط (LOGOHEIGHT ، هو عدد البكسل لأسفل (Y) لرسم الصورة النقطية من نقطة الربط ، يمكن إدخال بكسلات X و Y يدويًا ولكن من الأسهل استخدام العناصر المحددة مسبقًا بدلاً من تذكرها جميعًا (1 ، القيمة الأخيرة هي اللون حيث أن الشاشة أحادية اللون. أعلى اليسار ، x ، y ، اسم الصورة النقطية ، العرض X ، الارتفاع Y ، شاشة ملونة. هذا في الواقع يرسم المخزن المؤقت إلى الشاشة على الإطلاق}
قم بتحميل كود اردوينو الخاص بك وتأكد من أنه يعمل (صورة 3).
الخطوة 5: نقل كائن نقطي




باستخدام التعليمات السابقة ، استخدم paint.net وأنشئ ملفًا جديدًا اجعله 30 × 15 بكسل (صورة 1) وارسم سيارة خشنة يبدأ مصممنا الشاب بالزجاج الأمامي أولاً (صور 2 و 3).
احفظه مرة أخرى كملف windows bmp (كما في الخطوة 2) ، وقم بالتحويل إلى صورة نقطية C (الخطوة 3) ووضع ملف car.c (أو أي شيء تقرره) في نفس المجلد مثل arduino ino الذي تم إنشاؤه حديثًا (رسم تخطيطي) ملف.
(تذكر أن تضيف السطر # include في السيارة ، والذي كان يستخدم في جذب انتباهنا كثيرًا)
قم أولاً بربط ما يعادل car.c
#يشمل
# تضمين # تضمين Adafruit_GFX.h> // https://github.com/adafruit/Adafruit-GFX-Library # تضمين Adafruit_SSD1306 //
عرض Adafruit_SSD1306 (128 ، 64) ؛ // ضبط دقة العرض
/ * bmpX / bmpY نحتاج إلى أن تكون هذه متغيرات كتغيير هذه القيم وإعادة الرسم
الشاشة هي كيفية إنشاء تأثير حركة الحركة. hitSide و hitTop هو كيف نحافظ على الكائن في الشاشة * / uint8_t bmpX، bmpY = 0 ؛ // ذاكرة احتياطية لـ 2 8 بت ints (0-255) لسنا بحاجة إلى أكبر 128 سيكون أكبر عدد مستخدم bool hitSide = 0 ؛ منطقية hitTop = 0 ؛
الإعداد باطل()
{تأخير (100) ؛ // امنح العرض وما إلى ذلك وقتًا لتشغيل العرض. begin (SSD1306_SWITCHCAPVCC، 0x3C) ؛ // هذا لتهيئة شاشة العرض. // ابدأ بشاشة فارغة
}
حلقة فارغة()
{display.clearDisplay () ، // فارغ الشاشة // صورة نقطية مستمدة من أعلى اليسار ، x ، y ، اسم الصورة النقطية ، العرض X ، الارتفاع Y ، عرض اللون. // display.display () ؛ // هذا في الواقع يرسم المخزن المؤقت إلى الشاشة على الإطلاق / * هذه هي الطريقة التي نتتبع بها حافة الشاشة ونقرر ما إذا كنا سنضيف بكسل يتحرك من أعلى إلى أسفل) أو نزيل بكسل (تحرك من الأسفل إلى الأعلى) * / التبديل (hitSide) // يختار اتجاه السيارة بناءً على القيمة المنطقية {case 0: bmpX ++؛ استراحة؛
حالة 1:
bmpX-- ؛ استراحة؛ } // هذه العبارات 2 if تعيّن قيمة bool على صواب أو خطأ إذا (bmpX == 0) {hitSide = 0؛ } إذا (bmpX == 96) // عرض الشاشة مطروحًا منه السيارة {hitSide = 1 ؛ } // كما هو مذكور أعلاه للمحور Y إذا (bmpY == 0) {hitTop = 0 ؛ } إذا (bmpY == 49) // ارتفاع الشاشة مطروحًا منه ارتفاع السيارة {hitTop = 1 ؛ } switch (hitTop) {case 0: bmpY ++؛ استراحة؛ الحالة 1: bmpY-- ؛ استراحة؛ }
}
يمكنك مشاهدة البرنامج يعمل بالفيديو المرفق
الخطوة السادسة: صنع لعبة القيادة


نبدأ أولاً برسم عدد قليل من السيارات أو العوائق المختلفة كما في المراحل السابقة من البرنامج التعليمي مما يجعلها 30 × 15 بكسل. ثم نقوم بتحويلها إلى c bitmap وربطها في الكود.
# تضمين // سيتعين على هذه المسارات أن تتغير وفقًا
// في المكان الذي تخزن فيه الملفات // تحرير: لقد اكتشفت للتو إذا استبدلت // بـ "" فأنت لا تحتاج إلى المسار الكامل // بمكتباتك الخاصة # تضمين
#يشمل
# تضمين # تضمين
#يشمل
# تضمين // https://github.com/adafruit/Adafruit-GFX-Library #include <Adafruit_SSD1306 //
عرض Adafruit_SSD1306 (128 ، 64) ؛ // تحديد معلمات العرض
تحديد المتغيرات والقيم الثابتة
// حدد دبابيس الإدخال ، هذه هي المسامير الموجودة على arduino التي لا تتغير أبدًا ، لذا # حدد # حدد INTPIN 3 // فقط الدبابيس 2 و 3 يمكن أن تقاطع الدبابيس على UNO #define UPPIN 4 // هذه دبابيس متصلة tp Switch ذات الصلة # تعريف DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // حدد الاتجاهات
#define DIRUP 1 // هذه القيم هي ما ينظر إليه "الثعبان" ليقرر-
#define DIRDOWN 2 // الاتجاه الذي سيسلكه الثعبان #define DIRLEFT 3 #define DIRIGHT 4
uint8_t dirPressed = 0 ؛ // قيمة لتسجيل الاتجاه للتحرك على أي دبوس ارتفع
// مخزن القيم المنطقية الذي ارتفع دبوس
منطقي BUTUP = 0 ؛ منطقي BUTDWN = 0 ؛ منطقي BUTLFT = 0 ؛ منطقية BUTRHT = 0 ؛ // vars لموقف السيارة uint8_t carPosX = 1 ؛ uint8_t carPosY = {0، 16، 32، 48} ؛ // يحتاج قيمة cahnging المصفوفة
uint8_t lanePosArr = {0، 16، 32، 48} ؛ // مجموعة لتخزين مكان كل حارة
uint8_t carPosYCnt = 0 ؛ uint8_t carYTmp = 0 ؛ // متغيرات الخطوط في الطريق uint8_t roadLineX1 = 51 ؛ // تم تحديدها مسبقًا في البداية ثم تظهر الخطوط بشكل سلس uint8_t roadLineX2 = 102 ؛ uint8_t roadLineX3 = 153 ؛ uint8_t roadLineX4 = 254 ؛ uint8_t roadLineX5 = 200 ؛
// هذا هو عدد وحدات البكسل التي تتحركها منطقة التشغيل في المرة الواحدة
uint8_t drawSpeed = 4 ؛
// فارز للعدو 0
uint8_t العدو0PosX = 255 ؛ uint8_t العدو0PosY = 0 ؛ uint8_t العدو1PosX = 255 ؛ uint8_t العدو1PosY = 0 ؛ uint8_t العدو2PosX = 255 ؛ uint8_t العدو2PosY = 0 ؛
// قابل للتغير لتخصيص رقم حارة للعقبات بشكل عشوائي
uint8_t laneGen = 0 ؛
uint8_t laneGen0 = 0 ؛ uint8_t laneGen1 = 0 ؛ uint8_t laneGen2 = 0 ؛
// عداد النقاط
درجة طويلة = 0 ؛ // هذه هي النتيجة: / لول مقارنة طويلة = 0 ؛ // يقوم هذا بتخزين النتيجة في المستوى الأخير لأعلى للمقارنة مرة أخرى مع الدرجة العالية الطويلة = 25 ؛ uint8_t metreCnt = 0 ؛
هذا هو المكان الذي نبدأ فيه الوظائف
// هذه هي مجموعة الأوامر إذا تم تنشيط المقاطعة باطل المقاطعة () {delay (150) ؛ updateDirection () ، } // تحديث القيمة الموجودة في الاتجاه var عن طريق التحقق من قيم DIR bools // -------------------------- UPDATE DIRECTION (player) - ------------------------- void updateDirection () {//Serial.println("updateDirection Called ") ؛ BUTUP = digitalRead (UPPIN) ، BUTDWN = digitalRead (DWNPIN) ، BUTLFT = digitalRead (LFTPIN) ، BUTRHT = قراءة رقمية (RHTPIN) ؛ إذا (BUTUP == صحيح) {dirPressed = DIRUP؛ } إذا (BUTDWN == صحيح) {dirPressed = DIRDOWN؛ } إذا (BUTLFT == صحيح) {dirPressed = DIRLEFT؛ } إذا (BUTRHT == صحيح) {dirPressed = DIRRIGHT؛ }
}
// ------------------------------- MOVE CAR --------------- -------------------------
// سيؤدي هذا إلى تحديث الشاشة المحرك لعنصر السيارة
مركبة باطلة ()
{switch (dirPressed) {case DIRUP: carPosYCnt--؛ carPosY [carPosYCnt] ؛ نغمة (SND ، 100 ، 100) ؛ إذا (carPosYCnt == 255) {carPosYCnt = 0 ؛ } carYTmp = carPosY [carPosYCnt] ، dirPressed = 0 ؛ // Serial.println ("carPosY up") ؛ // Serial.println (carPosYCnt) ؛ استراحة؛ الحالة DIRDOWN: carPosYCnt ++ ؛ نغمة (SND ، 100 ، 100) ؛ إذا (carPosYCnt == 4) {carPosYCnt = 3 ؛ } // Serial.println ("carPosY") ؛ // Serial.println (carPosYCnt) ؛ carYTmp = carPosY [carPosYCnt] ، dirPressed = 0 ؛ استراحة؛ // علق على أن السيارة قادرة على تحريك كشف الاصطدام الأيمن والأيسر ليس جيدًا حتى الآن / * case DIRLEFT: carPosX-- ؛ إذا (carPosX == 0) {carPosX = 1 ؛ } // Serial.println ("carPosX") ؛ // Serial.println (carPosX) ؛ dirPressed = 0 ؛ استراحة؛ * / case DIRIGHT: // للمتعة فقط إذا ضغطت على اليمين فستحدث اللعبة نغمة ضوضاء (SND ، 100 ، 50) ؛ // carPosX ++ ؛ // إذا (carPosX == 128) // {// carPosX = 127 ؛ //} // Serial.println ("carPosX") ؛ // Serial.println (carPosX) ؛ // dirPressed = 0 ؛ استراحة؛ } updateDisplay () ، }
// -------------------------- RANDOM POS X ------------------- -----------
uint8_t randomPosX () // هذان الإجراءان يولدان فقط موقعًا عشوائيًا للعقبات
{uint8_t posValTmp = 0 ؛ posValTmp = عشوائي (129 ، 230) ؛ //Serial.println("random x ") ؛ //Serial.println(posValTmp) ؛ العودة (posValTmp) ؛ }
// --------------------------- RANDOM POS Y ------------------ ------------------
uint8_t randomPosY ()
{uint8_t laneVal = 0 ؛ laneVal = عشوائي (0 ، 4) ؛ // أضف ممرًا إضافيًا للعشوائية ، أي لا يوجد كائن على الشاشة أثناء التواجد في هذا الممر //Serial.println("RandomY ") ؛ //Serial.println(lanePosArr[laneVal]) ؛ العودة (lanePosArr [laneVal]) ، }// ------------------------------- SET GAME SPEED -------------- -------------- void setGameSpeed () // هذا يوقف المستوى الذهاب إلى أعلى من 20 مما يجعل اللعبة غير قابلة للتشغيل {إذا (drawSpeed <21) {drawSpeed = drawSpeed + 2 ؛ }}// ------------------------------------ DETECT CRASH ---------- ----------------------- كشف باطل تحطم () {
إذا (العدو0PosX = 0 && العدو0PosY == carYTmp)
{// Serial.println ("Game Over CRAASSSSHHHHHHEEEEDDD في حركة المرور 0")؛ انتهت اللعبة()؛ } if (flight1PosX = 0 && انتهت اللعبة()؛ } if (العدو2PosX = 0 && انتهت اللعبة()؛ }}
هذه هي الإجراءات التي ترسم العرض.
// ------------------------------- طريق السحب --------------- --------------------- void drawRoad () // X، Y، length، width {display.fillRect (roadLineX1، 15، 30، 4، WHITE) ؛ display.fillRect (roadLineX1، 30، 30، 4، WHITE) ؛ display.fillRect (roadLineX1، 45، 30، 4، WHITE) ؛ display.fillRect (roadLineX2، 15، 30، 4، WHITE) ؛ display.fillRect (roadLineX2، 30، 30، 4، WHITE) ؛ display.fillRect (roadLineX2، 45، 30، 4، WHITE) ؛ display.fillRect (roadLineX3، 15، 30، 4، WHITE) ؛ display.fillRect (roadLineX3، 30، 30، 4، WHITE) ؛ display.fillRect (roadLineX3، 45، 30، 4، WHITE) ؛ display.fillRect (roadLineX4، 15، 30، 4، WHITE) ؛ display.fillRect (roadLineX4، 30، 30، 4، WHITE) ؛ display.fillRect (roadLineX4، 45، 30، 4، WHITE) ؛ display.fillRect (roadLineX5، 15، 30، 4، WHITE) ؛ display.fillRect (roadLineX5، 30، 30، 4، WHITE) ؛ display.fillRect (roadLineX5، 45، 30، 4، WHITE) ؛
roadLineX1 = roadLineX1-drawSpeed ؛
roadLineX2 = roadLineX2-drawSpeed ؛ roadLineX3 = roadLineX3-drawSpeed ؛ roadLineX4 = roadLineX4-drawSpeed ؛ roadLineX5 = roadLineX5-drawSpeed ؛ display.display () ، } // ----------------------------------------- رسم أعداء ---- ------------------------------------------- void warsDraw () {// X، Y، اسم bmp ، عرض ، ارتفاع ، شاشة ملونة. العدو0PosX = العدو0PosX-drawSpeed ؛ display.drawBitmap (العدو 1PosX ، العدو 1PosY ، ENEMY1 ، ENEMY1_WIDTH ، ENEMY1_HEIGHT ، 1) ؛ العدو1PosX = العدو 1PosX-drawSpeed ؛ display.drawBitmap (العدو2PosX ، العدو 2PosY ، ENEMY2 ، ENEMY2_WIDTH ، ENEMY2_HEIGHT ، 1) ؛ العدو2PosX = العدو 2PosX-drawSpeed ؛ display.display () ، إذا (العدو0PosX> 231 && العدو0PosX231 && العدو1PosY = randomPosY () ، checkDuplicate () ، }
إذا (العدو2PosX> 231 && العدو2PosY = randomPosY () ، }} // ------------------------------------ UPDATE DISPLAY -------- ---------------------------------------- void updateDisplay () {display.clearDisplay () ؛ display.drawBitmap (carPosX ، carPosY [carPosYCnt] ، CARSPRITE ، 30 ، 15 ، 1) ؛ display.fillRect (100 ، 0 ، 28 ، 10 ، أسود) ؛ display.setCursor (100، 0) ؛ display.setTextColor (أبيض ، أسود) ؛ display.println (النتيجة) ؛ display.display () ،
}
// ------------------------- انتظر حلقة الضغط ------------------- ------
// this is the home screen code void waitForPress () {splashScreen ()؛ انتظار منطقي = 0 ؛ // الحلقة تنتهي عندما يكون هذا صحيحًا. display.clearDisplay () ؛ أثناء (الانتظار == 0) {
display.fillRect (19 ، 20 ، 90 ، 32 ، أسود) ؛ // خلفية فارغة للنص
display.setTextColor (WHITE) ، display.setCursor (23 ، 24) ؛ display.setTextSize (0) ، display.println ("Reckless") ؛ display.setCursor (36 ، 34) ؛ display.println ("المتسابق") ؛ display.drawBitmap (74، 24، CARSPRITE، CARWIDTH، CARHEIGHT، 1) ؛ // x y w h r col display.drawRoundRect (21، 21، 86، 23، 4، WHITE) ؛ // عرض ثعبان الحدود. رسم مستطيل (19 ، 20 ، 90 ، 33 ، أبيض) ؛ // مربع الحدود - 3 شاشات عرض. setCursor (25 ، 43) ؛ display.setTextSize (0) ، // عودة الخط إلى العرض العادي. println ("اضغط على أي مفتاح") ؛ display.fillRect (0 ، 0 ، 127 ، 8 ، أسود) ؛ display.setCursor (10، 0) ؛ display.print ("درجة عالية:") ؛ // عرض شاشة عرض الدرجة العالية (highScore) ؛ display.display () ، انتظار = digitalRead (INTPIN) ؛ // تحقق لمعرفة ما إذا كان الضغط على المفتاح في الانتظار سيتغير إلى 1 ينتهي بينما dirPressed = 0 ؛ // إعادة الضبط اضغط بلا اتجاه}} // -------------------------------------- ----- تحديث اللعبة ----------------------------------------- لعبة باطل التحديث () {moveCar () ، drawRoad () ، الأعداء // العدو1Draw () ، // العدو2Draw () ، metreCnt ++ ؛ كشف تحطم () ؛ if (metreCnt == 5) // يضيف نقطة لكل 10 دورات لتسجيل النتيجة {metreCnt = 0؛ النتيجة ++ ؛ } إذا كانت (النتيجة == قارن + 5) // تسرع اللعبة كل 5 نقاط بحد أقصى 20 سرعة {قارن = النتيجة ؛ setGameSpeed () ، } noTone (SND) ، updateDisplay () ،
}
// ------------------------------ انتهت اللعبة---------------- ------------------------------
// يرسم هذا الروتين الخطوط حول سيارة البطل الميت ثم يعرض اللعبة على الشاشة
لعبة باطلة
{نغمة (SND ، 200 ، 200) ؛ // play sound uint8_t linePosX، linePosY، pixwidth، pixheight = 0 ؛ // تعيين vars لرسم مربعات حول خط السيارة PosX = carPosY ؛ linePosY = carYTmp ؛ عرض البكسل = 30 ؛ ارتفاع البكسل = 15 ؛ display.drawRect (linePosX، linePosY، pixwidth، pixheight، WHITE) ؛ display.display () ، لـ (int i = 0؛ i <= 26؛ i ++) // هذه السيارة تحيط بالسيارة في مستطيلات تحاكي الانفجار {linePosX = linePosX-2؛ linePosY = linePosY-2 ؛ عرض بكسل = عرض بكسل + 4 ؛ pixheight = pixheight + 4 ؛ display.drawRect (linePosX، linePosY، pixwidth، pixheight، BLACK) ؛ display.drawRect (linePosX، linePosY، pixwidth، pixheight، WHITE) ؛ display.display () ، نغمة (SND ، أنا * 20 ، 50) ؛ تأخير (10) ؛ } display.setTextSize (2) ، display.setTextColor (أبيض ، أسود) ؛ display.setCursor (10 ، 23) ؛ نغمة (SND ، 50 ، 500) ؛ display.print ("GAME") ؛ display.display () ، تأخير (500) ؛ نغمة (SND ، 40 ، 500) ؛ display.print ("OVER") ؛ display.setTextSize (0) ، display.display () ، تأخير (3000) ؛ إعادة تشغيل اللعبة()؛ waitForPress () ، }
// ----------------------------------------- إعادة تشغيل اللعبة ----- -------------------------------------------------- -----
إعادة تشغيل باطلة () // هذا ينسخ درجة عالية ويعيد تعيين جميع الإحصائيات ويولد مواضع عشوائية
{if (Score> = highScore) // تحقق لمعرفة ما إذا كانت النتيجة أعلى من الدرجة العالية {highScore = Score؛ // حالة فردية لتحديث درجة عالية}
النتيجة = 0 ؛
drawSpeed = 4 ؛ metreCnt = 0 ؛ carPosYCnt = 0 ؛ العدو0PosX = randomPosX () ، العدو0PosY = randomPosY () ، العدو 1PosX = randomPosX () ؛ العدو1PosY = randomPosY () ، العدو2PosX = randomPosX () ، العدو2PosY = randomPosY () ، noTone (SND) ،
checkDuplicate () ،
}
// ------------------------------------------------ - تحقق من نسخة طبق الأصل ----------------------------------------------- ------ void checkDuplicate () // تحقق لمعرفة ما إذا كانت العوائق تشغل مساحة اللعبة نفسها {// Serial.println ("تم التحقق من النسخ المكررة") ؛ إذا (العدو2PosX> 230 && }}
إذا (العدو0PosX> 230 &&
//------------------------------------------- شاشة البداية --- --------------------------------
شاشة باطلة ()
{display.clearDisplay () ، display.drawBitmap (0، 0، CRASH، CRASHWIDTH، CRASHHEIGHT، 1) ؛ display.display () ، تأخير (2000) ؛ } // ----------------------------------------------- اقامة ------------------------------------------------- ----------- إعداد باطل () {delay (100) ؛ // دع الأشياء تبدأ // Serial.begin (9600) ؛ // uncomment هذا وكل المسلسل. بدء تشغيل أوامر عرض مخطط الخطأ (SSD1306_SWITCHCAPVCC ، 0x3C) ؛ display.clearDisplay () ، display.setTextColor (أبيض ، أسود) ؛ display.setTextWrap (خطأ) ؛ display.dim (0) ؛ pinMode (INTPIN ، INPUT) ؛ pinMode (UPPIN ، INPUT) ؛ pinMode (DWNPIN ، INPUT) ؛ pinMode (LFTPIN ، INPUT) ؛ pinMode (RHTPIN ، INPUT) ؛
attachInterrupt (digitalPinToInterrupt (INTPIN) ، المقاطعة ، RISING) ؛
// ضع العوائق بشكل عشوائي العدو0PosX = randomPosX () ؛ العدو0PosY = randomPosY () ، العدو1PosX = randomPosX () ، العدو1PosY = randomPosY () ، العدو2PosX = randomPosX () ، العدو2PosY = randomPosY () ، checkDuplicate () ، // تحقق من المواقع المكررة // Serial.println ("اكتمال الإعداد") ؛ شاشة البداية()؛ waitForPress () ، } // ----------------------------------------------- ----- حلقة -------------------------------------------- ----------
حلقة فارغة()
{updateGame () ، }
وهذا كل شيء إلى حد كبير ، نرحب بأي تعديلات وتعليقات. القضايا التي نحتاج إلى معالجة وميض الشاشة نحتاج إلى النظر في كيفية تقليله ولا تزال سيارات العدو قادرة على احتلال نفس المساحة.
موصى به:
مكونات لحام سطح جبل - أساسيات اللحام: 9 خطوات (بالصور)

مكونات لحام سطح جبل | أساسيات اللحام: حتى الآن في سلسلة أساسيات اللحام ، ناقشت أساسيات كافية حول اللحام لكي تبدأ في التدريب. في Instructable ، ما سأناقشه أكثر تقدمًا قليلاً ، لكنه بعض الأساسيات لحام Surface Mount Compo
لحام من خلال مكونات الثقب - أساسيات اللحام: 8 خطوات (بالصور)

لحام من خلال مكونات الثقب | أساسيات اللحام: في هذا Instructable ، سأناقش بعض الأساسيات حول لحام المكونات من خلال الفتحة في لوحات الدوائر. سأفترض أنك قمت بالفعل بفحص أول 2 Instructables لسلسلة Soldering Basics الخاصة بي. إذا لم تقم بإلقاء نظرة على دخولي
أساسيات واجهة Arduino TFT: 10 خطوات (بالصور)

أساسيات Arduino TFT Interfacing: شاشات اللمس TFT هي الواجهة الرسومية المذهلة التي يمكن استخدامها مع المتحكمات الدقيقة مثل Atmel و PIC و STM ، نظرًا لما تتمتع به من نطاق ألوان واسع وقدرة رسومية جيدة وتخطيط جيد للبكسل. للواجهة 2.4 بوصة TFT
أساسيات Arduino Esplora: 4 خطوات

أساسيات Arduino Esplora: Oh! لم اراك هناك! يجب أن ترغب في تعلم أساسيات لوحة Esplora الرائعة. حسنًا ، تعال ، تعال. سيعلمك هذا البرنامج التعليمي بعض الحيل الرائعة التي يمكنك القيام بها باستخدام Esplora
برنامج Pro-mini باستخدام Uno (أساسيات Arduino): 7 خطوات (بالصور)

برنامج Pro-mini باستخدام Uno (Arduino Basics): مرحبًا جميعًا ، في هذه التعليمات ، أود أن أشارككم تجربتي مع Arduino pro-mini الذي اشتريته مؤخرًا وكيف تمكنت من تحميل الكود إليه لأول مرة ، باستخدام Arduino Uno القديم. يحتوي Arduino pro-mini على الميزات التالية: إنه