Description
Context
Following our discussion in #2208 regarding multi-draw functions, it's evident that having numerous APIs for multi-operation tasks doesn't align with our goal of optimizing performance. This was particularly apparent with drawing functions, where faster looping couldn't compensate for the computational time required to render large shapes covering much of the screen.
Now, with the upcoming addition of numerous shapes and corresponding collision methods in the geometry module (#2267), we face a similar challenge. Unlike multi-draw functions, these collision methods' runtime isn't solely determined by pixel count but rather by the complexity of involved shapes. Thus, optimizing runtime and ensuring stability with longer collision sequences becomes more feasible.
The current plan
The current plan entails:
- 6 multi-collision methods (collidelist/all, collidedict/all, collideobjects/all)
- 6 single collision methods (point, circle, line, rect, polygon, collideswith)
Calculating for the 3 shapes, we'll have a total of: 6 * 3 + 6 * 3 + 3 = 39 functions. This presents a considerable number of collision methods, which could pose usability challenges.
It's worth noting that single collision functions like colliderect() also allow passing a quick tuple to represent the shape, although this doesn't provide a speed benefit. Additionally, with the introduction of shapes like Line, passing a tuple like (10, 10, 20, 10) to a general .collide() method would cause ambiguity between a line and a rectangle.
My alternative
PS. These ideas could also be expaded to the Rect class for pygame 3.0 in #2760.
The alternative proposal is based on two main ideas:
Generalize the Collision Interface
This involves two sub-ideas:
- Consolidate specific collision functions into a single .collide() function, which would streamline the interface but might limit possibilities since tuples can't be passed anymore.
- Extend multi-collision functions to accept all types of shapes, eliminating the need for shape-specific functions. However, tuples can't be accepted here due to conflicting representations.
Implementing both of these ideas would reduce the total number of collision functions from 48 (considering every collision function) to 4 + 24 = 28. This approach simplifies maintenance and testing, although it would require some programs to be rewritten, hence the proposal for pygame 3.0.
Accept a Variety of Input Types (Single and Sequence)
This idea stems from our earlier discussion and suggests retaining single collision functions while allowing them to accept sequences of shapes (both classes and tuples) as input and return a sequence of booleans.
This implementation would be relatively straightforward and would spare us from creating specific multi-collision functions for each shape. Moreover, given the nature of collision calculations compared to pixel drawing, performance improvements are predictable. For instance, testing one implementation for Circle.collidepoint yielded a consistent 3X performance improvement, which can be expected for other collision methods as well.