Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (803)
Games in Android Showcase (237)
games submitted by our members
Games in WIP (867)
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  
  Game loop and capping fps  (Read 11088 times)
0 Members and 1 Guest are viewing this topic.
Offline pelep

Senior Newbie





« Posted 2015-06-17 09:27:58 »

Hi, I currently have a game loop that has a fixed fps because the updates and the rendering are coupled together. I plan on separating the updates and rendering by changing the current loop into something like the following:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
private void runGameLoop()
{
    long nextUpdate = System.nanoTime();

    while (isRunning)
    {
        int skipped = 0;

        while (System.nanoTime() > nextUpdate && skipped++ < MAX_FRAME_SKIPS)
        {
            updateState();
            nextUpdate += UPDATE_INTERVAL;
        }

        float offset = (float)(UPDATE_INTERVAL - (nextUpdate - System.nanoTime())) / UPDATE_INTERVAL;
        updateDisplay(offset);
    }
}


My problem with that method is it renders as many frames as possible. I want to be able to control the fps and cap it when I want to, so I'm thinking of changing it further to this:

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  
private void runGameLoop()
{
    long nextStateUpdate = System.nanoTime();
    long nextFrameUpdate = System.nanoTime();

    while (isRunning)
    {
        int skipped = 0;
        long currentTime = System.nanoTime();

        while (currentTime > nextStateUpdate && skipped++ < MAX_FRAME_SKIPS)
        {
            updateState();
            nextStateUpdate += STATE_UPDATE_INTERVAL;
        }

        currentTime = System.nanoTime();

        if (currentTime > nextFrameUpdate)
        {
            float offset = (float)(frameUpdateInterval - (nextFrameUpdate - currentTime)) / frameUpdateInterval;
            updateDisplay(offset);
            nextFrameUpdate += frameUpdateInterval; // i'll be able to control the fps on the fly by changing frameUpdateInterval
        }
    }
}


I like that I'll be able to control the fps, but the game would constantly be running the loop even when there's nothing to do. Plus, I feel like I'm overlooking something. My main question is are there better ways to do this? Also, is there a better term for the float (offset) passed in updateDisplay?
Offline PocketCrafter7

Senior Devvie


Medals: 6
Projects: 2
Exp: 2 years


One man's bug is another man's feature


« Reply #1 - Posted 2015-06-17 15:35:59 »

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  
public void run() {
      requestFocus();
      long lastTime = System.nanoTime();
      final double ns = 1000000000.0 / 60.0;
      double delta = 0;
      long timer = System.currentTimeMillis();
      int frames = 0;
      int updates = 0;
      while (running) {
         long now = System.nanoTime();
         delta += (now - lastTime) / ns;
         lastTime = now;
         while (delta >= 1) {
            update();
            delta--;
            updates++;
            render();
            frames++;
         }
         if (System.currentTimeMillis() - timer > 1000) {
            timer += 1000;
            frame.setTitle(title + " | " + updates + " ups, " + frames + " fps");
            updates = 0;
            frames = 0;
         }
      }
   }


This will update and render the game at a rate of 60 times per second, you can easily change it according to your needs.

Nothing is difficult in this world. It is just how you look at it.
Offline pelep

Senior Newbie





« Reply #2 - Posted 2015-06-17 19:36:19 »

Sorry if I wasn't clear enough in my original post. As I said, my current loop does the updates and rendering together, but that's why I'm changing it. I want a fixed timestep with variable rendering. I can't use the code you posted since it pretty much still has a fixed rendering interval and it's done with the game updates. I edited my original post to make it clearer. Thanks though!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline PocketCrafter7

Senior Devvie


Medals: 6
Projects: 2
Exp: 2 years


One man's bug is another man's feature


« Reply #3 - Posted 2015-06-18 05:39:01 »

Your question is still not clear, you're contradicting yourself.
Quote
Hi, I currently have a game loop that has a fixed fps

Quote
My problem with this is it renders as many frames as possible.

Anyways, whether you want fixed or not, you can do it with this code, see the comments.
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  
public void run() {
      requestFocus();
      long lastTime = System.nanoTime();
      final double ns = 1000000000.0 / 60.0;              // Here you can change the rate
      double delta = 0;
      long timer = System.currentTimeMillis();
      int frames = 0;
      int updates = 0;
      while (running) {
         long now = System.nanoTime();
         delta += (now - lastTime) / ns;
         lastTime = now;
         while (delta >= 1) {
            update();
            delta--;
            updates++;                // Anything put inside this while loop will be executed 60 times per second
         }
         render();                      // By having the render() method outside of this while loop, it renders as many times it can
         frames++;
         
         if (System.currentTimeMillis() - timer > 1000) {
            timer += 1000;
            frame.setTitle(title + " | " + updates + " ups, " + frames + " fps");
            updates = 0;
            frames = 0;
         }
      }
   }

Nothing is difficult in this world. It is just how you look at it.
Offline pelep

Senior Newbie





« Reply #4 - Posted 2015-06-18 06:41:36 »

Your question is still not clear

I believe I made it quite clear already.

you're contradicting yourself.

changing the current loop to separate the updates and rendering. Something like the following:

I'm not. I appreciate that you're trying to help, but please read the post carefully before saying I'm contradicting myself. Even if I wasn't clear, I believe my code was. It does exactly the same thing as what you just posted. I'll edit the post again to be even clearer.
Offline Cero
« Reply #5 - Posted 2015-06-18 08:36:53 »

you dont have to do this yourself. which library or framework or whatever are you using?

Offline theagentd
« Reply #6 - Posted 2015-06-18 08:46:24 »

So much misinformation...

If the computer can't render fast enough, your game starts slowin down. The solution that lots of people posted involves skipping the rendering of some updates to catch up and prevent a slowdown. However, if the computer can't even keep up with updating, the game will inevitably slow down, or like many of the examples posted here seemingly freeze the game by falling further and further behind and doing more and more updates.

A solution is to reduce the update rate, but that gives you fewer unique frames to render, capping your FPS to a value even lower than 60 FPS. The somution is to add interpolation to generate frames inbetween updates. Almost all commercial games do this.


Myomyomyo.
Offline pelep

Senior Newbie





« Reply #7 - Posted 2015-06-18 08:50:39 »

you dont have to do this yourself. which library or framework or whatever are you using?

I know I don't Smiley Currently, I'm using only Java2D. I explain why here. Specifically, the second paragraph
Offline pelep

Senior Newbie





« Reply #8 - Posted 2015-06-18 08:56:01 »

A solution is to reduce the update rate, but that gives you fewer unique frames to render, capping your FPS to a value even lower than 60 FPS.

Wouldn't that pretty much behave the same way as my above code does when a computer falls behind?

The somution is to add interpolation to generate frames inbetween updates. Almost all commercial games do this.

If you look at the code I posted, it includes interpolation. One of the reasons why I want to change the game loop is to add interpolation actually, but I didn't mention it since it's not my issue.
Offline theagentd
« Reply #9 - Posted 2015-06-18 09:03:56 »

Look at the code of the LWJGL Display class which has a great sync() function which caps the FPS to a certain value.

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

Senior Newbie





« Reply #10 - Posted 2015-06-18 09:06:57 »

Thank you! will do Smiley

edit: it looks promising. again, thank you!
Offline Cero
« Reply #11 - Posted 2015-06-18 09:38:15 »

you dont have to do this yourself. which library or framework or whatever are you using?

I know I don't Smiley Currently, I'm using only Java2D. I explain why here. Specifically, the second paragraph

Quote
Hi, I'm currently rewriting the game engine

Stopped reading there. Sorry.
I will assume you are pretty young and wont listen, but dont write an engine yourself unless you have like 10 years of experience and a team. Just dont.
Especially not one that uses Java2D... that shit was outdated in... well actually always.

Offline pelep

Senior Newbie





« Reply #12 - Posted 2015-06-18 10:25:51 »

I will assume you are pretty young and wont listen

Hahah. "Young" is a relative term. But I can tell you I'm well past puberty at least Tongue. Anyway, why do you say I shouldn't make one by myself? Lots of people do it. I'm not aiming for anything fancy/professional anyway; just something clean and functional with enough challenge to be fun.

Also, since you didn't read the rest of the post, I mentioned I actually plan to use a library (LWJGL most likely) once I get bored of Java2D (which may be soon).
Offline ags1

JGO Kernel


Medals: 367
Projects: 7


Make code not war!


« Reply #13 - Posted 2015-06-18 10:34:31 »

I've seen some impressive stuff done with Java2d... Have a look here:

http://www.java-gaming.org/index.php?topic=30371.0

Just a thought: Java2D was too slow for a certain level of graphical fidelity in 2010. Since then the API has been improved at least a little bit. And graphics hardware has vastly increased in power since 2010. On the other hand, the graphical level of the average Java2d game has not increased much over the past few years. So I conclude that java2d has never been a better choice for game development!

Offline Cero
« Reply #14 - Posted 2015-06-19 02:10:59 »

@ags1
Really?
Performance wasn't even my main concern...
You'll end up with a codebase you cant port to anything, different from OpenGL code.
Why build expertise in an API no one uses?
There are literally zero advantages to handicapping yourself like that, EXCEPT "java2D is easier". But compared to libgdx this isn't even true, especially considering super hacks you have to do in java2D to get performance.

There is no point.


@pelep
We have discussed this over the years in this forum countless times.
Basically, since this is a gaming forum one would assume you want to make a GAME. You will either do a game or an engine, not both. And to be perfectly realistic you wont do an engine. At least a GOOD one. Now whats the point of making an inferior weak lackluster maybe unstable engine? Fun. I guess If its fun to you I can't really argue... If you want to be productive though, this is certainly the wrong approach.

Offline pelep

Senior Newbie





« Reply #15 - Posted 2015-06-19 10:10:18 »

Well, that's a lot more convincing than "just don't" Smiley

Quote
If you want to be productive though, this is certainly the wrong approach.

I'll take your word for it. I guess it's on to libraries for me. Thanks for the advice!
Offline ags1

JGO Kernel


Medals: 367
Projects: 7


Make code not war!


« Reply #16 - Posted 2015-06-19 10:45:16 »

@Cero, I'm not really arguing with you, I'm fully aware that java2d is just about the worst possible choice for game development. My focus was more on the "super hacks to get performance" part. I can understand these were necessary 5-6 years ago, but surely less so today given the dramatic increase in rendering performance we have seen over the past half decade. My budget Android phone has better graphics than my above-average 2008 laptop... (yes, I know my android phone cannot run java2d, I'm only using it as an example of the preformance differential we see in the recent past). I don't really know as I have not used java2d very much myself. From the little I have seen it seems very similar to OpenGL direct mode rendering.

Regarding porting, I don't think that is such a big issue. It's a luxury problem for the average java2d game. In general you should isolate third-party libraries so you have the minimum dependencies on them, regardless of how similar that library may be to other libraries. And porting is always possible - consider princec's ports from Java to C++ for example.

Also, pelep has another thread where princec mentioned that anyone looking at java2d should really be looking at javafx8 today.

Offline Cero
« Reply #17 - Posted 2015-06-20 05:42:22 »

@ags1

I'm not really arguing that performance available was never better and the codebase of java2D was probably never better. Sure. Nevertheless I see no point why anyone would start getting into Java2D... there is just no point. I dont really see a OpenGL binding as a "dependency" because, I mean, we all use some sort of codebase to build a game with, you never start with zero, so whats the difference. And a OpenGL binding is really the basis of any game development framework.

I remember getting hardware acceleration in java2D was a nightmare... A) There was no real dependable way to get the information on IF we are hardware accelerated or not
and B) The rules for getting and worse the rules for losing hardware acceleration were completely arbitrary.

yeah but cas uses opengl and those instructions are easily ported, let alone to other opengl systems.

I mean by porting I kinda also mean your knowledge... knowing java2D is not beneficial when you could know OpenGL. Better that nothing obviously, but many of the concepts are actually complete Java2D's own bullshit...

tl;dr
Yeah I also dont argue with you. If you do want to do Java2D it probably has never been easier performance-wise and codebase-wise.
However that being said, I dont see why anyone would ever do Java2D to begin with.

Pages: [1]
  ignore  |  Print  
 
 

 
Riven (397 views)
2019-09-04 15:33:17

hadezbladez (5280 views)
2018-11-16 13:46:03

hadezbladez (2204 views)
2018-11-16 13:41:33

hadezbladez (5544 views)
2018-11-16 13:35:35

hadezbladez (1150 views)
2018-11-16 13:32:03

EgonOlsen (4584 views)
2018-06-10 19:43:48

EgonOlsen (5462 views)
2018-06-10 19:43:44

EgonOlsen (3119 views)
2018-06-10 19:43:20

DesertCoockie (4015 views)
2018-05-13 18:23:11

nelsongames (4708 views)
2018-04-24 18:15:36
A NON-ideal modular configuration for Eclipse with JavaFX
by philfrei
2019-12-19 19:35:12

Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08
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!