Sprites pixel perfect
Parte da seção Sprites e imagens do Journey de Pygame da Coddy. Lição 23 de 36.
Os sprites também podem usar máscaras, e o pygame calcula o deslocamento para você. Atribua a cada sprite um self.mask, criado uma única vez em __init__:
self.mask = pygame.mask.from_surface(self.image)Em seguida, passe pygame.sprite.collide_mask como quarto argumento para spritecollide:
hits = pygame.sprite.spritecollide(player, balls, False, pygame.sprite.collide_mask)O quarto argumento é o teste usado para cada par. Sem ele, o teste usa os Rects. Com collide_mask, ele usa as máscaras, posicionadas pelo Rect de cada sprite. groupcollide recebe o mesmo quinto argumento.
Os testes com máscaras custam mais do que os testes com Rects, mas overlap compara apenas os pixels em que os dois Rects se sobrepõem, então os pares distantes são processados rapidamente. Com algumas dezenas de sprites, você não vai notar o custo. Se um sprite não tiver mask, collide_mask cria uma a partir da imagem dele em cada teste, então defina-a em __init__.
Desafio
Médio- Dê a
PlayereBallumaself.maskcriada a partir deself.image. - Passe
pygame.sprite.collide_maskparaspritecollide, para queHit!apareça somente enquanto a imagem da nave tocar uma bola.
Experimente você mesmo
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()
Todas as lições de Sprites e imagens
1Carregando imagens
Carregue uma imagemPosicione-a com um RectMova a imagemLadrilhe o plano de fundoPixels transparentes2Girar, Inverter, Redimensionar
Girar em torno do centroFicar de frente para a direção do vooRedimensionar uma imagemGirar a partir do original3Classes para Objetos de Jogos
Sua primeira classeMétodosSelf é o objetoUma lista de objetosObjetos com imagensUma subclasse6Animação com Sprite Sheets
Recorte uma Sprite SheetUm contador de quadrosAnime com o tempoUma explosão de disparo únicoPratique por conta própria: Playground de Pygame