Sprite’y z dokładnością do piksela
Część sekcji Sprite’y i obrazy ścieżki Pygame w Coddy. Lekcja 23 z 36.
Duski również mogą używać masek, a pygame sam oblicza przesunięcie. Przypisz każdemu duszkowi self.mask, utworzoną raz w __init__:
self.mask = pygame.mask.from_surface(self.image)Następnie przekaż pygame.sprite.collide_mask jako czwarty argument do spritecollide:
hits = pygame.sprite.spritecollide(player, balls, False, pygame.sprite.collide_mask)Czwarty argument określa test wykonywany dla każdej pary. Bez niego testowane są prostokąty Rect. Z collide_mask testowane są maski, umieszczone zgodnie z położeniem prostokąta Rect każdego duszka. groupcollide przyjmuje taki sam piąty argument.
Testy masek są bardziej kosztowne niż testy Rect, ale overlap porównuje tylko piksele, na których obszary dwóch prostokątów Rect się pokrywają, więc pary położone daleko od siebie są szybko sprawdzane. W przypadku kilkudziesięciu duszków nie zauważysz tego kosztu. Jeśli duszek nie ma mask, collide_mask tworzy ją z jego obrazu przy każdym teście, więc ustaw ją w __init__.
Wyzwanie
Średni- Utwórz dla
PlayeriBallself.maskna podstawieself.image. - Przekaż
pygame.sprite.collide_maskdospritecollide, abyHit!wyświetlało się tylko wtedy, gdy obraz statku dotyka piłki.
Spróbuj swoich sił
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()
Wszystkie lekcje w sekcji Sprite’y i obrazy
1Wczytywanie obrazów
Wczytaj obrazUmieść go za pomocą RectPrzesuń obrazPowiel tłoPrzezroczyste piksele2Obracaj, odbijaj, skaluj
Obracaj wokół środkaKieruj się w stronę lotuSkaluj obrazObracaj względem oryginału5Kolizje z dokładnością do piksela
Prostokąty wydają się niesprawiedliweMaskiSprite’y z dokładnością do pikselaKołowe hitboxy6Animacja z arkuszy sprite’ów
Przytnij arkusz sprite’ówLicznik klatekAnimacja w czasieJednorazowa eksplozjaPoćwicz samodzielnie: Edytor online Pygame