Pygame already offers some solutions for this.
If you use pygame's collision handling, (e.g. pygame.sprite.spritecollide
, pygame.sprite.groupcollide
or pygame.sprite.spritecollideany
), note that you can use a callback function used to calculate if two sprites are colliding (the collided
argument).
The default that is used is pygame.sprite.collide_rect
, but in your case, you should take a look at pygame.sprite.collide_rect_ratio
:
pygame.sprite.collide_rect_ratio()
Collision detection between two sprites, using rects scaled to a ratio.
collide_rect_ratio(ratio) -> collided_callable
A callable class that checks for collisions between two sprites, using a scaled version of the sprites rects.
Is created with a ratio, the instance is then intended to be passed as a collided callback function to the *collide functions.
A ratio is a floating point number - 1.0 is the same size, 2.0 is twice as big, and 0.5 is half the size.
Here's how collide_rect_ratio
is implemented.
Of course you can write such a callback function yourself if you need some custom behaviour.
So maybe you want to change the function to check if a sprite has a pseudo_rect
attribute, and then use this instead of the rect
attribute.
Then, in your sprite classes, you could do something like this:
self.rect = self.image.get_rect()
self.pseudo_rect = self.rect.inflate(5, 5)
if you want to give a sprite a bigger hitbox (don't forget to set pseudo_rect's center
attribute to rect.center
everything you change rect
).
Another way could be to give your sprites a collision_ration
attribute and use it in the collision function, if set.