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

Java实现支持运行时调整帧率上限且不影响update逻辑速度的游戏循环

核心实现思路

你需要将**逻辑更新(update)和画面渲染(render)**的计时逻辑完全解耦:逻辑更新采用固定时间步长执行,不受渲染帧率上限调整的影响,仅渲染环节单独做帧率上限控制。

具体实现步骤
  • 预先定义固定的逻辑更新间隔,比如要求每秒固定执行60次update,就定义常量:long FIXED_UPDATE_STEP = 1000_000_000L / 60;(单位为纳秒,计时精度更高),该值全程固定不随渲染帧率配置修改。
  • 维护独立的逻辑更新时间累加器:每次游戏循环先计算当前帧与上一帧的时间差,将时间差累加到累加器变量中;只要累加器数值大于等于FIXED_UPDATE_STEP,就执行一次update(),并将累加器减去FIXED_UPDATE_STEP,直到累加器不足一个步长为止。
  • 渲染环节单独做帧率限制:仅在渲染前根据当前设置的渲染帧率上限计算需要等待的时间,动态调整帧率上限时仅修改渲染环节的等待阈值即可,完全不接触逻辑更新的计时逻辑。
  • 可选优化:可以将累加器剩余的不足一个步长的时间作为插值参数传给render()方法,用于画面帧插值,避免高帧率下画面卡顿。
Java代码示例
public class GameLoop implements Runnable {
    // 固定逻辑更新率:每秒60次
    private static final long FIXED_UPDATE_STEP = 1000_000_000L / 60;
    // 渲染帧率上限,支持运行时动态修改
    private volatile int renderFpsCap = 60;

    @Override
    public void run() {
        long lastTickTime = System.nanoTime();
        long accumulator = 0;

        while (isRunning()) {
            long currentTime = System.nanoTime();
            long frameDelta = currentTime - lastTickTime;
            lastTickTime = currentTime;
            accumulator += frameDelta;

            // 逻辑更新:固定步长,不受渲染帧率影响
            while (accumulator >= FIXED_UPDATE_STEP) {
                update();
                accumulator -= FIXED_UPDATE_STEP;
            }

            // 计算插值参数,可选传入render实现平滑渲染
            float interpolation = (float) (accumulator / (double) FIXED_UPDATE_STEP);
            render(interpolation);

            // 仅渲染环节做帧率限制
            long renderInterval = 1000_000_000L / renderFpsCap;
            long renderCost = System.nanoTime() - currentTime;
            if (renderCost < renderInterval) {
                try {
                    long sleepMs = (renderInterval - renderCost) / 1000_000L;
                    int sleepNano = (int) ((renderInterval - renderCost) % 1000_000L);
                    Thread.sleep(sleepMs, sleepNano);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }

    // 运行时动态调整渲染帧率上限的入口,完全不影响逻辑更新速度
    public void setRenderFpsCap(int renderFpsCap) {
        this.renderFpsCap = Math.max(1, renderFpsCap);
    }

    private boolean isRunning() {
        // 游戏运行状态判断逻辑
        return true;
    }

    private void update() {
        // 游戏逻辑更新代码
    }

    private void render(float interpolation) {
        // 画面渲染代码
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:30:00