Работа с масками
Маски это лучший способ обрабатывать столкновения картинок сложной формы. У картинки должен быть прозрачный фон. Тогда маска будет массивом такого же размера как и изображение в пикселях, и каждый элемент будет отображать, прозрачный этот пискель или нет (0
- прозрачный). Тогда проверка столкновения будет происходить попиксельно.
Вот пример маски небольшого изображения (клеточки символизируют пиксели).
[[1,0,0,0,1],
[0,1,0,1,0],
[0,1,1,1,0]
[1,1,0,1,1]]
То есть каждому пикселю соотвествует 0
, если он прозрачный, 1
- иначе.
Создание маски
mask = pygame.mask.from_surface(image)
Наша маска теперь лежит в переменной mask
.
Проверка столкновения
Основная цель работы с масками - это проверка на то, что одна картинка пересеклась с другой.
Для этого создадим для обеих картинок mask1
и mask2
и будем использовать функцию
mask1.overlap_area(mask2, offset)
Она возвращает количество пикселей в которых эти картинки пересекаются.
Не пугайтесь использования неизвестной переменной offset
, мы вернемся к ней позже.
Таким образом проверка пересечения может выглядеть так
if mask1.overlap_area(mask2, offset) > 0:
# do something
Offset
Осталось разобраться, что такое переменная offset
, по-русски - сдвиг.
Переменная маски, также как и переменная изображения, хранит в себе только информацию о картинке. При этом она не знает о положении маски. То есть чтобы проверить что два спрайта пересеклись надо знать не только их маски но и то где они расположены. Действительно картинки могут находиться в разных углах экрана и точно не пересекаться, а могут быть и совсем рядом.
Специально для этого в функцию overlap_area
нужно передавать аргумент offset
. Он хранит в себе то, как расположены картинки относительно друг друга.
Например если первая картинка левым верхним углом находится в точке 100, 150
а вторая - 300, 400
, тогда сдвиг (offset
) определится так:
(300 - 100, 400 - 150) = (200, 250)
то есть это разница между первой и второй координатами.
В программе можно написать так
offset = (pos2_x - pos1_x, pos2_y - pos1_y)
Если вам непонятно что написано в последнем параграфе, то обратитесь к примеру ниже.