תיבות פגיעה מעגליות
חלק מהיחידה ספרייטים ותמונות במסלול ה-Pygame של Coddy. שיעור 24 מתוך 36.
בדיקת פיקסלים היא מדויקת, אבל דיוק הוא לא תמיד מה שמרגיש הוגן. שפיץ שנוגע בקצה הכנף נחשב לפגיעה. במקום זאת, משחקים רבים בודקים צורה קטנה ופשוטה יותר, תיבת פגיעה, ומאפשרים לפספוסים קרובים לעבור.
עבור דברים עגולים, בודקים מעגלים. נותנים לכל ספרייט radius, והפונקציה pygame.sprite.collide_circle מחשיבה זאת לפגיעה כשהמרחק בין המרכזים קטן מסכום שני הרדיוסים:
self.radius = 24 # בתוך Player.__init__
self.radius = 22 # בתוך Ball.__init__
hits = pygame.sprite.spritecollide(player, balls, False, pygame.sprite.collide_circle)כאן מדובר ב־24 + 22 = 46 פיקסלים בין המרכזים. המעגלים קטנים מהתמונות, ולכן הקצוות ממש יכולים לגעת בלי שתתרחש פגיעה. גם בדיקת מעגל היא זולה: חישוב מרחק אחד, בלי פיקסלים.
בלי radius, collide_circle משתמש במעגל שמקיף את כל ה־Rect, והוא גדול יותר מה־Rect עצמו. עבור ספרייט בצורת תיבה, Rect קטן יותר עושה את אותה העבודה: self.rect.inflate(-16, -16) הוא Rect שרוחבו וגובהו קטנים ב־16 פיקסלים, ומרכזו נשאר זהה.
אתגר
בינוני- הגדר ל־
Playerאתself.radius = 24ול־Ballאתself.radius = 22. - בדוק באמצעות
pygame.sprite.collide_circleבמקוםcollide_mask.
נסו בעצמכם
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Spike Field")
clock = pygame.time.Clock()
ship_image = pygame.image.load("assets/images/ship.png").convert_alpha()
ball_image = pygame.image.load("assets/images/spike_ball.png").convert_alpha()
font = pygame.font.Font(None, 40)
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = ship_image
self.rect = self.image.get_rect(topleft=(420, 320))
self.mask = pygame.mask.from_surface(self.image)
def update(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.rect.x -= 4
if keys[pygame.K_RIGHT]:
self.rect.x += 4
if keys[pygame.K_UP]:
self.rect.y -= 4
if keys[pygame.K_DOWN]:
self.rect.y += 4
class Ball(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = ball_image
self.rect = self.image.get_rect(center=(x, y))
self.mask = pygame.mask.from_surface(self.image)
player = Player()
balls = pygame.sprite.Group(Ball(160, 240), Ball(320, 240), Ball(480, 240))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
player.update()
hits = pygame.sprite.spritecollide(player, balls, False, pygame.sprite.collide_mask)
screen.fill((20, 22, 40))
balls.draw(screen)
screen.blit(player.image, player.rect)
if hits:
text = font.render("Hit!", True, (240, 240, 240))
screen.blit(text, (10, 10))
pygame.display.flip()
clock.tick(60)
pygame.quit()
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה ספרייטים ותמונות
5התנגשויות מדויקות ברמת הפיקסל
מלבנים מרגישים לא הוגניםמסכותספרייטים מדויקים ברמת הפיקסלתיבות פגיעה מעגליות3מחלקות לאובייקטים במשחק
המחלקה הראשונה שלךמתודותself הוא האובייקטרשימה של אובייקטיםאובייקטים עם תמונותתת־מחלקהתרגלו בעצמכם: Pygame אונליין