Máscaras
Parte de la sección Sprites e imágenes del Journey de Pygame de Coddy. Lección 22 de 36.
Una máscara es una cuadrícula de sí y no, uno por píxel: sí donde la imagen es sólida, no donde es transparente. pygame crea una a partir de cualquier imagen con alfa:
ship_mask = pygame.mask.from_surface(ship)
ball_mask = pygame.mask.from_surface(ball)Crea las máscaras una sola vez, antes del bucle, igual que las imágenes de las que provienen.
Dos máscaras se superponen cuando un píxel sólido de una cae sobre un píxel sólido de la otra. Una máscara no tiene posición, así que indicas dónde está la segunda con respecto a la primera: el desplazamiento, la posición superior izquierda de la otra menos la posición superior izquierda de esta.
offset = (ball_rect.x - ship_rect.x, ball_rect.y - ship_rect.y)
if ship_mask.overlap(ball_mask, offset):overlap devuelve el primer punto donde se tocan, o None cuando no se tocan, así que funciona como prueba en un if. Si calculas el desplazamiento al revés, la pelota se comprueba como si estuviera en el otro lado de la nave.
Ahora el contorno rojo necesita un contacto real: solo las esquinas se quedan grises.
Desafío
Intermedio- Antes del bucle, crea
ship_maskyball_maskconpygame.mask.from_surface. - Colorea el contorno de rojo cuando
ship_mask.overlap(ball_mask, offset)encuentra un punto, con el desplazamiento deship_rectaball_rect; de lo contrario, de gris.
Pruébalo tú mismo
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()
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Sprites e imágenes
1Cargar imágenes
Cargar una imagenColocarla con un rectánguloMover la imagenRepetir un fondo en mosaicoPíxeles transparentes2Girar, voltear y escalar
Girar alrededor del centroApuntar en la dirección del vueloEscalar una imagenGirar desde la imagen original5Colisiones precisas a nivel de píxel
Los rectángulos parecen injustosMáscarasSprites precisos a nivel de píxelHitboxes circulares3Clases para objetos del juego
Tu primera claseMétodosSelf es el objetoUna lista de objetosObjetos con imágenesUna subclase6Animación con hojas de sprites
Recortar una hoja de spritesUn contador de fotogramasAnimar con el tiempoUna explosión de una sola vezPractica por tu cuenta: Playground de Pygame