【问题标题】:Pygame click on image (not a rectangle)Pygame点击图像(不是矩形)
【发布时间】:2019-06-12 12:34:18
【问题描述】:

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

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

这张图片看起来像这样:

[

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

我尝试了一些解决方案,但大多数都在图片上绘制了一个“不可见”的矩形,并且变量的值不断增加,即使有人点击了三角形附近的空白区域。

【问题讨论】:

    标签: python image pygame rectangles


    【解决方案1】:

    mask module 非常简单。

    来自文档:

    对于快速像素完美碰撞检测很有用。掩码使用每像素 1 位来存储碰撞的部分。


    首先,从图片中创建一个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:

    【讨论】:

      【解决方案2】:

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

      您正在加载的图像 (button1.png) 是方形图像,因此 pygame 或任何其他库无法知道它的“实际”形状是什么。您要么必须自己做,要么允许用户点击空白区域。

      【讨论】:

      • 谢谢。是否有任何方程式或东西包含三角形的所有点?或者我该如何计算?
      • 算出它的三个点的坐标是什么。有了这些信息,您可以在网上找到plenty of methods,以确定用户是否在该三角形内单击。
      【解决方案3】:

      您可以使用Surface.get_at() 来检查鼠标点击的像素的颜色。如果它是背景颜色(在您的情况下为白色),您将其视为外部,否则在内部并触发操作。

      这是一个工作示例。 insideimage 函数检查单击是否在表面 button(矩形)内,并检查鼠标坐标处像素的颜色。如果单击在表面内且颜色不是白色,则返回 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()
      

      【讨论】:

      • 这很好,但我在屏幕上使用按钮颜色的次数更多。
      • 代码只检查矩形的表面,所以如果你有其他表面(比如从其他图像中获取的其他按钮)是安全的。只有在图像本身内部使用图像的背景颜色(如外部和内部的三角形白色)时,您才会有一个缺点。不是你上传的图片的情况。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-01
      • 1970-01-01
      相关资源
      最近更新 更多