返回

碰撞检测指南:用 HTML5 Canvas 实现完美动画

前端

在 HTML5 Canvas 的世界中,碰撞检测是创造身临其境的交互式动画的关键。它让我们能够确定对象之间的重叠,从而触发事件并改进用户体验。

碰撞检测算法在本质上非常简单。它涉及检查两个对象的边界是否重叠。然而,当涉及到不规则形状或运动物体时,事情就会变得复杂起来。

本指南将带你一步一步了解 HTML5 Canvas 中的碰撞检测基础知识,重点关注矩形碰撞。我们还将提供一个简单的代码示例,让你亲身体验碰撞检测是如何工作的。

矩形碰撞检测

矩形碰撞检测的本质是检查两个矩形的边界是否重叠。为了做到这一点,我们需要获取每个矩形的 x、y 坐标及其宽度和高度。

以下是用于矩形碰撞检测的基本算法:

function checkCollision(rectA, rectB) {
  // 获取矩形边界
  let rectAX1 = rectA.x;
  let rectAX2 = rectA.x + rectA.width;
  let rectAY1 = rectA.y;
  let rectAY2 = rectA.y + rectA.height;

  let rectBX1 = rectB.x;
  let rectBX2 = rectB.x + rectB.width;
  let rectBY1 = rectB.y;
  let rectBY2 = rectB.y + rectB.height;

  // 检查重叠
  return (
    rectAX1 < rectBX2 &&
    rectAX2 > rectBX1 &&
    rectAY1 < rectBY2 &&
    rectAY2 > rectBY1
  );
}

如果两个矩形的边界重叠,则 checkCollision() 函数返回 true;否则返回 false

代码示例

以下代码示例展示了一个简单的 HTML5 Canvas 动画,其中两个矩形(一个固定,一个跟随鼠标移动)之间的碰撞检测:

<canvas id="canvas" width="500" height="500"></canvas>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

// 创建矩形对象
const rectA = {
  x: 100,
  y: 100,
  width: 100,
  height: 100,
};

const rectB = {
  x: 200,
  y: 200,
  width: 100,
  height: 100,
};

// 碰撞检测
function checkCollision() {
  return (
    rectA.x < rectB.x + rectB.width &&
    rectA.x + rectA.width > rectB.x &&
    rectA.y < rectB.y + rectB.height &&
    rectA.y + rectA.height > rectB.y
  );
}

// 动画循环
function animate() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // 绘制矩形
  ctx.fillStyle = "blue";
  ctx.fillRect(rectA.x, rectA.y, rectA.width, rectA.height);

  ctx.fillStyle = "red";
  ctx.fillRect(rectB.x, rectB.y, rectB.width, rectB.height);

  // 检查碰撞
  if (checkCollision()) {
    console.log("碰撞!");
  }

  // 更新 rectB 的位置
  rectB.x = event.clientX - rectB.width / 2;
  rectB.y = event.clientY - rectB.height / 2;

  requestAnimationFrame(animate);
}

animate();

运行此代码,你将看到两个矩形在 Canvas 上渲染。当鼠标移动到第二个矩形上时,控制台将输出 "碰撞!"。

结论

碰撞检测是创建交互式 HTML5 Canvas 动画的基础。通过理解矩形碰撞检测的基本原理,你可以将你的动画提升到一个新的水平。通过练习和实验,你将能够轻松地检测动画中的碰撞,从而创造引人入胜的体验。