Answers:
对于基本的游戏循环,您需要运行while循环,在该循环中,您可以使用nanoTime()获取时间,确定自上一帧以来经过了多少时间,然后更新游戏状态并进行渲染。
使用http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#nanoTime%28%29,您可以轮询经过的时间。基本上...
public static void main(String [ ] args)
{
long current_frame_time = system.nanoTime();
long last_frame_time = current_frame_time;
while(gameIsRunning)
{
last_frame_time = current_frame_time;
current_frame_time = system.nanoTime();
long timeTaken = current_frame_time - last_frame_time;
//update and render game here
}
}
可以在http://www.koonsolo.com/news/dewitters-gameloop/和http://gafferongames.com/game-physics/fix-your-timestep/上对此基本方法进行改进。
或者,您可以创建一个计时器并将其设置为每X毫秒运行一次更新并呈现。但是,构建这样的游戏循环有一些弊端。
根据http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html:“ 与每个Timer对象相对应的是一个单独的后台线程,用于执行所有计时器的计时器任务应快速完成;如果计时器任务花费过多时间来完成,它将“占用”计时器的任务执行线程,从而可能延迟后续任务的执行,从而可能“束缚”任务并延迟任务的执行。当(如果有问题)任务最终完成时,迅速连续执行。 ”
根据http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html#scheduleAtFixedRate%28java.util.TimerTask,%20java.util.Date,%20long%29: “ 在固定速率执行中,每个执行是相对于初始执行的预定执行时间进行调度的。如果某个执行由于任何原因(例如垃圾回收或其他后台活动)而延迟,则将连续快速发生两个或更多个执行“赶上”。从长远来看,执行的频率将是完全可逆的规定期间(假设系统时钟底层的Object.wait(长)是准确的)的。 “
由于您通常不提前知道游戏循环需要多长时间,因此设置计时器每X毫秒执行一次游戏循环(取决于目标帧速率)可能会导致一些帧堆积,每当帧出现时就会执行完成而不是安排帧时。当发生这种情况时...为什么首先要使用计时器?
现在,请不要误会我,计时器不是一个坏类,但是它通常更适合需要定期或在某个时间完成的小任务,例如,邮件客户端可能希望每5秒钟检查一次新邮件分钟,否则计数器可能会每秒减少以在比赛开始前显示倒计时。