5

I made my first game in Java - Snake, it's main loop looks like this

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();
            }
        }
    }

But in my project's requirments there is a responsivity point, so I need to change the Thread.sleep() into something else, but I have no idea how to do this in an easy way. Thanks in advance for any advice.

Emanuel Graf
  • 756
  • 17
  • 37
Azathanai
  • 65
  • 6

2 Answers2

4

I've done a simple game or two with Java and to handle the main game loop I've used a Swing Timer. The timer will allow you to set an ActionListener to be fired after a provided delay has elapsed. The in-between delay would be derived from your frame rate. The most basic usage would look like:

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

This would set the initial and in-between delays to the same value. You could also set them to be different values if needed like so:

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

In the above example, the listener will fire ASAP after starting and with a delay in-between thereafter.

ChiefTwoPencils
  • 13,548
  • 8
  • 49
  • 75
-1

A better idea is to use a Timer as suggested above which will allow you to trigger after a specified delay without calling sleep().

if you want it a little more complicated but self-made start a new Thread to handle the sleeps. You can put pooling mechanism with some pooling frequency to avoid thread.sleep.Put your condition in while loop and wait for some tine if condition is not met.And wait time should be less so it will poll with small interval.

//more code here It is a sample code
    synchronized(this) {
         while (delta < model.getFrameTime()) {
          this.wait(500);
         }
       //more code 
gati sahu
  • 2,576
  • 2
  • 10
  • 16
  • 2
    you just can not invoke `wait` without aquiring a lock on the object on which you invoke it. You should include that as well in your answer. `sleep` does not require the lock aquisition but `wait` needs it. – nits.kk Jun 11 '17 at 08:06
  • Added a synchronized block ,I have not added as I am trying to highlight only wait part – gati sahu Jun 11 '17 at 08:12
  • ok now next step. The thread is waiting , can you tell in your answer if it is the main thread or any other thread. If it is the main thread and it is waiting how is responsiveness solved ? If it is another thread , where in your answer do you mention it. – nits.kk Jun 11 '17 at 08:20
  • I think you did not understand pooling mechanism.Instead of sleep for some time I am pooling the condition with frequency of small interval.Your system will not responsive only if just after pooling the condition satisfied.It will wait for pooling interval time.You can configure waiting interval time. – gati sahu Jun 11 '17 at 08:39
  • 1
    Such system will be jerky for the user. Moreover aquiring the lock itself in non multi threaded sysstem is expensive and not needed. – nits.kk Jun 11 '17 at 08:39
  • 1
    You could have just implemented your solution using `sleep` i.e polling with sleep. – nits.kk Jun 11 '17 at 08:42
  • I do not know how you conclude it ,but the fact is lot of asynchronous working like this like jms queue only theoretically in event driven model you will use push or pull model.If you have other option you can explain me. – gati sahu Jun 11 '17 at 08:42
  • sleep has some short comings so as best practice people avoid it. – gati sahu Jun 11 '17 at 08:43
  • the point here is not pull vs push model but the usuage of wait instead of sleep as wait has forced you to use synchronization. after each wake up the thread scheduler puts the thread in runnable state and it re aquires the lock which is a costly matter. If you do not want to use a separate Thread and wish to poll using the main thread itself you wished to use polling you could have simply achieved it with `sleep`. **Main thread should be as much free as possible**. Any waiting or expensive processing must be delegated to another Thread, and now you could use a lock, wait and notify model. – nits.kk Jun 11 '17 at 08:46
  • agree.wait will release the lock and you can communicate between thread.If you dont need any thing you can go for sleep.And from sleep also thread will go to the schedule again. – gati sahu Jun 11 '17 at 08:57