1

i've been following a series on youtube on how to create a 2d game using java, and i cant seem to wrap my head around how this piece of code works, if anyone can elaborate how this code works id be very gratefull.

public void run() {
    long lastTime = System.nanoTime();
    final double clock = 1000000000.0 / 60.0;
    double delta = 0;

    while (running) {
        long now = System.nanoTime();
        delta +=(now - lastTime) / clock;
        System.out.println(now-lastTime);
        lastTime = now;

        while (delta >= 1){
            update();
            delta--;
        }
        render();
    }
}

What i have understood from this piece of code is that the clock variable contains how much time one frame should take if our game were to run 60 frames per second,but i cant seem to wrap my head around the now-lastTime variables since they seem to vary all the time, but we get the same time taken in every execution of the loop, thus getting 60 fps. I understand the purpose of the loop, what i actually dont understand is how it mathematically comes down together so that delta >= 1 happens 60 times a second.

Filip Bog
  • 19
  • 2

3 Answers3

0

Edit. Basically that code is first calculating the number of nanoseconds per 1/60 second, then using that to convert the delta to a normalized value. It's a confusing way of doing it though.

This might be easier to think about:

double nano = 1000000000.0;
double updateIntervalInSec =  1 / 60.0;
double delta = 0;

delta += (now-lastTime) / nano;//convert nano to seconds here

while(delta >= updateIntervalInSec)
{
  delta -= updateIntervalInSec;
}

Earlier answer; might be useful for someone.

This type of game loop is designed to solve a couple problems.

  1. Make the update rate independent of rendering rate
  2. Make the time increment per update constant.

The first consideration is important for slow or potentially slow computers; even if you can't SHOW updates fast enough, the game should (usually) still update at normal speed.

The second consideration is important for games with physics; updating a physics system with variable time intervals/increments makes physics unhappy.

Now for that implementation.

//run this loop as fast as possible
while (running) { 
    long now = System.nanoTime();

    //delta is to collect up the amount of time since the last loop and put it
    //into our bucket of time
    delta +=(now - lastTime) / clock;


    System.out.println(now-lastTime);
    lastTime = now;

    //if we have accumulated enough time to meet the minimum requirements for an update, then run one update, and remove one increment of time from our bucket of available time.
    //but what if we have more time left in the delta bucket?   We need to keep doing updates until we've used up all the available time.
    while (delta >= 1){
    //update requires 1 time
        update();
        delta--;
    }
    //now that we've made sure all the updates are up to date, we can render
    //note that render happens no matter if 10 updates, or 0 updates were just run
    render();
}
Kal_Torak
  • 2,532
  • 1
  • 21
  • 40
  • Thank you for your explanation, i guess i forgot to mention that i actually understand why this game loop is used and what it does, what i actually dont understand is how in mathematical terms it actually computes the frames, for example, the way that it adds one loops worth of time onto delta and then divides it by 1/60th of a second, how is it that when you check if delta >= 1 it just so takes enough for one frame to fit in. – Filip Bog Apr 08 '15 at 20:18
0

This is considered Delta Timing; it removes any differences in visual speed that might appear when observing your applications on fast and slow computers.


The logic goes like this:

We specify how many nano seconds each frame should be. That's the 1000000000/60: 1b is a nano second, 60 is how many frames (as you probably know).

Here are some results from my computer when printing now-last, which is how many nano seconds have passed between each frame:

7270.0
2566.0
4704.0
4276.0

The idea is to add all the results until you get to 16m~ nano seconds. Once you hit 16m, it's time to update. You could actually do this:

double timePerFrame = 1000000000/60; //16m
long last = System.nanoTime();
while(true) {
    long now = System.nanoTime();
    double elapsedTime = now - last;

    delta += elapsedTime;
    last = now;

    if(delta >= timePerFrame) {
        update();
        delta = 0;
    }
}

Instead, the condition is delta >= 1, where 1 represents "one frame". Dividing the elapsed time by how much time should pass before updating gives you the % of progress through your current frame. Instead of each loop being a frame, a frame passes each time delta >= 1. delta represents the current progress through that frame.

Vince
  • 14,470
  • 7
  • 39
  • 84
  • Thank you for the explanation but what i dont actually understand is how is it so that when you divide the time it takes for one frame, and divide it by the time a frame should actually take to render you get this kind of effect, why is it that delta >=1 will only happen 60 times a second, in mathematical terms. – Filip Bog Apr 08 '15 at 20:24
  • @FilipBog Check out my edit. Let me know if you need a deeper understanding of anything – Vince Apr 08 '15 at 20:55
  • Oh thank you now i finally understand it the way you have explained it, i have thought of it that way but i havent thought of the % conversion, now its clear to me, guess i have long ways to go, thank you for taking time to explain this to me. – Filip Bog Apr 08 '15 at 21:04
0

The clock speed is basically just the number of nanoseconds that can occur per second. final double clock = 1000000000.0 / 60.0; is simply returning the number of 1 / 60th of the nanoseconds in a second.

The next interesting part is calculating the delta variable (which when it is greater than or equal to one means we need to draw again because at least 1/60th of a second has passed.)

They do now - lastTime to get the difference in nanoseconds between now and the last time the loop ran. We then divide this number by the clock speed (which is 1/60th of a second).

Now delta simply shows how many 1/60th of a seconds have passed since the last time the loop executed.

Then we check if at least 1/60th of a second has passed and if it has then we update the game and decrement delta (because we did one frame / we did 1/60th of a second).

The loop continues to update so it draws for each 1/60th of a second that has passed to basically force the game to run at 60fps (technically but in reality this is probably not true).

Hopefully that makes some sense. I am not very good at explaining things.

edit

Just to clarify here. Delta is simply the number of 1/60th of a second that has passed. So delta could be 60 (meaning 1 second has passed or 360 meaning 6 seconds has passed or some other number). The while(delta >= 1) will run until delta is back to 0. So update could be run 300 times in a row if delta is large enough.

If update() is blocking in some way than delta can be higher than 1 (which means that update() took more than 1/60th of a second to execute).

honerlawd
  • 1,499
  • 11
  • 10