寻找一种简洁的方法来检查Rects列表中的点碰撞

时间:2014-06-05 08:18:26

标签: python-2.7 optimization pygame collision-detection rect

我正试图找到一种方法来检查一个点是否位于Rects列表中的任何Rect内,并获取该列表中的Rect(或第一个,如果是多个)的索引。

我目前的解决方案是使用我想要检查的点制作单像素Rect,然后使用collidelist将该点与我想要搜索的列表进行比较。

看起来像这样:

tgtrect = pygame.Rect(coords, (1,1)).collidelist(rectlist)

...其中coords是检查的点(通常,并非总是,鼠标位置),rectlist是要评估的Rect列表。 tgtrect接收冲突的Rect的索引号,如果没有,则返回-1。 我需要这个索引值来解决其他地方碰撞的Rect的身份。

我觉得有更好的方式来获取此信息(即,针对列表检查coords,返回索引(如果没有命中则返回False / None / -1),而不必每次都做一个Rect),但我不知道它是什么(或者它是否存在)。

基本上,我需要的是<Rect>.collidelist(rectlist),但对于(x,y)元组而不是Rect,或<Rect>.collidepoint(coords),但是对于Rects列表而不是单个列表。 (我可以使用第二种方法和rectlist的迭代器,但是获取碰撞Rect的索引会更加困难。)

我环顾四周发现了这个, Pygame action when mouse 'click' on .rect?, 它提供了一种检查单个Rect的方法,但不提供许多列表。重要的是我的目标Rects列表是动态的; Rect的数量及其位置经常变化。

我也读完了这个, Pygame .Rect won't "collide" with mouse, 由于同样的原因,它给出的解决方案并不适合这种情况。

谢谢!

((Auth。注意:这是我的第一个问题,所以请原谅我,如果它有点难看。请告诉我,如果它没有提供足够的信息,或者我可以采取一些措施来改进它。))

1 个答案:

答案 0 :(得分:1)

您可以使用简单的生成器表达式和collidepoint(),例如

>>> rects = [pygame.Rect(0,0,100,100), pygame.Rect(30,30,30,30)]
>>> next((r for r in rects if r.collidepoint(10, 10)), None)
<rect(0, 0, 100, 100)>
>>> next((r for r in rects if r.collidepoint(200, 200)), None)
>>>

或者,如果你真的想要索引而不是Rect本身:

>>> rects = [pygame.Rect(0,0,100,100), pygame.Rect(30,30,30,30)]
>>> next((i for (i, r) in enumerate(rects) if r.collidepoint(10, 10)), -1)
0
>>> next((i for (i, r) in enumerate(rects) if r.collidepoint(100, 200)), -1)
-1
>>>