Domanda

ANSWER: The first loop is constantly rendering, even when update() isn't being called, so unless you have other threads affecting variables other than the one calling update(), it will render the same thing a few times until it's updated again. The main loop is running at max speed, which causes the higher CPU usage.

The second loop updates, renders, then sleeps for a bit, leaving the main thread completely idle. If other threads affect variables, you must wait until the the thread calling render() is done sleeping and updating using update() so render() can finally render the new screen depending on how other threads affected it.

First loop is better if you are making a large-scale game consisting of multithreading, Second loop is better for games that only use one thread to run the entire game (so no delays between updating vars and rendering them, since one threaded games only update on one thread, and render triggers right after updating.


I've seen all kinds of different loops. my Question is what is the difference between these two loops: (all the reference vars arent needed, but are given for example)

long starttime = System.nanoTime();
int onesec = 1000000000;
int fps = 60;
double difference = 0;
double updatechecker;

while(true) {
     long currenttime = System.nanoTime();
     difference = (currenttime - starttime);
     updatechecker = difference/(onesec/fps);

     while(updatechecker >= 1) {
          //update() here
          updatechecker = 0;
     }
     //render() here

     starttime = currenttime;
}

I understand that with more complicated loops like that, you can do things like seeing if theres time to render another screen before updating again and what not.

My question is whats the point of rendering faster than updating anyways? Why wouldn't something like this be more efficient:

while(running) {
    long starttime = System.currentTimeMillis();
    //update() here
    //render() here
    long endtime = System.currentTimeMillis();

    try {
        Thread.sleep((1000/60) + (starttime - endtime));
    } catch(InterruptedException e) {
        e.printStackTrace();
    }

}

I know that with the first loop, you can do things like checking if theres time to render again before updating, but is there really a big difference between updating/rendering at the same and at different times? (you could also just use the first loop and put the render method where update is)

I found that using the Thread.sleep method drops my cpu usage by a ton. Im usually averaging 23-26% cpu with the first loop (rendering as fast as possible), and I average 2-4% cpu with the second loop. What's the better way to go? (pros and cons?)

È stato utile?

Soluzione 2

Standard software engineering may not apply to game dev, but generally, you'd aim for MVC. Controller changes Model, View renders Model. You also want event driven code if it's an option, but it looks like you're polling rather than using callbacks.

So if this were pong, your controller is inputting 'up', and in update(), you increase the 'y' variable by 1, and then render() draws it one pixel higher.

So thinking about it simply, you would expect it to be this... and I don't think you'll get any better based on a polling mechanism.

while(running) {
    if (pollTime) update();
    render();    
}

Having a thread that sleeps occasionally in the background isn't going to change anything.

Altri suggerimenti

The point of your first set of code is not to render more frequently than updating, but rather to permit updating more frequently than rendering. For example, if updating takes 1/80 of a second, and rendering takes 1/80 of a second, then you just don't have time to do an update plus a render for each 1/60 of a second frame. The first set of code will allow the updates to occur as fast as they are supposed to - every frame - while rendering when there is time to do so - in this case, every third frame. The frame rate drops, but the action continues at the normal expected pace.

With the same parameters - updating taking 1/80 of a second and rendering taking 1/80 of a second - the second case would fall further and further behind on the action, taking 1/40 of a second for each 1/60 of a second frame. Your game would act as if it was in slow motion.

Now, the first set of code does use more CPU. It could be improved by changing the updatechecker to check for zero before handling the >= 1 case. If the calculated updatechecker is zero, you can then sleep until the time for the next update - difference % (onesec/fps) / 1000000 milliseconds.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top