rework the main loop to use a different method for fixed timestep
Use Glenn Fiedler's "Fix your timestep!" article's approach instead. Just need to remember to always interpolate between prevState and currentState and not extrapolate from the currentState when rendering (for best results!)
This commit is contained in:
parent
8cd834c455
commit
8d9457b872
|
@ -1,7 +1,7 @@
|
||||||
package ca.blarg.gdx;
|
package ca.blarg.gdx;
|
||||||
|
|
||||||
public interface GameLooper {
|
public interface GameLooper {
|
||||||
void setTiming(int updatesPerSecond, int maxFrameSkip);
|
void setTiming(int updatesPerSecond, float maxFrameTimeSeconds);
|
||||||
|
|
||||||
int getUpdateFrequency();
|
int getUpdateFrequency();
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,13 @@ package ca.blarg.gdx;
|
||||||
|
|
||||||
import com.badlogic.gdx.ApplicationListener;
|
import com.badlogic.gdx.ApplicationListener;
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.utils.TimeUtils;
|
|
||||||
|
|
||||||
public class GdxGameAppListener implements ApplicationListener, GameLooper {
|
public class GdxGameAppListener implements ApplicationListener, GameLooper {
|
||||||
int updatesPerSecond;
|
int updatesPerSecond;
|
||||||
int updateFrequency;
|
int updateFrequency;
|
||||||
int maxFrameSkip;
|
float maxFrameTime;
|
||||||
|
|
||||||
long nextTick = 0;
|
float accumulator;
|
||||||
int loops;
|
|
||||||
|
|
||||||
float updateDelta = 0.0f;
|
float updateDelta = 0.0f;
|
||||||
float renderDelta = 0.0f;
|
float renderDelta = 0.0f;
|
||||||
|
@ -29,7 +27,7 @@ public class GdxGameAppListener implements ApplicationListener, GameLooper {
|
||||||
|
|
||||||
Services.register(GameLooper.class, this);
|
Services.register(GameLooper.class, this);
|
||||||
|
|
||||||
setTiming(20, 5);
|
setTiming(20, 0.25f);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
gameApp = gameAppType.newInstance();
|
gameApp = gameAppType.newInstance();
|
||||||
|
@ -46,7 +44,6 @@ public class GdxGameAppListener implements ApplicationListener, GameLooper {
|
||||||
|
|
||||||
gameApp.onCreate();
|
gameApp.onCreate();
|
||||||
|
|
||||||
nextTick = TimeUtils.millis();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -57,15 +54,18 @@ public class GdxGameAppListener implements ApplicationListener, GameLooper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render() {
|
public void render() {
|
||||||
loops = 0;
|
float frameTime = Gdx.graphics.getRawDeltaTime();
|
||||||
while (TimeUtils.millis() > nextTick && loops < maxFrameSkip) {
|
if (frameTime > maxFrameTime)
|
||||||
gameApp.onUpdate(updateDelta);
|
frameTime = maxFrameTime;
|
||||||
|
|
||||||
nextTick += updateFrequency;
|
accumulator += frameTime;
|
||||||
++loops;
|
|
||||||
|
while (accumulator >= updateDelta) {
|
||||||
|
gameApp.onUpdate(updateDelta);
|
||||||
|
accumulator -= updateDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderDelta = (float)(TimeUtils.millis() + updateFrequency - nextTick) / (float)updateFrequency;
|
renderDelta = accumulator / updateDelta;
|
||||||
|
|
||||||
gameApp.onRender(renderDelta);
|
gameApp.onRender(renderDelta);
|
||||||
}
|
}
|
||||||
|
@ -90,11 +90,11 @@ public class GdxGameAppListener implements ApplicationListener, GameLooper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTiming(int updatesPerSecond, int maxFrameSkip) {
|
public void setTiming(int updatesPerSecond, float maxFrameTimeSeconds) {
|
||||||
this.updatesPerSecond = updatesPerSecond;
|
this.updatesPerSecond = updatesPerSecond;
|
||||||
updateFrequency = 1000 / this.updatesPerSecond;
|
updateFrequency = 1000 / this.updatesPerSecond;
|
||||||
this.maxFrameSkip = maxFrameSkip;
|
|
||||||
this.updateDelta = updateFrequency / 1000.0f;
|
this.updateDelta = updateFrequency / 1000.0f;
|
||||||
|
this.maxFrameTime = maxFrameTimeSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in a new issue