durianodour

Android The main game loop FPS independent

Recommended Posts

I am just a newbie game developer, I am trying to create a frame independent game loop.

I am currently using the following code

 private class MainGameThread extends Thread {
        public static final int PAUSE_SLEEP_TIME = 10;
        long previous = getCurrentTimeInMillis();
        long totalElapsed = 0;
        long gameTimeStart = 0;
        long currentTime = getCurrentTimeInMillis();
        long accumulatorTime = 0;

        @Override
        public void run() {
            gameTimeStart = getCurrentTimeInMillis();
            while (mIsRunning) {
                // Pause game
                while (mIsPaused) {
                    try {
                        Thread.sleep(PAUSE_SLEEP_TIME);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                long current = getCurrentTimeInMillis();
                long elapsed = current - previous;
                previous = current;
                processGameInput();
                updateGameState(elapsed);
                totalElapsed += elapsed;
                if (totalElapsed > MainGame.MS_PER_FRAME) {
                    drawGame();
                    totalElapsed -= MainGame.MS_PER_FRAME;
                    if (totalElapsed > MainGame.MS_PER_FRAME) {
                        Log.e("GAME", "Performance warning, rendering or update took too long");
                    }
                }
                checkIfGameShouldStop(gameTimeStart);
            }
            shutdownGracefully();
        }

        private void shutdownGracefully() {
        }
    }

It works, how ever it performs differently on different devices

In my game models update method I am performing the following actions

  mCenterX += (mVelocityVector.x * timeElapsed);
  mCenterY += (mVelocityVector.y * timeElapsed + gameSpeed.getValue())

I have read this article https://gafferongames.com/post/fix_your_timestep/

But I can't understand the final example

double t = 0.0;
double dt = 0.01;

double currentTime = hires_time_in_seconds();
double accumulator = 0.0;

State previous;
State current;

while ( !quit )
{
    double newTime = time();
    double frameTime = newTime - currentTime;
    if ( frameTime > 0.25 )
        frameTime = 0.25;
    currentTime = newTime;

    accumulator += frameTime;

    while ( accumulator >= dt )
    {
        previousState = currentState;
        integrate( currentState, t, dt );
        t += dt;
        accumulator -= dt;
    }

    const double alpha = accumulator / dt;

    State state = currentState * alpha + 
        previousState * ( 1.0 - alpha );

    render( state );
}

What does the State class object mean in this case.

Could someone please help to adapt this example to my case or explain the example from the article and how I could update my loop to be frame independent ?

Thanks

Share this post


Link to post
Share on other sites

I'm familiar with that article and have used it as reference for my own projects. The state object represents the state-of-being of objects being simulated in the game/physics/whatever simulation.

That is, the state contains position, velocity, rotation/orientation, etc. And each game object has 2 states: the most recently computed state (let's call it the previous state), and the one before that (let's call it the ultra-previous state).

Then, all that talk of accumulators and interpolation is saying to compute the "actual current state of the world" by interpolating between the ultra-previous state and the previous state. The motivation of this approach is to always "consume" all of the frame time available, in each cycle of the loop. And it probably helps for when you get into online multiplayer (a big topic on the gafferongames blog) - it probably helps ensure that each instance of the networked game has the same idea of what state each object in the game world is in.

Personally, I prefer not to go that route. Instead, I just carry over whatever remains in the accumulator, for the next game loop cycle. It saves the cost of interpolating between states, and it works well enough for my purposes.

(I just realized I said all that, but didn't say how to change your code, which was a party of your original question. But I'll leave that as an exercise for the reader :-D hopefully the explanation of state helped)

Edited by masskonfuzion

Share this post


Link to post
Share on other sites

As masskonfuzion says, at frame N there will be three states:

  • The Physics state at frame N-1; that is the state of the previous frame (state in this case means position, orientation and scale of all objects; and maybe something else if needed, like velocity)
  • The Physics state at frame N; that is the state of the current frame
  • The graphics state, which is an interpolation somewhere between N-1 and N.

 

1 hour ago, masskonfuzion said:

And it probably helps for when you get into online multiplayer (a big topic on the gafferongames blog) - it probably helps ensure that each instance of the networked game has the same idea of what state each object in the game world is in.

Personally, I prefer not to go that route. Instead, I just carry over whatever remains in the accumulator, for the next game loop cycle. It saves the cost of interpolating between states, and it works well enough for my purposes.

Errr... really the main motivation for interpolating is to detach physics framerate from graphics framerate. So your physics may be updated at 30hz and your graphics rendered at 60hz; or physics at 120hz and graphics at 60hz.

Another big reason is to combine variable frame rate for graphics (which is good for smoothness and performance) and fixed frame for physics (which is good for simulation stability and required for achieving determinism). Without interpolation, you either update at fixed framerate, or at variable framerate. Interpolation gives you both.

You can even go beyond what gafferongames' teaches and put graphics in a separate thread; allowing to do graphics in a different CPU core, but this is a more advanced topic.

Share this post


Link to post
Share on other sites

Thanks everyone for answers. I have much simpler case. I don't need to have all these complex calculations depending on different forces currently acting on an object.

I have  a simple game. I have only one object a ball that is falling down, or a different shape. I need just to catch it or skip. 

So I guess I don't need to integrate and save states between frames.

The only one variable that I change in my update method is 

mCenterX += (mVelocityVector.x * timeElapsed);

mCenterY += (mVelocityVector.y * timeElapsed + gameSpeed.getValue())

These variables just represent the position of a falling shape and that is all. 

The reason I tried to apply described method, just to develop even a simple game following best practices.

So maybe you could suggest me another way to achieve FPS independent rendering considering my requirements. 

I would be grateful for any further help

 

Edited by durianodour

Share this post


Link to post
Share on other sites

At first glance your code looks fine, can you be more specific about how it's inconsistent across different devices?

You haven't provided your drawing code, but note that if you are using Repaint, the screen will not be repainted immediately (it will wait for the next RepaintManager cycle). If you are using Repaint, try changing it to paintImmediately.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Forum Statistics

    • Total Topics
      627764
    • Total Posts
      2978976
  • Similar Content

    • By Canislupus54
      I aspire to develop games one day, and often write down ideas for game concepts I have. These aren't full design documents, and I'm not even sure they're full concept documents, if that's even a thing, but they've gotten more detailed overtime. This is the most recent one I wrote.
      I want critique on the document and the concept itself.
      I'm honestly not sure what the document should look like.
      For the game, I basically want to know if it sounds interesting/fun.
      Thanks.
      https://docs.google.com/document/d/1Ifjy7B1ylUPljtYrjwnLRWg9JaLrlBDHVC9H74fIFTc/edit?usp=sharing
    • By AFV
      Hello,
       
      I'm trying to get familiar with making interactive music via middlewares, but I'm not in projects that use this tools currently.
       
      So, I was wondering if someone can recommend me a way to practice things like layering, combining loops, transitions in a middleware without the need to be in a project that use middlewares.
       
      I would like to train this before I get to a project that actually use this technology, as an anticipation. Because maybe then I will be overworked if I have to learn everything having a deadline.
       
      Thanks ^^,
      Albert.
    • By Nazar22
      Hello guys. I've finally build my first game and if you got some free time please play it
      You can email me (forevernils@gmail.com) so I can send you invitation to test the game. There is first two location in attach


    • By ScyllaBus
      Using my loop based on this: https://gafferongames.com/post/fix_your_timestep/
      Trying to get my game to run at fixed 60FPS (both update and render) for all machines. Studied the link above and have been stuck on this game loop for weeks trying to get it to work smoothly to glide this image across the screen. I had dealt constantly with jittering and possible tearing. I can't recall what I did to fix it exactly, but I believe it may have something to do with not rounding a variable properly (such as delta).
       
      So yeah, currently the loop works but I'm afraid as I develop the game more and have to render more, eventually something I'm doing in my loop could cause slowdowns or larger CPU usage. Does the structure of the game loop below seem okay or is there something I can do to optimize it?
      The 2D game is a generic sidescroller. Not too heavy on physics, mainly just simple platformer physics. I feel as though I'm using way too much CPU.
       
      void Game::mainLoop() { double fps = 60.0f; int frameSkip = 5; int deltaSkip = frameSkip; double miliPerFrame = 1000.0 / fps; double xx = 0.0f; double playSpeed = 5; Uint64 previous = SDL_GetPerformanceCounter(); double accumulator = 0.0f; bool shouldRender = false; bool running = true; while(running){ Uint64 current = SDL_GetPerformanceCounter(); double elapsed = (current-previous) * 1000; elapsed = (double) (elapsed / SDL_GetPerformanceFrequency() ); previous = current; // handleEvents() handleEvents(); // when we press escape reset x to 0 to keep testing // when he goes off screen if(key_states[SDL_SCANCODE_ESCAPE]) xx = 0; accumulator+=elapsed; if(accumulator >= miliPerFrame * frameSkip) accumulator = 0; shouldRender = accumulator >= miliPerFrame; while(accumulator >= miliPerFrame){ // update() //cout << playSpeed << endl; double delta = ceil(elapsed); if(delta > deltaSkip) delta = 1; //if(elapsed >= 1) delta = elapsed; xx+= playSpeed * delta;// * (1 / fps); // /update() accumulator -= miliPerFrame; //get what's left over } if(shouldRender){ // render() SDL_SetRenderDrawColor(gameRenderer, 0xFF, 0xFF, 0xFF, 0xFF); SDL_RenderClear(gameRenderer); imageController.drawImage("colorkeytest", floor(xx), 0); SDL_RenderPresent(gameRenderer); // /render() } } }  
    • By TobyTheRandom
      Which is the best beginner game engine to try for the very first time? and why 
  • Popular Now