Colorkey столкновение между Rects в Pygame, Python 3

В настоящее время я работаю над игрой на Pygame, Python 3, и одной из важных частей игры является столкновение Rects в ситуации пули-мишени.

Это довольно легко достичь с помощью colliderect функция, но необходимо, чтобы пиксели того же цвета, что и цветовой ключ, не учитывались.

Например, если один из спрайтов (персонаж) имеет форму большого равностороннего треугольника с горизонтальным основанием, а пуля идет сверху слева, colliderect обнаружит столкновение сразу, хотя пиксели в верхнем левом углу спрайта игрока прозрачны.

Мне нужно сделать функцию, которая будет обнаруживать столкновения только тогда, когда пуля достигнет пикселей, которые имеют другой цвет, чем цветовой ключ. Это достаточно просто, если маркер имеет всего один пиксель:

if player.get_at((bullet[0] - player.left, bullet[1] - player.top)) != player.get_colorkey():

Я попытался повторить приведенное выше утверждение для каждого пикселя в маркере, но, конечно, это вызвало значительную задержку. Есть ли другой, более эффективный способ?

Заранее спасибо!!

2 ответа

Посмотрите на функцию collide_mask:

http://www.pygame.org/docs/ref/sprite.html

Вкратце, вы даете каждому спрайту атрибут self.mask (используя pygame.mask.from_surface()), который вы можете сделать, используя цветовой ключ или альфа для каждого пикселя. Затем вы включаете его в качестве обратного вызова для функции spritecollide следующим образом:

pygame.sprite.spritecollide (игрок, пули, True, pygame.sprite.collide_mask)

Надеюсь это поможет!

Мне удалось сделать алгоритм, который смотрит на углы каждого прямоугольника:

def rectsCollideSimple (rect1, surf1, rect2, surf2):
    collide = False
    try:
        if surf1.get_at((rect2.left - rect1.left, rect2.top - rect1.top)) != surf1.get_colorkey():
            collide = True
    except IndexError:
        useless = None
    try:
        if surf1.get_at((rect2.right - rect1.left, rect2.top - rect1.top)) != surf1.get_colorkey():
            collide = True
    except IndexError:
        useless = None
    try:
        if surf1.get_at((rect2.left - rect1.left, rect2.bottom - rect1.top)) != surf1.get_colorkey():
            collide = True
    except IndexError:
        useless = None
    try:
        if surf1.get_at((rect2.right - rect1.left, rect2.bottom - rect1.top)) != surf1.get_colorkey():
            collide = True
    except IndexError:
        useless = None
    return collide

def rectsCollide (rect1, surf1, rect2, surf2):
    if rectsCollideSimple(rect1, surf1, rect2, surf2) or rectsCollideSimple(rect2, surf2, rect1, surf1):
        return True
    else:
        return False

Вероятно, не самый эффективный способ, но это решило мою проблему:)

Другие вопросы по тегам