Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (748)
Games in Android Showcase (226)
games submitted by our members
Games in WIP (834)
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  
  Java2D game loop stuttering  (Read 351 times)
0 Members and 1 Guest are viewing this topic.
Offline mooneko

Innocent Bystander





« Posted 2018-02-09 19:15:23 »

Hey. I am currently developing a 2D Java game using Swing components.
The game randomly stutters. Sometimes it runs completely smooth for the first minute and then it randomly jitters like mad, sometimes it starts of as a jittery mess.
Iv'e tried to omit certain parts of my code, thinking that they cause the lag, and now I am 100% sure that the problem lies within the way my game loop is written. Here it is:

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  
package map;

public class GameLoop implements Runnable
{
   private Thread _gameThread;
   private MapPanel _gamePanel;
   private final double _updateCap = 1.0 / 60.0;
   private int _fps;
   
   public GameLoop(MapPanel panel)
   {
      this._gamePanel = panel;
   }
   
   public void startGame()
   {
      this._gameThread = new Thread(this);
      this._gameThread.start();
   }
   
   @Override
   public void run()
   {
      double firstTime = 0,
            lastTime = System.nanoTime() / 1000000000.0,
            passedTime = 0,
            unprocessedTime = 0,
            frameTime = 0;
      int frames = 0;
     
      while (this._gamePanel.isRunning())
      {
         firstTime = System.nanoTime() / 1000000000.0;
         passedTime = firstTime - lastTime;
         lastTime = firstTime;
         unprocessedTime += passedTime;
         frameTime += passedTime;
         
         while (unprocessedTime >= _updateCap)
         {
            unprocessedTime -= _updateCap;
            this.tick();
           
            if (frameTime >= 1.0)
            {
               frameTime = 0;
               _fps = frames;
               frames = 0;
               System.out.println("FPS: " + _fps);
            }
         }
         
         render();
         frames++;
         
         /**
          * Preventing over-consumption of the CPU -
          */

         try
         {
            Thread.sleep(1);
         }
         catch (InterruptedException e)
         {
            // TODO Auto-generated catch block
            e.printStackTrace();
         }
      }
   }
   
   private void render()
   {
      _gamePanel.repaint();
   }
   
   private void tick()
   {
      _gamePanel.setLogic();
   }
}


When am I doing wrong? What alternatives can you recommend if I want a game loop that can ensure a relatively smooth gameplay without dealing with anything that is way too advanced?
Thanks alot!
Offline KevinWorkman

« JGO Plugged Duke »


Medals: 278
Projects: 12
Exp: 12 years


HappyCoding.io - Coding Tutorials!


« Reply #1 - Posted 2018-02-10 19:12:29 »

You'll have better luck if you post a MCVE that demonstrates the problem.

One thing that sticks out to me is that it looks like you're updating your game state on a different thread than the one that's drawing your game.

Quote
What alternatives can you recommend if I want a game loop that can ensure a relatively smooth gameplay without dealing with anything that is way too advanced?

Use a library. I really like Processing.

HappyCoding.io - Coding Tutorials!
Happy Coding forum - Come say hello!
Offline philfrei
« Reply #2 - Posted 2018-02-11 02:38:12 »

The way the code is written we could have either of the following two scenarios (depending upon the values of unprocessedTime and _updateCap):

  • multiple tick() calls without intervening render() calls
  • multiple render() calls without intervening tick() calls

Could this cause the stuttering? Seems like that would be the likely result if the two need to alternate in order to preserve continuity.

I'd try moving timing stuff to after the update and render. They should just be run directly in sequence unless there is a good reason not to.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
      while (this._gamePanel.isRunning())
      {
           tick();
           render();

           timeDiff = Systerm.currentTimeMillis() - beforeTime;
           sleepTime = PERIOD - timeDiff;   // I would imagine  PERIOD = 16 for just slightly better than 60fps?
           sleepTime = Math.max(sleepTime, 1); // even if lagging, sleep a little
           Thread.sleep(sleepTime);  // will need to be in try/catch or add exception handling
           beforeTime = system.currentTimeMillis();
      }

This code is slightly modified from "Killer Game Programming".

I happen to think using a util.Timer or an ExecutorService (even better is the AnimationTimer provided in JavaFX) is the best way to go in terms of setting a steady FPS for a "game loop" rather than manually handling sleep times. But a lot of people will disagree, and there is no need to argue about it. Just do what works.

music and music apps: http://adonax.com
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline DesertCoockie
« Reply #3 - Posted 2018-02-18 11:10:53 »

Using repaint often leaves games using Swing stuttering. The way I've fixed is to draw everything to a BufferedImage and then drawing that image to the screen.
Pages: [1]
  ignore  |  Print  
 
 

 
xxMrPHDxx (331 views)
2017-12-31 17:17:51

xxMrPHDxx (107 views)
2017-12-31 17:15:51

xxMrPHDxx (157 views)
2017-12-28 18:11:33

Ecumene (339 views)
2017-09-30 02:57:34

theagentd (503 views)
2017-09-26 18:23:31

cybrmynd (542 views)
2017-08-02 12:28:51

cybrmynd (484 views)
2017-08-02 12:19:43

cybrmynd (459 views)
2017-08-02 12:18:09

Sralse (421 views)
2017-07-25 17:13:48

Archive (1343 views)
2017-04-27 17:45:51
Java Gaming Resources
by philfrei
2017-12-05 19:38:37

Java Gaming Resources
by philfrei
2017-12-05 19:37:39

Java Gaming Resources
by philfrei
2017-12-05 19:36:10

Java Gaming Resources
by philfrei
2017-12-05 19:33:10

List of Learning Resources
by elect
2017-03-13 14:05:44

List of Learning Resources
by elect
2017-03-13 14:04:45

SF/X Libraries
by philfrei
2017-03-02 08:45:19

SF/X Libraries
by philfrei
2017-03-02 08:44:05
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!