LibGDX运动不流畅

4

我正在使用LibGDX制作游戏。我有4个纹理作为视差背景以及一些障碍物(其中一个在屏幕的上部,其他在下部),这是移动部分:

//Parallax    
if (bckgndmiddle_x <= -Const.VIEWPORT_W*2+(game_speed*delta)/2) bckgndmiddle_x=-(game_speed*delta)/2; else bckgndmiddle_x-=(game_speed*delta)/2;
    if (bckgndfar_x <= -Const.VIEWPORT_W*2+(game_speed*delta)/5)      bckgndfar_x=-(game_speed*delta)/5; else bckgndfar_x-=(game_speed*delta)/5;

    for (Obstacle obst:obstacles) {
        obst.update(game_speed*delta);
    }

    //End Main game loop

    player.update();
    game.batch.begin();
    game.batch.draw(wall, bckgndfar_x,floor.getRegionHeight()+100);
    game.batch.draw(wall, bckgndfar_x+wall.getRegionWidth(),floor.getRegionHeight()+100);
    game.batch.draw(bot_furniture, bckgndmiddle_x,floor.getRegionHeight());
    game.batch.draw(bot_furniture, bckgndmiddle_x+bot_furniture.getRegionWidth(),floor.getRegionHeight());
    game.batch.draw(floor, bckgndmiddle_x,0);
    game.batch.draw(floor, bckgndmiddle_x+floor.getRegionWidth(),0);
    game.batch.draw(ceiling, bckgndfar_x,Const.VIEWPORT_H-ceiling.getRegionHeight());
    game.batch.draw(ceiling, bckgndfar_x+ceiling.getRegionWidth(),Const.VIEWPORT_H-ceiling.getRegionHeight());

障碍物更新方法只是x-=speed;因为speed是接收的参数。

问题在于有时纹理会奇怪地晃动,就像设备无法处理游戏并且会冻结一小段时间。

有什么线索说明为什么会发生这种情况吗?

编辑

发生的是纹理不时地卡顿(我是西班牙人,不知道那个词)

我认为这必须与背景每部分的第二张图像有关,即增加宽度。 像它增加宽度一样,但有时由于fps下降而太多,下一次它会“移回”到正常位置,因为fps恢复正常。

编辑2 我尝试了没有障碍物,还是出现了卡顿现象,我又试了一遍加上障碍物但去掉背景,就没有问题了,所以肯定是我在第一个编辑中说的问题。

顺便说一句,FPS下降不到1(已检查)

我刚刚尝试了绘制整个背景图像(没有视差),仍然存在同样的问题。


听起来像是垃圾回收问题。你在渲染循环中分配了很多对象吗? - Tenfour04
我不认为这是垃圾回收问题,因为我没有使用太多的对象。我认为这与每个背景的第二次绘制有关,其中宽度的分配没有应用增量,但我尝试了一些方法,仍然无法解决。 - J. Arenas
这个程序运行在什么样的帧率上?一个1 fps的掉帧似乎不太可能产生可见的卡顿。 - rbennett485
@rbennett485 它正在以60fps的速度运行。在日志中,最小值约为59.2到59.9 fps。 - J. Arenas
2个回答

2

我看到一个可能的原因,与FPS下降无关:

以下是您的第一行,为了易读性而分开:

if (bckgndmiddle_x <= -Const.VIEWPORT_W*2+(game_speed*delta)/2) 
    bckgndmiddle_x = -(game_speed*delta)/2; 
else 
    bckgndmiddle_x -= (game_speed*delta)/2;

通常,else语句用于以恒定速度移动背景。但是每当它到达if语句时,位置会被明确设置,而不考虑其先前的位置,因此移动将不平滑。您需要将其移动到一个位置,看起来就像它从先前的位置移动了-(game_speed*delta)/2
一种方法是始终使用速度移动对象,并仅在必要时通过纹理宽度向前移动作为修正。例如,假设您将屏幕左下角保持在(0,0):
float midWidth = floor.getRegionWidth();

bckgndmiddle_x -= game_speed*delta/2; //Always move it at constant speed.
if (bckgndmiddle_x + 2*midWidth < Const.VIEWPORT_W) //Right edge starting to show. 
    bckgndmiddle_x += midWidth; // Shift it exactly by its width so the jump is undetectable

上述的2*是因为我假设你的其他代码实际上在一侧绘制了两份背景纹理。如果你正在绘制一个比视口宽度常量更宽的单个纹理,则应删除2*

当然,这个问题也适用于你的第二行代码,其中你设置了远背景位移。


2*是因为纹理是相机宽度的两倍。我仍然在绘制两份副本,所以当第一份刚从屏幕上消失时,它被移动了它的长度以匹配另一份的末尾。我会尝试一下,因为这对我来说很有意义,我会尽快回复。 - J. Arenas
我已经做了那个,但行为仍然一样。我注意到它随机发生,并不一定是在需要修正位置时发生的。 - J. Arenas

0

遇到了类似的问题,通过禁用垂直同步解决了

    LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
    config.vSyncEnabled = false; 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接