如何在Canvas游戏中正确检测鼠标与圆形中心点的相对位置
Canvas交互问题修复方案
1. 单次点击触发数百次
- 原因:点击事件监听注册逻辑放在了
draw()函数内部,而draw()通过requestAnimationFrame每秒执行约60次,每执行一次就会给canvas新增一个点击监听器,运行几秒后就会累积数百个监听器,单次点击会触发所有绑定的监听器。 - 修复方案:将
canvas.addEventListener('click', ...)逻辑移动到draw()函数外部,全局仅注册一次。同时将Circle类定义、circle实例创建逻辑移到全局作用域,保证点击监听器可以正常访问到circle实例。
2. 点击距离计算与实际值存在偏差
- 原因:绘制时对画布做了相机平移变换
ctx.translate(camX, camY),圆形存储的是世界坐标系下的坐标值,而点击事件获取到的是canvas的屏幕坐标系坐标,两个坐标系不一致导致计算结果存在偏差,偏差值正好等于相机偏移量camX/camY,因此会随窗口尺寸变化。 - 修复方案:计算距离前先把鼠标的屏幕坐标转换为世界坐标,转换逻辑如下:
// 点击监听内的处理逻辑 canvas.addEventListener('click', (event) => { const rect = canvas.getBoundingClientRect(); const screenX = event.clientX - rect.left; const screenY = event.clientY - rect.top; // 转换为世界坐标 const camX = -player.x + canvas.width / 2; const camY = -player.y + canvas.height / 2; const worldX = screenX - camX; const worldY = screenY - camY; circle.clickCircle(worldX, worldY); });
额外优化建议
- 你提供的CSS代码块和JS代码完全重复,属于粘贴错误,
style.css文件内不要写入JS逻辑,删除对应的错误代码即可。
内容的提问来源于stack exchange,提问作者Saint
相关产品推荐
相关产品推荐

