2D无尽跑酷游戏碰撞检测与分数更新失效问题求助
问题修复:跑酷游戏碰撞检测与分数更新异常
核心问题分析
- 障碍物移动方向错误:当前代码中障碍物的
right属性递增,导致障碍物向右远离玩家,永远不会靠近,自然无法触发碰撞。正确逻辑应该是让障碍物向左移动(right属性递减)。 - 碰撞检测逻辑颠倒:现有代码在碰撞时加分,但实际需求是玩家成功越过障碍物时加分,碰撞应该触发失败逻辑(比如游戏暂停)。同时需要避免障碍物通过时重复加分。
- 跳跃缺少过渡动画:
.jump类没有添加过渡属性,导致跳跃动作生硬,也会影响碰撞检测的位置准确性。
修复后的完整代码
HTML(无需修改)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Endless Runner Game</title> <link rel="stylesheet" href="style.css"> </head> <body> <div id="game-container"> <div id="player"></div> <div id="obstacle"></div> <div id="score">Score: <span id="score-value">0</span></div> <script src="script.js"></script> </div> </body> </html>
CSS(添加跳跃过渡)
body { margin: 0; overflow: hidden; } #game-container { position: relative; width: 100%; height: 100vh; background-color: #f0f0f0; } #player { position: absolute; bottom: 0; left: 50px; width: 50px; height: 50px; background-color: pink; /* 添加过渡让跳跃更平滑 */ transition: transform 0.5s ease; } #obstacle { position: absolute; bottom: 0; right: 0; width: 50px; height: 50px; background-color: gray; } #score { position: absolute; top: 10px; left: 10px; font-size: 20px; } .jump { transform: translateY(-100px); }
JavaScript(修正移动、碰撞与分数逻辑)
const player = document.getElementById('player'); const obstacle = document.getElementById('obstacle'); const scoreValue = document.getElementById('score-value'); let score = 0; let hasScored = false; // 标记是否已为当前障碍物加分 function updateScore() { score++; scoreValue.innerText = score; } function moveObstacle() { const speed = 5; let obstaclePosition = parseInt(window.getComputedStyle(obstacle).getPropertyValue('right')); // 修正移动方向:向左移动(right值减小) if (obstaclePosition > -50) { // 障碍物完全移出屏幕左侧时重置 obstacle.style.right = `${obstaclePosition - speed}px`; } else { obstacle.style.right = `${window.innerWidth}px`; // 从屏幕右侧重新进入 hasScored = false; // 重置加分标记 } detectCollision(); checkScore(); // 检查是否需要加分 } function jump() { if (!player.classList.contains('jump')) { player.classList.add('jump'); setTimeout(() => { player.classList.remove('jump'); }, 500); } } function detectCollision() { let playerRect = player.getBoundingClientRect(); let obstacleRect = obstacle.getBoundingClientRect(); // 碰撞检测逻辑:重叠则触发碰撞(比如游戏结束) if (playerRect.left < obstacleRect.right && playerRect.right > obstacleRect.left && playerRect.top < obstacleRect.bottom && playerRect.bottom > obstacleRect.top) { alert('碰撞!游戏结束!'); location.reload(); // 重置游戏 } } // 检查是否成功越过障碍物 function checkScore() { let playerRect = player.getBoundingClientRect(); let obstacleRect = obstacle.getBoundingClientRect(); // 障碍物完全通过玩家位置,且未加过分时加分 if (obstacleRect.right < playerRect.left && !hasScored) { updateScore(); hasScored = true; } } document.addEventListener('keydown', (event) => { if (event.code === 'Space') { jump(); } }); setInterval(moveObstacle, 20);
关键修复点说明
- 障碍物移动方向:将
obstaclePosition + speed改为obstaclePosition - speed,让障碍物向左移动,靠近玩家;重置位置时从屏幕右侧重新进入。 - 分数逻辑优化:新增
hasScored变量,确保每个障碍物只加一次分,避免重复触发。当障碍物完全通过玩家左侧时,判定为越过并加分。 - 碰撞检测修正:碰撞时触发游戏结束逻辑(弹窗+重置),符合跑酷游戏的常规逻辑。
- 跳跃动画优化:给玩家元素添加
transition属性,让跳跃动作更平滑,也保证碰撞检测时的位置计算更准确。
内容的提问来源于stack exchange,提问作者Brexton Appleseed
相关产品推荐
相关产品推荐

