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]
  ignore  |  Print  
  [SOLVED] Issue with smooth game loop  (Read 2075 times)
0 Members and 1 Guest are viewing this topic.
Offline StonePickaxes

JGO Coder


Medals: 4
Projects: 2


Nathan Kramber


« Posted 2013-11-26 02:47:51 »

EDIT: Problem solved! Thanks so much to theagentd for helping me!

It's been a while!

I've been dealing with a minor issue for a few days. I'd been having issues with consistency in screen scrolling and small screen tears, so I rewrote my game loop based on examples from ra4king and Eli. I'm still seeing small issues, though, and was wondering if I could have a few more pairs of eyes check it out.

Here's a jar edit: updated to current version
Here's the full source on BitBucket

Here's the most relevant source

Game loop

----------

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  
@Override
   public void run() {
      createBufferStrategy(2);
      BufferStrategy bs = getBufferStrategy();

      init();

      while (running) {
         final double GAME_HERTZ = 60.0;
         final double TIME_BETWEEN_UPDATES = 1000000000 / GAME_HERTZ;
         final int MAX_UPDATES_BEFORE_RENDER = 1;
         double lastUpdateTime = System.nanoTime();
         double lastRenderTime = System.nanoTime();

         final double TARGET_FPS = 60;
         final double TARGET_TIME_BETWEEN_RENDERS = 1000000000 / TARGET_FPS;

         while (running) {
            double now = System.nanoTime();
            int updateCount = 0;

            if (!paused) {
               while (now - lastUpdateTime > TIME_BETWEEN_UPDATES && updateCount < MAX_UPDATES_BEFORE_RENDER) {
                  tick();
                  lastUpdateTime += TIME_BETWEEN_UPDATES;
                  updateCount++;
               }

               render(bs);
               lastRenderTime = now;
               
               while (now - lastRenderTime < TARGET_TIME_BETWEEN_RENDERS && now - lastUpdateTime < TIME_BETWEEN_UPDATES) {
                  Thread.yield();
                  now = System.nanoTime();
               }
            }
         }
      }

      System.exit(0);
   }


----------

Render function

----------

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
private void render(BufferStrategy bs) {
      do {
         do {
            Graphics g = image.getGraphics();
            g.clearRect(0, 0, WIDTH, HEIGHT);

            game.draw(screen);

            g = bs.getDrawGraphics();
            g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
            g.dispose();

         } while (bs.contentsRestored());

         bs.show();

      } while (bs.contentsLost());
   }

edit: added code tags

----------

Thanks for taking the time to help me!

Nathan

Check out my website!
Offline opiop65

JGO Kernel


Medals: 156
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #1 - Posted 2013-11-26 02:51:13 »

I'm not seeing any issues, but the screen isn't scrolling at all, so I have no idea where you would see tears! That, and your little guy doesn't actually move smoothly, so I don't know where you would see any graphical issues. Maybe you can state specifically what the issue is? Sorry!

Offline StonePickaxes

JGO Coder


Medals: 4
Projects: 2


Nathan Kramber


« Reply #2 - Posted 2013-11-26 02:52:48 »

Sorry! I just updated the download to the most current version - that one was a few days old.

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

JGO Kernel


Medals: 156
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #3 - Posted 2013-11-26 02:56:12 »

Oh, that's alright!

Well, I tested out the new version and again saw nothing wrong with it, maybe try running it outside of the IDE if you haven't yet? The only think I noticed is that the player sort of floats to a stop after I release the keys, I think it might be intentional though because it happened consistently. But other than that, nope no screen tearing! Smiley

Offline StonePickaxes

JGO Coder


Medals: 4
Projects: 2


Nathan Kramber


« Reply #4 - Posted 2013-11-26 02:57:33 »

Yeah, it's on a tile based movement system.

Hm. Maybe it'll happen if someone else tries? It very well could be a hardware related occurrence.

Thanks for your time though!

Check out my website!
Offline opiop65

JGO Kernel


Medals: 156
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #5 - Posted 2013-11-26 02:59:50 »

No problem! What CPU do you have? Seeing as you're using Java2D, which isn't hardware accelerated, I would guess that maybe you don't have an amazing CPU? But that's just a guess Tongue

Offline StonePickaxes

JGO Coder


Medals: 4
Projects: 2


Nathan Kramber


« Reply #6 - Posted 2013-11-26 03:00:58 »

Couldn't be the cpu - I have a 1.3ghz i5 Haswell; IE the new Macbook air, and I'm running dual-boot with Windows 7, which is what I'm programming in.

I'm not emulating Windows so I doubt it's related to the Macbook hardware.

Check out my website!
Offline opiop65

JGO Kernel


Medals: 156
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #7 - Posted 2013-11-26 03:03:58 »

No offense, but they make a 1.3 GHz i5? Wow, I never knew, I always thought the i- series was high end strictly. To be honest with you, that's not the best CPU out there, but I doubt it couldn't handle a simple Java2D program. So I guess that's not the issue!

Offline StonePickaxes

JGO Coder


Medals: 4
Projects: 2


Nathan Kramber


« Reply #8 - Posted 2013-11-26 03:06:18 »

You're mistaken, but no worries.

This processor can actually run League at 60fps on medium settings, WoW at 100fps on medium settings, Minecraft on 60 on normal render distance, etc. The low clock speed is to conserve battery life (it's unreal. 12 hours). In short, I'm positive it isn't my processor. Smiley

Check out my website!
Offline opiop65

JGO Kernel


Medals: 156
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #9 - Posted 2013-11-26 03:08:37 »

Ah, I see. Its just strange, I've never heard of a processor with that low of a clock speed in a multi-thousand dollar laptop, its just different to me!

Well, I'm just spamming the thread now with my naivness, so I'll stop and hopefully someone else could have a look! Because I quite honestly have no idea as it runs fine on my desktop!

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online theagentd
« Reply #10 - Posted 2013-11-26 03:12:54 »

Tearing is solved by V-sync, which you have no direct control over when using Java2D. Make sure you haven't forced it off in your drivers and it should be on by default.

I would not recommend a busy loop around Thread.yeild(). Try removing at and see if it's any smoother.

Are you doing anything that depends on a delta time value for example? If you're not moving your objects evenly, they won't appear smooth.

Off-topic:
This processor can actually run League at 60fps on medium settings...
Running League maxed at 5120x2880 (a bit over 4K) at 200-300 FPS. Desktops are OP...

Myomyomyo.
Offline StonePickaxes

JGO Coder


Medals: 4
Projects: 2


Nathan Kramber


« Reply #11 - Posted 2013-11-26 03:20:43 »

I agree, desktops are the best Cheesy I've got a pretty decent rig myself, but I got this for the portability/battery life almost exclusively.

I would not recommend a busy loop around Thread.yeild(). Try removing at and see if it's any smoother.

WOW. This fixed it immediately! See here!

Thanks so much friend!

Check out my website!
Online theagentd
« Reply #12 - Posted 2013-11-26 03:27:40 »

It was just a wild guess... Could've been that System.nanoTime() didn't have very good accuracy or something.

Myomyomyo.
Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #13 - Posted 2013-11-26 03:41:28 »

The best way to sleep for a smooth game loop is this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
long sleepTime = .... // in nanoseconds

long t = System.nanoTime(), diff;
while((diff = System.nanoTime() - t) < sleepTime) {
    if(diff < sleepTime * 0.8)
        Thread.sleep(1);
    else
        Thread.yield();
}


This came from my earlier post about game loops, which contains more in-depth explanation and code.

Offline opiop65

JGO Kernel


Medals: 156
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #14 - Posted 2013-11-26 03:44:35 »

I've always been told using Thread.sleep is bad for games because different computers have slightly different clock speeds, and therefore some computers will sleep for longer while others will sleep for less. I don't think its a huge issue because it shouldn't be that big of a difference, but is it an issue?

Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #15 - Posted 2013-11-26 03:50:04 »

Not for Linux and OS X, but it is a problem on Windows, since by default a lower-resolution timer is used for Thread.sleep. The fix for this is shown in the link to the earlier post of mine, by putting this code at the first line in your main method:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
if(System.getProperty("os.name").startsWith("Win")) {
   new Thread() {
      {
         setDaemon(true);
         start();
      }
     
      public void run() {
         while(true) {
            try {
               Thread.sleep(Long.MAX_VALUE);
            }
            catch(Exception exc) {}
         }
      }
   };
}


This forces the use of the high resolution timer under Windows.

Offline Kyperbelt

Junior Duke


Medals: 1



« Reply #16 - Posted 2013-11-26 03:53:41 »

i ran your fixed jar and it looks like you did away with the syncing all together.

this is the sync method i use and it works out really good  Smiley you can fit it into your code by simply calling sync(60); each loop cycle
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
   public void sync(int sync) {
         if (sync!=-1) {
            long diff = 1000000000L / sync + lastFrame;
            long now = System.nanoTime();
           
            try {
               while (diff > now) {
                  Thread.sleep((diff-now) / 2000000L);
                  now = System.nanoTime();
               }
            } catch (Exception e) {}

            lastFrame = now;
         }
    }

edit: also lastFrame is a long outside of the method initialized when you start your loop as lastFrame = System.nanoTime();
Pages: [1]
  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 (41 views)
2014-10-17 03:59:02

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

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

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

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

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

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

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

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

BurntPizza (80 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!