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

如何修复Pacman游戏switch按键逻辑中setInterval重复触发bug

吃豆人游戏定时器问题修复方案

问题根源

  • 每次触发方向键时没有清除之前的定时器,导致多个定时器同时运行:重复按同一方向时多个定时器同时执行移动逻辑,速度成倍加快;按不同方向时多个方向的移动逻辑交替执行,导致角色来回移动。

修复方法

在每次创建新定时器前,先清除上一个正在运行的定时器,确保全局永远只有一个移动定时器生效。

修复后的完整代码

let myInt = null; // 初始值改为null更合理
function move(e) {
    // 核心修复:每次触发方向键先清除之前的定时器
    if (myInt) clearInterval(myInt);
    squares[pacManPosition].classList.remove('pac-man');

    switch (e.key) {
        case 'ArrowUp':
            // 可选优化:按下按键先移动一次,不用等定时器首次触发的延迟
            if (!squares[pacManPosition - width].classList.contains('wall')) {
                pacManPosition -= width;
            }
            myInt = setInterval( function () {
                if (!squares[pacManPosition - width].classList.contains('wall')) {
                    squares[pacManPosition].classList.remove('pac-man');
                    pacManPosition -= width;
                    squares[pacManPosition].classList.add('pac-man');
                    // 吃豆逻辑移到定时器里,每次移动后触发
                    pacdotsEaten();
                    powerPelletsEaten();
                }
            }, 400)
        break;

        case 'ArrowRight':
            if (!squares[pacManPosition + 1].classList.contains('wall')) {
                pacManPosition++;
            }
            myInt = setInterval( function () {
                if (!squares[pacManPosition + 1].classList.contains('wall')) {
                    squares[pacManPosition].classList.remove('pac-man');
                    pacManPosition++;
                    squares[pacManPosition].classList.add('pac-man');
                    pacdotsEaten();
                    powerPelletsEaten();
                }
            }, 400)
        break;

        case 'ArrowDown':
            if (!squares[pacManPosition + width].classList.contains('wall')) {
                pacManPosition += width;
            }
            myInt = setInterval( function () {
                if (!squares[pacManPosition + width].classList.contains('wall')) {
                    squares[pacManPosition].classList.remove('pac-man');
                    pacManPosition += width;
                    squares[pacManPosition].classList.add('pac-man');
                    pacdotsEaten();
                    powerPelletsEaten();
                }
            }, 400)
        break;

        case 'ArrowLeft':
            if (!squares[pacManPosition - 1].classList.contains('wall')) {
                pacManPosition--;
            }
            myInt = setInterval( function () {
                if (!squares[pacManPosition - 1].classList.contains('wall')) {
                    squares[pacManPosition].classList.remove('pac-man');
                    pacManPosition--;
                    squares[pacManPosition].classList.add('pac-man');
                    pacdotsEaten();
                    powerPelletsEaten();
                }
            }, 400)
        break;
    }
    squares[pacManPosition].classList.add('pac-man');
    pacdotsEaten();
    powerPelletsEaten();
}
// 可选优化:把事件从keyup改成keydown,按下按键立刻响应,体验更流畅
document.addEventListener('keydown', move);

额外优化建议

  • 可以把四个方向的重复逻辑抽成公共函数,减少代码冗余
  • 如果需要支持松开按键停止移动,可以监听keyup事件,在松开时执行clearInterval(myInt)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:36:00