This week we extended our colliders so that we could used them to prevent the player going off the edges of the screen. We used it to show how software design needs to evolve.
Colliders
Our colliders were designed to be connected to an object with three things:
- A property x containing the x-coordinate of its location
- A property y containing the y-coordinate of its location
- A function hit() which was called if the attached collider touched another collider
Something to Connect To
We had colliders already attached to our:
- Enemy
- Bullets
but we didn’t have anything to attach to that could represent the side of the screen.
We created a new class called Static() with nothing more than the x, y and hit() that we needed so that we could connect a collider to it (stored in one more property – collider).
Screen Edges
We created a pair of these colliders positioned at the right and left-hand side of the screen. We made sure to add them to our list in check_colliders(). Nothing much happened. Why? Well, first, the Player didn’t have a collider, so we added one, liberally copying code from Enemy, which a minor change to the description argument.
Now we could see the contact occurring between the edge and the player, though nothing was stopping it moving yet.
Unintended Consequences
As often happens with code, this change had unexpected consequences; bullets were not firing properly any more. Why? Because the player now had a collider and the bullets were becoming inactive immediately because they were hitting that. The fix was to modify the Bullet’s hit() function to ignore hitting a collider with the description “player”.
Stopping the Player Moving
We now knew our player was hitting an edge, but another problem became apparent: we didn’t know which edge!
To properly stop the player and stop it moving too far, we really needed to know which side of the player the collider we’d hit was, but that information wasn’t available to us with the current design.
A couple of quick changes were necessary:
- In Collider.touching(), instead of just passing the descriptors to the objects hit() functions, we changed it to pass the Collider itself.
- In all the hit() functions, we had to made a small adjustment to account for the fact that we were now getting a Collider and not just a string.
With the extra information from the collider, were were able to determine how far the player should be allowed to move to and prevent it going further by setting the x value appropriately.
Download
The files for this week can be found on our GitHub repository.