pygame-community / pygame-ce

🐍🎮 pygame - Community Edition is a FOSS Python library for multimedia applications (like games). Built on top of the excellent SDL library.
https://pyga.me
767 stars 120 forks source link

Add `(F)Rect.collidecircle()` #2886

Open damusss opened 1 month ago

damusss commented 1 month ago

As we near the completion of porting Circle's functionality, we're preparing to implement collision methods for Rect, such as .collidecircle() and .collideswith().

Though this might seem straightforward, it's more complex than it appears. PR #2731 by @itzpr3d4t0r attempted to reorganize our include files to facilitate this, but it wasn't entirely successful. While it allowed for partial implementation of these functionalities, it didn't fully resolve the issue. The current include structure, combined with Rect's, prevents us from recognizing when a Circle object (or, in the future, a Line or Polygon) is passed as an argument.

This is a significant problem because it undermines the core value of the pygame-geometry project: having interconnected shapes with common methods, enabling method calls across different object types.

@itzpr3d4t0r and I explored various approaches in C, but none were successful because we need to include the rect module inside geometry and vice versa. The only viable solution, short of completely rewriting the C code for Rect/Frect and Circle, is to solve the problem using Python. By moving Rect/Frect to the geometry module, we can call methods from any shape.

This PR achieves that while maintaining 100% backward compatibility. You can still use pygame.Rect or pygame.rect.Rect as before, but now you can also use pygame.geometry.Rect. This change does not affect the end user but allows us to properly implement all of pygame-geometry's features.

MyreMylar commented 1 month ago

I think a reasonable argument can be made, regardless of the technical difficulties, that it just makes sense to have all our geometry shapes (Rect, FRect & Circle) under one submodule long term.

damusss commented 1 month ago

I think a reasonable argument can be made, regardless of the technical difficulties, that it just makes sense to have all our geometry shapes (Rect, FRect & Circle) under one submodule long term.

Exactly, I totally agree. geometry is not geometry if there aren't all geometries in it.

itzpr3d4t0r commented 1 month ago

Needless to say I'm on the same boat with @Damus666 on this one. I think this move makes sense and it's actually an elegant solution which requires minimal code change on our end and has 0 impact to the end user. It might even solve some people's questions like: "why can't I import Rect/Frect from geometry? Isn't it a shape?" in the future.