Last active
July 3, 2018 19:11
-
-
Save 6174/6149022 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Ticker by Grant Skinner. Dec 5, 2010 | |
* Visit http://easeljs.com/ for documentation, updates and examples. | |
* | |
* | |
* Copyright (c) 2010 Grant Skinner | |
* | |
* Permission is hereby granted, free of charge, to any person | |
* obtaining a copy of this software and associated documentation | |
* files (the "Software"), to deal in the Software without | |
* restriction, including without limitation the rights to use, | |
* copy, modify, merge, publish, distribute, sublicense, and/or sell | |
* copies of the Software, and to permit persons to whom the | |
* Software is furnished to do so, subject to the following | |
* conditions: | |
* | |
* The above copyright notice and this permission notice shall be | |
* included in all copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
* OTHER DEALINGS IN THE SOFTWARE. | |
*/ | |
/** | |
* The Easel Javascript library provides a retained graphics mode for canvas | |
* including a full, hierarchical display list, a core interaction model, and | |
* helper classes to make working with Canvas much easier. | |
* @module EaselJS | |
**/ | |
(function(window) { | |
// constructor: | |
/** | |
* The Ticker class uses a static interface (ex. Ticker.getPaused()) and should not be instantiated. | |
* Provides a centralized tick or heartbeat broadcast at a set interval. Listeners can subscribe | |
* to the tick event to be notified when a set time interval has elapsed. | |
* Note that the interval that the tick event is called is a target interval, and may be broadcast | |
* at a slower interval during times of high CPU load. | |
* @class Ticker | |
* @static | |
**/ | |
Ticker = function() { | |
throw "Ticker cannot be instantiated."; | |
} | |
/** | |
* Event broadcast once each tick / interval. The interval is specified via the | |
* .setInterval(ms) or setFPS methods. | |
* @event tick | |
* @param {Number} timeElapsed The time elapsed in milliseconds since the last tick event. | |
*/ | |
// private static properties: | |
/** | |
* @property _listeners | |
* @type Array[Object] | |
* @protected | |
**/ | |
Ticker._listeners = []; | |
/** | |
* @property _pauseable | |
* @type Array[Boolean] | |
* @protected | |
**/ | |
Ticker._pauseable = []; | |
/** | |
* @property _paused | |
* @type Boolean | |
* @protected | |
**/ | |
Ticker._paused = false; | |
/** | |
* @property _inited | |
* @type Boolean | |
* @protected | |
**/ | |
Ticker._inited = false; | |
/** | |
* @property _startTime | |
* @type Number | |
* @protected | |
**/ | |
Ticker._startTime = 0; | |
/** | |
* @property _pausedTime | |
* @type Number | |
* @protected | |
**/ | |
Ticker._pausedTime=0; | |
/** | |
* Number of ticks that have passed | |
* @property _ticks | |
* @type Number | |
* @protected | |
**/ | |
Ticker._ticks = 0; | |
/** | |
* Number of ticks that have passed while Ticker has been paused | |
* @property _pausedTickers | |
* @type Number | |
* @protected | |
**/ | |
Ticker._pausedTickers = 0; | |
/** | |
* @property _interval | |
* @type Number | |
* @protected | |
**/ | |
Ticker._interval = 50; // READ-ONLY | |
/** | |
* @property _intervalID | |
* @type Number | |
* @protected | |
**/ | |
Ticker._intervalID = null; | |
/** | |
* @property _lastTime | |
* @type Number | |
* @protected | |
**/ | |
Ticker._lastTime = 0; | |
/** | |
* @property _times | |
* @type Array[Number] | |
* @protected | |
**/ | |
Ticker._times = []; | |
// public static methods: | |
/** | |
* Adds a listener for the tick event. The listener object must expose a .tick() method, | |
* which will be called once each tick / interval. The interval is specified via the | |
* .setInterval(ms) method. | |
* The exposed tick method is passed a single parameter, which include the elapsed time between the | |
* previous tick and the current one. | |
* @method addListener | |
* @static | |
* @param {Object} o The object to add as a listener. | |
* @param {Boolean} pauseable If false, the listener will continue to have tick called | |
* even when Ticker is paused via Ticker.pause(). Default is true. | |
**/ | |
Ticker.addListener = function(o, pauseable) { | |
if (!Ticker._inited) { | |
Ticker._inited = true; | |
Ticker.setInterval(Ticker._interval); | |
} | |
this.removeListener(o); | |
Ticker._pauseable[Ticker._listeners.length] = (pauseable == null) ? true : pauseable; | |
Ticker._listeners.push(o); | |
} | |
/** | |
* Removes the specified listener. | |
* @method removeListener | |
* @static | |
* @param {Object} o The object to remove from listening from the tick event. | |
**/ | |
Ticker.removeListener = function(o) { | |
if (Ticker._listeners == null) { return; } | |
var index = Ticker._listeners.indexOf(o); | |
if (index != -1) { | |
Ticker._listeners.splice(index, 1); | |
Ticker._pauseable.splice(index, 1); | |
} | |
} | |
/** | |
* Removes all listeners. | |
* @method removeAllListeners | |
* @static | |
**/ | |
Ticker.removeAllListeners = function() { | |
Ticker._listeners = []; | |
Ticker._pauseable = []; | |
} | |
/** | |
* Sets the target time (in milliseconds) between ticks. Default is 50 (20 FPS). | |
* Note actual time between ticks may be more than requested depending on CPU load. | |
* @method setInterval | |
* @static | |
* @param {Number} interval Time in milliseconds between ticks. Default value is 50. | |
**/ | |
Ticker.setInterval = function(interval) { | |
if (Ticker._intervalID != null) { clearInterval(Ticker._intervalID); } | |
Ticker._lastTime = Ticker._getTime(); | |
Ticker._interval = interval; | |
Ticker._intervalID = setInterval(Ticker._tick, interval); | |
} | |
/** | |
* Returns the current target time between ticks, as set with setInterval. | |
* @method getInterval | |
* @static | |
* @return {Number} The current target interval in milliseconds between tick events. | |
**/ | |
Ticker.getInterval = function() { | |
return Ticker._interval; | |
} | |
/** | |
* Returns the target frame rate in frames per second (FPS). For example, with an | |
* interval of 40, getFPS() will return 25 (1000ms per second divided by 40 ms per tick = 25fps). | |
* @method getFPS | |
* @static | |
* @return {Number} The current target number of frames / ticks broadcast per second. | |
**/ | |
Ticker.getFPS = function() { | |
return 1000/Ticker._interval; | |
} | |
/** | |
* Sets the target frame rate in frames per second (FPS). For example, with an interval of 40, getFPS() will | |
* return 25 (1000ms per second divided by 40 ms per tick = 25fps). | |
* @method setFPS | |
* @static | |
* @param {Number} value Target number of ticks broadcast per second. | |
**/ | |
Ticker.setFPS = function(value) { | |
Ticker.setInterval(1000/value); | |
} | |
/** | |
* Returns the actual frames / ticks per second. | |
* @method getMeasuredFPS | |
* @static | |
* @param {Number} ticks Optional. The number of previous ticks over which to measure the actual | |
* frames / ticks per second. | |
* @return {Number} The actual frames / ticks per second. Depending on performance, this may differ | |
* from the target frames per second. | |
**/ | |
Ticker.getMeasuredFPS = function(ticks) { | |
if (Ticker._times.length < 2) { return -1; } | |
// x >> 1 : use bitwise to divide by two (int math) | |
if (ticks == null) { ticks = Ticker.getFPS()>>1; } | |
ticks = Math.min(Ticker._times.length-1, ticks); | |
return 1000/((Ticker._times[0]-Ticker._times[ticks])/ticks); | |
} | |
/** | |
* While Ticker is paused, pausable listeners are not ticked. See addListener for more information. | |
* @method setPaused | |
* @static | |
* @param {Boolean} value Indicates whether to pause (true) or unpause (false) Ticker. | |
**/ | |
Ticker.setPaused = function(value) { | |
Ticker._paused = value; | |
} | |
/** | |
* Returns a boolean indicating whether Ticker is currently paused, as set with setPaused. | |
* @method getPaused | |
* @static | |
* @return {Boolean} Whether the Ticker is currently paused. | |
**/ | |
Ticker.getPaused = function() { | |
return Ticker._paused; | |
} | |
/** | |
* Returns the number of milliseconds that have elapsed since the first tick event listener was added to | |
* Ticker. For example, you could use this in a time synchronized animation to determine the exact amount of | |
* time that has elapsed. | |
* @method getTime | |
* @static | |
* @param {Boolean} pauseable Indicates whether to include time elapsed | |
* while Ticker was paused. If false only time elapsed while Ticker is not paused will be returned. | |
* If true, the value returned will be total time elapsed since the first tick event listener was added. | |
* @return {Number} Number of milliseconds that have elapsed since Ticker was begun. | |
**/ | |
Ticker.getTime = function(pauseable) { | |
return Ticker._getTime() - Ticker._startTime - (pauseable ? Ticker._pausedTime : 0); | |
} | |
/** | |
* Returns the number of ticks that have been broadcast by Ticker. | |
* @method getTicks | |
* @static | |
* @param {Boolean} pauseable Indicates whether to include ticks that would have been broadcast | |
* while Ticker was paused. If false only tick events broadcast while Ticker is not paused will be returned. | |
* If true, tick events that would have been broadcast while Ticker was paused will be included in the return | |
* value. The default value is false. | |
* @return {Number} of ticks that have been broadcast. | |
**/ | |
Ticker.getTicks = function(pauseable) { | |
return Ticker._ticks - (pauseable ?Ticker._pausedTickers : 0); | |
} | |
// private static methods: | |
/** | |
* @method _tick | |
* @protected | |
**/ | |
Ticker._tick = function() { | |
Ticker._ticks++; | |
var time = Ticker.getTime(false); | |
var elapsedTime = time-Ticker._lastTime; | |
var paused = Ticker._paused; | |
if (paused) { | |
Ticker._pausedTickers++; | |
Ticker._pausedTime += elapsedTime; | |
} | |
Ticker._lastTime = time; | |
var pauseable = Ticker._pauseable; | |
var listeners = Ticker._listeners; | |
var l = listeners ? listeners.length : 0; | |
for (var i=0; i<l; i++) { | |
var p = pauseable[i]; | |
var listener = listeners[i]; | |
if (listener == null || (paused && p) || listener.tick == null) { continue; } | |
listener.tick(elapsedTime); | |
} | |
Ticker._times.unshift(time); | |
if (Ticker._times.length > 100) { Ticker._times.pop(); } | |
} | |
/** | |
* @method _getTime | |
* @protected | |
**/ | |
Ticker._getTime = function() { | |
return new Date().getTime(); | |
} | |
//docced above | |
Ticker._startTime = Ticker._getTime(); | |
window.Ticker = Ticker; | |
}(window)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
* @class Animation | |
*/ | |
KISSY.add('fp-dsf/CatGameAnim', function(S, Event, util) { | |
var nullf = function() {} | |
var _reqAnimFrame = window.requestAnimationFrame; | |
var _cancelAnimFrame = window.cancelAnimationFrame; | |
(function() { | |
var a = ["ms", "moz", "webkit", "o"]; | |
var i = a.length; | |
while (--i > -1 && !_reqAnimFrame) { | |
_reqAnimFrame = window[a[i] + "RequestAnimationFrame"]; | |
_cancelAnimFrame = window[a[i] + "CancelAnimationFrame"] || window[a[i] + "CancelRequestAnimationFrame"]; | |
} | |
})() | |
//--globals | |
var getTimeNow = function() { | |
return +new Date(); | |
} | |
var _ticker = null; | |
var _tickerActive = false; | |
/** | |
* @class ticker | |
*/ | |
var Ticker = util.Klass(null, { | |
__construct: function(fps, useRAF) { | |
var self = this; | |
//--attrs | |
util.mix(self, { | |
_startTime: getTimeNow(), | |
_id: null, //intervalId | |
_useRAF = useRAF !== false && _reqAnimFrame, | |
_fps: null, | |
//interval function use setTimeout if no _requestAnimFrame | |
_req: nullf, | |
_gap: 0, | |
_nextTime: 0, | |
_frame: 0, | |
time: 0 | |
}); | |
//--event | |
util.mix(self, S.EventTartget); | |
//--method | |
self._tick = function(manual) { | |
var id = self._id; | |
self.time = (getTimeNow() - self._startTime) / 1000; | |
var overlap = self.time - self._nextTime; | |
if (!self._fps || overlap > 0 || manual === true) { | |
self.frame++; | |
self._nextTime = overlap + (overlap >= self._gap ? 0.004 : self._gap - overlap); | |
self.fire('tick', { | |
time: self.time, | |
frames: self.frame | |
}); | |
} | |
//fire('tick') may change self._id | |
if (manual !== true && id === self._id) { | |
self._id = self._req(self._tick); | |
} | |
} | |
self.fps(fps); | |
//ios6 bug reqanimFrame init error | |
setTimeout(function() { | |
if (self._useRAF && (!self._id || self.frame < 5)) self.useRAF(false); | |
}, 1500); | |
}, | |
tick: function() { | |
var self = this; | |
self._tick(true); | |
}, | |
sleep: function() { | |
var self = this; | |
if (self._id === null) return; | |
if (!self._useRAF || !_cancelAnimFrame) { | |
clearTimeout(self._id); | |
} | |
//make the req func be nullf | |
self._req = nullf; | |
self._id = null; | |
/////////////////wraning ---unknow _ticker/// | |
if (self === _ticker) { | |
_tickerActive = false; | |
} | |
}, | |
wake: function() { | |
var self = this; | |
var id = self._id; | |
if (id !== null) self.sleep(); | |
function noRAF(f) { | |
var time = (self._nextTime - self.time) * 1000 + 1 | 0; | |
return setTimeout(util.proxy(self, f), time); | |
} | |
self._req = (self._fps === 0) ? nullf : (!_useRAF || !_reqAnimFrame) ? noRAF : _reqAnimFrame; | |
if (self === _ticker) _tickerActive = true; | |
self._tick(2); | |
}, | |
fps: function(value) { | |
var self = this; | |
if (!arguments.length) return self._fps; | |
self._fps = value > 60 ? 60 : value; | |
self._gap = 1 / (_fps || 60); | |
self._nextTime = self.time + self._gap; | |
}, | |
useRAF: function(value) { | |
var self = this; | |
if (!arguments.length) return self._useRAF; | |
self.sleep(); | |
self._useRAF = value; | |
self.fps(self._fps); | |
} | |
}); | |
_ticker = new Ticker(60, true); | |
}, { | |
requires: [ | |
'dom', 'event', 'fp-dsf/CatGameUtil' | |
] | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* ---------------------------------------------------------------- | |
* Ticker | |
* ---------------------------------------------------------------- | |
*/ | |
var _reqAnimFrame = window.requestAnimationFrame, | |
_cancelAnimFrame = window.cancelAnimationFrame, | |
_getTime = Date.now || function() { | |
return new Date().getTime(); | |
}; | |
//now try to determine the requestAnimationFrame and cancelAnimationFrame functions and if none are found, we'll use a setTimeout()/clearTimeout() polyfill. | |
a = ["ms", "moz", "webkit", "o"]; | |
i = a.length; | |
while (--i > -1 && !_reqAnimFrame) { | |
_reqAnimFrame = window[a[i] + "RequestAnimationFrame"]; | |
_cancelAnimFrame = window[a[i] + "CancelAnimationFrame"] || window[a[i] + "CancelRequestAnimationFrame"]; | |
} | |
_class("Ticker", function(fps, useRAF) { | |
var _self = this, | |
_startTime = _getTime(), | |
_useRAF = (useRAF !== false && _reqAnimFrame), | |
_fps, _req, _id, _gap, _nextTime, | |
_tick = function(manual) { | |
_self.time = (_getTime() - _startTime) / 1000; | |
var id = _id, | |
overlap = _self.time - _nextTime; | |
if (!_fps || overlap > 0 || manual === true) { | |
_self.frame++; | |
_nextTime += overlap + (overlap >= _gap ? 0.004 : _gap - overlap); | |
_self.dispatchEvent("tick"); | |
} | |
if (manual !== true && id === _id) { | |
//make sure the ids match in case the "tick" dispatch triggered something that caused the ticker to shut down or change _useRAF or something like that. | |
_id = _req(_tick); | |
} | |
}; | |
EventDispatcher.call(_self); | |
this.time = this.frame = 0; | |
this.tick = function() { | |
_tick(true); | |
}; | |
this.sleep = function() { | |
if (_id == null) { | |
return; | |
} | |
if (!_useRAF || !_cancelAnimFrame) { | |
clearTimeout(_id); | |
} else { | |
_cancelAnimFrame(_id); | |
} | |
_req = _emptyFunc; | |
_id = null; | |
if (_self === _ticker) { | |
_tickerActive = false; | |
} | |
}; | |
this.wake = function() { | |
if (_id !== null) { | |
_self.sleep(); | |
} | |
_req = (_fps === 0) ? _emptyFunc : (!_useRAF || !_reqAnimFrame) ? function(f) { | |
return setTimeout(f, ((_nextTime - _self.time) * 1000 + 1) | 0); | |
} : _reqAnimFrame; | |
if (_self === _ticker) { | |
_tickerActive = true; | |
} | |
_tick(2); | |
}; | |
this.fps = function(value) { | |
if (!arguments.length) { | |
return _fps; | |
} | |
_fps = value; | |
_gap = 1 / (_fps || 60); | |
_nextTime = this.time + _gap; | |
_self.wake(); | |
}; | |
this.useRAF = function(value) { | |
if (!arguments.length) { | |
return _useRAF; | |
} | |
_self.sleep(); | |
_useRAF = value; | |
_self.fps(_fps); | |
}; | |
_self.fps(fps); | |
//a bug in iOS 6 Safari occasionally prevents the requestAnimationFrame from working initially, so we use a 1.5-second timeout that automatically falls back to setTimeout() if it senses this condition. | |
setTimeout(function() { | |
if (_useRAF && (!_id || _self.frame < 5)) { | |
_self.useRAF(false); | |
} | |
}, 1500); | |
}); | |
p = gs.Ticker.prototype = new gs.events.EventDispatcher(); | |
p.constructor = gs.Ticker; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
* @class Animation | |
*/ | |
KISSY.add('fp-dsf/CatGameTicker', function(S, Event, util) { | |
var nullf = function() {} | |
var _reqAnimFrame = window.requestAnimationFrame; | |
var _cancelAnimFrame = window.cancelAnimationFrame; | |
(function() { | |
var a = ["ms", "moz", "webkit", "o"]; | |
var i = a.length; | |
while (--i > -1 && !_reqAnimFrame) { | |
_reqAnimFrame = window[a[i] + "RequestAnimationFrame"]; | |
_cancelAnimFrame = window[a[i] + "CancelAnimationFrame"] || window[a[i] + "CancelRequestAnimationFrame"]; | |
} | |
})() | |
//--globals | |
var getTimeNow = function() { | |
return +new Date(); | |
} | |
/** | |
* @Object ticker | |
* --use Ticker manage whole game | |
* --what other need to do is to regist on('tick') event | |
*/ | |
var Ticker = util.mix({}, S.EventTarget); | |
util.mix(Ticker, { | |
init: function(fps, useRAF) { | |
var self = this; | |
//--attrs | |
util.mix(self, { | |
_startTime: getTimeNow(), | |
_id: null, //intervalId | |
_useRAF: useRAF !== false && _reqAnimFrame, | |
_fps: null, | |
//interval function use setTimeout if no _requestAnimFrame | |
_req: nullf, | |
_gap: 0, | |
_nextTime: 0, | |
_frame: 0, | |
time: 0, | |
_tickerActive: false | |
}); | |
//--method | |
var _tick = function(manual) { | |
self.time = (getTimeNow() - self._startTime) / 1000; | |
var id = self._id; | |
var overlap = self.time - self._nextTime; | |
var deltaTime = 0; | |
// console.log("time-info", self.time, self._nextTime, overlap); | |
if (!self._fps || overlap > 0 || manual === true) { | |
self._frame += 1; | |
deltaTime = overlap + (overlap >= self._gap ? 0.004 : self._gap - overlap); | |
self._nextTime += deltaTime; | |
self.fire('tick', { | |
time: deltaTime > 0.1 ? self._gap : deltaTime, | |
frame: self._frame, | |
nextTime: self._nextTime | |
}); | |
} | |
//fire('tick') may change self._id | |
if (manual !== true && id === self._id) { | |
// if(self._frame < 60) { | |
self._id = self._req.call(window, self._tick); | |
// console.log(self._id); | |
// } | |
// console.log("time :" + self.time) | |
} | |
} | |
self._tick = _tick; | |
self.fps(fps); | |
// ios6 bug reqanimFrame init error | |
setTimeout(function() { | |
if (self._useRAF && (!self._id || self.frame < 5)) self.useRAF(false); | |
}, 1500); | |
}, | |
tick: function() { | |
var self = this; | |
self._tick(true); | |
}, | |
sleep: function() { | |
var self = this; | |
if (self._id === null) return; | |
//clear _req | |
if (!self._useRAF || !_cancelAnimFrame) { | |
clearTimeout(self._id); | |
} else { | |
_cancelAnimFrame(self._id); | |
} | |
//make the req func be nullf | |
self._req = null; | |
self._id = null; | |
self.fire('sleep'); | |
self._tickerActive = false; | |
}, | |
wake: function() { | |
var self = this; | |
var id = self._id; | |
if (id !== null) self.sleep(); | |
function noRAF(f) { | |
var time = (self._nextTime - self.time) * 1000 + 1 | 0; | |
return setTimeout(util.proxy(self, f), time); | |
} | |
self._req = (self._fps === 0) ? nullf : (!self._useRAF || !_reqAnimFrame) ? noRAF : _reqAnimFrame; | |
self._tickerActive = true; | |
self.fire('wakeup'); | |
self._tick(2); | |
}, | |
fps: function(value) { | |
var self = this; | |
if (!arguments.length) return self._fps; | |
self._fps = value > 60 ? 60 : value; | |
self._gap = 1 / (self._fps || 60); | |
self._nextTime = self.time + self._gap; | |
}, | |
useRAF: function(value) { | |
var self = this; | |
if (!arguments.length) return self._useRAF; | |
self.sleep(); | |
self._useRAF = value; | |
self.fps(self._fps); | |
} | |
}); | |
Ticker.init(60, true); | |
window.ticker = Ticker; | |
return Ticker; | |
}, { | |
requires: [ | |
'event', 'fp-dsf/CatGameUtil' | |
] | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment