فهرست مطالب:

بازی Arduino OLED Snake: 3 مرحله
بازی Arduino OLED Snake: 3 مرحله

تصویری: بازی Arduino OLED Snake: 3 مرحله

تصویری: بازی Arduino OLED Snake: 3 مرحله
تصویری: NOOBS PLAY CLASH ROYALE FROM START LIVE 2024, جولای
Anonim
بازی مار آردوینو OLED
بازی مار آردوینو OLED

سلام و خوش آمدید ، به دستورالعمل های ما در مورد نحوه ساخت و arduino OLED Game ، این پروژه در حالی ایجاد شد که ما سعی می کردیم اولین بازی خود را با arduino انجام دهیم ، بنابراین ، ما فکر کردیم که بهتر از مار کلاسیک نوکیا از کجا شروع کنیم (خوب در حداقل یک کلون مار:))

آنچه شما نیاز خواهید داشت

تدارکات

آردوینو UNO یا کلون

صفحه نمایش OLED

4 دیود

مقاومت 500-1k

4 دکمه کنترل

زنگ منفعل پیزو

اختیاری

تخته نان بدون جوش

لطفاً توجه داشته باشید که این پیوندها فقط برای مثال هستند

مرحله 1: مدار

مدار
مدار

در تصویر بالا می توانید مدار ما را مشاهده کنید ، ما از پین d3 در آردوینو به عنوان پین درخواست وقفه استفاده می کنیم تا آردوینو اولویت خواندن ورودی های کنترلر را که d4 d5 d6 d7 هستند ، قرار دهد. اصول اولیه مدار این است که یک دکمه جهت فشار داده می شود که 5 ولت بالا می رود و این باعث می شود که پین درخواست وقفه (سیم بنفش d3) و یک پین جهت مربوطه فعال شود ، تابع وقفه یک تابع جهت به روز رسانی می نامد و این کد مار را بر این اساس حرکت می دهد. پین 9 به عنوان پین صدا استفاده می شود زیرا یک PWM (مدولاسیون عرض پالس) است که مستقیماً به یک پیزو 5 ولت در پین + متصل می شود و - به 0 ولت/زمین باز می گردد.

(FYI در arduino uno و کلون فقط d2 و d3 می تواند به عنوان پین درخواست وقفه عمل کند).

پین های جهت:

d4 تا نارنجی

d5 پینک پایین

d6 چپ آبی

d7 راست BROWN

صدای d9 خاکستری است

هر دکمه دارای ورودی اتصال 5 ولت و خروجی است که ابتدا به آردوینو به ورودی دیجیتال مربوطه متصل می شود ، همین خروجی هر دکمه سپس به دیود خود متصل می شود ، ما از دیودها برای متوقف کردن تغذیه ولتاژ به دکمه های دیگر و فعال سازی آنها در انتهای کاتد (-) هر 4 دیود ما آنها را به هم متصل می کنیم تا یک اتصال خروجی ایجاد کنیم که به d3 متصل می شود و سپس از طریق یک مقاومت به 0v/earth پین های آردوینو را پایین می کشد تا در صورت عدم وجود پین های شناور باقی نماند. فعال شد

(FYI یک پین شناور می تواند ولتاژ فانتوم را دریافت کرده و باعث ایجاد رفتار غیرمعمول شود)

2 پین آنالوگ برای هدایت صفحه نمایش استفاده می شود ، این پین های سخت افزاری arduino i2c هستند.

A5 به SCL YELLOW متصل است

A4 به SDA GREEN متصل است

خروجی +5v و 0v (زمین) از آردوینو به عنوان منبع تغذیه کل مدار استفاده می شود که می تواند توسط USB یا شارژر تلفن تغذیه شود.

مرحله 2: کد

// ------------------------ بازی ANJAWARE SNAKE با کمک مردم خالص --------------- -------

#عبارتند از

#شامل // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // مجموعه نمایش (عرض ، ارتفاع) صفحه نمایش Adafruit_SSD1306 (128 ، 64) ؛ // پین های ورودی را تعریف کنید اینها پین های آردوینو هستند که هرگز تغییر نمی کنند بنابراین #تعریف کنید #INTPIN 3 را تعریف کنید // فقط پین های 2 و 3 را می توان در UNO #depine UPPIN 4 پین متصل کرد // این پین ها هستند که tp سوئیچ مربوطه #تعریف می کنند DWNPIN 5 #تعریف LFTPIN 6 #تعریف RHTPIN 7 #تعریف SND 9 // تعریف مسیرها #تعریف DIRUP 1 // این مقادیر همان چیزی است که "مار" برای تصمیم گیری به آن نگاه می کند- #تعریف DIRDOWN 2 // جهت حرکت مار # تعریف DIRLEFT 3 #تعریف DIRRIGHT 4

// متغیرهای دکمه را تنظیم کنید

// volitile cos ما به آن نیاز داریم تا با interupt به روز شود ، بنابراین می تواند هر مقدار از چرخه باشد

// هرگز بالاتر از 4 نیست بنابراین فقط به 8bit int نیاز دارید تا منابع فرار uint8_t buttonpressed = 0؛ bool butup = 0؛ bool butdown = 0؛ // ما از این مورد برای تعیین true برای "تشخیص" جهت فشاردهی bool butleft = 0 استفاده می کنیم. bool butright = 0؛

// مارهای داخلی

بایت snakePosX [30]؛ // آرایه برای ساخت بدن مار بایت snakePosY [30]؛

int snakeX = 30 ؛ // موقعیت سر مار

int snakeY = 30 ؛ int snakeSize = 1؛ // تعداد مارها محدود به اندازه آرایه است

// بین المللی جهان

uint8_t worldMinX = 0؛ // اینها محدوده های منطقه بازی را تعیین می کنند

uint8_t worldMaxX = 128؛ uint8_t worldMinY = 10 ؛ uint8_t worldMaxY = 63؛

// جمع آوری اسکران (غذا) و موقعیت اسکران

bool scranAte = 0؛ uint8_t scranPosX = 0 ؛ uint8_t scranPosY = 0 ؛

// متغیرها را نمره گذاری می کند

امتیاز بازی طولانی = 0 ؛ بالاترین امتیاز = 30 ؛ // نمره بالا را به عنوان جمع آوری 3 به عنوان نقطه شروع تنظیم کنید

// --------------------------- این چیزی است که interupt در افزایش ولتاژ اجرا می کند ------------ -------------

void interruptpressed () {تاخیر (150)؛ // تاخیر اندک برای افزودن حفاظت "bounce" updatedirection ()؛ } // ------------------ مقدار جهت را با فشار دکمه به روز کنید ----------------- void updatedirection () { // Serial.println ("updatedirection") ؛ butup = digitalRead (UPPIN) ؛ // بررسی کنید که کدام ورودی بالا رفته است و bool true butdown = digitalRead (DWNPIN) را تنظیم کنید ؛ butleft = digitalRead (LFTPIN)؛ butright = digitalRead (RHTPIN) ؛ // اینها در صورتی که ورزشکاران ببینند کدام ورودی زیاد شده و مقدار مربوطه را در متغیر "buttonpressed" // وارد می کند ، این متغیر جهت حرکت را تعیین می کند اگر (butup == true) {buttonpressed = DIRUP؛ // Serial.println ("UP pressed") ؛ // Serial.println (تحت فشار) butup = false؛ تن (SND ، 1500 ، 10) ؛ } if (butdown == true) {buttonpressed = DIRDOWN؛ // Serial.println ("DOWN pressed") ؛ // Serial.println (تحت فشار) butdown = false؛ تن (SND ، 1500 ، 10) ؛ }

if (butleft == true)

{buttonpressed = DIRLEFT؛ // Serial.println ("چپ فشار داده شده") ؛ // Serial.println (تحت فشار) butleft = false؛ تن (SND ، 1500 ، 10) ؛ } if (butright == true) {buttonpressed = DIRRIGHT؛ // Serial.println ("RIGHT pressed") ؛ // Serial.println (تحت فشار) butright = false؛ تن (SND ، 1500 ، 10) ؛ }}

// -------------------------- رسم روالهای نمایش ------------------ -----------------

void updateDisplay () // رسم نمرات و طرح کلی

{// Serial.println ("به روز رسانی صفحه نمایش") ؛

display.fillRect (0 ، 0 ، display.width ()-1 ، 8 ، BLACK) ؛

display.setTextSize (0) ؛ display.setTextColor (سفید) ؛ // رسم نمرات display.setCursor (2 ، 1) ؛ display.print ("امتیاز:")؛ display.print (رشته (نمای پخش ، DEC)) ؛ display.setCursor (66 ، 1) ؛ display.print ("بالا:")؛ display.print (رشته (بالاترین امتیاز ، DEC)) ؛ // رسم منطقه بازی // pos 1x، 1y، 2x، 2y، color display.drawLine (0، 0، 127، 0، WHITE)؛ // بسیار بالای صفحه نمایش. drawLine (63 ، 0 ، 63 ، 9 ، WHITE) ؛ // نمره seperator display.drawLine (0 ، 9 ، 127 ، 9 ، WHITE) ؛ // زیر صفحه نمایش text.drawLine (0 ، 63 ، 127 ، 63 ، WHITE) ؛ // صفحه پایانی display.drawLine (0 ، 0 ، 0 ، 63 ، WHITE) ؛ // border left display.drawLine (127 ، 0 ، 127 ، 63 ، WHITE) ؛ // مرز راست

}

// --------------------------------------- به روز رسانی منطقه بازی ---------- --------------------

void updateGame () // این صفحه منطقه بازی را به روز می کند

{display.clearDisplay ()؛

display.drawPixel (scranPosX ، scranPosY ، WHITE) ؛

scranAte = scranFood ()؛

// روال مار را بررسی کنید

if (outOfArea () || selfCollision ())

{ بازی تمام شد()؛ }

// نمایش مار

برای (int i = 0؛ i0؛ i--) {snakePosX = snakePosX [i-1]؛ snakePosY = snakePosY [i-1] ؛ } // پیکسل اضافی به مار اضافه کنید اگر (scranAte) {snakeSize+= 1؛ snakePosX [snakeSize-1] = مار x؛ snakePosY [snakeSize-1] = snakeY؛ }

سوئیچ (فشرده) (// snakeDirection بود

{case DIRUP: snakeY- = 1؛ زنگ تفريح؛ مورد DIRDOWN: snakeY+= 1؛ زنگ تفريح؛ مورد DIRLEFT: snakeX- = 1؛ زنگ تفريح؛ مورد DIRRIGHT: snakeX+= 1؛ زنگ تفريح؛ } snakePosX [0] = snakeX؛ snakePosY [0] = مارY؛ updateDisplay ()؛ display.display ()؛ // --------------------- اسکران را قرار دهید -------------------

void placeScran ()

{scranPosX = تصادفی (worldMinX+1 ، worldMaxX-1) ؛ scranPosY = تصادفی (worldMinY+1 ، worldMaxY-1) ؛ } // ------------------------ SCRAN ATE POINT UP ---------------- bool scranFood () {if (snakeX == scranPosX && snakeY == scranPosY) {playcore = امتیاز بازی+10 ؛ تن (SND ، 2000 ، 10) ؛ updateDisplay ()؛ placeScran ()؛ بازگشت 1 ؛ } else {return 0؛ } } //--------------------- خارج از منطقه---------------------- bool outOfArea () {return snakeX = worldMaxX || snakeY = worldMaxY؛ } //---------------------- بازی تمام شد----------------------- --- void gameOver () {uint8_t rectX1 ، rectY1 ، rectX2 ، rectY2 ؛ rectX1 = 38 ؛ rectY1 = 28 ؛ rectX2 = 58 ؛ rectY2 = 12 ؛ display.clearDisplay ()؛ display.setCursor (40 ، 30) ؛ display.setTextSize (1) ؛ تن (SND ، 2000 ، 50) ؛ display.print ("GAME")؛ تن (SND ، 1000 ، 50) ؛ display.print ("OVER") ؛ اگر (امتیاز بازی> = بالاترین امتیاز) // بررسی کنید که آیا نمره بالاتر از نمره بالا است {highscore = امتیاز بازی ؛ // single if statment برای به روز رسانی نمره بالا} برای (int i = 0؛ i <= 16؛ i ++) // این برای کشیدن مستطیل در اطراف بازی روی {display.drawRect (rectX1 ، rectY1 ، rectX2 ، rectY2 ، WHITE) است ؛ Serial.println ("اگر حلقه") ؛ display.display ()؛ rectX1- = 2 ؛ // تغییر 2 پیکسل rectY1- = 2؛ rectX2+= 4 ؛ // انتقال بیش از 2 پیکسل از آخرین نقطه rectY2+= 4؛ تن (SND ، i*200 ، 3) ؛ } display.display ()؛ // Screen Wipe پس از شهرت بیش از rectX1 = 0؛ // تنظیم موقعیت شروع خط rectY1 = 0 ؛ rectX2 = 0 ؛ rectY2 = 63 ؛ برای (int i = 0؛ i <= 127؛ i ++) {uint8_t cnt = 0؛ display.drawLine (rectX1 ، rectY1 ، rectX2 ، rectY2 ، BLACK) ؛ rectX1 ++ ؛ rectX2 ++ ؛ display.display ()؛ } display.clearDisplay ()؛ امتیاز بازی = 0 ؛ // تنظیم مار و اطلاعات بازیکن snakeSize = 1؛ snakeX = display.width ()/2؛ snakeY = display.height ()/2؛ waitForPress ()؛ // منتظر شروع بازی توسط بازیکن باشید // // ------------------------- منتظر حلقه فشار ---------- --------------- void waitForPress () {bool սպասում = 0؛ // حلقه به پایان می رسد این درست است. display.clearDisplay ()؛ در حالی که (انتظار == 0) {drawALineForMe (WHITE)؛ // رسم خط سفید تصادفی drawALineForMe (BLACK) ؛ // یک خط سیاه تصادفی بکشید تا صفحه سفید کاملاً سفید نشود.fillRect (19 ، 20 ، 90 ، 32 ، BLACK) ؛ // پس زمینه خالی برای نمایش متن. setTextColor (WHITE)؛ display.setCursor (35 ، 25) ؛ display.setTextSize (2) ؛ // فونت بزرگتر display.println ("SNAKE") ؛ // x y w h r col display.drawRoundRect (33 ، 22 ، 62 ، 20 ، 4 ، WHITE) ؛ // border Snake display.drawRect (19 ، 20 ، 90 ، 32 ، WHITE) ؛ // جعبه مرز - 3 display.setCursor (28 ، 42) ؛ display.setTextSize (0) ؛ // بازگشت فونت به حالت عادی display.println ("هر کلیدی را فشار دهید") ؛ display.display ()؛ انتظار = digitalRead (INTPIN) ؛ // بررسی کنید که آیا کلید فشار داده شده در حالت فشرده شدن = 0 به 1 پایان تغییر می کند یا خیر. // دکمه تنظیم مجدد را فشار دهید}} // -------------------- ترسیم رنگ ورودی تصادفی خط uint8_t -------------- ----- void drawALineForMe (uint8_t clr) {uint8_t line1X ، line1Y ، line2X ، line2Y = 0 ؛ // مختصات تصادفی را برای یک خط تنظیم کنید سپس آن را بکشید // متغیر نه کمتر نه بیشتر line1X = تصادفی (worldMinX+1 ، worldMaxX-1) ؛ line1Y = تصادفی (worldMinY+1 ، worldMaxY-1) ؛ line2X = تصادفی (worldMinX+1 ، worldMaxX-1) ؛ line2Y = تصادفی (worldMinY+1 ، worldMaxY-1) ؛ display.drawLine (line1X ، line1Y ، line2X ، line2Y ، clr) ؛ } // ---------------------------------------- تشخیص برخورد -------- ---------------------------

برای (بایت i = 4؛ i <snakeSize؛ i ++) {if (snakeX == snakePosX && snakeY == snakePosy ) {بازگشت 1 ؛ تن (SND ، 2000 ، 20) ؛ تن (SND ، 1000 ، 20) ؛ } بازگشت 0؛ }

//-------------------------------- برپایی--------------- -----------------------------------

void setup () {تاخیر (100)؛ // فقط به "بوت" فرصتی برای "بوت" بدهید // Serial.begin (9600) ؛ // اگر می خواهید خروجی های سریال display.begin (SSD1306_SWITCHCAPVCC ، 0x3C) را ببینید ، این تیک را بردارید. display.clearDisplay ()؛ // با یک صفحه نمایش تمیز شروع کنید. setTextColor (WHITE) ؛ // تنظیم اندازه چرخش رنگ متن و غیره display.setRotation (0) ؛ display.setTextWrap (false) ؛ display.dim (0)؛ // تنظیم pinMode صفحه نمایش (INTPIN ، INPUT) ؛ // پورت های صحیح را برای ورودی pinMode (UPPIN ، INPUT) تنظیم کنید ؛ pinMode (DWNPIN ، INPUT) ؛ pinMode (LFTPIN ، INPUT) ؛ pinMode (RHTPIN ، INPUT) ؛ // این دستور interupt است که آردوینو را برای خواندن ورودی ها متوقف می کند // command- function- pin-function to execute-condition on pin attachInterrupt (digitalPinToInterrupt (INTPIN) ، interpresspressed ، RISING) ؛ // Serial.println ("Setup Passed") ؛ waitForPress ()؛ // نمایش مارک start up screenScran ()؛ // قرار دادن اولین بیت غذا} // --------------------- MAIN LOOP ----------------- ---------------------- حلقه خالی () {updateGame ()؛ // این عملکرد همان چیزی است که کد اصلی را حمل می کند}

مرحله 3:

توصیه شده: