不同大小的圆的碰撞

collision of Circles with different sizes

我遇到了两个不同大小的圆圈碰撞的问题,但我不明白我到底做错了什么。

现在参考 i post 相同圆圈大小的代码,你可以 运行 测试它的工作正常。

但是当您将 circle2 的大小从 css (440px) 更改时,碰撞将不再起作用。

如果有人能帮我解决这个问题,期待帮助。

const circle1 = document.getElementById('circle1');
const circle2 = document.getElementById('circle2');
const square1 = document.getElementById('square1');

const circle1_w = circle1.offsetWidth / 2;
const circle1_h = circle1.offsetHeight / 2;

const circle2_w = circle2.offsetWidth / 2;
const circle2_h = circle2.offsetHeight / 2;

const square_w = square1.offsetWidth / 2;
const square_h = square1.offsetHeight / 2;

document.addEventListener('mousemove', (e) => {
  circle2.style.left = e.clientX - circle2_w + 'px';
  circle2.style.top = e.clientY - circle2_h + 'px';
  square1.style.left = e.clientX - square_w + 'px';
  square1.style.top = e.clientY - square_h + 'px';
  collideCircle();
});

console.log(circle2);

function collideCircle() {
  var circle1Bounding = circle1.getBoundingClientRect();
  var circle2Bounding = circle2.getBoundingClientRect();

  const circle1_x = circle1Bounding.x;
  const circle1_y = circle1Bounding.y;

  const circle2_x = circle2Bounding.x;
  const circle2_y = circle2Bounding.y;

  /* first we get the x and y distance between the two circles. */
  let distance_x = circle1_x - circle2_x;
  let distance_y = circle1_y - circle2_y;

  /* Then we get the sum of their radii. */
  let radii_sum = circle1_w + circle2_w;

  let sideA = Math.abs(circle1_y - circle2_y);
  let sideB = Math.abs(circle1_x - circle2_x);
  let distance = Math.sqrt(Math.pow(sideA, 2) + Math.pow(sideB, 2));
  if (distance <= (circle1Bounding.width + circle2Bounding.width) / 2) {
    circle1.innerHTML = 'Collision occured';
    circle1.style.backgroundColor = 'pink';
  } else {
    circle1.innerHTML = '';
    circle1.style.backgroundColor = 'yellow';
  }
}
body {
  margin: 0;
  padding: 0;
}

#circle1 {
  width: 110px;
  height: 110px;
  position: absolute;
  left: 50vw;
  top: 50vh;
  background-color: rgb(255, 233, 36);
  border-radius: 50%;
}

#circle2 {
  position: absolute;
  width: 110px;
  height: 110px;
  background-color: rgb(255, 80, 80);
  font-size: 1.5em;
  z-index: 1;
  border-radius: 50%;
}

#square1 {
  position: absolute;
  width: 110px;
  height: 110px;
  background-color: transparent;
  border: 1px solid blue;
  font-size: 1.5em;
  z-index: 1;
}
<div id="circle1"></div>
<div id="circle2"></div>
<div id="square1"></div>

知道我到底做错了什么吗?

对于圆碰撞检测,您想测量它们的 中心 点之间的距离,并查看该距离是否小于圆的半径之和。

getBoundingClientRect returns 一个矩形,其 X, Y 值表示 upper-left 角。你的错误是用那个值继续计算。

我更新了您的代码,因此 circle1_x(和 y,对于圆 1 和 2)说明圆的中心位置相对于边界矩形的角。

此外,假设它们是 而不是椭圆,您可以获取宽度而忽略高度,以确定 半径 。我更新了您的代码以分别为每个圆派生 circle1_rcircle2_r 而不是 h/w。

const circle1 = document.getElementById('circle1');
const circle2 = document.getElementById('circle2');
const square1 = document.getElementById('square1');

// assume circle H=W and just get its radius
const circle1_r = circle1.offsetWidth / 2;
const circle2_r = circle2.offsetWidth / 2;

const square_w = square1.offsetWidth / 2;
const square_h = square1.offsetHeight / 2;

document.addEventListener('mousemove', (e) => {
  circle2.style.left = e.clientX - circle2_r + 'px';
  circle2.style.top = e.clientY - circle2_r + 'px';
  square1.style.left = e.clientX - square_w + 'px';
  square1.style.top = e.clientY - square_h + 'px';
  collideCircle();
});

console.log(circle2);

function collideCircle() {
  var circle1Bounding = circle1.getBoundingClientRect();
  var circle2Bounding = circle2.getBoundingClientRect();

  // get *center* position for circles
  const circle1_x = circle1Bounding.x + circle1_r;
  const circle1_y = circle1Bounding.y + circle1_r;

  const circle2_x = circle2Bounding.x + circle2_r;
  const circle2_y = circle2Bounding.y + circle2_r;

  /* first we get the x and y distance between the two circles. */
  let distance_x = circle1_x - circle2_x;
  let distance_y = circle1_y - circle2_y;

  /* Then we get the sum of their radii. */
  let radii_sum = circle1_r + circle2_r;

  let sideA = Math.abs(circle1_y - circle2_y);
  let sideB = Math.abs(circle1_x - circle2_x);
  let distance = Math.sqrt(Math.pow(sideA, 2) + Math.pow(sideB, 2));
  if (distance <= (circle1Bounding.width + circle2Bounding.width) / 2) {
    circle1.innerHTML = 'Collision occured';
    circle1.style.backgroundColor = 'pink';
  } else {
    circle1.innerHTML = '';
    circle1.style.backgroundColor = 'yellow';
  }
}
body {
  margin: 0;
  padding: 0;
}

#circle1 {
  width: 210px;
  height: 210px;
  position: absolute;
  left: 50vw;
  top: 50vh;
  background-color: rgb(255, 233, 36);
  border-radius: 50%;
}

#circle2 {
  position: absolute;
  width: 110px;
  height: 110px;
  background-color: rgb(255, 80, 80);
  font-size: 1.5em;
  z-index: 1;
  border-radius: 50%;
}

#square1 {
  position: absolute;
  width: 110px;
  height: 110px;
  background-color: transparent;
  border: 1px solid blue;
  font-size: 1.5em;
  z-index: 1;
}
<div id="circle1"></div>
<div id="circle2"></div>
<div id="square1"></div>