Как сделать так, чтобы анимация JavaScript воспроизводилась с одинаковой скоростью во всех браузерах на всех системах? - PullRequest
6 голосов
/ 29 июня 2010

У меня есть функция, которая вычисляет следующий кадр в анимации различных объектов, движущихся по осям X и Y [я называю это frameRender()], и функция, которая применяет этот результирующий кадр к объектам [я называю это frameDisplay()]. Объекты не просто перемещаются из точки A в B, они постоянно перемещаются, всегда получая новые целевые координаты. Я использую setInterval() с интервалом 1000/frameRate, но это, похоже, совсем не работает, так как браузеры не имеют точного времени.

Вопрос: как я могу убедиться, что анимация имеет постоянную частоту кадров и будет работать с одинаковой скоростью во всех браузерах, во всех системах? Я перепробовал все и не могу получить точный результат даже на разных браузерах (я тестирую на Firefox и Chrome, Chrome обычно показывает намного быстрее).

Результат должен быть следующим: при медленном воспроизведении интервал анимации должен сначала уменьшиться, а затем попытаться пропустить некоторые кадры [пропуская frameDisplay()], если DOM отображает медленно, до тех пор, пока он не будет воспроизводиться правильно. Когда он воспроизводится быстро, интервал анимации должен увеличиваться, чтобы анимация воспроизводилась с правильной скоростью.

Но как вы сохраняете последовательность во всем этом, поскольку вы не всегда можете быть уверены, когда браузеры станут медленными или когда они будут работать быстро. Например, если есть огромный всплеск движений, и мы уменьшаем интервал, чтобы поддерживать постоянную частоту кадров, а затем внезапно большинство движущихся объектов останавливаются или не двигаются много, это внезапно будет работать очень быстро!

Есть идеи?

Ответы [ 3 ]

7 голосов
/ 29 июня 2010

Вопрос: как я могу убедиться, что анимация имеет постоянную частоту кадров и будет работать с одинаковой скоростью во всех браузерах, во всех системах?

Вы можете 'ничего не делать с частотой кадров.Единственное, что вы можете контролировать, это то, как ваши приложения обновляются с течением времени.Это относится и к браузерам, и к общей теме разработки игр.

Лучшее, что можно сделать, - это отслеживать дельту (читай: разницу во времени) между обновлениями.

(function () {
    function getTime() {
        return new Date().getTime();
    }
    var last = getTime();

    function update(delta) {
        // Update your application state on delta (ms of time passed)
    }

    (function loop() {
        update(last = getTime()-last);
        render();
        setTimeout(loop, 20); // 20 = attempt 50fps
    }());
}());

Обратите внимание на использование setTimeout здесь.Это сделано для того, чтобы избежать вызова функции loop () из синхронизации.setInterval продолжит его запускать, даже если предыдущий вызов не завершился.

3 голосов
/ 29 июня 2010

Ответ здесь , отличная статья Гленна Фидлера, нуждается в небольшой настройке, чтобы преобразовать ее в Javascript, но принципы те же. По сути, вам нужно использовать аккумулятор, который складывает дельта-тайминги, и выполнять шаги, основанные на этом. Не нужно менять физику, математику или что-то еще, решение - подключи и играй. Также имеет классный интерполятор, который устраняет заикание, а также позволяет делать супер медленное плавное движение (для повторов и т. Д.). Это фантастика, работает для физики и должна работать на любом шаговом движении. В основном, все, что вам нужно для точного определения времени игры, есть.

2 голосов
/ 29 июня 2010

Вы можете синхронизировать анимацию с системным временем.

Сохранить текущее системное время в переменной. Затем на всех кадрах вы хотите перерисовать картинку, чтобы проверить, является ли текущее время - ваша переменная равна некоторому дельта-времени. затем нарисуйте свою анимацию. иначе подожди эту разницу

...