Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   setInterval(); и FPS (https://javascript.ru/forum/misc/24546-setinterval-%3B-i-fps.html)

BorodinKO 05.01.2012 12:36

setInterval(); и FPS
 
Делаю игру,
где в в функции
function frame(){
находится все вычисления и отрисовка, затем я запускаю ее
setInterval(frame, 10);

Но тут возникает одна проблема, в разных браузерах, на разных устройствах скорость игры - разная. и это из за того что некоторые браузеры тормозят на подсчете и отрисовки.
Вопрос: как сделать так чтобы те кадры которые не успевают прорисоваться "проглатывались".
Или как правильно реализуются подобные игры?

Gvozd 05.01.2012 12:53

Например так, для 20-и кадров в секунду
setInterval(function() {
    if((new Date) - last_time > 1000/20) {
        last_time = new Date;
        frame();
    }
}, 10);

BorodinKO 05.01.2012 13:28

Спасибо, а как теперь подсчитать сколько кадров в секунду отрисовывается?

Livaanderiamarum 05.01.2012 14:07

Как делают настоящие пасоны)))!!1

//requestAnimFrame
setAnimation = (function() {
	return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
	function(/* function */callback, /* DOMElement */element) {
		return window.setTimeout(callback, 1000 / 60);
	};

})();
//canselRequestAnimFrame
clearAnimation = (function() {
	return window.cancelRequestAnimationFrame || window.webkitCancelRequestAnimationFrame || window.oCancelRequestAnimationFrame || window.msCancelRequestAnimationFrame ||
	function(id) {
		clearTimeout(id)
	}

})();



Как юзать:

function ня() {
	myAnimation = setAnimation(function() {
		ня()
	})
}

//чтоб остановить
clearAnimation(myAnimation)


как настоящие пасоны получают fps:
function ня(f) {
	log(f)

	setAnimation(function() {
		var thisLoop = new Date;
		var fps = 1000 / (thisLoop - lastLoop);
		lastLoop = thisLoop;
		// получили сколько кадров в секунду
		ня(fps)
	})
}
lastLoop = new Date;
ня()

Livaanderiamarum 06.01.2012 01:43

Есть умельцы которые папкин вариант побьют)?

Livaanderiamarum 06.01.2012 05:29

а, ну вот вам еще, петлевая анимация)
аналог setInterval

//start loop animation
 function loopAnimation(call, fpsEnable, last) {
		last = last || new Date
		return setAnimation(function() {
			if (fpsEnable) {
				var now = new Date
				var fps = 1000 / (now - last)
				call(fps)
			} else {
				call()
			}
			loopAnimation(call, fpsEnable, now)
		})
}


называется loopAnimation(call, fpsEnable) ,
принимает калбак и булеан значение означающее передавать в калбак FPS или нет,
калбак вызывается каждый раз когда браузер рендерит страничку)
loopAnimation возвращает айдишник анимации для того чтобы можно было остановить clearAnimation'oм

Применяется так
loopAnimation(function(fps) {
	log(fps)
}, true)

miha-ha 06.01.2012 10:59

Для разделения обработки перемещений и отрисовки можно так:
 
run:function () {
        var me = this,
            loops = 0,
            skipTicks = 33, // ~1000/30
            nextGameTick = (new Date()).getTime();

            var loop = function () {
                loops = 0;

                while ((new Date).getTime() > nextGameTick) {
                    me.update();
                    nextGameTick += skipTicks;
                    loops++;
                }

                me.render();
                requestAnimFrame(loop);
            };

            loop();
    }


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