آردوینو یک برد الکترونیکی است که به‌صورت اپن سورس عرضه شده است و افزون بر میکروکنترلر، امکاناتی را برای دریافت ورودی‌ها، پردازش آن‌ها و تولید خروجی، روی خود دارد. به زبان ساده، آردوینو را می‌توانید کامپیوتر بسیار کوچکی در نظر بگیرید که می‌توان روی آن برنامه‌نویسی کرد تا از این طریق وظایف خاصی که در نظر دارید را انجام دهد. آردوینو موارد استفاده جذاب و گوناگونی دارد و می‌توان گفت که افزون بر اهداف آموزشی می‌تواند در پیاده‌سازی پروژه‌های متعددی نظیر بازی‌سازی نیز مورد استفاده قرار گیرد. در این مطلب از مجله فرادرس، سعی کرده‌ایم تا به زبانی ساده و تا حد ممکن به‌طور کامل به شما توضیح دهیم که نحوه ساخت بازی با آردوینو چگونه است و برای انجام آن، به چه ابزاری نیاز دارید، چه مراحلی را می‌بایست طی کنید و به‌طور کلی چه کارهایی را باید انجام دهید.

فهرست مطالب این نوشته
997696

بردهای آردوینو یا «آردوئینو» (Arduino) در مدل‌های گوناگونی عرضه می‌شوند و از میکروکنترلر‌ها یا ریزپردازنده‌های متنوعی بهره می‌برند. از مدل‌های آردوینو می‌توان آردوینو‌های «اونو» (UNO)، مگا، نانو، MKR و میکرو اشاره کرد. روی این‌گونه بردها افزون بر ریزپردازنده یا میکروکنترلر، موارد دیگری مانند پین‌های «ورودی و خروجی» برای داده‌های آنالوگ و دیجیتال، کریستال، LED تست، رگولاتور ۳٫۳ ولت و ۵ ولت، دکمه ریست، کریستال‌های نوسان‌ساز، پین‌های تغذیه ماژول‌ها، پین ICSP و غیره اشاره کرد. به‌طور معمول، این بردها را می‌توان با اتصال آداپتور DC به سوکت تعبیه شده روی برد، تغذیه کرد و محدوده ولتاژ توصیه شده برای آن بین ۷ تا ۱۲ ولت است. ضمن اینکه با اتصال کابل USB به برد و کامپیوتر خود نیز می‌توانید آن را راه‌اندازی کنید. برای برنامه‌نویسی بردهای آردوینو از زبان مخصوصی شبیه به C++‎ استفاده می‌شود. این پلتفرم‌ها در موارد گوناگونی همچون اتوماسیون منازل، گلخانه هوشمند، انواع ربات‌ها، پهپادها، پرینتر ۳-بُعدی و بسیاری موارد دیگر می‌توانند به‌کار گرفته شوند. در این نوشتار، تمرکز ما روی بازی‌سازی با Arduino است و ضمن معرفی ابزارهای موردنیاز، نحوه ساخت بازی با آردوینو را در قالب ۲ بازی Jumpman و Reflex، به شما توضیح می‌دهیم.

دختری خوشحال از ساخت بازی با آردوینو

ساخت بازی با آردوینو چگونه است؟

با پلتفرم اپن سورس آردوینو، پروژه‌های گوناگونی را می‌توانید انجام دهید که ساخت بازی، یکی از آن‌ها است. به‌طور معمول، ماژول‌های نمایشگر، پایه ثابت ساخت بازی با آردوینو محسوب می‌شوند.

در این مطلب، ساخت بازی با آردوینو را از طریق آموزش ساخت بازی‌های زیر به شما یاد می‌دهیم.

  • بازی جامپ‌من یا Jumpman: یک بازی پلتفرمی که کاراکتر بازی در حال دویدن است و می‌بایست آن را به نحوی هدایت کنید که از موانع پیش روی خود به سلامت عبور کند.
  • بازی تست واکنش Reflex: یک بازی بسیار ساده که سرعت عکس‌العمل شما را به خاموش شدن یک LED می‌سنجد.

همان‌طور که در مقدمه هم اشاره شد به لطف وجود بردهای آردوینو می‌توان سنسورهایی را به ورودی‌های فراهم شده در این برد متصل کرد تا داده‌ها و ورودی‌های آنالوگ و دیجیتال را از محیط پیرامون خود دریافت کند. سپس این داده‌ها توسط میکروکنترلر پردازش شده و در نهایت می‌‌توانند اثری را روی محیط اطراف خود داشته باشند. به‌طور مثال، آردوئینو را می‌توان به نحوی برنامه‌ریزی کرد که با ماژول سنسور دما، میزان گرم بودن هوای اطراف خود را سنجیده و در صورتی که مقدار دما از حد مشخصی فراتر رفت، سیستم سرمایشی را روشن کند و بسیاری کاربرد جذاب دیگر که می‌توان از آن‌ها بهره‌مند شد.

به‌طور کلی، پروژ‌ه‌های زیادی وجود دارند که به‌عنوان یک فرد مشتاق به فناوری یا یک دانش‌آموز که قصد افزایش مهارت‌های خود را دارد می‌توانید آن‌ها را با آردوینو پیاده‌سازی کنید.

دانش آموز در حال ساخت بازی با آردوینو

یادگیری آردوینو با فرادرس چگونه است؟

آموختن کار با بردهای آردوینو و نحوه برنامه‌نویسی آن‌ها را می‌توان یکی از بهترین شیوه‌های ورود به برنامه‌نویسی میکروکنترلرها و خلق پروژه‌ها بسیار جذاب الکترونیکی دانست. این فرایند، پیچیدگی زیادی ندارد و افراد گوناگون با پیش‌زمینه‌‌های مختلف نیز می‌توانند آن را بیاموزند و از مزایای آن بهره‌مند شوند. فرقی نمی‌کند دانش‌آموز باشید و برای سرگرمی قصد یادگیری آردوئینو را دارید یا اینکه فردی با سن بسیار بالاتر، در هر حال اگر بخواهید مهارت جدیدی مانند استفاده از بردهای آردوینو برای برنامه‌نویسی الکترونیک و پیاده‌سازی پروژه‌هایی نظیر اتوماسیون منازل را یاد بگیرید، روش‌های گوناگون و متنوعی برای این کار پیشِ روی شما قرار دارد. به‌طور مثال، می‌توانید در کلاس‌های حضوری شرکت کنید، یا حتی دوره‌های آموزشی در پلتفرم‌هایی نظیر یوتیوب را تماشا کنید و غیره. هر کدام از این منابع، مزایا و معایب خود را دارند. در این میان، تماشای فیلم‌های آموزشی یکی از شیوه‌های مدرن و مؤثر در یادگیری مهارت‌های جذابی مانند آردوینو به‌شمار می‌روند و فارغ از اینکه در چه شهر و کشوری زندگی می‌کنید یا چه ساعاتی از روز را به یادگیری اختصاص می‌دهید، این فیلم‌های آموزش، شما را در مسیر یادگیری مهارت مورد نظرتان همراهی می‌کنند. ضمن اینکه در زمان و هزینه شما نیز صرفه‌جویی می‌شود.

فرادرس به‌عنوان یکی از محبو‌ب‌ترین پلتفرم‌های آموزشی کشور، فیلم‌های آموزشی گوناگونی را برای مهارت‌های مختلف مرتبط با علوم کامپیوتری از جمله نحوه استفاده و برنامه‌نویسی بردهای آردوینو، منتشر کرده است. در ادامه، مجموعه فیلم‌های آموزش «آردوینو» (Arduino)، مقدماتی تا پیشرفته از فرادرس را آورده‌ایم. این فیلم‌های آموزشی، مباحث گوناگون و پروژه‌محوری از بردهای آردوئینو را شامل می‌شوند که بسته به اهداف خود می‌توانید مورد دلخواه را تهیه و مشاهده کنید.

مجموعه فیلم‌های آموزش مقدماتی تا پیشرفته آردوینو از فرادرس
برای مشاهده فیلم‌های آموزش مقدماتی تا پیشرفته Arduino از فرادرس، روی تصویر کلیک کنید.

برخی از فیلم‌‌های آموزش موجود در این مجموعه را در ادامه معرفی کرده‌ایم.

شما همچنین می‌توانید با فیلم‌های آموزش رایگان آردوینو شروع کنید که لینک آن‌ها را در ادامه آورده‌ایم.

ساخت بازی Jumpman با آردوینو چگونه است؟

در این بخش می‌خواهیم به نحوه ساخت بازی Jumpman با آردوینو بپردازیم.

معرفی بازی Jumpman

بازی Jumpman یا «مردی که می‌پرد»، یک بازی ساده در سبک پرشی و همچنین «حرکت به طرفین» (Side-Scrolling) است. درست مانند بازی پلتفرمی سوپرماریو، در این نوع بازی‌ها زاویه دید بازیکن از پهلوی صفحه است و کاراکتر را می‌بایست به چپ یا راست هدایت کنیم. تصویر آورده شده در زیر نمایی از این بازی را نشان می‌دهد.

بازی Jumpman
نمایی از بازی Jumpman

در این بازی ساده، شخصیت بازی را مشاهده می‌کنیم که در مسیری مستقیم در حال دویدن است و موانع متعددی در مقابل او قرار می‌گیرند. شخصیت بازی می‌بایست با نزدیک شدن به موانع، از روی آن‌ها بپرد یا در صورتی که موانع در بالای سر او قرار گرفته باشند، از پریدن خودداری کند. در صورتی‌که بازیکن با موانع برخوردی داشته باشد، بازی تمام می‌شود. در گوشه صفحه بازی، یک شمارنده قرار گرفته که می‌توان آن را معادل امتیاز یا زمان پیشرفت در بازی در نظر گرفت. در این بازی تنها یک دکمه فشاری وجود دارد که عمل پرش شخصیت اصلی بازی را بر عهده دارد. یعنی با هر مرتبه فشردن این دکمه، شاهد یک‌مرتبه پرش کاراکتر بازی خواهیم بود.

در صورتی‌که تمایل به انجام این بازی از طریق شبیه‌سازی کامپیوتری را دارید، می‌توانید از لینک آورده شده در زیر استفاده کنید و در صفحه باز شده روی دکمه Simulate و سپس روی Start Simulation کلیک کنید. همان‌طور که در تصور زیر هم قابل مشاهده است، تنها یک دکمه برای شروع و کنترل بازی داریم که در کنار ماژول LCD قرار گرفته است.

  • لینک شبیه‌ساز بازی Jumpman: «+»

«برای مشاهده تصویر در اندازه اصلی، روی آن کلیک کنید».

ساخت این بازی ساده با آردوئینو، می‌تواند نقطه شروع خوبی برای بازی‌سازی با این نوع از پلتفرم‌های الکترونیکی باشد.

وسایل مورد نیاز برای ساخت بازی Jumpman با آردوینو

در ادامه، عناوین وسایل و لوازم مورد نیاز برای ساخت این بازی با آردوینو را آورده‌ایم.

  • برد آردوینو UNO
  • نمایشگر LCD (۱۶×۲ کاراکتری)
  • بردبورد (Breadboard)
  • مقاومت ۲۲۰ اُهم
  • دکمه فشاری
  • کابل USB
  • سیم جامپر یا سیم تک‌رشته‌ای برای اتصالات

ابزارهای مورد نیاز برای ساخت بازی با آردوینو

«برای مشاهده تصویر در اندازه اصلی، روی آن کلیک کنید».

در این پروژه از آردوینو مدل «اونو» استفاده کرده‌ایم که نمایی از آن را در تصویر زیر مشاهده می‌کنید.

برد آردوینو اونو
برد آردوینو UNO

گام اول: سرهم کردن قطعات سخت افزاری

توجه داشته باشید که در ابتدای کار و هنگام اسمبل یا مونتاژ قطعات، بورد آردوینو می‌بایست خاموش باشد. پس اگر کابل USB متصل به آردوینو، به سیستم کامپیوتری شما وصل است، لازم است تا آن را فعلا جدا کنید.

سپس با استفاده از یک قطعه سیم تک‌رشته‌ای، پین 5v آردوینو را به یکی از لاین‌های بردبورد که با خطی قرمزرنگ و برچسب + نشان داده شده است، وصل می‌کنیم. این مورد را با فلش قرمزرنگ در تصویر زیر نشان داده‌ایم.

لاین مثبت و منفی برد بورد

با توجه به اتصالات داخلی بردبورد، سوراخ‌های موجود در هریک از این ردیف‌ها از داخل به هم وصل هستند. بنابراین با اتصال پین 5v آردوینو به یکی از این سوراخ‌ها، دیگر سوراخ‌ها‌ی موجود در این ردیف از بردبورد نیز دارای ولتاژ 5v خواهند بود.

با قطعه سیم دیگری، پین GND آردوینو را به یکی از سوراخ‌های لاین منفی بردبورد که با فلش مشکی‌رنگ مشخص شده، وصل می‌کنیم.

حالا به سراغ ماژول LCD می‌رویم. این قطعه، مجموعه‌ای ۱۶ عددی از پین‌های نری را در زیر خود دارد. شما می‌بایست این ماژول و پین‌های آن را روی بردبورد قرار دهید. به‌وسیله همین پین‌ها، انرژی موردنیاز ماژول LCD تأمین شده و می‌توان آن را از طریق آردوینو کنترل کرد.

پین‌های ماژول LCD

سپس می‌توانیم اتصالات لازم را انجام دهیم. این مورد در تصویر زیر مشخص شده است.

ماژول LCD و اتصالات آن روی بردبورد

«برای مشاهده تصویر در اندازه اصلی، روی آن کلیک کنید».

نحوه اتصال پین های LCD به آردوینو

با استفاده از سیم جامپر یا سیم تک‌رشته‌ای می‌توانید اتصالات بین ماژول LCD کاراکتری و برد آردوینو را به‌واسطه بردبورد انجام دهید.

در یکی از مطالب پیشین مجله فرادرس به زبان ساده گفتیم که «بردبورد» (Breadboard) چیست که مطالعه آن می‌تواند اطلاعات مفیدی را در مورد این قطعه کاربردی به شما بدهد.

راهنمای پین‌های ماژول نمایشگر ۱۶۰۲ را در ادامه آورده‌ایم.

پین LCD کاراکتری کاربرد
GND پین منفی یا GND تغذیه
VCC پین مثبت یا VCC تغذیه
V0 پین تنظیم کنتراست
RS پین انتخاب رجیستر
R/W پین انتخاب خواندن و نوشتن
E پین E یا سیگنال فعال‌سازی
DB0 پین داده ۰
DB1 پین داده ۱
DB2 پین داده ۲
DB3 پین داده ۳
DB4 پین داده ۴
DB5 پین داده ۵
DB6 پین داده ۶
DB7 پین داده ۷
LED+‎ پین 5v یا مثبت LED پس‌زمینه
LED-‎ پین GND یا منفی LED پس‌زمینه

پین‌های DB2 ،DB1 ،DB0 و DB3 در این پروژه استفاده نمی‌شوند. تصویر آورده شده در زیر نیز، نمایی از پین‌های این نمایشگر را نشان می‌دهد.

نمایی از یک ماژول LCD

اکنون، اتصال پین‌های LCD به پین‌های آردوینو را انجام می‌دهیم. برای این منظور بهتر است از سیم‌هایی با اندازه کوتاه استفاده کنیم تا مدار خلوت و واضح‌تری داشته باشیم. به‌همین دلیل سیم‌های تک‌رشته‌ای انتخاب بهتری هستند.

  • به‌خاطر بیاورید که یکی از لاین‌های بردبورد را به GND اختصاص داده‌ بودیم. در اینجا، پین اول و آخر LCD را به همین لاین مشکی‌رنگ متصل می‌کنیم.
  • به‌همین‌ترتیب، دومین پین LCD یعنی VCC را به لاین قرمزرنگ بردبورد وصل می‌کنیم.
  • در ادامه، پین یکی مانده به آخر LCD یعنی LED+‎ را از طریق یک مقاومت، به لاین قرمزرنگ بردبورد وصل می‌کنیم. به‌گونه‌ای که قطعه مقاومت، در میانه این اتصال قرار می‌گیرد. مقاومت استفاده شده در اینجا یک مقاومت ۲۲۰ اُهمی با خطوط رنگی «قرمز-قرمز-قهوه‌ای» است.

باقی اتصالات LCD به آردوینو را طبق جدول آورده شده در زیر، انجام می‌دهیم.

پین LCD شماره پین آردوینو
DB7 ۳
DB6 ۴
DB5 ۵
DB4 ۶
E ۹
R/W ۱۰ یا به لاین مشکی‌رنگ بردبورد
RS ۱۱
V0 ۱۲ یا به لاین مشکی‌رنگ بردبورد

به‌طور مثال پین DB7 از ماژول LCD را به پین شماره ۳ از روی برد آردوینو متصل می‌کنیم.

حالا می‌توانیم دکمه فشاری یا شستی را روی بردبورد قرار دهیم. به محل قرارگیری این دکمه روی بردبورد در تصویر آورده در زیر توجه کنید. این دکمه را روی شیار وسط بردبورد قرار داده‌ایم.

محل قرار گیری دکمه فشاری روی برد بورد

اکنون، با توجه به پایه‌های سمت بالایی دکمه، اتصالات زیر را انجام می‌دهیم.

  • یکی از پایه‌های سمت بالایی دکمه را به لاین مشکی‌رنگ بردبورد وصل کنید.
  • پایه دیگر را نیز به پین شماره ۲ آردوینو وصل می‌کنیم.

مرحله سرهم کردن قطعات سخت‌افزاری در اینجا به پایان می‌رسد و به سراغ بخش نرم‌افزاری ساخت بازی با آردوینو می‌رویم.

مردی در حال پریدن از موانع

گام دوم: برنامه نویسی بازی Jumpman برای آردوینو

برنامه‌نویسی آردوینو را در محیط کدنویسی و IDE مخصوص Arduino انجام می‌دهیم. بنابراین لازم است تا ابتدا، این برنامه را روی سیستم خود نصب کنید.

  • صفحه دانلود IDE آردوینو: «+»

در صفحه دانلود می‌توانید فایل نصب را با توجه به سیستم عامل خود نظیر ویندوز، مک و لینوکس دانلود کنید. پس از دانلود و نصب این برنامه، با محیطی شبیه به تصویر زیر، رو به رو خواهید شد.

«محیط برنامه نویسی آردوینو» – برای مشاهده تصویر در اندازه اصلی، روی آن کلیک کنید.

سورس کد بازی Jumpman

سورس کد این بازی آردوینو، در قالب یک فایل زیپ از لینک زیر قابل دانلود است.

  • لینک دانلود سورس‌کدهای بازی Jumpman: «+»

پس از دسترسی به فایل سورس‌کدهای بازی به‌نام LCD_Game.ino

 می‌توانید آن را درون IDE آردوینو باز کنید.

دانش آموز در حال طراحی مدار برای ساخت بازی با آردوینو

همچنین، به‌عنوان یک راه دیگر می‌توانید کدهای بازی را از کادر پایین کپی کرده و در ادیتور آردوینو Paste کنید.

1#include <LiquidCrystal.h>
2
3#define PIN_BUTTON 2
4#define PIN_AUTOPLAY 1
5#define PIN_READWRITE 10
6#define PIN_CONTRAST 12
7
8#define SPRITE_RUN1 1
9#define SPRITE_RUN2 2
10#define SPRITE_JUMP 3
11#define SPRITE_JUMP_UPPER '.'         // Use the '.' character for the head
12#define SPRITE_JUMP_LOWER 4
13#define SPRITE_TERRAIN_EMPTY ' '      // User the ' ' character
14#define SPRITE_TERRAIN_SOLID 5
15#define SPRITE_TERRAIN_SOLID_RIGHT 6
16#define SPRITE_TERRAIN_SOLID_LEFT 7
17
18#define HERO_HORIZONTAL_POSITION 1    // Horizontal position of hero on screen
19
20#define TERRAIN_WIDTH 16
21#define TERRAIN_EMPTY 0
22#define TERRAIN_LOWER_BLOCK 1
23#define TERRAIN_UPPER_BLOCK 2
24
25#define HERO_POSITION_OFF 0          // Hero is invisible
26#define HERO_POSITION_RUN_LOWER_1 1  // Hero is running on lower row (pose 1)
27#define HERO_POSITION_RUN_LOWER_2 2  //                              (pose 2)
28
29#define HERO_POSITION_JUMP_1 3       // Starting a jump
30#define HERO_POSITION_JUMP_2 4       // Half-way up
31#define HERO_POSITION_JUMP_3 5       // Jump is on upper row
32#define HERO_POSITION_JUMP_4 6       // Jump is on upper row
33#define HERO_POSITION_JUMP_5 7       // Jump is on upper row
34#define HERO_POSITION_JUMP_6 8       // Jump is on upper row
35#define HERO_POSITION_JUMP_7 9       // Half-way down
36#define HERO_POSITION_JUMP_8 10      // About to land
37
38#define HERO_POSITION_RUN_UPPER_1 11 // Hero is running on upper row (pose 1)
39#define HERO_POSITION_RUN_UPPER_2 12 //                              (pose 2)
40
41LiquidCrystal lcd(11, 9, 6, 5, 4, 3);
42static char terrainUpper[TERRAIN_WIDTH + 1];
43static char terrainLower[TERRAIN_WIDTH + 1];
44static bool buttonPushed = false;
45
46void initializeGraphics(){
47  static byte graphics[] = {
48    // Run position 1
49    B01100,
50    B01100,
51    B00000,
52    B01110,
53    B11100,
54    B01100,
55    B11010,
56    B10011,
57    // Run position 2
58    B01100,
59    B01100,
60    B00000,
61    B01100,
62    B01100,
63    B01100,
64    B01100,
65    B01110,
66    // Jump
67    B01100,
68    B01100,
69    B00000,
70    B11110,
71    B01101,
72    B11111,
73    B10000,
74    B00000,
75    // Jump lower
76    B11110,
77    B01101,
78    B11111,
79    B10000,
80    B00000,
81    B00000,
82    B00000,
83    B00000,
84    // Ground
85    B11111,
86    B11111,
87    B11111,
88    B11111,
89    B11111,
90    B11111,
91    B11111,
92    B11111,
93    // Ground right
94    B00011,
95    B00011,
96    B00011,
97    B00011,
98    B00011,
99    B00011,
100    B00011,
101    B00011,
102    // Ground left
103    B11000,
104    B11000,
105    B11000,
106    B11000,
107    B11000,
108    B11000,
109    B11000,
110    B11000,
111  };
112  int i;
113  // Skip using character 0, this allows lcd.print() to be used to
114  // quickly draw multiple characters
115  for (i = 0; i < 7; ++i) {
116	  lcd.createChar(i + 1, &graphics[i * 8]);
117  }
118  for (i = 0; i < TERRAIN_WIDTH; ++i) {
119    terrainUpper[i] = SPRITE_TERRAIN_EMPTY;
120    terrainLower[i] = SPRITE_TERRAIN_EMPTY;
121  }
122}
123
124// Slide the terrain to the left in half-character increments
125//
126void advanceTerrain(char* terrain, byte newTerrain){
127  for (int i = 0; i < TERRAIN_WIDTH; ++i) {
128    char current = terrain[i];
129    char next = (i == TERRAIN_WIDTH-1) ? newTerrain : terrain[i+1];
130    switch (current){
131      case SPRITE_TERRAIN_EMPTY:
132        terrain[i] = (next == SPRITE_TERRAIN_SOLID) ? SPRITE_TERRAIN_SOLID_RIGHT : SPRITE_TERRAIN_EMPTY;
133        break;
134      case SPRITE_TERRAIN_SOLID:
135        terrain[i] = (next == SPRITE_TERRAIN_EMPTY) ? SPRITE_TERRAIN_SOLID_LEFT : SPRITE_TERRAIN_SOLID;
136        break;
137      case SPRITE_TERRAIN_SOLID_RIGHT:
138        terrain[i] = SPRITE_TERRAIN_SOLID;
139        break;
140      case SPRITE_TERRAIN_SOLID_LEFT:
141        terrain[i] = SPRITE_TERRAIN_EMPTY;
142        break;
143    }
144  }
145}
146
147bool drawHero(byte position, char* terrainUpper, char* terrainLower, unsigned int score) {
148  bool collide = false;
149  char upperSave = terrainUpper[HERO_HORIZONTAL_POSITION];
150  char lowerSave = terrainLower[HERO_HORIZONTAL_POSITION];
151  byte upper, lower;
152  switch (position) {
153    case HERO_POSITION_OFF:
154      upper = lower = SPRITE_TERRAIN_EMPTY;
155      break;
156    case HERO_POSITION_RUN_LOWER_1:
157      upper = SPRITE_TERRAIN_EMPTY;
158      lower = SPRITE_RUN1;
159      break;
160    case HERO_POSITION_RUN_LOWER_2:
161      upper = SPRITE_TERRAIN_EMPTY;
162      lower = SPRITE_RUN2;
163      break;
164    case HERO_POSITION_JUMP_1:
165    case HERO_POSITION_JUMP_8:
166      upper = SPRITE_TERRAIN_EMPTY;
167      lower = SPRITE_JUMP;
168      break;
169    case HERO_POSITION_JUMP_2:
170    case HERO_POSITION_JUMP_7:
171      upper = SPRITE_JUMP_UPPER;
172      lower = SPRITE_JUMP_LOWER;
173      break;
174    case HERO_POSITION_JUMP_3:
175    case HERO_POSITION_JUMP_4:
176    case HERO_POSITION_JUMP_5:
177    case HERO_POSITION_JUMP_6:
178      upper = SPRITE_JUMP;
179      lower = SPRITE_TERRAIN_EMPTY;
180      break;
181    case HERO_POSITION_RUN_UPPER_1:
182      upper = SPRITE_RUN1;
183      lower = SPRITE_TERRAIN_EMPTY;
184      break;
185    case HERO_POSITION_RUN_UPPER_2:
186      upper = SPRITE_RUN2;
187      lower = SPRITE_TERRAIN_EMPTY;
188      break;
189  }
190  if (upper != ' ') {
191    terrainUpper[HERO_HORIZONTAL_POSITION] = upper;
192    collide = (upperSave == SPRITE_TERRAIN_EMPTY) ? false : true;
193  }
194  if (lower != ' ') {
195    terrainLower[HERO_HORIZONTAL_POSITION] = lower;
196    collide |= (lowerSave == SPRITE_TERRAIN_EMPTY) ? false : true;
197  }
198  
199  byte digits = (score > 9999) ? 5 : (score > 999) ? 4 : (score > 99) ? 3 : (score > 9) ? 2 : 1;
200  
201  // Draw the scene
202  terrainUpper[TERRAIN_WIDTH] = '';
203  terrainLower[TERRAIN_WIDTH] = '';
204  char temp = terrainUpper[16-digits];
205  terrainUpper[16-digits] = '';
206  lcd.setCursor(0,0);
207  lcd.print(terrainUpper);
208  terrainUpper[16-digits] = temp;  
209  lcd.setCursor(0,1);
210  lcd.print(terrainLower);
211  
212  lcd.setCursor(16 - digits,0);
213  lcd.print(score);
214
215  terrainUpper[HERO_HORIZONTAL_POSITION] = upperSave;
216  terrainLower[HERO_HORIZONTAL_POSITION] = lowerSave;
217  return collide;
218}
219
220// Handle the button push as an interrupt
221void buttonPush() {
222  buttonPushed = true;
223}
224
225void setup(){
226  pinMode(PIN_READWRITE, OUTPUT);
227  digitalWrite(PIN_READWRITE, LOW);
228  pinMode(PIN_CONTRAST, OUTPUT);
229  digitalWrite(PIN_CONTRAST, LOW);
230  pinMode(PIN_BUTTON, INPUT);
231  digitalWrite(PIN_BUTTON, HIGH);
232  pinMode(PIN_AUTOPLAY, OUTPUT);
233  digitalWrite(PIN_AUTOPLAY, HIGH);
234  
235  // Digital pin 2 maps to interrupt 0
236  attachInterrupt(0/*PIN_BUTTON*/, buttonPush, FALLING);
237  
238  initializeGraphics();
239  
240  lcd.begin(16, 2);
241}
242
243void loop(){
244  static byte heroPos = HERO_POSITION_RUN_LOWER_1;
245  static byte newTerrainType = TERRAIN_EMPTY;
246  static byte newTerrainDuration = 1;
247  static bool playing = false;
248  static bool blink = false;
249  static unsigned int distance = 0;
250  
251  if (!playing) {
252    drawHero((blink) ? HERO_POSITION_OFF : heroPos, terrainUpper, terrainLower, distance >> 3);
253    if (blink) {
254      lcd.setCursor(0,0);
255      lcd.print("Press Start");
256    }
257    delay(250);
258    blink = !blink;
259    if (buttonPushed) {
260      initializeGraphics();
261      heroPos = HERO_POSITION_RUN_LOWER_1;
262      playing = true;
263      buttonPushed = false;
264      distance = 0;
265    }
266    return;
267  }
268
269  // Shift the terrain to the left
270  advanceTerrain(terrainLower, newTerrainType == TERRAIN_LOWER_BLOCK ? SPRITE_TERRAIN_SOLID : SPRITE_TERRAIN_EMPTY);
271  advanceTerrain(terrainUpper, newTerrainType == TERRAIN_UPPER_BLOCK ? SPRITE_TERRAIN_SOLID : SPRITE_TERRAIN_EMPTY);
272  
273  // Make new terrain to enter on the right
274  if (--newTerrainDuration == 0) {
275    if (newTerrainType == TERRAIN_EMPTY) {
276      newTerrainType = (random(3) == 0) ? TERRAIN_UPPER_BLOCK : TERRAIN_LOWER_BLOCK;
277      newTerrainDuration = 2 + random(10);
278    } else {
279      newTerrainType = TERRAIN_EMPTY;
280      newTerrainDuration = 10 + random(10);
281    }
282  }
283    
284  if (buttonPushed) {
285    if (heroPos <= HERO_POSITION_RUN_LOWER_2) heroPos = HERO_POSITION_JUMP_1;
286    buttonPushed = false;
287  }  
288
289  if (drawHero(heroPos, terrainUpper, terrainLower, distance >> 3)) {
290    playing = false; // The hero collided with something. Too bad.
291  } else {
292    if (heroPos == HERO_POSITION_RUN_LOWER_2 || heroPos == HERO_POSITION_JUMP_8) {
293      heroPos = HERO_POSITION_RUN_LOWER_1;
294    } else if ((heroPos >= HERO_POSITION_JUMP_3 && heroPos <= HERO_POSITION_JUMP_5) && terrainLower[HERO_HORIZONTAL_POSITION] != SPRITE_TERRAIN_EMPTY) {
295      heroPos = HERO_POSITION_RUN_UPPER_1;
296    } else if (heroPos >= HERO_POSITION_RUN_UPPER_1 && terrainLower[HERO_HORIZONTAL_POSITION] == SPRITE_TERRAIN_EMPTY) {
297      heroPos = HERO_POSITION_JUMP_5;
298    } else if (heroPos == HERO_POSITION_RUN_UPPER_2) {
299      heroPos = HERO_POSITION_RUN_UPPER_1;
300    } else {
301      ++heroPos;
302    }
303    ++distance;
304    
305    digitalWrite(PIN_AUTOPLAY, terrainLower[HERO_HORIZONTAL_POSITION + 2] == SPRITE_TERRAIN_EMPTY ? HIGH : LOW);
306  }
307  delay(100);
308}

در این برنامه، از کتابخانه #include <LiquidCrystal.h>

استفاده کرده‌ایم تا از قابلیت‌های نمایشگر کاراکتری بهره‌مند شویم.

از آنجایی‌که قرار است این سورس کد روی آردوینو پروگرام شود، بنابراین لازم تا ابتدا بررسی کنید که نوع برد در IDE آردوینو به‌درستی انتخاب شده باشد. برای این منظور به منوی Tools و گزینه Board رفته و مدل بورد خود – در اینجا Arduino Uno – را انتخاب کنید.

اکنون زمان آن رسیده تا برد آردوینو را به سیستم خود متصل کرده و کدهای بازی را به آن منتقل کنیم. برای این کار کابل USB آردوینو را به سیستم خود وصل می‌کنیم. در صورتی‌که مراحل اتصال را به‌درستی انجام داده باشید، صفحه LCD روشن می‌شود. برای شروع عملیات پروگرام آردوینو، کافی است تا از منوی فایل، گزینه Upload را انتخاب کنید. همچنین می‌توانید از آیکن‌های بالا صفحه، روی «فلش سمت راست» کلیک کنید. پس از چند لحظه که عملیات با موفقیت انجام شد می‌توانید صفحه شروع بازی را روی LCD متصل به آردوینو ببینید. تصویر زیر این مورد را به‌خوبی نشان می‌دهد.

صفحه شروع بازی روی LCD کاراکتری

تصویر آورده شده در زیر نیز، اتصالات بین پین‌های آردوینو و LCD لازم را به‌صورت مختصر و مفید نشان داده است.

«برای مشاهده تصویر در اندازه اصلی، روی آن کلیک کنید».

ایده‌ هایی برای توسعه این بازی

تا این قسمت توانستیم ساخت بازی با آردوینو را به لحاظ سخت‌افزاری و نرم‌افزاری، با موفقیت انجام دهیم و بازی را اجرا و تست کنیم. اکنون می‌خواهیم بگوییم، در صورتی‌که قصد توسعه این پروژه را دارید، یکی از کارهای ممکن می‌تواند این باشد که از بردهای سوراخ‌دار ارزان‌قیمت استفاده کنید و یک شیلد شامل ماژول LCD و دکمه فشاری بسازید که روی آردوئینو قرار می‌گیرد و اتصالات سیمی شلوغ را حذف می‌کند. تصویر زیر، نمونه‌ای از این بردهای خام را نشان داده می‌دهد.

حتی می‌توانید کل مجموعه قطعات را درون جعبه‌ای قرار دهید که کاربر تنها LCD و دکمه فشاری را ببیند. همچنین بسیاری موارد دیگر که با توجه به خلاقیت خود می‌توانید ساختن آن را شروع کنید.

قرار دادن سخت افزار بازی آردوینو درون جعبه

ساخت بازی Reflex با آردوینو چگونه است؟

در این بخش می‌خواهیم به نحوه ساخت یک بازی بسیار ساده به‌نام Reflex با آردوینو بپردازیم که زمان واکنش شما را می‌سنجد و یکی از ساده‌ترین پروژه‌هایی است که می‌توان با آردوینو انجام داد.

معرفی بازی Reflex

در این بازی، یک لامپ LED به حالت روشن و همچنین یک دکمه فشاری در مقابل بازیکن قرار دارد. بازیکن می‌بایست تمامی حواس خود را جمع کند تا هنگام خاموش شدن LED، در سریع‌ترین زمان ممکن، دکمه را فشار دهد. سپس میزان زمان واکنش کاربر برای او به نمایش در می‌آید. هر چه میزان تأخیر پایین‌تر باشد بهتر است.

بازیکن هیجان زده و لامپ روشن - ساخت بازی با آردوینو

وسایل مورد نیاز برای ساخت بازی Reflex با آردوینو

در ادامه، وسایلی که برای ساخت بازی «واکنش» لازم است را فهرست کرده‌ایم.

  • برد آردوینو UNO و کابل USB برای اتصال آن به کامپیوتر
  • بردبورد
  • مقاومت 220Ω
  • مقاومت 10KΩ
  • دکمه فشاری
  • سیم جامپر
  • LED

برای انجام برنامه‌نویسی این بازی نیز از IDE آردوینو استفاده می‌کنیم.

پس از اینکه اتصالات لازم بین قطعات و برد آردوینو و همچنین برنامه‌نویسی آن انجام شد، لازم است تا پنجره سریال‌مانیتور آردوینو را نیز باز کنید. در این پنجره، پیامی با این مضمون به شما نشان داده می‌شود که برای شروع بازی دکمه را فشار دهید. سپس لازم است تا تمامی حواس خود را به LED جمع کنید، هنگامی‌که این لامپ خاموش شد، می‌بایست در سریع‌ترین زمان ممکن دکمه را فشار دهید. با این کار، مدت‌زمانی که طول کشیده تا دکمه را فشار دهید برای شما چاپ می‌شود. این بازی را می‌توانید با دوستان و خانواده خود نیز انجام دهید و در به‌دست آوردن عددی پایین‌تر به رقابت بپردازید.

سریال‌مانیتور، قابلیتی است که در IDE آردوینو می‌توانید به آن دسترسی داشته باشید تا به‌کمک آن پروژه‌های خود را دیباگ کرده، برخی موارد را تست کنید یا اینکه با برد آردوینوی خود تعامل داشته باشید. نحوه دسترسی به این ابزار را در تصویر زیر نشان داده‌ایم.

«نمایی از پنجره Serial Monitor» – برای مشاهده تصویر در اندازه اصلی، روی آن کلیک کنید.

گام اول: سرهم کردن قطعات سخت افزاری

تصویری که در ادامه آورده‌ایم، نمایی از اتصالات بین برد آردوینو و سایر قطعات موجود در این پروژه را به‌خوبی نشان می‌دهد. توجه داشته باشید که در شروع کار لازم نیست تا برد آردوینو را با کابل USB به سیستم خود وصل کنیم.

«برای مشاهده تصویر در اندازه اصلی، روی آن کلیک کنید».

اکنون می‌توانیم اتصالات را به شرح زیر انجام دهیم.

  • پین 5v آردوینو را با یک قطعه سیم جامپر به لاین مثبت بردبورد وصل می‌کنیم.
  • پین GND آردوینو را نیز به‌همین ترتیب به لاین منفی بردبورد متصل می‌شود.
  • پایه مثبت LED را به واسطه یک مقاومت ۲۲۰ اُهمی به پین شماره ۱۳ آردوینو وصل می‌کنیم. پایه منفی آن نیز به لاین منفی بردبورد – که به GND آردوینو متصل است – وصل می‌شود.
  • یکی از پایه‌های دکمه فشاری را به لاین مثبت بردبورد وصل می‌کنیم. پایه دیگر آن را نیز دارای اتصالات زیر است.
    • از طریق مقاومت ۱۰ کیلو اُهمی به لاین منفی بردبورد وصل می‌شود.
    • همچنین، با یک قطعه سیم جامپر، این پایه را به پین شماره ۲ آردوینو وصل می‌کنیم. این مورد در تصویر بالا به‌وضوح مشخص شده است.

گام دوم: برنامه نویسی بازی Reflex برای آردوینو

اکنون زمان آن رسیده تا برنامه‌نویسی این پروژه را انجام دهیم. برای این منظور طبق مراحل زیر پیش می‌رویم.

  • برد آردوینو را با کابل USB به سیستم خود متصل می‌کنیم.
  • مانند پروژه قبل، وارد برنامه IDE آردوینو می‌شویم تا کدها را به روی برد آردوینو منتقل کنیم.
  • نوع برد آردوینو خود را از منوی Tools و گزینه ‌Board انتخاب می‌کنیم.

کدهای آورده شده در این قسمت را کپی کرده و در ادیتور آردوینو، Paste می‌کنیم.

1int ledPin = 13;
2int sensorPin1 = 2;
3long ranDelay = 0;
4int  sensorValue = 0;
5float realTime;
6
7void setup()
8{
9  Serial.begin(9600);
10  pinMode(ledPin, OUTPUT);
11  pinMode(sensorPin1, INPUT);
12}
13
14void loop(){
15  Serial.println("");
16  Serial.println("");
17  Serial.println("");
18  Serial.println("Push the button to start game");
19  
20  while (digitalRead(sensorPin1) == 0) {
21  }
22  Serial.println("");
23  Serial.println("");
24  Serial.println("");
25  Serial.println("Get Ready!");
26  delay(1000);
27  Serial.println("Get Set!");
28  delay(1000);
29  ranDelay = random(5000);
30  delay(ranDelay);
31  Serial.println("Go!");
32  
33  realTime = millis();
34  digitalWrite(ledPin, HIGH);
35 
36  
37  while (digitalRead(sensorPin1)== 0) {
38    
39  }
40  digitalWrite(ledPin, LOW);
41  Serial.println("Your time was");
42  realTime = millis()-realTime;
43  Serial.print(realTime/1000,2);
44  Serial.println(" seconds");
45 delay(2000); 
46}

اکنون، از میان دکمه‌‌های بالای IDE، روی آیکن «فلش سمت راست» کلیک کرده و صبر می‌کنیم تا عملیات آپلود تمام شود.

در ادامه، توضیحات مربوط به این کدها را آورده‌ایم.

خطوط شماره ۱ تا ۵: در این خطوط متغیرهایی تعریف کرده‌ایم که به پین‌های مورد استفاده روی آردوینو اشاره دارند. به‌طور مثال، ledPin

نامی است که برای پین شماره ۱۳ در نظر گرفته‌ایم. sensorPin1

نیز به پین متصل به دکمه، یعنی پین شماره ۲ اشاره دارد. همچنین، متغیرهایی مانند realTime

و ranDelay

را تعریف کرده‌ایم که برای نگه‌داری زمان استفاده می‌شوند. sensorValue

نیز وضعیت دکمه را حفظ می‌کند.

خطوط شماره ۹ تا ‍‍۱۱: در این خطوط، ابتدا پورت سریال با نرخ ۹۶۰۰ بیت بر ثانیه تنظیم می‌شود. پس از آن، پین‌های ledPin

و sensorPin1

، به‌ترتیب به‌عنوان پین‌هایی از جنس «خروجی» ( OUTPUT

 ) و «ورودی» ( sensorPin1

 ) تعریف شده‌اند.

نوجوان در حال ساخت بازی با آردوینو

سپس وارد بدنه اصلی برنامه می‌شویم.

  • خطوط شماره ۱۵ تا ‍‍۱۸: از دستور Serial.println(“”)

     برای درج چندین خط خالی در پنجره سریال‌مانیتور و با دستور Serial.println(“Push the button to start game”);

     به بازیکن می‌گوییم که برای شروع بازی، کلید را فشار دهد.

  • خط شماره ۲۰: در اینجا مقدار پین دیجیتال sensorPin1

    خوانده می‌شود. سنسور یا همان دکمه ما، در حالت فشرده نشده دارای مقداری برابر با 0

    خواهد بود. بنابراین در اینجا منتظر فشردن دکمه توسط بازیکن می‌ماند. پس از فشردن دکمه، اجرای کدها ادامه پیدا می‌کند.

  • خطوط شماره ۲۲ تا ‍‍۳۱: پس از درج ۳ خط خالی، پیام Get Ready!

    به مدت ۱ ثانیه – یا ۱۰۰۰ میلی‌ثانیه – در سریال‌مانیتور نمایش داده می‌شود. پس از آن، پیام Get Set!

    نیز چاپ می‌شود. سپس با تابع random

     ، عددی تصادفی بین ۰ تا ۴۹۹۹ میلی‌ثانیه تولید شده و پس از گذشت همین مقدار مدت‌زمان، پیام Go!

    برای کاربر چاپ می‌شود.

  • خط شماره ۳۳: مدت‌زمان سپری شده از زمان روشن شدن آردوینو تا این لحظه را به‌کمک تابع millis()

    در متغیر realTime

    قرار می‌دهیم.

  • خط شماره ۳۴: در نهایت LED روشن می‌شود.
  • خطوط شماره ۳۷ تا ‍‍۴۶: در این خطوط حلقه دوم را داریم که منتظر می‌ماند تا کاربر، دکمه را مجدد فشار دهد. در این ‌صورت، LED خاموش می‌شود. پس از محاسبه زمان واکنش کاربر، مقدار آن را نیز چاپ می‌کند. زمان واکنش در واقع مدت‌زمان بین روشن شدن LED تا فشردن دکمه توسط کاربر است.

ادامه یادگیری آردوینو با فرادرس

اکنون که با نحوه طراحی و ساخت بازی با آردوینو آشنا شدید، وقت آن رسیده تا مهارت‌های خود را در مورد بردهای آردوینو تقویت کنید. برای این منظور، به شما پیشنهاد می‌کنیم تا فیلم‌های آموزشی زیر از فرادرس را نیز تماشا کنید.

نوجوان در حال ساخت بازی با آردوینو

جمع‌بندی

بردهای آردوئینو به زبان ساده، پلتفرم‌‌هایی هستند که به کمک آن‌ها می‌توانید پروژه‌های جذاب الکترونیکی خود را با کم‌ترین پیچیدگی ایجاد کرده و برنامه‌نویسی کنید.

این بردها را می‌توان با زبانی شبیه به زبان C++‎ برنامه‌نویسی کرد تا ورودی‌‌های دریافتی از طریق سنسورها را پردازش کرده و خروجی مناسبی را تولید کنند. ورودی‌های آردوینو به‌طور مثال، می‌توانند داده‌های آنالوگی باشند که از سنسور تشخیص گاز می‌آیند یا فرمان دیجیتالی باشند که برد ما از طریق کامپیوتر دریافت می‌کند یا سایر موارد این‌چنینی که پس از پردازش شدن توسط میکروکنترلر می‌توانند تبدیل به خروجی شوند و یک‌سری عملیات را انجام دهند.

بردهای Arduino در موارد گوناگونی از جمله اهداف آموزشی می‌توانند مورد استفاده قرار گیرند و ما در این مطلب از مجله فرادرس به یکی از کاربردهای جذاب آن یعنی ساخت بازی با آردوینو پرداختیم. نخستین بازی مورد بحث در این نوشتار، Jumpman نام داشت و با افزودن یک ماژول LCD، دکمه فشاری و مقاومت توانستیم آن را راه‌اندازی کنیم. سپس بازی ساده دیگری را ساختیم که زمان واکنش بازیکن به خاموش شدن LED را نشان می‌داد. شما می‌توانید خلاقیت به خرج داده و با کمی تغییر، هر یک از این بازی‌ها را توسعه دهید و در این بین، مباحث جدیدتری را یاد بگیرید.

source

توسط expressjs