单击 pygame 中的重叠矩形

问题描述

我正在尝试使用 pygame 制作一个简单的游戏,但遇到了以下一般问题。

假设我们有两个精灵,分别命名为 sprite1sprite2,每个都有对应的 rectimage 属性。这些精灵是“可点击的”,也就是说当用户点击它们时应该会发生一些事情。我通常通过在游戏循环中添加以下内容来实现这一点:

if event.type == pygame.MOUSEBUTTONDOWN:
    mouse_pos = pygame.mouse.get_pos()
    if spritex.collidepoint(mouse_pos):
        (whatever clicking on spritex triggers)

在我的游戏中,sprite1sprite2 偶尔会重叠,假设我总是想在 sprite2 之上绘制 sprite1。我知道我可以通过在 screen.blit(sprite1.image,sprite1.rect) 之前使用 screen.blit(sprite2.image,sprite2.rect) 来实现这一点。但是,我希望每当 sprite1sprite2 重叠,并且用户点击 sprite1.rectsprite2.rect 上方的点时,只有 {{1} 的动作}} 应该触发。

在这个简单的例子中,我知道可以用

sprite2

但是这个解决方案不容易推广到更复杂的情况(更多精灵、更多类型的精灵、pygame_gui 元素等)。

我想知道:有没有更简单、更优雅的解决方案来解决这些问题?

解决方法

您可以按照 z-index/它们在前面多远的顺序创建所有精灵的列表,从更近的精灵开始。

sprites = [sprite2,sprite1]

然后迭代直到找到第一个匹配项:

def find_clicked(mouse_pos):
    for sprite in sprites:
        if sprite.collidepoint(mouse_pos):
            return sprite

您仍然需要根据点击的精灵进行处理。这仍然需要某种 if 树,除非您有一个巧妙的实现,例如函数引用字典(只有在您从不重新创建 sprite 对象时才有效!)。但是,这比按精灵位置顺序硬编码 if 树要健壮得多,因为您可以轻松地对列表重新排序,一切都会正常工作。