Delphi + Arduino = Pong

"פונג" (Pong), משחק המטקות האלקטרוני הפרימיטיבי, נחשב אחת מאבני הדרך החשובות של עולם הגיימינג. הסיבה לכך היא שרבות מקונסולות המשחקים הביתיות הראשונות, שיצאו לשוק בסביבות אמצע שנות השבעים, הציעו בעיקר גרסאות של המשחק הזה.

הבקרים לשליטה במשחק לא היו משוכללים הרבה יותר: בדרך כלל, כל בקר היה לא יותר מאשר פוטנציומטר או נגד משתנה במארז מהודר. כשהייתי ילד קטן, גם אצלי בבית היתה קונסולה כזו. לכן, אחרי שהצלחתי להעביר דרך הארדואינו קריאה של פוטנציומטר לתוכנה שכתבתי במחשב, היישום הראשון שעלה בדעתי היה משחק פונג – והנה התוצאה:

כדי להפוך את החוויה לאותנטית יותר, הוספתי למשחק גם צלילים: כאשר ה"כדור" משנה כיוון, או חולף על פני ה"מטקה" והולך לאיבוד, התוכנה שבמחשב שולחת לתוכנה שבארדואינו הוראה להשמיע צליל מתאים דרך הרמקול המחובר. בפוסט זה אדבר קצת על הצד של המחשב, קצת על הצד של הארדואינו – וגם אתן לכם את התוכנה, כדי שתוכלו להרכיב את בקר הארדואינו ולבזבז את זמנכם על המשחק הזה כאילו לא עברו כמעט ארבעים שנה… 🙂

Pong Console
קונסולת פונג עתיקה (לא פעילה) עם בקר משחק

הצד של המחשב

התוכנה שמופיעה על המסך בסרטון נכתבה בשפת התכנות Object Pascal בסביבת הפיתוח Delphi XE2. את התקשורת הטורית מימשתי בעזרת הרכיב TurboPower Async Professional, שמוצע להורדה חינם.

הקוד עצמו הוא קצר – כמאה וארבעים שורות ברוטו, בריווח נדיב – ו"מלוכלך" מאד: הוא נכתב כדי שיעבוד, ולא שום דבר מעבר לזה. לכן לא אציג אותו כאן ורק אסביר את העיקרון הכללי של תכנות משחק פונג לשחקן יחיד.

הכדור הוא ריבוע קטן, שמצויר בקואורדינטות x,y וגודלו 8×8 פיקסלים. התוכנה שומרת עבורו שני משתנים, dx ו-dy, שקובעים את ה"מהירות" שלו בציר האופקי ובציר האנכי. בכל "צעד", שמבוצע מדי שלושים מילישניות בערך, מוסיפים ל-x של הכדור את dx, ל-y את dy, ומציירים את הכדור במיקומו החדש (בהתאם לטכניקה הספציפית בה אתם עובדים, ייתכן שתצטרכו גם למחוק אותו קודם לכן מהמיקום הקודם!). כמו כן, אחרי כל תזוזה כזו מתבצעות מספר השוואות, שמטרתן לבדוק אם ה"כדור" פגע באחד משולי המגרש. למשל, אם x+8 (שזה הקצה הימני של הכדור) גדול מרוחב החלון, סימן שהכדור פגע בקצה הימני: נשדר לארדואינו פקודה להשמעת צליל פגיעה, ונהפוך את הסימן של dx. כך, בתזוזה הבאה והלאה, הכדור ינוע שמאלה, ב"מורד" הציר האופקי. בדיקות דומות מבוצעות על ציר y עבור הקצה העליון והתחתון של החלון.

Pong screenshot
צילום מסך מהתוכנה

זיהוי ההתנגשות עם המטקה קצת יותר מורכב: כאן אנחנו צריכים לא רק לזהות את חציית הגבול האופקי, אלא גם לבדוק אם המיקום של הכדור בציר y נופל בין הקצה העליון לתחתון של המטקה עצמה. אם כן, נהפוך שוב את dx והכדור יחזור לנוע ימינה. אם לא, הוא "הולך לאיבוד" והמשחק נגמר.

המטקה, בדומה לכדור, היא אובייקט בגובה קבוע, שמצויר החל ממיקום y מסוים בציר האנכי. המיקום הזה יכול להשתנות, בהתאם לקלט שמגיע מהארדואינו.

התוכנה במחשב כוללת עוד כמה פרטים, כגון מונה הזמן, ניהול הגדלה/הקטנה של החלון ועוד, אבל לא לשם כך התכנסנו כאן. נעבור ל…

הצד של הארדואינו

הארדואינו אינו יודע, כמובן, שהוא משמש למשחק פונג. התוכנה שלו עושה שני דברים פשוטים – שולחת דרך ה-Serial את הקריאה מהפוטנציומטר (כדי לצמצם את נפח התקשורת, הקוד שולח מידע רק כאשר הקריאה משתנה), ומשמיעה צליל דרך הרמקול בהתאם להוראות שמגיעות דרך ה-Serial. הנה הקוד במלואו:

#define SPEAKER_PIN 6
#define POT_PIN A0
byte lastPotPos = 0;

void setup() {
   Serial.begin(9600);
}

void loop() {

  byte potPos;

  // Look for sound commands
  if (Serial.available()) {
    switch (Serial.read()) {
      case 1 : tone(SPEAKER_PIN, 150, 15); break;
      case 2: tone(SPEAKER_PIN, 700, 20); break;
      case 3: tone(SPEAKER_PIN, 100, 100); break;
      default: noTone(SPEAKER_PIN);
    } 
  }

  // Read potentiometer 20 times per second
  delay(50); 

  // The ">> 2" part divides the 10-bit result by 4
  // to reduce noise and make it an 8-bit Byte
  potPos = analogRead(POT_PIN) >> 2;
  if ( potPos != lastPotPos) {
    Serial.write(potPos);
    lastPotPos = potPos;
  }  

}

 לחבר הכל ביחד

כדי לשחק בפונג הזה, העלו את הקוד לארדואינו, חברו רמקול קטן לפין 6 ול-Ground, ופוטנציומטר רגיל ל-5V, ל-Ground ולפין האנלוגי A0. הארדואינו חייב, כמובן, להישאר מחובר בכבל ה-USB למחשב. בקובץ ה-ZIP להורדה תמצאו את הקוד הנ"ל וכן את תוכנת הפונג עצמה, שמיועדת למערכת ההפעלה Windows. לצערי, מכיוון שהתוכנה משתמשת בכל מיני רכיבים מוכנים מראש שעושים הרבה דברים מאחורי הקלעים, היא יצאה מנופחת למדי – 7.5 מגהבייט… אם כי אני בטוח שהמחשב שלכם יסתדר עם זה.

שימו לב, בזמן שתוכנת הפונג רצה על המחשב, סביבת הפיתוח של הארדואינו אינה יכולה לתקשר עם הלוח: כדי לטעון קוד חדש או לעבוד עם ה-Serial Monitor, סגרו קודם כל את חלון הפונג.

כמו כן, מסיבה שעדיין לא חקרתי, לוקח לתוכנת הפונג קצת זמן מרגע יצירת החיבור הראשוני עם לוח הארדואינו ועד שהיא מצליחה לקרוא פקודות בפועל. אם נתקלתם בבעיות אחרות, דווחו לי!

להרשמה
הודע לי על
5 Comments
מהכי חדשה
מהכי ישנה לפי הצבעות
Inline Feedbacks
הראה את כל התגובות

נ.ב. יש באג קטן אך מעצבן. המחבט מעיט משמעותית כאשר הוא מתקרב לקצוות המסך.

שיא אישי: http://www.siz.co.il/view/izh4zynjntnz.png.htm

מגניב!!!
הפרוייקט הזה כל- כך דורש להחליף את הפוטוציומטר לחיישן (מה שעלה לי לראש
זה חיישן פונג [:)

מגניב ביותר!
תודה על הפוסט המרענן והיצירתי 🙂

וואו איזה יופי!