Menu
CoddyTech

Mặt nạ

Thuộc phần Sprite và hình ảnh trong hành trình Pygame của Coddy. Bài học 23 trên 39.

Mặt nạ là một lưới gồm các giá trị có và không, mỗi giá trị ứng với một điểm ảnh: có ở nơi hình ảnh đặc, không ở nơi hình ảnh trong suốt. pygame tạo mặt nạ từ bất kỳ hình ảnh nào có alpha:

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

Tạo mặt nạ một lần, trước vòng lặp, giống như các hình ảnh dùng để tạo ra chúng.

Hai mặt nạ chồng lên nhau khi một điểm ảnh đặc của mặt nạ này nằm trên một điểm ảnh đặc của mặt nạ kia. Mặt nạ không có vị trí, vì vậy bạn cần cho biết mặt nạ thứ hai nằm ở đâu so với mặt nạ thứ nhất: độ lệch, tọa độ góc trên bên trái của mặt nạ kia trừ tọa độ góc trên bên trái của mặt nạ này.

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

overlap trả về điểm đầu tiên nơi hai mặt nạ chạm nhau, hoặc None khi chúng không chạm nhau, nên có thể dùng làm phép kiểm tra trong câu lệnh if. Nếu tính ngược độ lệch, bạn sẽ kiểm tra quả bóng như thể nó nằm ở phía bên kia của con tàu.

Giờ đây, đường viền màu đỏ cần tiếp xúc thực sự: các góc vẫn giữ màu xám.

challenge icon

Thử thách

Trung bình

Chỉ chuyển đường viền sang màu đỏ khi các hình ảnh chạm nhau.

  1. Trước vòng lặp, tạo ship_mask và ball_mask bằng pygame.mask.from_surface.
  2. Chuyển đường viền sang màu đỏ khi ship_mask.overlap(ball_mask, offset) tìm thấy một điểm, với độ lệch từ ship_rect đến ball_rect; nếu không thì chuyển sang màu xám.

Nhấn Chơi: đường viền vẫn màu xám khi chỉ có các góc chồng lên nhau. Sau đó nhấn Kiểm tra.

Tự làm thử

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()

Tất cả bài học trong Sprite và hình ảnh

Tự luyện tập: Playground Pygame