Как я могу замедлить анимацию спрайтов в javascript?

Я сделал простую анимацию спрайтов, но она слишком быстрая. Он тоже почему-то мигает.
Мой код:

<!doctype html>
<html>
    <head>
        <script type="text/javascript" src="raf.js"></script>
        <script>
            var ctx;
            var count = 0;
            var x;
            var y;
            var img = new Image();
            img.src = "images/character.png";
            img.onload = draw;

            function draw() {
                requestAnimationFrame(draw)

                ctx.clearRect(0,0,450,586);

                x = (count % 16) * 450;
                y = Math.floor(count / 16) * 586;
                ctx.drawImage(img, x, y, 450, 586, 0, 0, 450, 586);

                if(count == 16){
                    count = 0;
                } else {
                    count++;
                }
            }

            function init() {
                ctx = document.getElementById("canvas").getContext("2d");
            }

        </script>
    </head>
    <body onload = "init()">
        <canvas id="canvas" width="800" height="600">
        </canvas>
    </body>
</html>

Есть ли способ исправить это?


person Asphys    schedule 09.03.2016    source источник
comment
requestAnimationFrame запускает (или пытается запустить) обратный вызов со скоростью обновления монитора. Стандартное решение управления скоростью анимации — привязать изменения значений ко времени, а не к обновлениям экрана.   -  person weaknespase    schedule 09.03.2016
comment
@VallyN Но как мне это сделать? Я пробовал такие вещи, как setInterval и setTimeout, но пока они у меня не работают.   -  person Asphys    schedule 09.03.2016
comment
Нет нет нет. Просто сделайте так, чтобы счет увеличивался не так быстро, как сейчас. Замените count++ на count+=.1 и убедитесь сами.   -  person weaknespase    schedule 09.03.2016
comment
@VallyN Я заменил count++ на count+=.1, но теперь моя таблица спрайтов какое-то время просто прокручивается справа налево, а затем просто исчезает. Странно, теперь тоже мигает постоянно.   -  person Asphys    schedule 09.03.2016
comment
Строка x = (count % 16) * 450: умножьте 16 на 450 и сравните с шириной.   -  person weaknespase    schedule 09.03.2016
comment
Кроме того, в строке if(count == 16) count никогда не может быть равно 16. Прочтите о числах с плавающей запятой и замените оператор равенства оператором «больше или равно» (>=). Кроме того, вы можете использовать fillRect вместо clearRect и исправить его положение, чтобы стереть/перерисовать область, где был спрайт - это может уменьшить мигание.   -  person weaknespase    schedule 09.03.2016
comment
@VallyN Я имею в виду, что весь спрайт-лист просто прокручивается с правой стороны моего холста на левую сторону моего холста. Хотя больше не исчезает. Я проверил ширину изображения, и она должна быть правильной.   -  person Asphys    schedule 09.03.2016
comment
Извините, я вас неправильно понял. Подождите секунду, я отправляю ответ.   -  person weaknespase    schedule 09.03.2016


Ответы (2)


По сути, вам нужно регулировать частоту кадров анимации.

        var ctx;
        var count = 0;
        var x;
        var y;
        var img = new Image();
        img.src = "images/character.png";
        img.onload = draw;

        var time = Date.now();
        var delay = 100;

        function draw() {
            requestAnimationFrame(draw)

            ctx.clearRect(0,0,450,586);

            x = (count % 16) * 450;
            y = Math.floor(count / 16) * 586;
            ctx.drawImage(img, x, y, 450, 586, 0, 0, 450, 586);

            if(Date.now() - time >= delay){
                if(count == 16){
                    count = 0;
                } else {
                    count++;
                }
                if ((Date.now() - time - delay) > delay){
                    time = Date.now();
                } else {
                    time += delay;
                }
            }
        }

        function init() {
            ctx = document.getElementById("canvas").getContext("2d");
        }

delay — это задержка кадра в миллисекундах (в примере 100 означает ~10 кадров в секунду), time используется для отслеживания времени отображения текущего кадра.

Проблема с миганием может быть связана с отсутствием спрайта в листе спрайтов.

person weaknespase    schedule 09.03.2016

Вы можете сделать это с помощью SpriteAnimJS, его можно настроить на использование WebGL и холста в качестве запасного варианта.

Чтобы запустить спрайт-лист с ним, как показано в его демонстрации:

var mySpriteAnimation = new SpriteAnim(canvasIdHere,useOnlyCanvasBoolean)
mySpriteAnimation.start({
            frameWidth: 100,
            frameHeight: 100,
            image: image_element, // must be preloaded
            fps: 10,
            className: 'class_name',
            loop: true,
            onStart: function() {},
            onComplete: function() {}
        });

Как видите, в настройках можно легко установить FPS, не вычисляя их самостоятельно.

Библиотека + демоверсии здесь

person CatalinBerta    schedule 26.10.2016