For animation control, may be a bit of error, we will not be aware, but if the number of cyclic accumulation or network synchronization, and so on, we will be very aware of the schedule error problem.
First do an example to prove that:
varInaccuracytestlayer =cc. Layer.extend ({ctor:function () { This. _super (); varStartTime =NewDate (). GetTime (); varCount = 0; This. Schedule (function(){ varTimepass =NewDate (). GetTime ()-StartTime; Count++; varDelta = timepass-(count*100); Trace ("Time Pass", Timepass, "Total Delta", Delta, "Count", Count); }, 0.1); This. Scheduleupdate (); }, Update:function () { for(vari = 0; I < 100000; i++) {b= 1/0.22222; } }});
The lower the frame rate, the faster it slows down.
Time pass, 1481, Total Delta, 381, Count, one-ccdebugger.js:334 1608, Total delta, 408, Count, ccdebugger.js:334 1735, Total Delta, 435, Count, ccdebugger.js:3341861, Total Delta, 461, Count, ccdebugger.js:334
So try to solve the problem?
Timer principle: Cocos2d-js bottom in each frame calculation, traverse all timers to see if the trigger time is reached. If it is reached, the timer is triggered and the time is reset to the current time. Okay, here's the problem, "reset to current time."
Look at a new timer:
Schedule2:function(callback, interval) {varthen =Date.now (); Interval= interval*1000; This. Schedule (function(){ varnow =Date.now (); varDelta = Now-Then ; if(Delta >interval) { Then= Now-(Delta%interval); Callback.call ( This); }}.bind ( This), 0); }
Here the core is then=now-(Delta%interval), each time the trigger, the error is calculated to the next trigger control.
For example 60fps, then schedule2 every 16ms triggered once, the user set the 100ms interval, then there will be 16*7=112>100,7 frame to trigger 1 times the user's timer. This accumulates the 12ms error and calculates the 12ms to then.
Then next time will have 12+16*6=108>100, only need 96ms to trigger the 2nd time User's timer, this time advance 4ms, make up the error of 1th time.
This timer is tested to remain stable even in low frame-rate conditions.
varBetterschedulelayer =cc. Layer.extend ({ctor:function () { This. _super (); varStartTime =Date.now (); varCount = 0; This. Schedule2 (function(){ varTimepass = Date.now ()-StartTime; Count++; varDelta = timepass-(count*100); Trace ("Time Pass", Timepass, "Total Delta", Delta, "Count", Count); }, 0.1); This. Scheduleupdate (); }, Schedule2:function(callback, interval) {varthen =Date.now (); Interval= interval*1000; This. Schedule (function(){ varnow =Date.now (); varDelta = Now-Then ; if(Delta >interval) { Then= Now-(Delta%interval); Callback.call ( This); }}.bind ( This), 0); }, Update:function () { for(vari = 0; i < 10000000; i++) {b= 1/0.22222; } }});
Output:
Time Pass, 3447, Total Delta, Max, Count, ccdebugger.js:3343510, Total Delta, count, Ccdebugger.js:334
3637, Total Delta, PNS, Count, ccdebugger.js:334
3701, Total delta, 1, Count, PNs ccdebugger.js:334
3828, Total delta, +, COUNT, ccdebugger.js:3343955, Total Delta, count, ccdebugger.js:334
Cocos2d-js slower timer schedule make constant slow timer