045 : Basic collision

Balthazar:

There are many ways of handling collision detection, but one of the simplest is to check the rectangles for each object to see if they overlap.

You:

Uh-oh, is this where things start getting hard?

Balthazar:

Not really, but if you don't understand the basic ideas of how the collision detection works, you'll find the code to be confusing. So that's why I want to make sure that you understand how it works before we start with the code.

You:

OK ...but it still sounds like this is going to be hard

Balthazar:

Let's say we have 2 objects: obj1 and obj2 and we want to know if they overlap.

You:

"We have 2 objects..."

Balthazar:

No, no, no. Don't actually say it. I meant, let's pretend that we have 2 objects, obj1 and obj2.

You:

Oh, OK, that's easier. I'm pretending now.

Balthazar:

Each of these object has an x,y position and a width and a height. For object1, these values are stored in: obj1.x, obj1.y, obj1.width and obj1.height.

Balthazar:

Let's focus initially on the x-direction. We know that the objects do *not* overlap in the x-direction if the right-most edge of object1 is to the left of the left-most edge of object2.

You:

And I could code that like: if (obj1.x + obj1.width < obj2.x) and have it return false=?

Balthazar:

Exactly. And also do a similar check for the other side by swapping the objects: if the right-most edge of object1 is to the left of the left-most edge of object1, then they don't overlap.

You:

Hmm.. that doesn't sound too hard.

Balthazar:

Doing the same thing for the y-direction and you eliminate all the cases where they object don't overlap. Any object pairs that pass these checks must overlap.

You:

Cool. So I can just add 4 of these if checks and that's it?

Balthazar:

Well, there's one more thing.

You:

sigh There always is...

Balthazar:

Remember that we added an origin to our player? We need to take that into account when calculating the left, right, top and bottom boundaries.

You:

So instead of obj1.x + obj1.width, I need to subtract the origin to get the upper-left point, just like I did when I was drawing. That's makes it obj1.x - obj1.origin_x + obj1.width.

Balthazar:

Exactly!

// Return true if the 2 objects overlap. function collide(obj1, obj2) { // NYI if ((obj1.x - obj1.origin_x + obj1.width) <= (obj2.x - obj2.origin_x)) return false; if ((obj1.y - obj1.origin_y + obj1.height) <= (obj2.y - obj2.origin_y)) return false; if ((obj2.x - obj2.origin_x + obj2.width) <= (obj1.x - obj1.origin_x)) return false; if ((obj2.y - obj2.origin_y + obj2.height) <= (obj1.y - obj1.origin_y)) return false; return false; return true; }
Balthazar:

And now if you run your code it will detect when the player touches the goal.

You:

I think I did something wrong. It's not working - I can walk over to the goal and the game doesn't end.

Balthazar:

Actually, the collision check is working -- it's just not obvious that it's doing anything. When the player touches the goal, the boolean variable game_over is indeed set to true. The problem is that you don't currently do anything special when the game is over.

You:

We should fix that.

Balthazar:

And that's just what you'll do next.

GOTO 046 if you already have the Movement III - Gravity badge.

GOTO 044