原生vanillaJS网页游戏两个img元素碰撞检测失效问题求助
问题原因
- 你的碰撞检测代码仅在页面首次加载时执行一次,后续通过方向键移动角色后不会重新运行检测逻辑,所以一直输出首次检测的结果
- 直接读取DOM元素的
.x/.y属性获取坐标不可靠,该属性不是元素实时渲染后的实际位置,不同定位方式下会出现取值偏差
修复方案
1. 核心逻辑调整
使用getBoundingClientRect()获取元素实时的视口坐标和尺寸,把碰撞检测封装为函数,每次角色移动后/逐帧调用检测:
// 获取两个元素 const perso = document.querySelector('.perso') const obstacle = document.querySelector('.obstacle') // 封装碰撞检测函数 function checkCollision() { // 拿到实时位置和尺寸 const rect1 = perso.getBoundingClientRect() const rect2 = obstacle.getBoundingClientRect() const isCollision = rect1.left < rect2.left + rect2.width && rect1.left + rect1.width > rect2.left && rect1.top < rect2.top + rect2.height && rect1.top + rect1.height > rect2.top if (isCollision) { console.log("collision") // 取消注释即可跳转页面 // window.location.href = 'htmlpage1.html' } else { console.log("no collision") } } // 逐帧检测碰撞,也可以选择在每次键盘移动角色后直接调用checkCollision() function loop() { checkCollision() requestAnimationFrame(loop) } loop() // 方向键移动示例,如果你已有完整移动逻辑可以忽略这部分,只需在移动后调用checkCollision()即可 let posX = 0, posY = 0 document.addEventListener('keydown', e => { const step = 10 // 每次移动的步长 switch(e.key) { case 'ArrowUp': posY -= step; break case 'ArrowDown': posY += step; break case 'ArrowLeft': posX -= step; break case 'ArrowRight': posX += step; break } perso.style.transform = `translate(${posX}px, ${posY}px)` })
2. 可选优化
你的角色当前是relative定位,使用transform做移动性能更好,不会触发页面重排,比修改top/left属性的运行效率更高。
内容的提问来源于stack exchange,提问作者MikaMikashu
相关产品推荐
相关产品推荐

