Reputation: 377
This is the part of my code, where the problem is:
button = pygame.image.load("button1.png")
screen.blit(button, (100, 100))
This image looks like this:
[
I need to increase a value of a variable, when the user clicks on the image.
I tryed some solutions, but most of them was drawing an "invisible" rectangle over the picture, and the variable's value vas increasing, even if someone clicked on the white space near the triangle.
Upvotes: 1
Views: 1364
Reputation: 7361
You could use Surface.get_at() to check the color of the pixel where the mouse clicks. If it's the background color (white in your case) you consider it outside, otherwise is inside and you trigger the action.
Here a working example. The insideimage
function checks that the click is inside the surface button
(the rectangle) and checks the color of the pixel at mouse coordinates. Returns True
if the click is inside the surface and the color is not white.
This works if the background color is not used again inside the image.
import sys
import pygame
SCREENWIDTH = 500
SCREENHEIGHT = 500
pygame.init()
screen = pygame.display.set_mode((SCREENWIDTH, SCREENHEIGHT))
button = pygame.image.load("button1.png")
screen.blit(button, (100, 100))
def insideimage(pos, rsurf, refcolor):
"""rsurf: Surface which contains the image
refcolor: background color, if clicked on this color returns False
"""
refrect = rsurf.get_rect().move((100, 100))
pickedcol = screen.get_at(pos)
return refrect.collidepoint(pos) and pickedcol != refcolor
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.MOUSEBUTTONUP:
valid = insideimage(event.pos, button, (255, 255, 255, 255))
#(255, 255, 255, 255) this is color white with alpha channel opaque
print(valid)
pygame.display.update()
Upvotes: 1
Reputation: 101042
It's quite easy with the mask
module.
From the docs:
Useful for fast pixel perfect collision detection. A mask uses 1 bit per-pixel to store which parts collide.
First, create a Mask
from the image
mask = pygame.mask.from_surface(button)
Then, when checking for the mouse click event, check if the point in the mask is set.
Here's a simple example:
import pygame
def main():
pygame.init()
screen = pygame.display.set_mode((480, 320))
button = pygame.image.load('button.png').convert_alpha()
button_pos = (100, 100)
mask = pygame.mask.from_surface(button)
x = 0
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT:
return
if e.type == pygame.MOUSEBUTTONDOWN:
try:
if mask.get_at((e.pos[0]-button_pos[0], e.pos[1]-button_pos[1])):
x += 1
print(x)
except IndexError:
pass
screen.fill((80,80,80))
screen.blit(button, button_pos)
pygame.display.flip()
main()
Example button.png for testing:
Upvotes: 3
Reputation: 2359
There's no easy way to do this in pygame other than manually calculating where the mouse is and figuring out if it's in the triangle or not.
The image you're loading (button1.png
) is a square image, and so there's no way for pygame or any other library to know what it's "actual" shape is. You'll either have to do it yourself or be okay with the user being able to click on the white space.
Upvotes: 1