Clock负责提供一个真实时间和一个虚拟时间,真实时间从0开始按ms递增,和硬件时钟是同步的;虚拟时间也从0开始按ms递增,但不一定和真实时间同步。
要获得系统时间可以用System.currentTimeMillies(),系统硬件有一个计数器,当计算机启动时,计数器从0开始每1ms加1,System.currentTimeMillies()返回从开机到现在经过的ms。我们不需要知道时分秒,只需要一个递增的整数计时就可以了。
Clock改自Marshall "Game Programming Gems 3"中的C++代码,主要成员变量:
thisTime:当前硬件时间,即System.currentTimeMillies()
systemTime:游戏的系统时间,即把thisTime转换为从0递增的时间
virtualTime:虚拟时间,从0递增,但和真实时间不同步
代码如下:
package game.engine.core; class Clock { // Clock是否运行: private boolean running; // 当前hardware clock: private int thisTime; // record the last hardware clock when calling stop(): private int lastTime; // systemTime从0开始递增,和硬件时钟同步: private int systemTime; // systemOffset就是硬件时钟和systemTime的差: private int systemOffset; // 上一次停止的systemTime: private int pauseAt; // virtualTime starts from 0. private int virtualTime; // virtualOffset records how long the clock paused: private int virtualOffset; private int frameStart; private int frameEnd; private int frameCount; public Clock() { reset(); } // 重置Clock: public void reset() { running = false; // get the hardware clock: thisTime = (int)System.currentTimeMillis(); lastTime = thisTime; // and systemTime starts from 0: systemTime = 0; systemOffset = thisTime; pauseAt = 0; // init virtual time: virtualTime = 0; virtualOffset = 0; // init frame time: frameStart = 0; frameEnd = 0; frameCount = 0; } // 同步hardware clock: private void update() { lastTime = thisTime; thisTime = (int)System.currentTimeMillis(); // increase the systemTime: systemTime += (thisTime - lastTime); } // 启动Clock: public void start() { if(!running) { running = true; update(); virtualOffset += (systemTime - pauseAt); System.out.println("[start]"); } } // 停止Clock: public void stop() { if(running) { running = false; update(); pauseAt = systemTime; System.out.println("[stop] at " + pauseAt); } } // Clock是否运行: public boolean isRunning() { return this.running; } // 开始Frame: public void beginFrame() { if(running) { update(); frameCount++; frameStart = frameEnd; frameEnd = systemTime - virtualOffset; virtualTime = frameStart; System.out.println("[beginFrame] virtual time = " + virtualTime + ", systemTime = " + systemTime); } } // 将virtual time提前到Frame结束: public void advanceToEnd() { if(running) { virtualTime = frameEnd; System.out.println("[advanceToEnd] virtual time = " + virtualTime); } } public int getVirtualTime() { return virtualTime; } // 获取系统时间: public int getSystemTime() { update(); return systemTime; } // 获取Frame开始时间: public int getFrameStart() { return frameStart; } // 获取Frame结束时间: public int getFrameEnd() { return frameEnd; } public int getFrameCount() { return frameCount; } }参考:Marshall:"Game Programming Gems 3"
待续 :)