ב.6 — טעינה והצגה של תמונות
צורות גאומטריות מספיקות למשחקים רבים, אבל חללית, דמות או רקע מצויר קשה מאוד להרכיב מקווים ומעגלים. במשחקים כאלה מכינים את הגרפיקה מראש בתוכנת ציור, שומרים אותה כקובץ תמונה (למשל PNG) ונותנים למשחק להציג אותה. כך עובדים כמעט כל המשחקים הדו־ממדיים: הדמות היא תמונה קטנה, והתוכנית רק מחליטה היכן להציב אותה בכל פריים.
במקום לצייר עצם בכל פעם מקווים ומעגלים, אפשר לטעון תמונה ולהציג אותה. הרעיון המרכזי בפרק הוא שלאחר הטעינה גם התמונה היא משטח, בדיוק מהסוג שהכרנו בפרק ב.4: אפשר לשנות את גודלה ולהעתיק אותה לחלון באמצעות blit, כמו כל משטח אחר. לכן כל מה שלמדנו על משטחים תקף גם לתמונות, ואין צורך ללמוד מנגנון חדש.
המצגת: מבוא ל־Pygame (עותק מקומי)
טוענים תמונה לזיכרון
לפני הצגת תמונה, טוענים את הקובץ שלה מהדיסק למשטח בזיכרון. הורידו את תמונת הדוגמה, שמרו אותה בתיקייה img לצד main.py ופתחו את תיקיית העבודה ב־VS Code. בקוד נשתמש בנתיב img/star.png. זהו נתיב יחסי לתיקייה שממנה התוכנית מורצת, ולכן חשוב להריץ את התוכנית מתוך תיקיית העבודה. הפעולה pygame.image.load() קוראת את קובץ התמונה ומחזירה משטח שתוכנו הוא פיקסלי התמונה:
image = pygame.image.load("img/star.png")
מבצעים את הטעינה פעם אחת, לפני הלולאה, כפי שראינו בטבלת ההכנה החד־פעמית בפרק ב.2. קריאה מהדיסק היא פעולה איטית בהרבה מציור בזיכרון, וטעינה חוזרת בכל פריים אינה נדרשת לתמונה שאינה משתנה.
מתאימים את הגודל ומציגים
כדי שהתמונה תתאים למקום המיועד לה בחלון, אפשר לשנות את גודלה. הפעולה scale מקבלת משטח ומידות חדשות ומחזירה משטח בגודל המבוקש. שומרים את התוצאה במשתנה, ואז מציגים אותה:
image = pygame.transform.scale(image, (80, 80))
screen.blit(image, (280, 160))
הגודל כאן הוא 80×80 פיקסלים. הזוג (280, 160) קובע את הפינה השמאלית העליונה, ולא את מרכז התמונה. שינוי יחס הרוחב והגובה עלול לעוות את התמונה; בדוגמה המקור והיעד ריבועיים.
שומרים על הרקע השקוף
תמונה של דמות היא כמעט תמיד מלבנית, אבל הדמות עצמה אינה מלבן. אם הפיקסלים שמסביב לדמות היו אטומים, היינו רואים מסביבה מסגרת שמסתירה את הרקע. לכן קובצי PNG של דמויות נשמרים עם רקע שקוף — כל פיקסל נושא גם ערך Alpha, כפי שראינו בפרק ב.4. לתמונת הכוכב יש פינות שקופות. אחרי יצירת החלון אפשר להשתמש ב־convert_alpha() כדי להתאים את המשטח לתצוגה תוך שימור השקיפות; ההתאמה הופכת את ההעתקה למסך למהירה יותר. לתמונה אטומה אפשר להשתמש ב־convert(); הוא אינו שומר שקיפות נפרדת לכל פיקסל.
בתוכנית המלאה נשלב את הטעינה, ההתאמה ושינוי הגודל לפני הלולאה, ובכל פריים נצבע את הרקע ונציב עליו את הכוכב:
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 400))
image = pygame.image.load("img/star.png").convert_alpha()
image = pygame.transform.scale(image, (80, 80))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if not running:
break
screen.fill((17, 43, 65))
screen.blit(image, (280, 160))
pygame.display.update()
pygame.quit()
אם מתקבלת FileNotFoundError, בדקו שהתמונה נשמרה בשם ובתיקייה הנכונים ושהטרמינל נמצא בתיקיית העבודה. אל תקראו לקובץ התוכנית pygame.py, כדי שלא יסתיר את הספרייה המותקנת.
קוד להורדה: הדוגמה המלאה. בדוגמאות המשתמשות בתמונה, שמרו את הכוכב בתוך img/star.png לצד הקובץ והריצו מתוך התיקייה שלו.