תוכן עניינים:

משחק נחש נחש ארדואינו OLED: 3 שלבים
משחק נחש נחש ארדואינו OLED: 3 שלבים

וִידֵאוֹ: משחק נחש נחש ארדואינו OLED: 3 שלבים

וִידֵאוֹ: משחק נחש נחש ארדואינו OLED: 3 שלבים
וִידֵאוֹ: פרויקט גמר פתיחת המכונית.AVI 2024, יולי
Anonim
משחק נחש נחש ארדואינו OLED
משחק נחש נחש ארדואינו OLED

היי וברוך הבא, למדריכים שלנו כיצד להכין ומשחק OLED של arduino, הפרויקט הזה הגיע כשניסינו לעשות את המשחק הראשון שלנו אי פעם עם ארדואינו, soooo, חשבנו איפה טוב יותר להתחיל מאשר ה- nokia classic Snake (טוב ב לפחות שיבוט נחש:)).

מה שאתה תצטרך

אספקה

ארדואינו UNO או שיבוט

תצוגת OLED

4 דיודות

נגד 500-1k

4 כפתורי בקר

זמזם פסיבי פסיו

אופציונאלי

לוח לחם ללא הלחמה

שים לב שהקישורים האלה הם למשל בלבד

שלב 1: המעגל

המעגל
המעגל

בתמונה למעלה אתה יכול לראות את המעגל שלנו, אנו משתמשים בסיכה d3 על הארדואינו כסיכת בקשה להפסקה, כך שהארדואינו יעניק עדיפות לקריאת כניסות הבקר שהם d4 d5 d6 d7. היסודות של המעגל הם שלחיצה על כפתור כיוון שהולך גבוה 5v זה מפעיל את סיכת בקשת ההפרעה (חוט סגול d3) וסיכת כיוון תואמת, פונקציית ההפרעה קוראת פונקציית כיוון עדכון והקוד הזה מניע את הנחש בהתאם. סיכה 9 משמשת כסיכת הצליל מכיוון שהיא PWM (~ אפנון רוחב הדופק) המחוברת ישירות לפייזו 5v בסיכה + וה - חוזר ל 0v/קרקע.

(לידיעתך ב- uno arduino ובשיבוטים רק d2 ו- d3 יכולים לשמש סיכות בקשה להפריע).

סיכות כיוון:

d4 למעלה כתום

d5 למטה ורוד

d6 שמאל כחול

d7 ימין חום

צליל d9 אפור

לכל כפתור יש כניסת חיבור ב -5 וולט ויציאה המחוברת תחילה לכניסה הדיגיטלית המתאימה שלהם על הארדואינו, אותו פלט של כל כפתור מחובר לאחר מכן לדיודה משלו, אנו משתמשים בדיודות כדי לעצור את הזנת המתח חזרה אל כפתורים אחרים והפעלתם. בקצה הקתודה (-) של כל 4 הדיודות אנו מחברים אותן יחד ליצירת צומת פלט המתחבר ל- d3 ולאחר מכן דרך הנגד ל 0v/אדמה כדי למשוך את סיכות הארדואינו נמוך כדי לא להשאיר סיכות צפות כאשר אינן מוּפעָל.

(לידיעתך סיכה צפה יכולה לקבל מתח רפאים ולגרום להתנהגות יוצאת דופן)

2 סיכות אנלוגיות משמשות להנעת התצוגה, אלה סיכות חומרה i2c של arduino.

A5 מחובר ל- SCL YELLOW

A4 מחובר ל- SDA GREEN

פלט +5v ו- 0v (אדמה) מהארדואינו משמש כמקור הכוח לכל המעגל שניתן להפעיל באמצעות USB או מטען טלפוני.

שלב 2: הקוד

// ------------------------ משחקי SNAKE ANJAWARE בעזרת אנשים ברשת --------------- -------

#לִכלוֹל

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // סט תצוגה (רוחב, גובה) תצוגת Adafruit_SSD1306 (128, 64); // הגדירו סיכות קלט אלה הסיכות בארדואינו שהם לעולם לא משתנים ולכן #define #define INTPIN 3 // רק סיכות 2 ו- 3 יכולות להיות סיכות interupt ב- UNO #define UPPIN 4 // אלה סיכות המחוברות tp switch רלוונטי #define DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // הגדר כיוונים #הגדר DIRUP 1 // ערכים אלה הוא מה שה"נחש "מסתכל עליו כדי להחליט- #הגדר DIRDOWN 2 // את הכיוון שהנחש ינוע # הגדר DIRLEFT 3 #define DIRRIGHT 4

// להגדיר משתני כפתורים

// volitile כי אנחנו צריכים את זה כדי לעדכן עם interupt כך יכול להיות כל ערך של מחזור

// אף פעם לא גבוה מ -4 אז צריך רק int 8bit כדי לחסוך במשאבים נדיפים uint8_t buttonpressed = 0; bool butup = 0; Butol Butdown = 0; // אנו משתמשים בזה כדי להגדיר נכון ל"זיהוי "לאיזה כיוון לחצו bool butleft = 0; בול אבל = 0;

// ints נחש

בייט snakePosX [30]; // מערך ליצירת גוף של בית נחש נחש snakePosY [30];

int snXX = 30; // מיקום ראש נחש

int snakeY = 30; int snakeSize = 1; // ספירת גודל הנחש מוגבלת לגודל המערך

// ints world

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 איסוף כנקודת מוצא

// --------------------------- זה מה שהאינטרפט מבצע בעת עליית מתח ------------ -------------

void interruptpressed () {delay (150); // עיכוב קל להוספת הגנת "הקפצה" updatedrection (); } // ------------------ עדכן את ערך הכיוון מלחיצת כפתורים ----------------- void updatedirection () { // Serial.println ("updatingdirection"); butup = digitalRead (UPPIN); // בדוק איזו קלט עלה גבוה והגדר רווח butol נכון של Butol = digitalRead (DWNPIN); butleft = digitalRead (LFTPIN); butright = digitalRead (RHTPIN); // אלה אם סטטמנטים מסתכלים על איזו קלט עלה גבוה ונכנס לערך הרלוונטי במשתנה "כפתורים" // משתנה זה מכתיב את כיוון התנועה אם (butup == true) {buttonpressed = DIRUP; // Serial.println ("UP לחוץ"); // Serial.println (בכפתורים); butup = false; טון (SND, 1500, 10); } אם (butdown == true) {buttonpressed = DIRDOWN; // Serial.println ("לחוץ למטה"); // Serial.println (בכפתורים); butdown = false; טון (SND, 1500, 10); }

אם (butleft == נכון)

{buttonpressed = DIRLEFT; // Serial.println ("לחיצה שמאלית"); // Serial.println (בכפתורים); butleft = false; טון (SND, 1500, 10); } אם (butright == true) {buttonpressed = DIRRIGHT; // Serial.println ("לחוץ ימינה"); // Serial.println (בכפתורים); butright = false; טון (SND, 1500, 10); }}

// -------------------------- צייר את שגרת התצוגה ------------------ -----------------

update voidDisplay () // לצייר ציונים ומתארים

{// 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); // display seperator display.drawLine (0, 9, 127, 9, WHITE); // מתחת לגבול הטקסט display.drawLine (0, 63, 127, 63, WHITE); // גבול תחתון display.drawLine (0, 0, 0, 63, WHITE); // תצוגת הגבול השמאלי.צייר (127, 0, 127, 63, לבן); // גבול ימני

}

// ----------------------------------- עדכון אזור משחק ---------- --------------------

void updateGame () // זה מעדכן את תצוגת אזור המשחק

{display.clearDisplay ();

display.drawPixel (scranPosX, scranPosY, WHITE);

scranAte = scranFood ();

// לבדוק את שגרת הנחשים

אם (outOfArea () || selfCollision ())

{ סוף המשחק(); }

// להציג נחש

עבור (int i = 0; i0; i--) {snakePosX = snakePosX [i-1]; snakePosY = snakePosY [i-1]; } // הוסף פיקסל נוסף לנחש אם (scranAte) {snakeSize+= 1; snakePosX [snakeSize-1] = snakeX; snakePosY [snakeSize-1] = snakeY; }

מתג (בלחיצת כפתור) // היה snakeDirection

{מקרה DIRUP: snakeY- = 1; לשבור; מקרה DIRDOWN: snakeY+= 1; לשבור; מקרה DIRLEFT: snakeX- = 1; לשבור; מקרה DIRRIGHT: snakeX+= 1; לשבור; } snakePosX [0] = snakeX; snakePosY [0] = snakeY; updateDisplay (); display.display (); // --------------------- הנח את הסריקה -------------------

מקום ריק Scran ()

{scranPosX = random (worldMinX+1, worldMaxX-1); scranPosY = random (worldMinY+1, worldMaxY-1); } // ------------------------ SCRAN ATE POINT UP ---------------- בול scran מזון () {if (snakeX == scranPosX && snakeY == scranPosY) {playscore = playscore+10; טון (SND, 2000, 10); updateDisplay (); placeScran (); החזרה 1; } אחר {החזרה 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 ("מעל"); if (playcore> = highscore) // לבדוק אם הציון גבוה מהציון הגבוה {highscore = playcore; // יחיד אם הצהרה לעדכון ציון גבוה} עבור (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 (); // ניגוב מסך לאחר תהילה מעל 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 (); scorecore = 0; // אפס את פרטי הנחש והשחקן snakeSize = 1; snakeX = display.width ()/2; snakeY = display.height ()/2; waitForPress (); // לחכות שהשחקן יתחיל את המשחק} // ------------------------- לחכות ללולאת לחיצות ---------- --------------- void waitForPress () {bool waiting = 0; // הלולאה מסתיימת כאשר זה נכון display.clearDisplay (); while (המתנה == 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); // גבול תצוגת נחש.צייר (19, 20, 90, 32, לבן); // תיבת גבול - 3 display.setCursor (28, 42); display.setTextSize (0); // גופן חזרה לתצוגה רגילה. println ("לחץ על מקש כלשהו"); display.display (); המתנה = digitalRead (INTPIN); // בדוק אם הלחיצה על מקש ההמתנה תשתנה לסוף אחד תוך לחיצה על כפתור = 0; // איפוס כפתור לחץ}} // -------------------- צייר צבע קלט של שורה אקראית uint8_t -------------- ----- void drawALineForMe (uint8_t clr) {uint8_t line1X, line1Y, line2X, line2Y = 0; // הגדר קואורדינטות אקראיות לקו ואז צייר אותו // משתנה לא פחות לא פחות שורה 1X = אקראית (worldMinX+1, worldMaxX-1); line1Y = random (worldMinY+1, worldMaxY-1); line2X = אקראי (worldMinX+1, worldMaxX-1); line2Y = random (worldMinY+1, worldMaxY-1); display.drawLine (line1X, line1Y, line2X, line2Y, clr); } // ------------------------------------- גילוי התנגשות -------- -----------------------

for (בת i = 4; i <snakeSize; i ++) {if (snakeX == snakePosX && snakeY == snakePosy ) {return 1; טון (SND, 2000, 20); טון (SND, 1000, 20); } החזר 0; }

//-------------------------------- להכין--------------- -------------------------------

הגדרת חלל () {עיכוב (100); // פשוט תנו לדברים הזדמנות "לאתחל" // Serial.begin (9600); // בטל את הסימון אם ברצונך לראות את הפלט הטורי display.begin (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); // התחל עם תצוגה נקייה display.setTextColor (WHITE); // הגדר גודל סיבוב צבע טקסט וכו 'display.setRotation (0); display.setTextWrap (שקר); 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), interruptpressed, RISING); // Serial.println ("ההתקנה עברה"); waitForPress (); // הצג את מסך הפעלת הנחש placeScran (); // מקם נתח אוכל ראשון} // --------------------- לולאה עיקרית ----------------- ---------------------- לולאת void () {updateGame (); // פונקציה זו היא הנושאת את הקוד הראשי}

שלב 3:

מוּמלָץ: