Пиксельно точные спрайты
Часть раздела Спрайты и изображения путешествия по Pygame на Coddy. Урок 23 из 36.
Спрайты тоже могут использовать маски, а pygame сам учитывает смещение. Задайте каждому спрайту self.mask, создав его один раз в __init__:
self.mask = pygame.mask.from_surface(self.image)Затем передайте pygame.sprite.collide_mask в качестве четвёртого аргумента функции spritecollide:
hits = pygame.sprite.spritecollide(player, balls, False, pygame.sprite.collide_mask)Четвёртый аргумент — это проверка, выполняемая для каждой пары. Без него проверяются Rect. С collide_mask проверяются маски, размещённые в соответствии с Rect каждого спрайта. Функция groupcollide принимает такой же пятый аргумент.
Проверка масок обходится дороже, чем проверка Rect, но overlap сравнивает только пиксели, на которых Rect пересекаются, поэтому пары, находящиеся далеко друг от друга, проверяются быстро. Для нескольких десятков спрайтов вы не заметите разницы. Если у спрайта нет mask, collide_mask создаёт её на основе его изображения при каждой проверке, поэтому задайте её в __init__.
Задание
Средне- Создай для
PlayerиBallself.maskна основеself.image. - Передай
pygame.sprite.collide_maskвspritecollide, чтобы надписьHit!отображалась, только пока изображение корабля касается шара.
Попробуйте сами
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Spike Field")
clock = pygame.time.Clock()
ship_image = pygame.image.load("assets/images/ship.png").convert_alpha()
ball_image = pygame.image.load("assets/images/spike_ball.png").convert_alpha()
font = pygame.font.Font(None, 40)
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = ship_image
self.rect = self.image.get_rect(topleft=(420, 320))
def update(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.rect.x -= 4
if keys[pygame.K_RIGHT]:
self.rect.x += 4
if keys[pygame.K_UP]:
self.rect.y -= 4
if keys[pygame.K_DOWN]:
self.rect.y += 4
class Ball(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = ball_image
self.rect = self.image.get_rect(center=(x, y))
player = Player()
balls = pygame.sprite.Group(Ball(160, 240), Ball(320, 240), Ball(480, 240))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
player.update()
hits = pygame.sprite.spritecollide(player, balls, False)
screen.fill((20, 22, 40))
balls.draw(screen)
screen.blit(player.image, player.rect)
if hits:
text = font.render("Hit!", True, (240, 240, 240))
screen.blit(text, (10, 10))
pygame.display.flip()
clock.tick(60)
pygame.quit()
Все уроки раздела Спрайты и изображения
1Загрузка изображений
Загрузить изображениеРазместить его с помощью RectПереместить изображениеЗамостить фонПрозрачные пиксели2Поворот, отражение, масштабирование
Вращение вокруг центраПовернись в направлении полётаИзменение масштаба изображенияВращение от исходного изображения5Пиксельно точные столкновения
Прямоугольники кажутся несправедливымиМаскиПиксельно точные спрайтыКруглые хитбоксы3Классы игровых объектов
Ваш первый классМетодыSelf — это объектСписок объектовОбъекты с изображениямиПодкласс6Анимация с помощью листов спрайтов
Разрезать лист спрайтовСчётчик кадровАнимация по времениОднократная анимация взрываПотренируйтесь самостоятельно: Песочница Pygame