In this week’s update we start tackling exercise 9, in which we add the ability to alter the speed that the ball is travelling (easy) and then try to decide on the exact mechanic or mechanics that will cause it to happen (harder). I have to say that it’s kind of nice to run up against a design hurdle instead of a technical one, so there’s that.
Using just the rough notes in my Todo (I once again find myself indebted to the PlainTasks plugin for Sublime Text 3) I set out to add the ability to change the speed of the ball through some external mechanism, since the game state is what owns the ball entity and is what should be making the decisions about ball speed.
In the original version of the code, I had a member named _speed which is a 2D vector that described the motion of the ball in both axes. The first step was to slap myself in the face because that’s not a particularly good name for such a variable, although it does actually represent the speed the ball is moving, after a fashion.
I renamed that particular member to be _velocity under the precept of not learning from past mistakes, and then added in a new _speed member, which is a number that indicates the overall speed of the ball.
Mostly the code is as it was before; the update method translates the position by the _velocity vector, does collisions, etc etc. However, the idea now is that the vector actually represents the direction that the ball is travelling in, which makes _speed represent the magnitude of that particular vector. So, setting the speed property on the ball first sets the member variable to track the requested speed, and then modifies the magnitude of the velocity vector to match. This keeps the direction the same but the speed constant.
That’s mostly all that is needed, except that anywhere the value of the X or Y component of the velocity vector changes, that inherently could change the magnitude of the vector, which would then require a re-tweak. Fortunately, most of the modifications to the velocity vector are just reflecting it around one or both axes, which changes the direction but leaves the magnitude intact.
In fact, the only places I tweaked up are the ball’s reset() method, and the collision detection between the ball and the paddle, since that alters the X component of the vector to change the direction of the reflection of the ball based on where on the paddle the hit takes place. As such, the reset() method now takes a speed parameter, and we do a little velocity magnitude tweak when colliding with the paddle.
None of that was particularly challenging, but I was perhaps more tickled than I needed to be to delve back into the textbook a bit and discover that this was actually the advice that was proffered on how to do this; go me!
Of more substance was trying to determine things like what would trigger a ball speed change and what speeds to actually use. I started off with that second one, trying to come up with some idea of how the controls related to various differing ball speeds; what seemed too slow and what seemed too fast.
I also investigated various scenarios for what would trigger the ball to speed up:
- Every X times the ball reflects off the paddle, alter the speed
- Every X ticks (30 ticks/second), slightly increase the speed, so as the level continues it gets harder and harder
- Split the level into a few horizontal “bands”, and the band closest to the top which has a brick removed sets the speed
I also pondered the idea of having one of the brick colors set up to trigger a speed increase whenever it was removed, but I didn’t get down into the nitty gritty of detecting that. This is not because that is hard, but an upcoming exercise (lucky number 13) covers different brick types, so that might be a thing to add there.
Each one of these things has it’s own level of complexity and balance, though; how many reflections is a good number before the ball speeds up? How long should the time interval be before the ball speeds up no matter what? Should both happen at the same time? Does the ball drop to the slowest possible speed when you start a new serve? Should it keep the same speed as it had when you lost? Maybe just drop by 1/2?
This is definitely an area that is both interesting and slightly frightening in terms of AP (Analysis Paralysis) and brings some interesting thoughts forward on game design that I hadn’t really fully pondered before.
I still haven’t fully decided on this one. As silly as it seems, I’m trying to both not get bogged down in minutae and also try to get some experience in tuning game design to be more fun. My plan is to experiment for a little bit longer and then impose a deadline on myself to just prioritize and choose which I think are the most fun and go from there.