Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   requestAnimationFrame или setInterval (https://javascript.ru/forum/misc/49621-requestanimationframe-ili-setinterval.html)

Straj 21.08.2014 14:55

requestAnimationFrame или setInterval
 
Змейка. Допустим мне надо сделать что бы она двигалась на 2 клетки в секунду. Щас у меня есть основной цикл через requestANimationFrame.

Нужно ли мне делать это перемещение c пом. переменной, которая итерируется каждый тик цикла, и при значении кратном 30 (60 кадров в секунду = 1 клетка каждые 30 кадров), запускалась функция движения. Или вместо реквестФрейма, мутить через setInterval? Какие подводные камни?

ixth 21.08.2014 15:05

Ничего из сказанного не понял.

Через setInterval меняй положение змейки. Через requestAnimationFrame — обновляй canvas.

tsigel 21.08.2014 15:25

ixth,
Лучше через setTimeout эмулировать setInterval, тогда вызовы будут идти с более равными промежутками времени

ixth 21.08.2014 15:48

Если честно, ни разу не сталкивался с проблемами, используя setInterval.

tsigel 21.08.2014 15:56

А я сталкивался :)

Straj 21.08.2014 16:33

Подредактировал описание, возможно не совсем точно выразился.
Но ваш ответ подходит.

Т.е. мне в цикле
function loop () {
	requestAnimationFrame(loop);
	//...	
}


Нужно добавить таймер setInterval, который при срабатывании будет вызывать обновление змейки?

tsigel 21.08.2014 16:37

Straj, в змейке наверно проблем не будет с интервалом, но в дальнейшем во избежания багов рекомендую пользваться таймаутом.
http://learn.javascript.ru/settimeout-setinterval

Straj 21.08.2014 17:12

Цитата:

Сообщение от tsigel (Сообщение 326871)
Straj, в змейке наверно проблем не будет с интервалом, но в дальнейшем во избежания багов рекомендую пользваться таймаутом.
http://learn.javascript.ru/settimeout-setinterval

Понял, спасибо. Просто я пока прототип сделать пытаюсь, так что с оптимизацией не сильно заморачиваюсь. На будущее учту.

MallSerg 21.08.2014 18:39

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

MallSerg 21.08.2014 19:11

Небольшой примерчик
<div id="moved" style="position: absolute;width:30px;height: 30px;background: red;"></div>
    <br>
    <input type="button" onclick="but1()" value="кнопка 1"> <br>
    <input type="button" onclick="but2()" value="кнопка 2">
    <script type="text/javascript">
var RequestAnimationFrame = requestAnimationFrame || mozRequestAnimationFrame || webkitRequestAnimationFrame || msRequestAnimationFrame;
function but1 (){
    var element = document.getElementById("moved");
    animateMove( element , 800 , 100 , 1500 , function () {
        animateMove( element , -750 , 10 , 200 ,function (){
            animateMove( element , 150 , -60 , 1000 ,function (){
                element.style.background = ("#" + ( Math.random() * (999-100)+100 )).substr(0,4) ;
                element.style.top = "30px";
                element.style.left = "100px";
            })
        })
    })
}
function but2 (){
    var element = document.getElementById("moved");
    var animation = animateMove( element , 100 , 0 , 10000 );
    element.onclick = function () {
        animation.time = 1;
        animation.onFinish = null;
    };
    animation.onFinish = function (){
        animateMove( element , -100 , 50 , 5000 );
        element.onclick = null;
    };
}
function animateMove ( element , x , y , time ,callBack){
    var j = animateMove;
    j.time = time || 1000;
    j.x = x;
    j.y = y;
    j.statX = element.offsetLeft;
    j.startY = element.offsetTop;
    j.onFinish = callBack;
    j.animate = function (){
        if ( j.startTime == undefined ){ j.startTime = new Date().getTime() }
	    var Time = new Date().getTime();
        var EA =  ( (Time - j.startTime) || 1 )/j.time;
        if ( EA < 1) {
            element.style.left = j.statX + (j.x * EA) + "px";
            element.style.top = j.startY + (j.y * EA) + "px";
            RequestAnimationFrame(j.animate );
        }else{
            delete j.startTime;
            j.onFinish? j.onFinish():0;
        }
	};
    j.animate();
    return j;
}
</script>


Часовой пояс GMT +3, время: 21:02.