the System.currentTimeMillis method on window have a low granularity around 16.xxx, this means that :
realtime = 1 => currentTimeMillis = 0
realtime = 2 => currentTimeMillis = 0
realtime = 10 => currentTimeMillis = 0
realtime = 15 => currentTimeMillis = 15
realtime = 17 => currentTimeMillis = 15
realtime = 20 => currentTimeMillis = 15
realtime = 25 => currentTimeMillis = 15
realtime = 30 => currentTimeMillis = 15
realtime = 32 => currentTimeMillis = 32
etc....
so if you got 0 it mean between 0 and 15
so if you got 15 it mean between 15 and 32
and etc...
Thread.sleep is more accurate but as you dont know the real time you cannot know how long you have to sleep/wait !!
below is the implementation I used wich give good results for me (maximum allowed fps == 1000/16 aprrox 62fps)
iTimer.getTime() return System.currentTimeMillis
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| this.fpsBuffer=new long[50]; this.maxFPS100=3000; thread run method: public void run() { try { while(this.runProcess) { if(!this.pauseProcess) { currentTime=this.iTimer.getTime()-this.startTime; while(currentTime==lastCurrentTime) { currentTime=this.iTimer.getTime()-this.startTime; Thread.sleep(1); } lastCurrentTime=currentTime; long frameTimeUs=100000000/this.maxFPS100;
long nbFrameSinceStart=(1000*currentTime)/frameTimeUs;
long currentFrameTimeMs=((nbFrameSinceStart+1)*frameTimeUs)/1000;
if(lastCurrentFrameTimeMs==currentFrameTimeMs) currentFrameTimeMs=lastCurrentFrameTimeMs+frameTimeUs/1000;
if((currentFrameTimeMs-lastCurrentFrameTimeMs)>(frameTimeUs/1000)) currentFrameTimeMs=lastCurrentFrameTimeMs+frameTimeUs/1000; lastCurrentFrameTimeMs=currentFrameTimeMs; while(currentTime<currentFrameTimeMs) { overEatCPU=0; Thread.sleep(1); if(this.iTimer.getTime()-this.startTime==currentTime) currentTime++; else currentTime=this.iTimer.getTime()-this.startTime; } if(overEatCPU>1) Thread.yield(); overEatCPU++; this.fpsBuffer[this.numLoop%this.fpsBuffer.length]=currentTime+startTime; this.render(); this.numLoop++; } else { Thread.sleep(1); Thread.yield(); } } } catch(InterruptedException ie) { Log.log(ie); } } |