문제

I'm trying to find a way to check if a point lies within any Rect in a list of Rects, and to get the index of that Rect (or the first, if multiple) on the list.

My current solution is to make a single-pixel Rect using the point I want to check for, then using collidelist to compare that point against the list I want to search for.

It looks like this:

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

...wherein coords is the point checked (usually, not always, a mouse location) and rectlist is the list of Rects to be evaluated. tgtrect receives the index number of a colliding Rect, or -1 if there are none. I need this index value to resolve the identity of the colliding Rect elsewhere.

I feel like there's a better way to get this information (that is, to check coords against a list, returning an index (or False/None/-1 if there are no hits), without having to make a Rect each time), but I don't know what it is (or if it exists at all).

Basically, what I need is <Rect>.collidelist(rectlist), but for an (x,y) tuple and not a Rect, or <Rect>.collidepoint(coords), but for a list of Rects and not a single one. (I could use this second method with an iterator for rectlist, but it would be more difficult to get the index for the colliding Rect.)

I looked around a bit and found this, Pygame action when mouse 'click' on .rect?, which offers a way to check for single Rects, but not a list of many. The significance is that my list of target Rects is dynamic; the number of Rects and their locations changes frequently.

I also read through this, Pygame .Rect won't "collide" with mouse, which gave a solution that didn't really suit the situation for the same reasons.

Thanks!

((Auth. note: This is my first question, so please forgive me if it's kind of ugly. Please let me know if it does not supply enough information, or there are things I can do to improve it.))

도움이 되었습니까?

해결책

You could use a simple generator expression and collidepoint(), like

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

or, if you really want the index instead of the Rect itself:

>>> 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
>>>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top