In this week’s update, yet another take on collision handling is covered in order to finish exercise #5. Haughtily, I presumed that the issue (as the course states it) did not in fact affect me due to the re-factor of the original code to work with ts-game-engine. At worst I thought that things would need to change a bit to stop the ball from being allowed off the screen while it was attached to the paddle.
How wrong I was.
In fact this issue did affect ts-breakout, but not in the manner that the course text predicted. The course indicates that the ball would be prone to an awful back-and-forth zig-zag up the side of the screen if the ball was placed too close to the edge at launch, due to the way the collision handling with the edge of the screen was implemented.
For me, that wasn’t an issue because I already had code in place to stop something like that from happening. In fact, the code was actually “smarter” because it would shift the ball backwards along its path if it moved too close towards the edge of the screen, allowing it to visually remain fully in bounds.
It turns out though that this code has its own problems if the ball is off the screen. The general gist of it is that if the ball gets too close to (or off) of the screen, the code would determine how far back along its current motion path it should be bumped so that it would end up with its edge touching the screen.
You may already see where this is headed (I sure didn’t), but if the ball is too close to the edge of the screen when you launch it, it will push backwards until it’s inside of the paddle (or worse, below it), and then things go to pot fairly quickly.
I thought of a few hacks around this (treat the initial collision after being launched different, lets say) but those left a bad taste in my mouth, so I went for the “it’s so obvious why didn’t I do it the first time” solution of just making sure that the ball never moves so much that it has to be moved back.
As such, the update method for the ball now determines if the ball would go off of the left or right of the screen (or get too close) if it moved it’s full velocity, and if so it instead calculates how far it SHOULD move in both dimensions in order to end up right where we want it.
This is just a simple variation of the push-back code, which uses some simple trig to determine, based on an angle of travel and one of the components what the other component should be.
With this in place, I also added some simple constraints to the bounds of movement on the paddle. Previously it was allowed a full range of motion that would allow it to go half off the screen on both sides. It is now set to remain wholly inside the screen with an extra side bound of the radius of the ball. This way no matter where on the paddle the ball is attached, it can never get too close to the edge of the screen.
So, lesson learned; don’t get too cocky about how “clever” your code is.