-
-
Notifications
You must be signed in to change notification settings - Fork 159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sprite group collide tweaks #3197
base: main
Are you sure you want to change the base?
Sprite group collide tweaks #3197
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line 505: is this an ok way to test against an empty returned list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've not thought about the API details yet, this review is just based on my initial look.
Thanks for contributing, anyways! 🎉
|
||
If the sprite collides with any single sprite in the group, a single | ||
sprite from the group is returned. On no collision None is returned. | ||
|
||
If you don't need all the features of the ``pygame.sprite.spritecollide()`` function, this | ||
function will be a bit quicker. | ||
function will be a bit quicker.. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor nitpick: extra .
here
As per initial discussion at: #3193
This PR expands two Sprite collide functions, pygame.sprite.spritecollideany() and pygame.sprite.spritecollide() to allow an optional arg, ignore_self that will disregard the sprite being tested, with itself.
Without this arg, both functions report collisions with the sprite's own rect, if that sprite belongs to the group being tested.
My feeling is that this could be counter-intuitive, especially to new users.
For example, if someone sets up a group "all_ships" and wanted to see if any of them are hitting each other, the result would always be a hit. Even if only one ship was being drawn to the screen, the above functions would report that the ship had hit something (it is hitting itself!).
[it is obviously fairly easy to work around the above situation, for example you could remove a sprite from a group prior to checking it and then add it back in - this PR doesn't dispute this, it is more about making things easier for new users]
With the new "ignore_self" arg, no collisions would be reported unless the sprite were actually overlapping a different sprite within the group, which I would suggest is what a new user would expect.
On the discord, there was talk of expanding this functionality to add an 'exclusion' list of sprites. This PR does not currently do this. My own feeling is that this perhaps adds too much complexity, especially to spritecollideany() which I think of as a "quick and cheap" way of doing initial collision detection, prior to more accurate checks such as using masks. However, I could obviously change the functionality to work like that if that is the consensus.
Finally, please note this is my first PR to the project, so apologies if I have done anything incorrectly (for example, I've done three commits, sorry!).
I have read the wiki contribution articles, run ruff on my changes and tested (more details below). I did not know how to regenerate the HTML documentation locally, but I've updated \docs\reST\ref\sprite.rst - is that all that is required?
--
Testing this PR, 1 of 2: Unit Tests
I updated sprite_text.py and added a new function to test both functions, both with default behaviour, and the new arg. I do this twice for each function, once with a callback collide function, and one with it omitted.
Testing this PR, 2 of 2: Messy visual test
I also cobbled together this test script (code below), which toggles between ignore_self = False and ignore_self = True by pressing the space bar. Move the box around using cursor keys. I use visual indicators to show how many sprites each box is hitting. (note orange is using a rectratio scale bigger than the sprite, so you turn orange before you overlap)
ignore_self = False - every box thinks it is hitting one sprite (themselves!). Orange and Red colours show spritecollideany() hits, black and yellow inner squares denote 1 hit each returned by two calls to spritecollide()
ignore_self = True - here we are actually overlapping some of the boxes. You can see the two top boxes are only reporting one hit (one black inner box, and one yellow one), and the bottom box is reporting two hits from each call.
(if this is confusing, I wrote it late at night! - look at the code and move the box around yourself and it will make sense :-) )
Test code: