Как получить прямоугольник поверхности Pygame без прозрачных частей?

Я реализую обнаружение столкновений и хочу проверить, касается ли прямоугольный объект игрока. Моя стена использует .set_colorkey(background) где background указанный цвет фона. Проблема в том, что когда я получаю прямоугольник моей стены с .get_rect(), он получает полный размер изображения, который включает в себя прозрачные части, а не только непрозрачные части.

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

for x, y in ((i, j) for i in land_x for j in land_y):
# land_x, land_y hold the tiles to be checked
    try:
        tx1, ty1, tx2, ty2 = \
             texture[land[y][x]].get_rect()
        # tx1, ty1 coordinates of top-left corner
        # tx2, ty2 width and height respectively
        if tx2 == 0 and ty2 == 0:
            continue    # skip to other objects
        tx1 = x*64 - tx2/2
        ty1 = y*64 - ty2/2
        px1, py1, px2, py2 = \
             PLAYER.get_rect()
        px1 = player_x - px2/2
        py1 = -player_y - py2/2
        if p.Rect(px1, py1, px2, py2).colliderect(
            p.Rect(tx1, ty1, tx2, ty2)
        ):
            player_x -= direction_x
            break    # go outside loop to start checking y
    except IndexError:    # incase player is outside map
        pass    # skip to other objects

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

Пример:texture изображение размером 64x64 с блоком 48x48 в центре. Цвет фона удаляется, и остается сплошной цветной блок 48x48 (хотя размер изображения все еще составляет 64x64).

Ожидаемый результат:texture.get_rect() должен вывести прямоугольник размером 48х48.

Фактический выход:texture.get_rect() вместо этого выводит прямоугольник размером 64х64.

Любая помощь в этом будет оценена:D

2 ответа

Решение

Если вы хотите игнорировать прозрачные пиксели при обнаружении столкновений, вы говорите об идеальном столкновении пикселей.

Чтобы сделать это в Pygame, Pygame предлагает Maskучебный класс. Вы обычно создаете свои маски с pygame.mask.from_surface и использовать его вместе с pygame.sprite.spritecollide а также pygame.sprite.collide_mask,

Может подумать об использовании Pygame's Sprite класс, чтобы использовать все функции, которые он предлагает.

Даже если вы не хотите использовать встроенное обнаружение коллизий в Pygame, вы можете взглянуть на источник, чтобы увидеть, как он работает.

Вы делаете это слишком сложно. Вы знаете размер ваших объектов. Добавьте меньший прямоугольник столкновения к каждому из ваших объектов во время создания и используйте его для столкновения. Или используйте круг, если это лучше для объекта.

tile.crect = Rect(whatever)

Или просто умножьте существующие размеры прямоугольника на некоторый масштабный коэффициент для вашего прямоугольника столкновения. Не делайте все эти вычисления. Сохраните Rect для каждого сталкиваемого объекта и получите прямоугольник для игрока.

    tx1 = x*64 - tx2/2
    ty1 = y*64 - ty2/2
    px1, py1, px2, py2 = \
         PLAYER.get_rect()
    px1 = player_x - px2/2
    py1 = -player_y - py2/2

Тогда просто протестируйте столкновение напрямую:

for t in tiles:
    if player.rect.colliderect( t.rect ):

Если игрок спрайт, его прямоугольник перемещается. Посмотрите на пример кода в документе.

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

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