Javascript - Collision detection

Circle vs Circle tip: delay event after collision

by katalin_2003

HTML

<h1>Mouse over/tap to test collisions</h1>

CSS

html {
   /* height: 100%;*/
}
body {
    transition: 1s all;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    align-content: center;
    height: 100%;
    font-size: 20pt;
    font-family: sans-serif;
    font-weight: bold;
    font-variant: small-caps;
    text-shadow: 2px 2px 10px rgba(0, 0, 0, 0.25);
    background-size: 100vmax;
}
canvas {
    background: white;
    border-top: 1px solid #CCC;
    border-left: 1px solid #CCC;
    border-right: 1px solid #666;
    border-bottom: 1px solid #666;
    border-radius: 6px;
    box-shadow: 2px 2px 20px rgba(0, 0, 0, 0.65);
    padding: 10px;
    margin: 30px;
    outline: 1px solid #CCC;
    outline-offset: -10px;
}

JavaScript

var canvas = document.body.appendChild(document.createElement("canvas")),
  ctx = canvas.getContext("2d"),
  ballA = {
    x: 65,
    y: 65,
    radius: 100
  },
  ballB = {
    x: 65,
    y: 65,
    radius: 50
  };

canvas.width = canvas.height = 512;

canvas.addEventListener("mousemove", function(e) {
  ballB.x = e.offsetX;
  ballB.y = e.offsetY;
}, false);

function aabb(a, b) {
  if (a.x + a.radius + b.radius > b.x && a.x < b.x + a.radius + b.radius && a.y + a.radius + b.radius > b.y && a.y < b.y + a.radius + b.radius) {
    return true;
  }

  return false;
}

function dist(a, b) {
  return Math.sqrt(
    ((a.x - b.x) * (a.x - b.x)) + ((a.y - b.y) * (a.y - b.y)));
}

function collides(a, b) {
  if (aabb(a, b)) {
    var distance = dist(a, b);

    if (distance < a.radius + b.radius) {
      return true;
    }
  }

  return false;
}

function collisionPoint(a, b) {
  return {
    x: ((a.x * b.radius) + (b.x * a.radius)) / (a.radius + b.radius),
    y: ((a.y * b.radius) + (b.y * a.radius)) / (a.radius + b.radius)
  };
}

function animate() {
  var collided = collides(ballA, ballB);
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  if (collided) {
    ctx.fillStyle = "red";
    document.body.style.backgroundColor = '#ECC';
  } else {
    ctx.fillStyle = "green";
    document.body.style.backgroundColor = '#CEC';
  }

  ctx.beginPath();
  ctx.arc(ballA.x, ballA.y, ballA.radius, 0, Math.PI * 2);
  ctx.fill();

  ctx.beginPath();
  ctx.arc(ballB.x, ballB.y, ballB.radius, 0, Math.PI * 2);
  ctx.fill();

  if (aabb(ballA, ballB)) {
    ctx.strokeStyle = "red";
	
  } else {
    ctx.strokeStyle = "green";
  }

  ctx.strokeRect(ballA.x - ballA.radius, ballA.y - ballA.radius, ballA.radius * 2, ballA.radius * 2);
  ctx.strokeRect(ballB.x - ballB.radius, ballB.y - ballB.radius, ballB.radius * 2, ballB.radius * 2);

  if (collided) {
    console.log("circles HIT!");
    var point = collisionPoint(ballA, ballB);
    ctx.fillStyle = "blue";
    ctx.beginPath();
   ...