var RequestAnimationFrame = require('../dom/RequestAnimationFrame'); var MainLoop = function (game, framerate){ this.game = game; this.raf = new RequestAnimationFrame(); this.timestep = 1000 / framerate; this.physicsStep = 1 / framerate; this.frameDelta = 0; this.discardedTime = 0; this.lastFrameTimeMs = 0; this.fps = 60; this.lastFpsUpdate = 0; this.framesThisSecond = 0; this.numUpdateSteps = 0; this.minFrameDelay = 0; this.running = false ; this.started = false ; this.panic = false ; } ; MainLoop.prototype.constructor = MainLoop; MainLoop.prototype = { setMaxFPS: function (fps){ if (fps === 0) { this.stop(); } else { this.minFrameDelay = 1000 / fps; } } , getMaxFPS: function (){ return 1000 / this.minFrameDelay; } , resetFrameDelta: function (){ var oldFrameDelta = this.frameDelta; this.frameDelta = 0; return oldFrameDelta; } , start: function (){ if (this.started) { return this; } this.started = true ; this.running = true ; this.lastFrameTimeMs = window.performance.now(); this.lastFpsUpdate = window.performance.now(); this.framesThisSecond = 0; this.raf.start(this.step.bind(this), this.game.config.forceSetTimeOut); } , step: function (timestamp){ var active = this.game.state.active; var renderer = this.game.renderer; var len = _AN_Read_length('length', active); if (len === 0 || timestamp < this.lastFrameTimeMs + this.minFrameDelay) { return ; } this.frameDelta += timestamp - this.lastFrameTimeMs; this.lastFrameTimeMs = timestamp; this.game.input.update(timestamp, this.frameDelta); for (var i = 0; i < len; i++ ){ active[i].state.sys.begin(timestamp, this.frameDelta); } if (timestamp > this.lastFpsUpdate + 1000) { this.fps = 0.25 * this.framesThisSecond + 0.75 * this.fps; this.lastFpsUpdate = timestamp; this.framesThisSecond = 0; } this.framesThisSecond++ ; this.numUpdateSteps = 0; while (this.frameDelta >= this.timestep){ for (i = 0; i < len; i++ ){ active[i].state.sys.update(this.timestep, this.physicsStep); } this.frameDelta -= this.timestep; if (++this.numUpdateSteps >= 240) { this.panic = true ; break ; } } var interpolation = this.frameDelta / this.timestep; renderer.preRender(); for (i = 0; i < _AN_Read_length('length', active); i++ ){ active[i].state.sys.render(interpolation, renderer); } renderer.postRender(); if (this.panic) { this.discardedTime = Math.round(this.resetFrameDelta()); } this.panic = false ; } , stop: function (){ this.running = false ; this.started = false ; return this; } } ; module.exports = MainLoop;