Java-Gaming.org Hi !
Featured games (81)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (576)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: 1 2 3 [4] 5
  ignore  |  Print  
  Solving Stuttering With Fixed Timesteps, Once and For All  (Read 24169 times)
0 Members and 1 Guest are viewing this topic.
Offline Saucer

Junior Duke


Medals: 1



« Reply #90 - Posted 2011-11-01 03:16:30 »

My game loop would work fine for LWJGL. Slick2D handles the game loop for you.

Alright, I'll try it some time; but again, I think we were saying that Display.sync(60), which I think Slick2D uses for its gameloop, causes stuttering.

Offline thaaks
« Reply #91 - Posted 2011-11-01 10:01:49 »

Slick does not use Display.sync() by default. You can switch it on by setting a target frame rate but it's off by default.

See method updateAndRender() in class GameContainer and method gameLoop() in class AppGameContainer.

Just be careful what example code you copy to start with  Wink

Cheers,
Tommy

Offline Saucer

Junior Duke


Medals: 1



« Reply #92 - Posted 2011-11-01 15:54:30 »

Slick does not use Display.sync() by default. You can switch it on by setting a target frame rate but it's off by default.

See method updateAndRender() in class GameContainer and method gameLoop() in class AppGameContainer.

Just be careful what example code you copy to start with  Wink

Cheers,
Tommy

Thank you very much; I guess I'll give Slick2D another go too, then. Has anyone looked at or tried the Slick2D example I posted, by the way? Here it is again:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
@Override
    public void update(GameContainer container, int delta)
            throws SlickException {
        double now = Sys.getTime() * 1000000000.0 / Sys.getTimerResolution();//*/
        int updateCount = 0;
         
        //Do as many game updates as we need to, potentially playing catchup.
        while(now - lastUpdateTime > timeBetweenUpdates && updateCount < maxUpdatesBeforeRender) {
            innerUpdate();
            lastUpdateTime += timeBetweenUpdates;
            updateCount++;
            updatesPerSecondCount++;//
        }
         
        //If for some reason an update takes forever, we don't want to do an insane number of catchups.
        //If you were doing some sort of game that needed to keep EXACT time, you would get rid of this.
        if (now - lastUpdateTime > timeBetweenUpdates) {
            lastUpdateTime = now - timeBetweenUpdates;
        }
 
        interpolation = Math.min(1.0f, (float) ((now - lastUpdateTime) / timeBetweenUpdates));      
         
        //Update the frames we got.
        int thisSecond = (int) (Sys.getTime() / Sys.getTimerResolution());
        if (thisSecond > lastSecondTime) {
            updatesPerSecond = updatesPerSecondCount;//
            updatesPerSecondCount = 0;//
            lastSecondTime = thisSecond;
        }
         
        deltaDisplay = delta;
    }
     
    public void innerUpdate() {
        for (int i = 0; i < positions.length; i++) {
            positions[i] += directions[i] * (SPEED * i + SPEED);
            if (positions[i] <= 0) directions[i] = 1;
            else if (positions[i] >= DEFAULT_WIDTH) directions[i] = -1;
        }
 
        for (int i = 0; i < positions.length; i++) {
            lastPositions[i] = positions[i];
        }//*/
    }
 
    @Override
    public void render(GameContainer container, Graphics g)
            throws SlickException {
        //double now = Sys.getTime() * 1000000000.0 / Sys.getTimerResolution();//*/
        g.scale(DEFAULT_SCALE, DEFAULT_SCALE);
        g.setColor(Color.lightGray);
        g.fillRect(0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT);//*/
        g.setColor(Color.red);
        for (int i = 0; i < positions.length; i++) {
            int x;
            if (drawInterpolated) {
                x = (int) ((positions[i] - lastPositions[i]) * interpolation + lastPositions[i]);
            } else {
                x = (int) positions[i];
            }
            for (int j = 0; j < 2; j++) {
                //g.fillRect(x, HEIGHTS[j] + 16 * i, 16, 16);
                sprite.draw(x, HEIGHTS[j] + 16 * i);
                //fonts[j].draw(":)", x, HEIGHTS[j] + 16 * i - 16);
            }
        }
        g.setColor(Color.white);
        g.drawString("Hello, Slick world!", 16, 100);
        g.drawString("Delta: " + deltaDisplay, 16, 116);
        g.drawString("Updates per second: " + updatesPerSecond, 16, 132);
        g.drawString("Sys.getTime(): " + Sys.getTime(), 16, 148);
        g.drawString("Sys.getTimerResolution(): " + Sys.getTimerResolution(), 16, 164);
        g.drawString("" + Sys.getTime() * 1000000000.0 / Sys.getTimerResolution(), 16, 180);
        g.drawString("Interpolation: " + interpolation, 16, 196);
        /*interpolation = Math.min(1.0f, (float) ((now - lastRenderTime) / timeBetweenUpdates));
        lastRenderTime = now;//*/

        /*for (int i = 0; i < positions.length; i++) {
            lastPositions[i] = positions[i];
        }//*/

    }

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline thaaks
« Reply #93 - Posted 2011-11-01 16:20:33 »

Saucer, your Slick2D example doesn't make much sense for the idea of Slick IMHO. Way too complicated.

Slick basically works by calling update() and render() in a loop. The time spent between the previous and the current update call is passed in milliseconds as delta. That's it. Update your positions by multiplying with a factor and the delta and you're done.

You can finetune Slick by switching on vsync, setting a target frame rate, delta smoothing, minimal and maximal update time and so on.

But basically I would start simple.

Give the games in my signature a try: they are all done with Slick, the source code to all those games is available on my website or part of MarteEngine. See if they stutter that much that you consider them unplayable or annoying (stuttering wise, not gameplay  Tongue).
SpiderTrap is completely based on calculations using the delta value. Back to the past and StarCleaner use a target frame rate of 60.

Don't overcomplify things - try to get some games done  Grin

Cheers,
Tommy

Offline Saucer

Junior Duke


Medals: 1



« Reply #94 - Posted 2011-11-02 01:24:00 »

Saucer, your Slick2D example doesn't make much sense for the idea of Slick IMHO. Way too complicated.

Slick basically works by calling update() and render() in a loop. The time spent between the previous and the current update call is passed in milliseconds as delta. That's it. Update your positions by multiplying with a factor and the delta and you're done.

You can finetune Slick by switching on vsync, setting a target frame rate, delta smoothing, minimal and maximal update time and so on.

But basically I would start simple.

Give the games in my signature a try: they are all done with Slick, the source code to all those games is available on my website or part of MarteEngine. See if they stutter that much that you consider them unplayable or annoying (stuttering wise, not gameplay  Tongue).
SpiderTrap is completely based on calculations using the delta value. Back to the past and StarCleaner use a target frame rate of 60.

Don't overcomplify things - try to get some games done  Grin

Cheers,
Tommy

Thank you for your advice, Tommy, but I'm specifically trying to avoid using that style of updating. Do you know the distinction between fixed and variable timesteps, or about making the physics framerate independent? I'm trying to implement fixed timesteps (independent physics), and that's (sorta?) what's causing the stuttering.

EDIT: I guess I could try to fix the delta on Slick's terms--- as, after further consideration, I think you may be suggesting--- by using various features such as minimal and maximal update time, but I feel that that would be too indirect; in other words, although the raw code seems more complicated, in the end it sounds to me like trying to incorporate a fixed timestep directly would be a lot simpler than trying to force Slick's internals to make a fixed timestep out of a variable timestep.

EDIT EDIT: Ah, this looks sort of promising:

Quote

Somehow I get the impression that setting both the min and the max to what I want (and thus achieving fixed timesteps?) will be a little less robust than directly doing it myself, but that remains to be seen. Also, I wonder if those functions only take integers...? An update rate of 60 updates per second corresponds to an interval of not exactly 16, nor exactly 17, right... I guess I'll still have to try similar things with LWJGL, but without Slick.

Offline thaaks
« Reply #95 - Posted 2011-11-02 09:18:05 »

Saucer, I even wrote a tutorial (!) about a gameloop using fixed timesteps for updates and required tweening for rendering.
Unfortunately it's for BlitzMax but of course the principle works the same regardless of the programming language (and BlitzMax has most OO features you'd require).

The tutorial can be found here: http://www.rightanglegames.com/topdownshootertu/index.html. The game loop is based on stuff you'll find at Gaffer's blog.

The code can easily be converted to Java and Slick. I would suggest you create your own AppGameContainer subclass where you implement your own game loop using the mechanisms above.
I guess this would be the cleanest way to introduce a different update/render behavior into Slick.

Hope that helps,
Tommy

Offline Saucer

Junior Duke


Medals: 1



« Reply #96 - Posted 2011-11-02 20:45:27 »

Saucer, I even wrote a tutorial (!) about a gameloop using fixed timesteps for updates and required tweening for rendering.
Unfortunately it's for BlitzMax but of course the principle works the same regardless of the programming language (and BlitzMax has most OO features you'd require).

The tutorial can be found here: http://www.rightanglegames.com/topdownshootertu/index.html. The game loop is based on stuff you'll find at Gaffer's blog.

The code can easily be converted to Java and Slick. I would suggest you create your own AppGameContainer subclass where you implement your own game loop using the mechanisms above.
I guess this would be the cleanest way to introduce a different update/render behavior into Slick.

Hope that helps,
Tommy

Ah, my apologies. Thank you for the tutorial! If I remember correctly I've seen this tutorial before, but I didn't look too closely at it because it was for BlitzMax. If I find an opportunity, I'll see if I'll be able to convert it to Java successfully, and report back with results!

Offline Saucer

Junior Duke


Medals: 1



« Reply #97 - Posted 2011-11-06 05:34:16 »

Hello everyone, it's been a while!

So currently I know of at least 10 different versions of the fixed timestep loop--- all from various sources, some of those sources being examples of code that people have submitted here--- so I prepared three different versions of the LWJGL example Cero posted, each of which incorporates one of the different fixed timestep code examples.

I've bundled together those examples in a single download, along with some other example programs (like a similar Game Maker example) and the source for all the different examples. You can download it here: box.com download

Note: example_simple.jar and example_variabletimestep.jar are examples without fixed timesteps; they're there for comparison.

There are various settings you can toggle within the JARs, like vsync and the usage of Thread.yield and Thread.sleep. More details are contained in the included readme file.

Here's what I discovered:

-With certain settings, the stuttering can be improved pretty well on all tested computers (at least one school computer, our desktop, and my laptop).

-Rendering as fast as possible seems to yield fairly smooth graphics, but it seems that our desktop and my laptop have difficulty with that kind of rendering (I can't tell if it's difficult for the computers at my school).

-I finally saw that LWJGL's vsync actually does have an effect, and yields some of the smoothest rendering I've seen yet! (That is, with Java.) ...However, although this smooth rendering was achieved on a computer at school, it doesn't seem to work on our desktop or my laptop. In fact the API documentation for LWJGL says:

Quote
[About Display.setVSyncEnabled:] This call is a best-attempt at changing the vertical refresh synchronization of the monitor, and is not guaranteed to be successful.

That being said, I think at least one particular setting on one example may yield suitably smooth rendering all around: example_delventhal.zip without Display.sync, with yield and sleep, and without frequent yield and sleep. It still stutters with those settings, but, if I'm not mistaken, it only stutters a little more than does the Game Maker example.

Admittedly, I don't know how this setting fares on a computer on which vsync works; it may have to be turned off on such computers. But then again, on such a computer, vsync might yield smooth rendering on its own.

EDIT: I guess it's also possible that the smooth rendering that seemed to be achieved with vsync on the computers at my school could only have been achieved with the speed of those computers (they seem pretty fast).

Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #98 - Posted 2011-11-06 22:35:12 »

Just another thing worth mentioning: not all monitors run at 60Hz - some will be 72hz or 75hz etc. This will screw your timing unless you change the display mode to 60Hz.

Cas Smiley

Offline Saucer

Junior Duke


Medals: 1



« Reply #99 - Posted 2011-11-06 23:23:17 »

Just another thing worth mentioning: not all monitors run at 60Hz - some will be 72hz or 75hz etc. This will screw your timing unless you change the display mode to 60Hz.

Cas Smiley

Ooh, good point. I think I do know of a way to get the default refresh rate, though; I wonder if that will be enough to accommodate this issue. Also, I found something you posted at lwjgl.org in 2010, Cas; it's contained in the following forum thread:

EDIT: That's strange, for some reason I can't get the link to work... The title of the thread is "Timer Comparison."

Would it be alright if I made a new example (as in, add another new member to my examples download) based (heavily) on your method?

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #100 - Posted 2011-11-07 09:12:32 »

Link worked from me in the email sent by JGO on my Android phone Smiley Yeah that's the loop all my games use now. Uses double floating point precision to calculate how many frames it should have ticked at by a given time, resets every now and again for sanity, and vsync takes care of fullscreen timing nicely but otherwise it seems to render nicely enough in windowed mode. I don't care much about windowed mode though. Proper games run fullscreen for that immersive experience Smiley

Cas Smiley

Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #101 - Posted 2011-11-07 09:16:42 »

Oh yeah and go ahead, all my code is public for a reason.

Cas Smiley

Offline Saucer

Junior Duke


Medals: 1



« Reply #102 - Posted 2011-11-08 00:19:06 »

Oh yeah and go ahead, all my code is public for a reason.

Cas Smiley

Thank you!!!

That being said, I think at least one particular setting on one example may yield suitably smooth rendering all around: example_delventhal.zip without Display.sync, with yield and sleep, and without frequent yield and sleep. It still stutters with those settings, but, if I'm not mistaken, it only stutters a little more than does the Game Maker example.

Looks like I spoke too soon:

I had already known that, sometimes, our desktop (which usually yields the most visible stuttering) runs the Java programs I've been testing pretty well for some reason; but only for a while, and in a currently unpredictable manner. Even the Java2D builds run smoothly in this situation! It seems that this had been the case when I was testing my LWJGL examples earlier, because yesterday they seemed to yield lots of stuttering... Looks like I might try to give Cas's method a go!

EDIT:

Quote
Admittedly, I don't know how this setting fares on a computer on which vsync works; it may have to be turned off on such computers. But then again, on such a computer, vsync might yield smooth rendering on its own.

Looks like the program runs just fine under these particular settings, at least as far as I can tell.

By the way: currently, the only way I know how to test if vsync has an effect is to turn off Display.sync (and frequent yielding and sleeping) and see if toggling vsync does anything. On my school's computers the FPS drops from several hundred (without vsync) to 60 (with vsync), whereas on our desktop and my laptop the FPS seems to stay at several hundred regardless of the state of vsync reported by the program.

Also, I'm still not really sure about the following point:

Quote
I guess it's also possible that the smooth rendering that seemed to be achieved with vsync on the computers at my school could only have been achieved with the speed of those computers (they seem pretty fast).

In other words, I don't know if my programs might still yield stuttering on other computers for which vsync has an effect; it could just be that, as usual, the main reason my programs run smoothly on my school's computers is that they're fast (or more powerful in some other fashion).

Offline Saucer

Junior Duke


Medals: 1



« Reply #103 - Posted 2011-11-11 09:17:42 »

Added three new examples based on code by Cas, Notch and Tommy: box.com download (Note: haven't tested these much yet)

Still haven't made it so the programs detect the refresh rate of the display.

A question for Cas, if it's alright to ask: In your code, how does the following code work? How is it different from calling just Sys.getTime?

1  
Sys.getTime() & 0x7FFFFFFFFFFFFFFFL

Offline philfrei
« Reply #104 - Posted 2011-11-11 10:08:40 »

Sys.getTime() & 0x7FFFFFFFFFFFFFFFL

The L indicates the value is a long integer (64 bits).
The bit-and operation sets the sign bit to zero, assuming that the long is signed. Thus the getTime value is guaranteed to be positive. Maybe you knew that and the question is why it would be necessary to reset the sign bit?

"It's after the end of the world! Don't you know that yet?"
Offline Saucer

Junior Duke


Medals: 1



« Reply #105 - Posted 2011-11-11 10:30:55 »

Sys.getTime() & 0x7FFFFFFFFFFFFFFFL

The L indicates the value is a long integer (64 bits).
The bit-and operation sets the sign bit to zero, assuming that the long is signed. Thus the getTime value is guaranteed to be positive. Maybe you knew that and the question is why it would be necessary to reset the sign bit?


No, I didn't know that; thank you for the explanation. Again, I'm kind of a novice... Please bear with me!

So is it basically a faster way of doing abs(x), or something along those lines?

Offline Chromanoid

Junior Duke


Medals: 3



« Reply #106 - Posted 2011-11-11 10:47:50 »

The GM Example is smooth, the rest is not Sad It really bugs me. In december I hopefully have the time to work on my perfect smooth loop for java Cheesy Thank you for putting everything together!
Offline sproingie

JGO Kernel


Medals: 202



« Reply #107 - Posted 2011-11-11 17:52:20 »

The mask causes the time to wrap around and restart at 0 instead of Long.MIN_VALUE.  This is important if you want to be able to generate consistent non-negative timestamps at some point after the heat death of the universe.
Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #108 - Posted 2011-11-11 18:41:57 »

That would depend on the resolution of Sys.getTime() and what number it starts at of course.

Cas Smiley

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 816
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #109 - Posted 2011-11-11 19:14:34 »

There are 292 years in 2^63 nanos. Your point about the start value is correct, but I doubt any CPU ever created has ever had its counter high-bit set.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #110 - Posted 2011-11-11 19:17:24 »

That's what I thought until exactly this somehow happened on my Galaxy S 2.

Cas Smiley

Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #111 - Posted 2011-11-11 21:46:40 »

O_______O

Offline Saucer

Junior Duke


Medals: 1



« Reply #112 - Posted 2011-11-11 21:48:02 »

Wait, I thought the wrapping was achieved later in the code by something like:

1  
if (now < then) { }


O_______O

...Yes?

More observations (although... note that most if not all of my observations throughout both the TIGForums thread and this thread are basically subjective...):

Recently I seem to have observed that the GM example actually stutters more than I had thought. I think it's usually better than the Java examples and all around GM's the most consistent, but currently I suspect that:

-When GM stutters it can be more noticeable than some Java implementations? Especially on (only on?) those computers on which LWJGL's vsync can take effect.

-GM usually tends to run smoothly for longer periods of time than the Java examples, but not? on those computers for which the Java examples don't stutter (i.e. my school's computers). Furthermore, on those computers GM seems to alternate between no stuttering and stuttering more frequently than the Java examples.

Also, another issue: While the simple GM example stutters on those school computers, I had difficulty detecting any stuttering (there was some stuttering, but very little of it) with the demo for a game of mine, Platform Battle 2. In fact I think this might also have been the case during some trials on our desktop (although Java stutters on it). This may have something to do with the implementation:

-With the simple example, nothing is scaled and the box is moved at 2 pixels, whereas, in PB2, although the object I observed (a moving platform in the tutorial) still moves at 2 pixels, the graphics are scaled to two times its "actual" size by a method by ChevyRay.

-PB2 uses a sprite for the platform and has a patterned background. (I do, however, think that I looked pretty closely...)

Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #113 - Posted 2011-11-11 22:20:19 »

Install FRAPS demo and report the FPS.

Cas Smiley

Offline Saucer

Junior Duke


Medals: 1



« Reply #114 - Posted 2011-11-19 20:36:09 »

Install FRAPS demo and report the FPS.

Cas Smiley

Wait, isn't the FPS reported by the program enough?

---

I updated the box.com download with a new example. If I understand correctly, it's a sort of hybrid between Cas's example and Eli Delventhal's. I'm not sure if it's any smoother than any of the other Java examples, but there's at least one new thing being done here.

I noticed that Cas's example can loop many times without CPU problems. I think this means that, even if one of these example programs loops many times, the CPU only starts groaning if it also renders very fast (although it seems that the CPU still starts groaning if the looping is too fast). I tried looping like this in the hybrid example because it seems to me that, since the program checks the time more often, the timing would be more precise.

Also, I incorporated Eli Delventhal's timing method but applied it not only to logic updates but also to the rendering, which amounts, if I understand correctly and if I'm using the right terms, to making logic and rendering almost completely independent of each other in a sense. Put another way, they're each sort of on their own schedule.

Again, I can't really tell if all this allows the program to run any better than any of the other examples, but there it is anyway.

Here's some of the relevant code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
public void start() {
      try {
         Display.setDisplayMode(new DisplayMode(800, 600));
         Display.create();
      } catch (LWJGLException e) {
         e.printStackTrace();
         System.exit(0);
      }
     
      initGL(); // init OpenGL
     
      vsync = false;
      dsync = false;
      wait = true;
      drawInterpolated = true;
     
      timerResolution = 1000000000;
      updateRate = 60;
      renderRate = GraphicsEnvironment.getLocalGraphicsEnvironment()
            .getDefaultScreenDevice()
            .getDisplayMode().getRefreshRate();
      if (renderRate == java.awt.DisplayMode.REFRESH_RATE_UNKNOWN) renderRate = 60;
     
      double updateInterval = timerResolution / (double) updateRate;
      double renderInterval = timerResolution / (double) renderRate;
      double lastFPSTime = System.nanoTime();
      double lastUpdateTime = lastFPSTime;
      double lastRenderTime = lastFPSTime;
      int updateCount = 0;
      int renderCount = 0;
      int loopCount = 0;
      updatesPerSecond = 0;
      rendersPerSecond = 0;
      loopsPerSecond = 0;
      maxUpdates = 5;
     
      Display.setVSyncEnabled(vsync);
     
      while (!Display.isCloseRequested()) {
         double now = System.nanoTime();
         int localUpdateCount = 0;
         while (now - lastUpdateTime > updateInterval && localUpdateCount < maxUpdates) {
            update();
            lastUpdateTime += updateInterval;
            localUpdateCount++;
            updateCount++;
         }
         if (now - lastUpdateTime > updateInterval) {
            lastUpdateTime = now - updateInterval;
         }
         now = System.nanoTime();
         if (now - lastFPSTime > timerResolution) {
            lastFPSTime = now;
            //lastFPSTime += timerResolution;
            updatesPerSecond = updateCount;
            rendersPerSecond = renderCount;
            loopsPerSecond = loopCount;
            updateCount = 0;
            renderCount = 0;
            loopCount = 0;
            Display.setTitle(updatesPerSecond
                  + ", " + rendersPerSecond
                  + ", " + loopsPerSecond
                  + "; VSync: "+ vsync
                  + "; Display.sync(): " + dsync
                  + "; Interpolated drawing: " + drawInterpolated
                  + "; Yield and sleep: " + wait);
         }
         interpolation = (float) ((now - lastUpdateTime) / updateInterval);
         now = System.nanoTime();
         if (now - lastRenderTime > renderInterval) {
            renderGL();
            Display.update();
            //lastRenderTime = now;
            lastRenderTime += renderInterval;
            renderCount++;
         }
         while (now - lastRenderTime > renderInterval) {
            lastRenderTime += renderInterval;
         }
         loopCount++;
         if (dsync) {
            Display.sync(60); // cap fps to 60fps
         } else if (wait) {
            Thread.yield();
            try {
               Thread.sleep(1);
            } catch (Exception e) {}
         }
      }
     
      Display.destroy();
   }

Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #115 - Posted 2011-11-20 09:45:02 »

FRAPS tells it like it is Smiley

Cas Smiley

Offline Saucer

Junior Duke


Medals: 1



« Reply #116 - Posted 2011-11-21 22:15:23 »

FRAPS tells it like it is Smiley

Cas Smiley

Well, I think I'll have to look into it more to be able to use it?

---

Two things:

a) You know, I think I'm just going to incorporate the "extra sleeping thread" fix; with it, at least three of the Java examples seem to work just fine, as far as I can tell so far. The Java examples still stutter on my laptop, but so does the Game Maker example. Note: the download has not yet been updated.

I still feel that this solution is a bit inelegant, though. The extra thread forces the program to use a more precise (?) timer, right? Does that mean that functions like System.nanoTime() become more precise, that Thread.sleep becomes more precise, or both? I'd like to think that it's Thread.sleep; it would be nice to know that the timing, at least, is always reliable.

Does anyone know why the reliability of Thread.sleep would be so conditional (?)? Will they ever make it so Thread.sleep always behaves as it does with this solution?

b) Before incorporating that solution, though, something strange happened on my laptop: it started acting like our desktop for a moment! That is, the Game Maker example seemed to run more smoothly than usual, and some if not most of the Java examples were less smooth than usual and couldn't maintain 60 FPS. The programs started to behave as normal after I restarted the computer; this sometimes works on my desktop. Thus, it seems to me that there are (at least) two common computer settings, one in which Game Maker and Java behave similarly, and one in which Game Maker gets less stuttering than usual but in which Java gets more. What could be the cause of this?

Offline Cero
« Reply #117 - Posted 2012-01-18 03:30:23 »

btw really appreciate your work here Saucer.
My game still jitters when there not much going on.

And the "DelventhalExample" looks the best to me. Gotta try that. Nice package

Offline Saucer

Junior Duke


Medals: 1



« Reply #118 - Posted 2012-01-18 23:13:47 »

Thanks for the input, Cero! It's been a while since I've visited this topic, ha ha.

Have you tried the "extra sleeping thread" method? It seems that the fix:

- has no effect on computers that yield little stuttering anyway,
- reduces most stuttering on the computer I tested that yielded the most stuttering, and
- has no effect on my laptop, on which the GM test program and my programs all stutter.

Note that I haven't updated the downloads with this fix.

By the way, although I had known about that fix from when this thread was started, it seemed too inelegant. Eventually, I decided to incorporate it into my programs.

Offline Cero
« Reply #119 - Posted 2012-01-25 16:30:22 »

Have you tried the "extra sleeping thread" method?

as yes you mean this

1  
2  
3  
4  
new Thread() { 
{ setDaemon(true); start(); }
@Override public void run() { while(true) {try {Thread.sleep(Integer.MAX_VALUE);}catch(Throwable t){} } }
};


sure, I use this.

Also I have to add. the stutter, in general, seems to happen more often when there is not a much going on.
For example in m game, when I'm just walking and there is nothing fancy going on, its more likely to happen than when there is more going on.
This would also explain why my simple cube example is so very vulnerable to this, and seems to stutter somewhat in all game loop examples
So my guess is that, why a game would run at a very high FPS normally, like > 600 or something, slowing it down to 60 can cause stutters way more likely than slowing it down form like 200 fps or 100 fps to 60.

so I guess this is the bottom line: The higher your fps WOULD BE, the more the slowing down has to be done, the higher the chance of stuttering is.
This doesn't seems to apply for fullscreen Vsynced.

Pages: 1 2 3 [4] 5
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (37 views)
2014-10-17 03:59:02

Norakomi (28 views)
2014-10-16 15:22:06

Norakomi (24 views)
2014-10-16 15:20:20

lcass (27 views)
2014-10-15 16:18:58

TehJavaDev (52 views)
2014-10-14 00:39:48

TehJavaDev (54 views)
2014-10-14 00:35:47

TehJavaDev (42 views)
2014-10-14 00:32:37

BurntPizza (64 views)
2014-10-11 23:24:42

BurntPizza (36 views)
2014-10-11 23:10:45

BurntPizza (77 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!