1

I am coding a game that involves the collision of a moving circle, controlled by the user, and a moving rectangle, controlled by the computer.

Full code can be found here: Game

I am having trouble with collision detection between the circle and the rectangle. When the rectangle is static, the collision detection works perfectly. The moment the edges of the circle and rectangle touch on any side, the program acts the way it is supposed to.

However, whenever I give the rectangle motion, the collision works fine on the right side of the rectangle, but not on the left.

I can play with the numbers to make it work on the left but not on the right, however, I can't get it to work correctly on both sides. Is there a simple fix I'm missing?

I have attached a few photos to illustrate what I mean.

This is the collision detection function.

function collisionDetection(player,rect) {
  var distX = Math.abs(player.x - player.dx - rect.x - rect.w/2);
  var distY = Math.abs(player.y - rect.y - rect.h/2);

  if (distX >= (rect.w / 2 + player.r - player.dx)) {
    return false;
  }
  if (distY > (rect.h / 2 + player.r)) {
    return false;
  }

  if (distX <= rect.w/2) {
    return true;
  }
  if (distY <= rect.h/2) {
    return true;
  }
}

if(collisionDetection(player,rect)) {
  alert("You Lose");
  document.location.reload();
}

Right side

Left side

Thank you

  • 1
    Possible duplicate of [Circle-Rectangle collision detection (intersection)](http://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection) – JHS Dec 27 '16 at 08:19

2 Answers2

1

You had a few glitches in your collision function.

Here's working code to detect rectangle vs circle collisions:

function collisionDetection(player,rect){
    var distX = Math.abs(circle.x - rect.x - rect.w/2);
    var distY = Math.abs(circle.y - rect.y - rect.h/2);

    if (distX > (rect.w/2 + circle.r)) { return false; }
    if (distY > (rect.h/2 + circle.r)) { return false; }

    if (distX <= (rect.w/2)) { return true; } 
    if (distY <= (rect.h/2)) { return true; }

    // also test for corner collisions
    var dx=distX-rect.w/2;
    var dy=distY-rect.h/2;
    return (dx*dx+dy*dy<=(circle.r*circle.r));
}
markE
  • 102,905
  • 11
  • 164
  • 176
  • I actually used your code from a previous post for this game. I really appreciate it. Although, with the code above, I still have a small gap on the right side and the circle overlaps the rectangle a bit on the left. Is this caused by the rect.dx value? – CheetahBongos Dec 17 '15 at 23:48
  • 1
    Glad you found (both!) posts useful. :-) Yes, the gap is being caused by incrementing rect in drawRect: (`rect.x += rect.dx;`). You might want to totally separate your drawing code from your positioning code to avoid these unintended glitches. ;-) – markE Dec 18 '15 at 00:21
  • Ok yep. I just added a the movement code for the rectangle to inside the draw() function and the collision works perfectly. Thanks again really helped me! :) – CheetahBongos Dec 18 '15 at 11:34
0

You should not be using width over 2 and height over 2.

You should check of the player.x and player.y are inside the rectangle + the radius. Essentially enlarge all sides of the rectangle by the radius.

rect.y + rect.h + player.r
rect.x + rect.w + player.r
rect.x - player.r
rect.y - player.r

if the player's position is inside the new enlarged rect there is a collision.

if(player.x > (rect.x - player.r) and player.x < (rect.x + rect.w + player.r) and player.y >  (rect.y - player.r) and player.y < rect.y + rect.h + player.r)
return true;