Mic Soto Mic Soto - 6 months ago 20
jQuery Question

How to check for a collision between two html elements using jquery

I've been working on a text based game, and I've run across the problem of creating a function that checks for a collision between two elements; a ball that you move with arrow keys, and a pipe (think flappy bird sorta). After quite a bit of research, and some of my own experimentation I still am unable to make it work.

Here is my current function:

function collision(div1, div2) {
var ballX = div1.offset().left;
var ballY = div1.offset().top;
var ballHeight = div1.outerHeight(true);
var ballWidth = div1.outerWidth(true);
var fullBallHeight = ballY + ballHeight;
var fullBallWidth = ballX + ballWidth;
var pipeX = div2.offset().left;
var pipeY = div2.offset().top;
var pipeHeight = div2.outerHeight(true);
var pipeWidth = div2.outerWidth(true);
var fullPipeHeight = pipeY + pipeHeight;
var fullPipeWidth = pipeX + pipeWidth;

if (fullBallHeight < pipeY || ballY > fullPipeHeight || fullBallWidth < pipeX || ballX > fullPipeWidth) {
return true;
}
return false;
}


And calling the function:

if (collision($("#ball"), $(".pipe")) == true) {
//code for game over
} else if (collision($("#ball"), $(".pipe")) == false) {
//calling loop function for ball animation
loop();
}


All input is appreciated, I will try almost anything at this point. Thanks.

Answer

For a 2D collision to occur, you need 4 things to happen at the same time (so it is an and, not or):

  • Ball's bottom must be below pipe's top (fullBallHeight > pipeY)
  • Ball's top must be above pipe's bottom (ballY < fullPipeHeight)
  • Ball's right must be to the right of pipe's left (fullBallWidth > pipeX)
  • Ball's left must be to the left of pipe's right (ballX < fullPipeWidth)

Image from http://jonathanwhiting.com/tutorial/collision/

(Image from http://jonathanwhiting.com/tutorial/collision/, which I recommend you to read)

So here's the resulting condition:

if (fullBallHeight > pipeY && ballY < fullPipeHeight && fullBallWidth > pipeX && ballX < fullPipeWidth) {