简体   繁体   中英

LibGDX render and update calling speed

In the ApplicationAdapter class, I override the render() method and draws my game from there. I also have an own method: update() inside the render method which is where I want to update everything.

The render() method is as I know called ~60 times a second. I dont want my update method to be dependent on how many times the render method is called. I want the render method to render as much as the device can handle below 60 FPS. I also want the update method to get called at a fixed rate: 60 times a second.


I´ve tried to call my update method 60 times a second in my render method like this:

double beforeMillis;
double FPS=4; //test
double millisPassed=0;
int x=0;


@Override 
public void render () {
    beforeMillis=System.currentTimeMillis();
    Gdx.gl.glClearColor(1, 1, 1, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    batch.begin();
    batch.draw(tex, x, 10);
    batch.end();
    millisPassed+=(System.currentTimeMillis()-beforeMillis);
    if(millisPassed>=1000/FPS){
        update();
        millisPassed=0;
    }
} 

...but it updates like once every four seconds.


Any good way of doing this? Thanks in advance!

The code you posted won't compare accurate time, because it ignores all the time spent doing things between batch.end() and the next call to render() , some of which occurs in the libgdx backend. And if you update after drawing in the render method, you will always have at least one visual frame of lag.

A basic implementation of a fixed timestep update in libgdx would be like this:

static final double DT = 1/60.0;
static final int MAX_UPDATES_PER_FRAME = 3; //for preventing spiral of death
private long currentTimeMillis;

public void create() {
    currentTimeMillis = System.currentTimeMillis();
}

public void render() {
    long newTimeMillis = System.currentTimeMillis();
    float frameTimeSeconds = (newTimeMillis - currentTimeMillis) / 1000f;
    currentTimeMillis = newTimeMillis;

    int updateCount = 0;
    while (frameTimeSeconds > 0f && updateCount <= MAX_UPDATES_PER_FRAME) {
        float deltaTimeSeconds = Math.min(frameTimeSeconds, DT);
        update(deltaTimeSeconds);
        frameTimeSeconds -= deltaTimeSeconds;
        ++updateCount;
    }

    draw();
}

This does result in update occurring more than 60 times a second, because it gets updated with the "leftovers" to keep the visuals current (no stuttering). The update(float delta) method must be designed to use a variable delta time.

You can do a truly fixed update as described here in the last two sections, but that has the disadvantage of visual stuttering or needing to implement a one-frame delay and interpolating ahead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM