ב.10 — מלבני מיקום: pygame.Rect
עד עכשיו מיקמנו תמונה באמצעות זוג מספרים: הפינה השמאלית העליונה שלה. במשחק אמיתי זה מהר מאוד נעשה מסורבל. כדי למרכז דמות בחלון צריך לחסר חצי מרוחבה ומגובהה; כדי לבדוק אם היא נגעה בקצה הימני של החלון צריך לחשב את הקצה הימני שלה מהפינה ומהרוחב; וכדי לדעת אם שני עצמים נוגעים זה בזה צריך להשוות את כל הגבולות שלהם. בכל המקרים האלה אנו חוזרים ומחשבים את אותם ערכים מתוך אותם ארבעה מספרים: מיקום, רוחב וגובה.
כשצריך ליישר תמונה למרכז, לבדוק את הקצה הימני שלה או להזיז אותה בלי לחשב מחדש כל נקודה, נוח לשמור את מסגרת התמונה באובייקט אחד. Rect הוא מלבן ששומר מיקום ומידות ומאפשר לגשת אליהם בכמה דרכים: דרך הפינה, דרך המרכז או דרך הקצוות, כשהכול נשאר עקבי מאליו. המלבן הזה הוא גם הבסיס לשני הפרקים הבאים, שבהם נעטוף כל עצם במשחק בספרייט ונבדוק התנגשויות.
המצגת: Pygame Rect (עותק מקומי) · תיעוד Rect
יוצרים מסגרת לתמונה
הדרך הנוחה לקבל מלבן בגודל התמונה היא לקרוא ל־get_rect() על המשטח. התמונה image היא זו שטענו בפרק התמונות:
rect = image.get_rect()
rect.center = (320, 200)
הקריאה הראשונה יוצרת מלבן בגודל התמונה, שמתחיל ב־(0, 0). ההצבה השנייה מעבירה את מרכז המלבן לאמצע החלון. אפשר לכתוב זאת גם בפעולה אחת:
rect = image.get_rect(center=(320, 200))
אם אין תמונה, אפשר ליצור מלבן ישירות מתוך מיקום ומידות:
rect = pygame.Rect(100, 80, 120, 60)
מאפייני המיקום והמידות
אפשר לתאר את אותו מלבן דרך מרכזו, קצותיו או פינותיו. המאפיינים הבאים מאפשרים לקרוא ולעדכן את המיקום והמידות בלי לחשב כל נקודה בנפרד.
| מאפיינים | משמעות |
|---|---|
x, y או left, top |
הפינה השמאלית העליונה |
right, bottom |
הגבול הימני והתחתון |
width, height, size |
רוחב, גובה וזוג המידות |
center, centerx, centery |
מרכז המלבן ורכיביו |
topleft, topright, bottomleft, bottomright |
ארבע הפינות |
midtop, midbottom, midleft, midright |
אמצע כל צלע |
כל המאפיינים מתארים אותו מלבן, ולכן עדכון של אחד מהם מעדכן את כל השאר. למשל, שינוי center מזיז גם את הקצוות והפינות; הוא אינו משנה את המידות. שינוי width משנה את רוחב המלבן, אך אינו משנה את גודל התמונה, כי המלבן הוא רק תיאור של מיקום ומידות ואינו קשור לפיקסלים עצמם. לשינוי התמונה משתמשים ב־transform.scale() ומעדכנים את המלבן בהתאם. בדוגמה הבאה ניצור מלבן שפינתו ב־(100, 80) ורוחבו וגובהו 120 ו־60, ונדפיס כמה מהמאפיינים שלו:
rect = pygame.Rect(100, 80, 120, 60)
print(rect.topleft)
print(rect.center)
print(rect.right, rect.bottom)
פלט
(100, 80)
(160, 110)
220 140
הזזה: move לעומת move_ip
בהזזת מלבן אפשר לקבל מלבן חדש במיקום אחר, או לשנות את מיקומו של המלבן הקיים. נראה את ההבדל בין שתי האפשרויות.
rect = pygame.Rect(100, 80, 120, 60)
moved = rect.move(30, -10)
print(rect.topleft)
print(moved.topleft)
rect.move_ip(30, -10)
print(rect.topleft)
פלט
(100, 80)
(130, 70)
(130, 70)
שני הארגומנטים הם ההזזה בפיקסלים בציר x ובציר y; כאן 30 ימינה ו־10 למעלה. move() מחזירה מלבן חדש ואינה משנה את המקורי, ולכן ההדפסה הראשונה עדיין מראה (100, 80). move_ip() (הסיומת ip מציינת in place, "במקום") משנה את המלבן הקיים עצמו. אין לכתוב rect = rect.move_ip(...), משום שערך ההחזרה שלה הוא None, וכך נאבד את המלבן. בלולאת משחק, שבה מזיזים את אותו עצם בכל פריים, move_ip() היא בדרך כלל הבחירה הנוחה.
משתמשים במלבן להצבת התמונה
המלבן יכול לקבוע היכן התמונה תופיע בחלון. לשם כך מעבירים אותו ל־blit() במקום זוג קואורדינטות:
rect.move_ip(3, 0)
screen.blit(image, rect)
ה־Rect אינו מצויר בעצמו. blit משתמשת בפינה השמאלית העליונה שלו להצבת התמונה. אם רוצים לראות את המסגרת לצורך הבנה, מציירים אותה במפורש:
pygame.draw.rect(screen, (245, 170, 45), rect, 2)
הערה אחרונה: המלבן שומר קואורדינטות שלמות בלבד, ולכן אם נוסיף לו בכל פריים תזוזה קטנה מפיקסל היא תיעלם. בתנועה לפי זמן עדיף לשמור מיקום עשרוני במשתנה נפרד, כמו בפרק הקודם, ולהעתיק את המיקום המעוגל ל־rect לצורך הציור.
קוד להורדה: הדוגמה המלאה. בדוגמאות המשתמשות בתמונה, שמרו את הכוכב בתוך img/star.png לצד הקובץ והריצו מתוך התיקייה שלו.