Pygame 点击图片(不是矩形)

Pygame click on image (not a rectangle)

这是我的代码部分,问题所在:

button = pygame.image.load("button1.png")
screen.blit(button, (100, 100))

这张图片看起来像这样:

[

当用户点击图片时,我需要增加一个变量的值。

我尝试了一些解决方案,但大多数解决方案都是在图片上绘制一个 "invisible" 矩形,变量的值在增加,即使有人点击三角形附近的白色 space 也是如此。

在 pygame 中没有简单的方法可以做到这一点,除了手动计算鼠标的位置并确定它是否在三角形中。

您正在加载的图像 (button1.png) 是方形图像,因此 pygame 或任何其他库无法知道它的 "actual" 形状。你要么必须自己做,要么让用户能够点击白色 space.

使用 mask module 非常简单。

来自文档:

Useful for fast pixel perfect collision detection. A mask uses 1 bit per-pixel to store which parts collide.


首先,从图像

创建一个Mask
mask = pygame.mask.from_surface(button)

然后,在检查鼠标点击事件时,检查掩码中的点是否为set

这是一个简单的例子:

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()

用于测试的示例 button.png:

您可以使用Surface.get_at()来检查鼠标点击的像素的颜色。如果它是背景颜色(在你的情况下是白色),你认为它在外面,否则在里面并且你触发动作。

这是一个工作示例。 insideimage 函数检查点击是否在表面 button(矩形)内,并检查鼠标坐标处像素的颜色。 Returns True 如果点击在表面内部并且颜色不是白色。
如果图像中不再使用背景颜色,此方法有效。

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()