Menu
CoddyTech

Sprite Presisi Piksel

Termasuk bagian Sprite dan Gambar dalam perjalanan Pygame di Coddy. Pelajaran 23 dari 36.

Sprite juga bisa menggunakan mask, dan pygame akan mengatur offset untukmu. Beri setiap sprite self.mask, yang dibuat sekali di __init__:

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

Lalu berikan pygame.sprite.collide_mask sebagai argumen keempat untuk spritecollide:

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

Argumen keempat adalah pengujian yang digunakan untuk setiap pasangan. Tanpanya, pengujian menggunakan Rect. Dengan collide_mask, pengujian menggunakan mask yang ditempatkan berdasarkan Rect setiap sprite. groupcollide menerima argumen kelima yang sama.

Pengujian mask membutuhkan biaya lebih besar daripada pengujian Rect, tetapi overlap hanya membandingkan piksel di area tumpang tindih kedua Rect, jadi pasangan yang berjauhan akan diproses dengan cepat. Untuk beberapa puluh sprite, kamu tidak akan merasakan biayanya. Jika sprite tidak memiliki mask, collide_mask akan membuatnya dari image sprite setiap kali pengujian dilakukan, jadi atur di __init__.

challenge icon

Tantangan

Sedang
  1. Buat Player dan Ball memiliki self.mask yang dibuat dari self.image.
  2. Berikan pygame.sprite.collide_mask kepada spritecollide, agar Hit! hanya muncul saat gambar kapal menyentuh bola.

Coba sendiri

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

Semua pelajaran di Sprite dan Gambar

Latihan sendiri: Playground Pygame