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

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);

关键修复点说明

  1. 障碍物移动方向:将obstaclePosition + speed改为obstaclePosition - speed,让障碍物向左移动,靠近玩家;重置位置时从屏幕右侧重新进入。
  2. 分数逻辑优化:新增hasScored变量,确保每个障碍物只加一次分,避免重复触发。当障碍物完全通过玩家左侧时,判定为越过并加分。
  3. 碰撞检测修正:碰撞时触发游戏结束逻辑(弹窗+重置),符合跑酷游戏的常规逻辑。
  4. 跳跃动画优化:给玩家元素添加transition属性,让跳跃动作更平滑,也保证碰撞检测时的位置计算更准确。

内容的提问来源于stack exchange,提问作者Brexton Appleseed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 05:54:53