آردوینو یک برد الکترونیکی است که بهصورت اپن سورس عرضه شده است و افزون بر میکروکنترلر، امکاناتی را برای دریافت ورودیها، پردازش آنها و تولید خروجی، روی خود دارد. به زبان ساده، آردوینو را میتوانید کامپیوتر بسیار کوچکی در نظر بگیرید که میتوان روی آن برنامهنویسی کرد تا از این طریق وظایف خاصی که در نظر دارید را انجام دهد. آردوینو موارد استفاده جذاب و گوناگونی دارد و میتوان گفت که افزون بر اهداف آموزشی میتواند در پیادهسازی پروژههای متعددی نظیر بازیسازی نیز مورد استفاده قرار گیرد. در این مطلب از مجله فرادرس، سعی کردهایم تا به زبانی ساده و تا حد ممکن بهطور کامل به شما توضیح دهیم که نحوه ساخت بازی با آردوینو چگونه است و برای انجام آن، به چه ابزاری نیاز دارید، چه مراحلی را میبایست طی کنید و بهطور کلی چه کارهایی را باید انجام دهید.
بردهای آردوینو یا «آردوئینو» (Arduino) در مدلهای گوناگونی عرضه میشوند و از میکروکنترلرها یا ریزپردازندههای متنوعی بهره میبرند. از مدلهای آردوینو میتوان آردوینوهای «اونو» (UNO)، مگا، نانو، MKR و میکرو اشاره کرد. روی اینگونه بردها افزون بر ریزپردازنده یا میکروکنترلر، موارد دیگری مانند پینهای «ورودی و خروجی» برای دادههای آنالوگ و دیجیتال، کریستال، LED تست، رگولاتور ۳٫۳ ولت و ۵ ولت، دکمه ریست، کریستالهای نوسانساز، پینهای تغذیه ماژولها، پین ICSP و غیره اشاره کرد. بهطور معمول، این بردها را میتوان با اتصال آداپتور DC به سوکت تعبیه شده روی برد، تغذیه کرد و محدوده ولتاژ توصیه شده برای آن بین ۷ تا ۱۲ ولت است. ضمن اینکه با اتصال کابل USB به برد و کامپیوتر خود نیز میتوانید آن را راهاندازی کنید. برای برنامهنویسی بردهای آردوینو از زبان مخصوصی شبیه به C++ استفاده میشود. این پلتفرمها در موارد گوناگونی همچون اتوماسیون منازل، گلخانه هوشمند، انواع رباتها، پهپادها، پرینتر ۳-بُعدی و بسیاری موارد دیگر میتوانند بهکار گرفته شوند. در این نوشتار، تمرکز ما روی بازیسازی با Arduino است و ضمن معرفی ابزارهای موردنیاز، نحوه ساخت بازی با آردوینو را در قالب ۲ بازی Jumpman و Reflex، به شما توضیح میدهیم.
ساخت بازی با آردوینو چگونه است؟
با پلتفرم اپن سورس آردوینو، پروژههای گوناگونی را میتوانید انجام دهید که ساخت بازی، یکی از آنها است. بهطور معمول، ماژولهای نمایشگر، پایه ثابت ساخت بازی با آردوینو محسوب میشوند.
در این مطلب، ساخت بازی با آردوینو را از طریق آموزش ساخت بازیهای زیر به شما یاد میدهیم.
- بازی جامپمن یا Jumpman: یک بازی پلتفرمی که کاراکتر بازی در حال دویدن است و میبایست آن را به نحوی هدایت کنید که از موانع پیش روی خود به سلامت عبور کند.
- بازی تست واکنش Reflex: یک بازی بسیار ساده که سرعت عکسالعمل شما را به خاموش شدن یک LED میسنجد.
همانطور که در مقدمه هم اشاره شد به لطف وجود بردهای آردوینو میتوان سنسورهایی را به ورودیهای فراهم شده در این برد متصل کرد تا دادهها و ورودیهای آنالوگ و دیجیتال را از محیط پیرامون خود دریافت کند. سپس این دادهها توسط میکروکنترلر پردازش شده و در نهایت میتوانند اثری را روی محیط اطراف خود داشته باشند. بهطور مثال، آردوئینو را میتوان به نحوی برنامهریزی کرد که با ماژول سنسور دما، میزان گرم بودن هوای اطراف خود را سنجیده و در صورتی که مقدار دما از حد مشخصی فراتر رفت، سیستم سرمایشی را روشن کند و بسیاری کاربرد جذاب دیگر که میتوان از آنها بهرهمند شد.
بهطور کلی، پروژههای زیادی وجود دارند که بهعنوان یک فرد مشتاق به فناوری یا یک دانشآموز که قصد افزایش مهارتهای خود را دارد میتوانید آنها را با آردوینو پیادهسازی کنید.
یادگیری آردوینو با فرادرس چگونه است؟
آموختن کار با بردهای آردوینو و نحوه برنامهنویسی آنها را میتوان یکی از بهترین شیوههای ورود به برنامهنویسی میکروکنترلرها و خلق پروژهها بسیار جذاب الکترونیکی دانست. این فرایند، پیچیدگی زیادی ندارد و افراد گوناگون با پیشزمینههای مختلف نیز میتوانند آن را بیاموزند و از مزایای آن بهرهمند شوند. فرقی نمیکند دانشآموز باشید و برای سرگرمی قصد یادگیری آردوئینو را دارید یا اینکه فردی با سن بسیار بالاتر، در هر حال اگر بخواهید مهارت جدیدی مانند استفاده از بردهای آردوینو برای برنامهنویسی الکترونیک و پیادهسازی پروژههایی نظیر اتوماسیون منازل را یاد بگیرید، روشهای گوناگون و متنوعی برای این کار پیشِ روی شما قرار دارد. بهطور مثال، میتوانید در کلاسهای حضوری شرکت کنید، یا حتی دورههای آموزشی در پلتفرمهایی نظیر یوتیوب را تماشا کنید و غیره. هر کدام از این منابع، مزایا و معایب خود را دارند. در این میان، تماشای فیلمهای آموزشی یکی از شیوههای مدرن و مؤثر در یادگیری مهارتهای جذابی مانند آردوینو بهشمار میروند و فارغ از اینکه در چه شهر و کشوری زندگی میکنید یا چه ساعاتی از روز را به یادگیری اختصاص میدهید، این فیلمهای آموزش، شما را در مسیر یادگیری مهارت مورد نظرتان همراهی میکنند. ضمن اینکه در زمان و هزینه شما نیز صرفهجویی میشود.
فرادرس بهعنوان یکی از محبوبترین پلتفرمهای آموزشی کشور، فیلمهای آموزشی گوناگونی را برای مهارتهای مختلف مرتبط با علوم کامپیوتری از جمله نحوه استفاده و برنامهنویسی بردهای آردوینو، منتشر کرده است. در ادامه، مجموعه فیلمهای آموزش «آردوینو» (Arduino)، مقدماتی تا پیشرفته از فرادرس را آوردهایم. این فیلمهای آموزشی، مباحث گوناگون و پروژهمحوری از بردهای آردوئینو را شامل میشوند که بسته به اهداف خود میتوانید مورد دلخواه را تهیه و مشاهده کنید.
برخی از فیلمهای آموزش موجود در این مجموعه را در ادامه معرفی کردهایم.
شما همچنین میتوانید با فیلمهای آموزش رایگان آردوینو شروع کنید که لینک آنها را در ادامه آوردهایم.
ساخت بازی Jumpman با آردوینو چگونه است؟
در این بخش میخواهیم به نحوه ساخت بازی Jumpman با آردوینو بپردازیم.
معرفی بازی Jumpman
بازی Jumpman یا «مردی که میپرد»، یک بازی ساده در سبک پرشی و همچنین «حرکت به طرفین» (Side-Scrolling) است. درست مانند بازی پلتفرمی سوپرماریو، در این نوع بازیها زاویه دید بازیکن از پهلوی صفحه است و کاراکتر را میبایست به چپ یا راست هدایت کنیم. تصویر آورده شده در زیر نمایی از این بازی را نشان میدهد.
در این بازی ساده، شخصیت بازی را مشاهده میکنیم که در مسیری مستقیم در حال دویدن است و موانع متعددی در مقابل او قرار میگیرند. شخصیت بازی میبایست با نزدیک شدن به موانع، از روی آنها بپرد یا در صورتی که موانع در بالای سر او قرار گرفته باشند، از پریدن خودداری کند. در صورتیکه بازیکن با موانع برخوردی داشته باشد، بازی تمام میشود. در گوشه صفحه بازی، یک شمارنده قرار گرفته که میتوان آن را معادل امتیاز یا زمان پیشرفت در بازی در نظر گرفت. در این بازی تنها یک دکمه فشاری وجود دارد که عمل پرش شخصیت اصلی بازی را بر عهده دارد. یعنی با هر مرتبه فشردن این دکمه، شاهد یکمرتبه پرش کاراکتر بازی خواهیم بود.
در صورتیکه تمایل به انجام این بازی از طریق شبیهسازی کامپیوتری را دارید، میتوانید از لینک آورده شده در زیر استفاده کنید و در صفحه باز شده روی دکمه Simulate و سپس روی Start Simulation کلیک کنید. همانطور که در تصور زیر هم قابل مشاهده است، تنها یک دکمه برای شروع و کنترل بازی داریم که در کنار ماژول LCD قرار گرفته است.
- لینک شبیهساز بازی Jumpman: «+»
ساخت این بازی ساده با آردوئینو، میتواند نقطه شروع خوبی برای بازیسازی با این نوع از پلتفرمهای الکترونیکی باشد.
وسایل مورد نیاز برای ساخت بازی Jumpman با آردوینو
در ادامه، عناوین وسایل و لوازم مورد نیاز برای ساخت این بازی با آردوینو را آوردهایم.
- برد آردوینو UNO
- نمایشگر LCD (۱۶×۲ کاراکتری)
- بردبورد (Breadboard)
- مقاومت ۲۲۰ اُهم
- دکمه فشاری
- کابل USB
- سیم جامپر یا سیم تکرشتهای برای اتصالات
در این پروژه از آردوینو مدل «اونو» استفاده کردهایم که نمایی از آن را در تصویر زیر مشاهده میکنید.
گام اول: سرهم کردن قطعات سخت افزاری
توجه داشته باشید که در ابتدای کار و هنگام اسمبل یا مونتاژ قطعات، بورد آردوینو میبایست خاموش باشد. پس اگر کابل USB متصل به آردوینو، به سیستم کامپیوتری شما وصل است، لازم است تا آن را فعلا جدا کنید.
سپس با استفاده از یک قطعه سیم تکرشتهای، پین 5v آردوینو را به یکی از لاینهای بردبورد که با خطی قرمزرنگ و برچسب + نشان داده شده است، وصل میکنیم. این مورد را با فلش قرمزرنگ در تصویر زیر نشان دادهایم.
با توجه به اتصالات داخلی بردبورد، سوراخهای موجود در هریک از این ردیفها از داخل به هم وصل هستند. بنابراین با اتصال پین 5v آردوینو به یکی از این سوراخها، دیگر سوراخهای موجود در این ردیف از بردبورد نیز دارای ولتاژ 5v خواهند بود.
با قطعه سیم دیگری، پین GND آردوینو را به یکی از سوراخهای لاین منفی بردبورد که با فلش مشکیرنگ مشخص شده، وصل میکنیم.
حالا به سراغ ماژول 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 به پینهای آردوینو را انجام میدهیم. برای این منظور بهتر است از سیمهایی با اندازه کوتاه استفاده کنیم تا مدار خلوت و واضحتری داشته باشیم. بههمین دلیل سیمهای تکرشتهای انتخاب بهتری هستند.
- بهخاطر بیاورید که یکی از لاینهای بردبورد را به 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 و دکمه فشاری را ببیند. همچنین بسیاری موارد دیگر که با توجه به خلاقیت خود میتوانید ساختن آن را شروع کنید.
ساخت بازی Reflex با آردوینو چگونه است؟
در این بخش میخواهیم به نحوه ساخت یک بازی بسیار ساده بهنام Reflex با آردوینو بپردازیم که زمان واکنش شما را میسنجد و یکی از سادهترین پروژههایی است که میتوان با آردوینو انجام داد.
معرفی بازی Reflex
در این بازی، یک لامپ LED به حالت روشن و همچنین یک دکمه فشاری در مقابل بازیکن قرار دارد. بازیکن میبایست تمامی حواس خود را جمع کند تا هنگام خاموش شدن LED، در سریعترین زمان ممکن، دکمه را فشار دهد. سپس میزان زمان واکنش کاربر برای او به نمایش در میآید. هر چه میزان تأخیر پایینتر باشد بهتر است.
وسایل مورد نیاز برای ساخت بازی Reflex با آردوینو
در ادامه، وسایلی که برای ساخت بازی «واکنش» لازم است را فهرست کردهایم.
- برد آردوینو UNO و کابل USB برای اتصال آن به کامپیوتر
- بردبورد
- مقاومت 220Ω
- مقاومت 10KΩ
- دکمه فشاری
- سیم جامپر
- LED
برای انجام برنامهنویسی این بازی نیز از IDE آردوینو استفاده میکنیم.
پس از اینکه اتصالات لازم بین قطعات و برد آردوینو و همچنین برنامهنویسی آن انجام شد، لازم است تا پنجره سریالمانیتور آردوینو را نیز باز کنید. در این پنجره، پیامی با این مضمون به شما نشان داده میشود که برای شروع بازی دکمه را فشار دهید. سپس لازم است تا تمامی حواس خود را به LED جمع کنید، هنگامیکه این لامپ خاموش شد، میبایست در سریعترین زمان ممکن دکمه را فشار دهید. با این کار، مدتزمانی که طول کشیده تا دکمه را فشار دهید برای شما چاپ میشود. این بازی را میتوانید با دوستان و خانواده خود نیز انجام دهید و در بهدست آوردن عددی پایینتر به رقابت بپردازید.
سریالمانیتور، قابلیتی است که در IDE آردوینو میتوانید به آن دسترسی داشته باشید تا بهکمک آن پروژههای خود را دیباگ کرده، برخی موارد را تست کنید یا اینکه با برد آردوینوی خود تعامل داشته باشید. نحوه دسترسی به این ابزار را در تصویر زیر نشان دادهایم.
گام اول: سرهم کردن قطعات سخت افزاری
تصویری که در ادامه آوردهایم، نمایی از اتصالات بین برد آردوینو و سایر قطعات موجود در این پروژه را بهخوبی نشان میدهد. توجه داشته باشید که در شروع کار لازم نیست تا برد آردوینو را با کابل 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