Menu
CoddyTech

Máscaras

Parte da seção Sprites e imagens do Journey de Pygame da Coddy. Lição 22 de 36.

Uma máscara é uma grade de valores sim e não, um por pixel: sim onde a imagem é sólida, não onde é transparente. O pygame cria uma a partir de qualquer imagem com canal alfa:

ship_mask = pygame.mask.from_surface(ship)
ball_mask = pygame.mask.from_surface(ball)

Crie as máscaras uma única vez, antes do loop, assim como as imagens das quais elas são feitas.

Duas máscaras se sobrepõem quando um pixel sólido de uma coincide com um pixel sólido da outra. Uma máscara não tem posição, então você indica onde a segunda fica em relação à primeira: o deslocamento, a posição superior esquerda da outra menos a posição superior esquerda desta.

offset = (ball_rect.x - ship_rect.x, ball_rect.y - ship_rect.y)
if ship_mask.overlap(ball_mask, offset):

overlap retorna o primeiro ponto em que elas se tocam, ou None quando não se tocam, então funciona como teste em um if. Inverta o deslocamento e a bola será testada como se estivesse do outro lado da nave.

Agora o contorno vermelho precisa de contato real: apenas os cantos continuam cinza.

challenge icon

Desafio

Médio
  1. Antes do loop, crie ship_mask e ball_mask com pygame.mask.from_surface.
  2. Deixe o contorno vermelho quando ship_mask.overlap(ball_mask, offset) encontrar um ponto, usando o deslocamento de ship_rect para ball_rect; caso contrário, deixe-o cinza.

Experimente você mesmo

import pygame

pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Near Miss")
clock = pygame.time.Clock()

ship = pygame.image.load("assets/images/ship.png").convert_alpha()
ship_rect = ship.get_rect(topleft=(420, 320))
ball = pygame.image.load("assets/images/spike_ball.png").convert_alpha()
ball_rect = ball.get_rect(center=(320, 240))

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        ship_rect.x -= 4
    if keys[pygame.K_RIGHT]:
        ship_rect.x += 4
    if keys[pygame.K_UP]:
        ship_rect.y -= 4
    if keys[pygame.K_DOWN]:
        ship_rect.y += 4

    screen.fill((20, 22, 40))
    screen.blit(ball, ball_rect)
    screen.blit(ship, ship_rect)
    if ship_rect.colliderect(ball_rect):
        colour = (230, 60, 60)
    else:
        colour = (90, 90, 120)
    pygame.draw.rect(screen, colour, ball_rect, 2)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Sprites e imagens

Pratique por conta própria: Playground de Pygame