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

JavaScript版Flappy Bird在新款MacBook Chrome中运行过快问题求助

问题分析

你的问题核心在于动画逻辑没有基于时间差(delta time)做标准化。requestAnimationFrame的回调执行频率完全依赖浏览器刷新率和设备性能——比如M2 MacBook Pro的Chrome可能以120fps运行,而Safari维持60fps,这就导致你的gravity和slideShipsAnimation函数执行次数差一倍,自然游戏速度快了一倍。

之前尝试delta time出问题,大概率是实现方式有误:要么没正确计算时间差,要么没把固定的每帧数值转换为每秒单位的移动/加速度,反而引入了新的不一致。

修复方案

我们需要把每帧的固定增量(比如velocity += gravityConstant、-3px)改成基于时间的动态计算,确保不管帧率波动,每秒的移动、加速度都是一致的。

1. 重构重力函数

let lastGravityTime = 0;
// 把重力常量改成「每秒加速度」,比如原60fps下每帧加0.5,每秒就是30px,直接设为30
const GRAVITY = 30; // px/秒²
let birdY = parseInt(getComputedStyle(bird).top); // 初始化时读取一次位置,避免频繁DOM查询

function startGravity() {
    function gravity(currentTime) {
        // 计算时间差(转成秒)
        const delta = (currentTime - lastGravityTime) / 1000;
        lastGravityTime = currentTime;

        // 按时间差更新速度和位置
        velocity += GRAVITY * delta;
        birdY += velocity * delta;
        bird.style.top = `${birdY}px`;

        loops.gravityAnimation = requestAnimationFrame(gravity);
    }

    loops.gravityAnimation = requestAnimationFrame(gravity);
}

2. 重构障碍物滑动函数

同样用时间差标准化移动速度,同时把setInterval生成障碍物的逻辑也改成基于帧的计时,避免浏览器节流影响间隔稳定性:

let lastShipTime = 0;
const SHIP_SPEED = 180; // px/秒(原60fps下每帧减3px,每秒就是180px)
let shipSpawnTimer = 0;
const SPAWN_INTERVAL = 5; // 生成障碍物的间隔(秒)

function runShips() {
    function spawnShips(currentTime) {
        const delta = (currentTime - lastShipTime) / 1000;
        shipSpawnTimer += delta;

        if (shipSpawnTimer >= SPAWN_INTERVAL) {
            // 你的生成障碍物逻辑
            createShip();
            shipSpawnTimer = 0;
        }
        requestAnimationFrame(spawnShips);
    }

    function slideShipsAnimation(currentTime) {
        const delta = (currentTime - lastShipTime) / 1000;
        lastShipTime = currentTime;

        document.querySelectorAll('.ships').forEach(ship => {
            let currentLeft = parseInt(getComputedStyle(ship).left);
            currentLeft -= SHIP_SPEED * delta;
            ship.style.left = `${currentLeft}px`;
        });
        loops.slideShipsAnimation = requestAnimationFrame(slideShipsAnimation);
    }

    requestAnimationFrame(spawnShips);
    loops.slideShipsAnimation = requestAnimationFrame(slideShipsAnimation);
}

3. 额外优化点

  • 避免频繁调用getComputedStyle:每次调用都会触发浏览器重排,把元素位置、尺寸存在变量里,仅在初始化或样式变更时更新。
  • 移动设备故障排查:标准化时间后,若仍有问题,检查触摸事件的处理逻辑——确保跳跃等操作是基于帧同步触发,而非直接修改velocity后立即生效,避免和动画循环冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 08:30:03