避免使用Thread.sleep的Java贪吃蛇游戏

5
我在Java中制作了我的第一个游戏-贪吃蛇,它的主循环如下。
while (true)
    {
        long start = System.nanoTime();
        model.eUpdate();
        if (model.hasElapsedCycle())
        {
            model.updateGame();
        }
        view.refresh();
        long delta = (System.nanoTime() - start) / 1000000L;
        if (delta < model.getFrameTime())
        {
            try
            {
                Thread.sleep(model.getFrameTime() - delta);
            } catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

但是在我的项目需求中有一个响应性问题,所以我需要将Thread.sleep()改成其他东西,但我不知道如何以简单的方式做到这一点。 提前感谢任何建议。

2个回答

4

我曾经用Java做过一两个简单的游戏,为了处理主要的游戏循环,我使用了Swing Timer. 这个计时器允许你设置一个ActionListener,在经过指定的delay后触发。中间的延迟时间将根据帧率来确定。最基本的用法如下:

Timer timer = new Timer(delay, listener);
timer.start();

这将把初始延迟和中间延迟设置为相同的值。如果需要,您也可以将它们设置为不同的值,如下所示:

Timer timer = new Timer(delay, listener);
timer.setInitialDelay(0);
timer.start();

在上面的示例中,listener会在启动后尽快触发,并在此后有一个delay

-1
更好的想法是像上面建议的那样使用计时器,这将允许您在指定的延迟后触发而不调用sleep()。
如果你想要更复杂但自制的话,可以启动一个新的线程来处理睡眠。您可以使用一些池化频率的池化机制来避免thread.sleep。将您的条件放在while循环中,并等待一段时间,如果条件不满足,则等待时间应该较短,这样它将以小间隔进行轮询。
//more code here It is a sample code
    synchronized(this) {
         while (delta < model.getFrameTime()) {
          this.wait(500);
         }
       //more code 

2
你不能在未获取对象锁的情况下调用 wait 方法。你应该在回答中包含这一点。sleep 不需要获取锁,但是 wait 需要。 - nits.kk
我添加了一个同步块,但我没有添加它,因为我只想强调等待部分。 - gati sahu
我认为你没有理解池化机制。我使用小间隔的频率来轮询条件,而不是暂停一段时间。只有在轮询条件满足后立即执行操作时,你的系统才会无响应。它将等待轮询间隔时间。你可以配置等待间隔时间。 - gati sahu
1
这样的系统对用户来说会很卡顿。此外,在非多线程系统中获取锁本身是昂贵且不必要的。 - nits.kk
1
你本可以使用 sleep 实现你的解决方案,即通过睡眠来进行轮询。 - nits.kk
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接