Menu
CoddyTech

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.

challenge icon

Desafío

Intermedio
  1. Antes del bucle, crea ship_mask y ball_mask con pygame.mask.from_surface.
  2. Colorea el contorno de rojo cuando ship_mask.overlap(ball_mask, offset) encuentra un punto, con el desplazamiento de ship_rect a ball_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()
quiz iconPonte a prueba

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

Practica por tu cuenta: Playground de Pygame