## Question of the Week

Create
the PongOut Game - Collision Detection
by Ilyas Usal aka pom : 3 January 2005

The Collision Detection
We are going to write the checkBricks method for the ball, just like we create the checkWalls method.

MovieClip.prototype.move = function (pGame) {
this.vx = pGame.speed * Math.cos (-45 * Math.PI / 180) ;
this.vy = pGame.speed * Math.sin (-45 * Math.PI / 180) ;
this.x = this._x ;
this.y = this._y ;
this.onEnterFrame = function () {
this.x += this.vx ;
this.y += this.vy ;
this.checkWalls (pGame) ;
this.checkBricks (pGame) ;
this._x = this.x ;
this._y = this.y ;
}
} ;

MovieClip.prototype.checkBricks = function (pGame) {
for (var cl in pGame.timeline.brick_board) {
var clip = pGame.timeline.brick_board[cl];
if (clip.hitTest(this.x, this.y, true)) {
var u = clip._y;
var d = clip._y + clip._height;
var l = clip._x;
var r = clip._x + clip._width;
var bounce = 0;
clip.life--;
if ( clip.life == 0) clip.removeMovieClip();
if (this._x <= l && this.x >= l) {
this.x = l;
this.vx *= -1;
bounce = 1;
}
else if (this._x >= r && this.x <= r) {
this.x = r;
this.vx *= -1;
bounce = 1;
}
if (this._y <= u && this.y >= u) {
this.y = u;
this.vy *= -1;
bounce = 1;
}
else if (this._y >= d && this.y <= d) {
this.y = d;
this.vy *= -1;
bounce = 1;
}
if (!bounce) {
trace ("Houston, we have a problem!");
this.vy *= -1 ;
trace (this.x + ":" + this._x + ":" + l + ":" + r);
trace (this.y + ":" + this._y + ":" + d + ":" + u);
}
pGame.checkEndLevel ();
}
}
} ;

Take a deep breath now. It's not as bad as it seems. In the following section, I will explain the code:

for (var cl in pGame.timeline.brick_board) {
var clip = pGame.timeline.brick_board[cl];

Thanks to this for...in loop, we have access to all the clips contained in the pGame.timeline.brick_board movie clip, that is to say the bricks, one after another. To make the code easier to read, I created a reference to the current brick that I named clip. This is a really important method, so make sure you understand what's happening (there's also a tutorial about for... in loops).

if (clip.hitTest(this.x, this.y, true)) {

This is the first time we use the hitTest method in this game. Notice that I used the point to clip form of the method, which means that I pretend that the ball is just a point, that it has no width. This is of course untrue, and this means that our game is not going to be 100% accurate.

Fortunately, it doesn't have to be 100% accurate, it just has to be accurate enough. If the ball were bigger, you'd better use the clip to clip version of hitTest.

OK, so now that we know that the ball has hit a brick, we need to find out which side of the brick was hit.

var u = clip._y;
var d = clip._y + clip._height;
var l = clip._x;
var r = clip._x + clip._width;

This retrieves the position of the upper, lower, left and right edges of the brick we've just hit (its registration point in on the top left corner).

var bounce = 0;
clip.life--;
if ( clip.life == 0) clip.removeMovieClip();

The bounce variable will tell us if we've managed to find out which side of the brick has been hit (it happens that we can't, but it's a problem with Flash, not with the code ). And of course, when the ball hits the bricks, its life decreases, and when it reaches 0, the brick is removed.

You are almost finished, but not yet! On the next page, I'll finish explaining the code!

 page 6 of 7