Контроль частоты кадров и фиксированный шаг update

В библиотеке Phaser управление частотой кадров является ключевым аспектом для стабильной работы игр и точного расчёта физики. Частота кадров (FPS, Frames Per Second) определяет, сколько раз в секунду вызываются методы рендеринга и обновления сцены. Phaser по умолчанию стремится максимально использовать ресурсы устройства, вызывая метод update столько раз, сколько позволяет браузер. Это может привести к нестабильной скорости игры на разных устройствах.

Настройка FPS через конфигурацию

При создании экземпляра игры используется объект конфигурации, где задаются параметры рендеринга и частоты кадров:

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    scene: {
        preload: preload,
        create: create,
        update: update
    },
    fps: {
        target: 60,
        forceSetTimeOut: false
    }
};

const game = new Phaser.Game(config);

Ключевые параметры объекта fps:

  • target — желаемое количество кадров в секунду. Обычно это 60 для плавной анимации.
  • forceSetTimeOut — при true используется setTimeout вместо requestAnimationFrame, что может быть полезно для совместимости, но снижает плавность.

Отслеживание текущей частоты кадров

Phaser предоставляет встроенный объект this.game.loop, который содержит текущую статистику FPS:

console.log(this.game.loop.actualFps); // реальная частота кадров
console.log(this.game.loop.delta);     // время между кадрами в миллисекундах
  • actualFps показывает реальную частоту кадров, которая может отличаться от target из-за нагрузки.
  • delta позволяет адаптировать движение объектов к изменяющейся частоте кадров, чтобы скорость была одинаковой на медленных и быстрых устройствах.

Фиксированный шаг update

Использование фиксированного шага в методе update необходимо для корректной работы физики и предсказуемой анимации. При переменной частоте кадров объекты движутся неравномерно, и расчёт столкновений может дать ошибки.

Принцип работы фиксированного шага

Идея фиксированного шага заключается в том, что логика игры обновляется через равные интервалы времени, независимо от FPS:

const FIXED_STEP = 1 / 60; // 60 обновлений в секунду
let accumulator = 0;

function update(time, delta) {
    accumulator += delta / 1000; // преобразование миллисекунд в секунды
    while (accumulator >= FIXED_STEP) {
        fixedUpdate(FIXED_STEP);
        accumulator -= FIXED_STEP;
    }
}
  • accumulator хранит накопленное время между кадрами.
  • fixedUpdate выполняет физические расчёты или движения с одинаковым шагом времени.
  • Такой подход обеспечивает стабильную симуляцию физики на любых устройствах.

Интеграция с физическим движком Phaser

Phaser поддерживает Arcade Physics, которая сама использует фиксированный шаг по умолчанию. Однако при ручной реализации поведения объектов можно применять собственный fixedUpdate:

function fixedUpdate(step) {
    player.x += player.vx * step;
    player.y += player.vy * step;

    // проверка столкновений
    this.physics.world.collide(player, platforms);
}

Использование фиксированного шага гарантирует одинаковую скорость движения объектов на экранах с разной частотой обновления.


Смешанный подход: delta-time и фиксированный шаг

В некоторых случаях удобно комбинировать delta-time с фиксированным шагом. Это позволяет адаптировать анимации к FPS, сохраняя стабильную физику:

function update(time, delta) {
    // переменные для анимации
    sprite.x += sprite.vx * (delta / 1000);

    // фиксированная логика
    accumulator += delta / 1000;
    while (accumulator >= FIXED_STEP) {
        fixedUpdate(FIXED_STEP);
        accumulator -= FIXED_STEP;
    }
}
  • Движение визуальных элементов выполняется с учетом delta, что делает анимацию плавной.
  • Физические расчёты происходят строго через фиксированный шаг, обеспечивая точность столкновений и реакций объектов.

Практические рекомендации

  • Для большинства игр достаточно 60 FPS и стандартного requestAnimationFrame.
  • Физические объекты и сложные столкновения рекомендуется обновлять через фиксированный шаг.
  • Delta-time удобно использовать для плавных визуальных эффектов и анимаций, не влияющих на точность физики.
  • Отслеживание actualFps позволяет выявлять узкие места производительности и корректировать нагрузку.

Фиксированный шаг в сочетании с контролем частоты кадров обеспечивает предсказуемое поведение игры и стабильность симуляции на любых устройствах.