ב.2 — מבנה הלולאה הראשית
תוכנית שמחשבת סכום יכולה לסיים את פעולתה מיד לאחר הצגת התוצאה. חלון גרפי צריך להישאר פעיל: המשתמש עשוי להזיז את העכבר, ללחוץ על מקש או לבקש לסגור אותו בכל רגע. לכן תוכנית Pygame חוזרת שוב ושוב על פעולות קבועות, עד שמחליטים לסיים. החזרה הזו נקראת הלולאה הראשית — Main Loop.
נחשוב על משחק פשוט שבו כדור נע על המסך והשחקן מזיז מחבט. בכל רגע המשחק צריך לבדוק אם השחקן לחץ על מקש, להזיז את הכדור קצת קדימה, לבדוק אם הוא פגע במחבט, ולצייר את המצב החדש. את סדרת הפעולות הזו המשחק מבצע שוב ושוב, עשרות פעמים בשנייה, וכך נוצרת אשליה של תנועה רציפה — בדיוק כפי שסרט מורכב מרצף של תמונות סטילס. הלולאה הראשית היא המנגנון שמריץ את החזרה הזו.
בפרק זה נכיר את השלד של תוכנית Pygame: מה נעשה פעם אחת לפני הלולאה, ומה חוזר בכל סיבוב שלה. בפרקים הבאים נמלא את השלד בתוכן — תגובה לפעולות של המשתמש, שעון, ציור ותמונות.
המצגת: מבוא ל־Pygame (עותק מקומי)
לפני הלולאה: מכינים את התוכנית
מחוץ ללולאה מבצעים פעולות שנדרשות פעם אחת: מייבאים את הספרייה, מאתחלים אותה, מגדירים את ממדי החלון ויוצרים אותו. בהמשך נטען כאן גם תמונות וניצור משאבים נוספים.
import pygame
pygame.init()
WIDTH, HEIGHT = 640, 400
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("My Pygame Window")
running = True
הקריאה pygame.init() מאתחלת את רכיבי הספרייה הזמינים (תצוגה, קלט, קול ועוד), ויש לקרוא לה פעם אחת לפני כל שימוש אחר בספרייה. הפעולה set_mode() פותחת חלון במידות שבחרנו ומחזירה משטח תצוגה — האזור שעליו נצייר, ושתוכנו הוא מה שמוצג בחלון; אותו שומרים במשתנה screen. המידות נמסרות כזוג: הערך הראשון הוא הרוחב בפיקסלים, והשני הוא הגובה. הכותרת שמופיעה במסגרת החלון נקבעת באמצעות set_caption(). המשתנה running ישמש דגל שקובע אם הלולאה ממשיכה; כל עוד ערכו True התוכנית פועלת.
בתוך הלולאה: חוזרים על פעולות התצוגה
כל סיבוב של הלולאה מכין תמונה אחת של התצוגה — פריים — Frame. בתוכנית מלאה נבדוק בכל סיבוב מה השחקן עשה, נשנה את מצב העצמים, נצייר אותם ונציג את התוצאה. הציור עצמו מתבצע על משטח התצוגה שבזיכרון, והקריאה pygame.display.update() היא שמעבירה את התוצאה אל החלון שעל המסך. בשלב הראשון אפשר להבין את הרעיון באמצעות לולאה שמעדכנת את המסך בלבד:
while running:
pygame.display.update()
ל־Pygame יש שתי פעולות שמעבירות את מה שצוירו בזיכרון אל החלון: pygame.display.update() ו־pygame.display.flip(). כשקוראים ל־update() בלי ארגומנטים, שתיהן עושות את אותו הדבר — מרעננות את כל החלון — ואפשר לבחור באחת מהן. בקוד של אחרים תפגשו את שתיהן. בספר נשתמש ב־update(), ובפרק השעון נראה מה ההבדל ביניהן.
הלולאה ממשיכה כל עוד running הוא True. בשלב זה שום דבר בתוכנית אינו משנה את running, ולכן הלולאה אינה מסתיימת מעצמה. בפרק הבא נלמד איך החלון מגיב ללחיצה על כפתור הסגירה.
החלק הסטטי והחלק הדינמי
תוכנית Pygame מתחלקת לשני חלקים. החלק הסטטי הוא כל מה שנעשה פעם אחת, לפני הלולאה: אתחול הספרייה, יצירת החלון, וכן הכנה וציור של מה שאינו משתנה במהלך המשחק — למשל רקע או לוח משחק. החלק הדינמי הוא מה שבתוך הלולאה: פעולות שחוזרות בכל פריים. אם רוצים אנימציה — כדור שנע, דמות שמשנה מקום — משנים את מיקומם בתוך הלולאה, פריים אחרי פריים, ומציגים כל פעם את התמונה החדשה.
| החלק הסטטי — לפני הלולאה | החלק הדינמי — בתוך הלולאה |
|---|---|
| אתחול הספרייה ויצירת החלון | שינוי המיקום או המצב של מה שזז |
| הגדרת מידות, צבעים ומצב התחלתי | ציור מחדש של התמונה |
| טעינת תמונות וציור של מה שאינו משתנה | הצגת הפריים על המסך |
בתוכנית שלנו החלק הדינמי מכיל כרגע רק את pygame.display.update(). בפרקים הבאים נמלא אותו בתוכן.
התוכנית המלאה
נחבר את שני החלקים לתוכנית שלמה. זו התבנית שכל תוכנית Pygame בספר תתחיל ממנה: הכנה פעם אחת, ואחריה הלולאה הראשית. שמרו את הקוד בקובץ main.py והריצו אותו מתוך VS Code.
import pygame
pygame.init()
WIDTH, HEIGHT = 640, 400
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("My Pygame Window")
running = True
while running:
pygame.display.update()
במצגת אותה תוכנית כתובה בתוך פונקציה main(), שנקראת מהשורה if __name__ == '__main__':. שתי הצורות פועלות באותו אופן; בספר נשתמש בצורה הקצרה.
בהרצה נפתח חלון שחור במידות שבחרנו, עם הכותרת שקבענו. לאחר כמה שניות מערכת ההפעלה מוסיפה לכותרת את המילים Not Responding, ולחיצה על כפתור הסגירה אינה סוגרת את החלון. זה בדיוק מה שאמור לקרות בשלב זה:
החלון שחור מפני שעדיין לא ציירנו עליו דבר. הוא „קופא” מפני שהלולאה עסוקה רק בעדכון התצוגה: היא אינה בודקת אף פעם מה המשתמש עשה, ולכן גם בקשת הסגירה נשארת ללא מענה. כדי לעצור את התוכנית לחצו על Ctrl+C בטרמינל של VS Code, או סגרו את הטרמינל בעזרת סמל פח האשפה. בפרק הבא נוסיף ללולאה את הבדיקה החסרה, והחלון יגיב ללחיצה על כפתור הסגירה.
קוד להורדה: הדוגמה המלאה.