Java 2D游戏编程:制作游戏循环的不同方法


10

我是Java游戏编程的新手,但是我阅读的内容越多,我就越困惑,因为我已经看到了制作游戏循环的几种不同方法:1.使用Timer类的标准方法(似乎要少一些)精确)。2.使用System.nanoTime的更精确的方法。3.使用scheduleAtFixedRate的简单方法。

通常应首选哪种方法,每种方法的优缺点在哪里?在此先感谢您的任何信息。

Answers:


7

对于基本的游戏循环,您需要运行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秒钟检查一次新邮件分钟,否则计数器可能会每秒减少以在比赛开始前显示倒计时。


问题是关于游戏循环,因此awt / swing信息是题外话。但是,由于问题无关紧要,因此看起来该信息是相关的,因此我删除了该信息。
轰动

我修改了答案,以反映对该问题所做的更改。
2013年

7

我不会将主循环放在计时器中。相反,我将创建一个“ while”循环来处理每个帧,然后使用某种计时功能(在Java中听起来像System.nanoTime)来计算自上一帧/最后一次迭代以来经过了多少时间。环。

某些语言在这里是例外(例如JavaScript,ActionScript),因为这些语言在具有隐式主循环(例如浏览器,Flash Player)的环境中运行,但该例外不适用于Java。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.