Reputation: 197
I create a clicker game and I have a transparent image (that I set in Mask for Pixel Perfect Collision ) but when I also click on the transparent part, the MOUSEBUTTONDOWN event is detected.
Actually, my code in the Player Class is:
self.image = pygame.image.load(str(level) + ".png").convert_alpha()
self.mask = pygame.mask.from_surface(self.image)
self.image_rect = self.image.get_rect(center=(WW, HH))
and this, in the main loop:
x, y = event.pos
if my_player.image_rect.collidepoint(x, y):
my_player.click()
So I would like the click event to be triggered only when I click on the colored part of the image and not on the transparent background.
Thanks,
Upvotes: 3
Views: 1752
Reputation: 101052
In addition to my_player.image_rect.collidepoint(x, y)
, check also for Mask.get_at
:
get_at()
Returns nonzero if the bit at (x,y) is set.
get_at((x,y)) -> int
Note that you have to translate the global mouse position to the position on the mask.
Here's a runnable example:
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
class Cat:
def __init__(self):
self.image = pygame.image.load('cat.png').convert_alpha()
self.image = pygame.transform.scale(self.image, (300, 200))
self.rect = self.image.get_rect(center=(400, 300))
self.mask = pygame.mask.from_surface(self.image)
running = True
cat = Cat()
while running:
for e in pygame.event.get():
if e.type == pygame.QUIT:
running = False
pos = pygame.mouse.get_pos()
pos_in_mask = pos[0] - cat.rect.x, pos[1] - cat.rect.y
touching = cat.rect.collidepoint(*pos) and cat.mask.get_at(pos_in_mask)
screen.fill(pygame.Color('red') if touching else pygame.Color('green'))
screen.blit(cat.image, cat.rect)
pygame.display.update()
Also, self.image_rect
should be named self.rect
by convention. It's not absolutly necessary; but it's still a good idea and enables you to work with pygame's Sprite
class (not shown in the example).
Upvotes: 7