如何检测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
相关产品推荐
相关产品推荐

