Menu
CoddyTech

كائنات Sprite مثالية على مستوى البكسل

جزء من قسم الكائنات والصور في رحلة Pygame على Coddy. الدرس 23 من 36.

يمكن للكائنات الرسومية استخدام الأقنعة أيضًا، وتتولى pygame حساب الإزاحة نيابةً عنك. أعطِ كل كائن رسومي قناعًا عبر self.mask، وأنشئه مرة واحدة في __init__:

self.mask = pygame.mask.from_surface(self.image)

ثم مرّر pygame.sprite.collide_mask وسيطًا رابعًا إلى spritecollide:

hits = pygame.sprite.spritecollide(player, balls, False, pygame.sprite.collide_mask)

الوسيط الرابع هو الاختبار المستخدم لكل زوج. من دونه، يكون الاختبار هو المستطيلات. أما مع collide_mask، فيكون الاختبار للأقنعة، التي يحدد مواضعها مستطيل كل كائن رسومي. يأخذ groupcollide الوسيط الخامس نفسه.

تستهلك اختبارات الأقنعة وقتًا أطول من اختبارات المستطيلات، لكن overlap لا يقارن إلا وحدات البكسل التي يتداخل عندها المستطيلان، لذا تكون مقارنة الأزواج المتباعدة سريعة. لن تلاحظ تكلفة ذلك مع بضع عشرات من الكائنات الرسومية. إذا لم يكن للكائن الرسومي mask، ينشئ collide_mask قناعًا من صورته في كل اختبار، لذا عيّنه في __init__.

challenge icon

التحدي

متوسط
  1. أنشئ لـ Player وBall قناعًا self.mask مستمدًا من self.image.
  2. مرّر pygame.sprite.collide_mask إلى spritecollide، لكي تظهر Hit! فقط عندما تلامس صورة السفينة إحدى الكرات.

جرّب بنفسك

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))

    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))


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)

    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()

جميع دروس الكائنات والصور

تدرّب بنفسك: Playground لـ Pygame