Note: I do not want to use pygame sprites.
I am making a simple game and I need a way to detect if two images overlap using pixel-perfect collision in pygame. All the answers I have found so far require that I use pygame sprites, which I prefer not to use because I have less control over the objects.
(These images have transparent backgrounds)
First of all, don't be afraid of Sprites.
A Sprite
is just a simple class with an image (a Surface
that is stored in the image
attribute) and the size and position of the image (a Rect
stored in the rect attribute).
So when you use a class like this:
class Player:
def __init__(self, image, pos):
self.image = image
self.pos = pos
def draw(self, screen):
screen.blit(self.image, self.pos)
you could simple use the Sprite
class instead, since not much would change:
class Player(pygame.sprite.Sprite):
def __init__(self, image, pos):
super().__init__()
self.image = image
self.rect = image.get_rect(center=pos)
Instead, it becames simpler, because we can let pygame handle blitting the image to the screen.
So, to use pixel perfect collision, you can use pygame's Mask
class. Use pygame.mask.from_surface
to create a Mask
from your Surface
, and use pygame.mask.Mask.overlap
to check if two masks overlap.
It's easier to use when you use the Sprite class, since you could just use functions like spritecollide
together with collide_mask
.
But if you don't want to use the Sprite
class, just take a look how collide_mask
is implemented to see how you can use masks:
def collide_mask(left, right):
xoffset = right.rect[0] - left.rect[0]
yoffset = right.rect[1] - left.rect[1]
try:
leftmask = left.mask
except AttributeError:
leftmask = from_surface(left.image)
try:
rightmask = right.mask
except AttributeError:
rightmask = from_surface(right.image)
return leftmask.overlap(rightmask, (xoffset, yoffset))