This week was all about collision detection and collision response. The plan was to add the ball to the Breakout game, get it moving around the screen and bouncing off the walls and the paddle. I probably did much more research than was required this week since I spent a lot of time reading about various
collision detection algorithms and the
physics of collision response. It turns out that didn't actually use any of the techniques I read about since a very simple technique works well enough for Breakout. It was worthwhile reading all that though, if for no other reason than I now have a much better appreciation for what I need to learn.
So, research aside, the coding up of the ball itself was very easy, it only took about an hour and half and most of that was spent tweaking various parameters to get the "feel" right. So on to the code.
As with the
paddle, there is a class for the
Ball with LoadContent, Update and Draw methods that are called by the
Breakout class. The Ball tracks it's own state in these instance variables:
private Texture 2D sprite;
private Vector2 position;
private Vector2 direction;
private int speed;
This is slightly different to the paddle in that we store the speed as a scalar value and the direction as a vector. The direction is a unit vector so it contains no speed information, which is why we need the speed as a separate variable. The reason I did it this way is that the ball can move in both x and y directions, unlike the paddle, so using a unit vector allows use to calculate directional changes for the ball without needing to worry about the length of the vector, since it will always be 1.
The ball also has a few other instance variables that hold initial states, ranges of speed and position and whether the ball is currently active or dead.
So, once again, all the interesting stuff happens in the Update method:
internal void Update(GameTime gameTime) {
if (state == State.Active) {
UpdatePosition(gameTime);
if (position.Y > screenHeight) {
state = State.Dead;
} else {
HandleCollisions();
}
} else if (state == State.Dead &&
Keyboard.GetState().IsKeyDown(Keys.Space)) {
LaunchBall();
}
}