问题描述
我正在尝试使用 pygame 制作一个简单的游戏,但遇到了以下一般问题。
假设我们有两个精灵,分别命名为 sprite1
和 sprite2
,每个都有对应的 rect
和 image
属性。这些精灵是“可点击的”,也就是说当用户点击它们时应该会发生一些事情。我通常通过在游戏循环中添加以下内容来实现这一点:
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = pygame.mouse.get_pos()
if spritex.collidepoint(mouse_pos):
(whatever clicking on spritex triggers)
在我的游戏中,sprite1
和 sprite2
偶尔会重叠,假设我总是想在 sprite2
之上绘制 sprite1
。我知道我可以通过在 screen.blit(sprite1.image,sprite1.rect)
之前使用 screen.blit(sprite2.image,sprite2.rect)
来实现这一点。但是,我希望每当 sprite1
和 sprite2
重叠,并且用户点击 sprite1.rect
和 sprite2.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
树要健壮得多,因为您可以轻松地对列表重新排序,一切都会正常工作。