我遇到了一个我自己无法解决的问题。
我已经在我的render()方法中实现了这个固定的时间步骤,如下所示:
double time = TimeUtils.millis();
loops = 0;
while (time > nextGameTick && loops< MAX_FRAMESKIP) {
gameLogic(1f / gameSpeed);
nextGameTick += SKIP_TICKS;
loops++;
}
if(!rendererDisposed) {
interpolation = (time + SKIP_TICKS - nextGameTick)/(SKIP_TICKS);
camera.update();
renderer.render(interpolation);
hud.draw(dt);
}
以上代码是此链接的最后一个实现:http://www.koonsolo.com/news/dewitters-gameloop/
我的渲染器类会像这样绘制一个批处理:
batch.draw(assets.getAnimation(),
player.getInterPos(interpolation).x,
player.getInterPos(interpolation).y,
player.getWidth() / 2,
player.getHeight() / 2,
player.getWidth(),
player.getHeight(), 1, 1,
player.getPolygon().getRotation());
getInterPos()
public Vector2 getInterPos(float delta){
interPosition.x = position.x *delta + previousPosition.x*(1-delta);
interPosition.y = position.y*delta + previousPosition.y*(1-delta);
return interPosition;
}
预期:插值返回从0到1的浮点值,用于在前一个位置和当前位置之间进行插值。
现在我有TICKS_PER_SEC = 25.拥有FPS:25意味着渲染器和gamelogic每帧被调用1次。这个工作。
问题在fps!= TICKS_PER_SEC时开始。例如,我们假设gamefic将被调用一次,渲染器将被调用两次。现在插值在第1和第2个渲染器调用时为0.5和1。这也是工作原理。然而,绘制的精灵开始表现得很奇怪并且上下跳跃。
这是一段显示精灵行为的视频: https://www.youtube.com/watch?v=CE6cQr9o0kA
现在最大的谜团是,如果我们在渲染器类中添加这些行
Gdx.app.log("player has y:"+player.getY()," and previous y:"+player.getPreviousPosition().y);
Gdx.app.log("interpolation: "+interpolation," position: +player.getInterPos(interpolation));
batch.draw(assets.getAnimation(), ... same as earlier
球员有y:23.62517:和之前的y:23.09717 插值:1.0:位置:(4.5,23.62517) 球员有y:24.145168:和之前的y:23.62517 插值:0.5:位置:(4.5,23.88517) 球员有y:24.145168:和之前的y:23.62517 插值:1.0:位置:(4.5,24.145168) 球员有y:24.657167:和之前的y:24.145168 插值:0.5:位置:(4.5,24.401169)
currentPosition和previousPosition得到正确更新,interpolatedPosition也是如此。 正如您所看到的那样,位置总是以递增的方式呈线性。所以问题是为什么批处理在2个不同的位置渲染精灵并在它们之间交替?
我的引力功能:
//dt is gameSpeed not the deltaTime
velocity.add(acceleration.x*dt,acceleration.y*dt);
position.add(velocity.x*dt,velocity.y*dt);
if (velocity.y<=-10)
velocity.y=-10;
当我按下屏幕时会发生这种情况:
velocity.set(0,20);
额外信息:
我真的希望我尽可能彻底。在过去的两周里,这件事让我疯狂,我似乎无法解决这个问题。
任何帮助将不胜感激!
编辑:
我设法解决了这个问题。这是因为我正在更新相机并向我的玩家提供当前逻辑位置而不是内插位置并在游戏逻辑功能中更新它。
所以我改变了我的相机定位
camera.position.y = player.getPosition().y;
要
camera.position.y = player.getInterPos(interpolate).y;
没有更多的文物!如果有人遇到类似的问题,请留在这里。
答案 0 :(得分:0)
不肯定这是你唯一的问题。
由于millis()
返回长,time
应该是长的,而不是双倍的:
long time = TimeUtils.millis(); // you declared time to be a double
SKIP_TICKS
和nextGameTick
也必须很长。然后你需要在分割之前将分子和分母强制转换为浮点数,这样你的插值并不总是得到整数(0或1)。
interpolation = (float)(time + SKIP_TICKS - nextGameTick)/(float)SKIP_TICKS;