You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测Canvas场景中绘制的墙体与玩家方块的碰撞接触

实现方案

你所有元素都是无旋转的矩形,直接用**轴对齐矩形碰撞检测(AABB)**即可,不需要读取画布像素,纯坐标计算效率很高。

步骤1:添加碰撞检测工具函数

// 传入两个矩形的(x, y, 宽度, 高度),返回是否发生碰撞
function checkCollision(rect1, rect2) {
  return !(
    rect1.x + rect1.w < rect2.x ||
    rect1.x > rect2.x + rect2.w ||
    rect1.y + rect1.h < rect2.y ||
    rect1.y > rect2.y + rect2.h
  );
}

步骤2:添加全局碰撞校验函数

用来检测指定偏移量下,玩家是否和任意墙体碰撞:

function hasCollision(testOffsetX, testOffsetY) {
  // 计算玩家的世界坐标系坐标
  const player = {
    x: 50 - testOffsetX,
    y: 50 - testOffsetY,
    w: 8,
    h: 8
  };
  // 遍历所有墙体逐一校验碰撞
  for (let i = 0; i < things.length; i++) {
    const wall = {
      x: things[i][0],
      y: things[i][1],
      w: things[i][2],
      h: things[i][3]
    };
    if (checkCollision(player, wall)) {
      return true;
    }
  }
  return false;
}

步骤3:修改按键逻辑,避免穿墙

不要直接修改偏移量,先预判移动后的偏移是否会触发碰撞,只有无碰撞时才更新偏移、重绘画面:

document.getElementById("canvas").addEventListener('keydown', function(e) {
  let newOffsetX = offsetx;
  let newOffsetY = offsety;
  if (e.keyCode === 37) { // 左
    newOffsetX++;
  } else if (e.keyCode === 39) { // 右
    newOffsetX--;
  } else if (e.keyCode === 38) { // 上
    newOffsetY++;
  } else if (e.keyCode === 40) { // 下
    newOffsetY--;
  }
  // 无碰撞才更新偏移重绘
  if (!hasCollision(newOffsetX, newOffsetY)) {
    offsetx = newOffsetX;
    offsety = newOffsetY;
    offset();
  }
}, false);

可选:实时检测碰撞状态

如果你需要在setInterval里实时获取碰撞状态,直接调用hasCollision(offsetx, offsety)即可,返回true就是当前玩家和墙体发生了接触。

内容的提问来源于stack exchange,提问作者Kyl Bar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 06:09:04