Как получить прямоугольник поверхности 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 ):
Если игрок спрайт, его прямоугольник перемещается. Посмотрите на пример кода в документе.