Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Camera LibGDX平铺:移动相机会导致平铺结巴/模糊/波动_Camera_Libgdx_Textures_Rendering_Tiled - Fatal编程技术网

Camera LibGDX平铺:移动相机会导致平铺结巴/模糊/波动

Camera LibGDX平铺:移动相机会导致平铺结巴/模糊/波动,camera,libgdx,textures,rendering,tiled,Camera,Libgdx,Textures,Rendering,Tiled,我试过到处寻找这个问题的解决办法,但没有成功;尽管我尝试了各种建议,但我将在下文随问题详述这些建议 我创建了一个非常小且简单的示例项目,用于测试渲染平铺地图,并设置带有视口和一些简单输入处理的摄影机,以便我可以使用WASD“平移”地图。问题是,当我尝试在地图周围平移时,我会在地图上得到奇怪的效果。这些措施包括: 瓦片“波动”。我的意思是,当我向上/向下滚动或穿过屏幕时,屏幕将显示“波动” 故障/口吃屏幕。相机有时看起来并不平滑 分幅变化(例如,移动相机时,黄色分幅上的黑色条的侧面或顶部将有一个

我试过到处寻找这个问题的解决办法,但没有成功;尽管我尝试了各种建议,但我将在下文随问题详述这些建议

我创建了一个非常小且简单的示例项目,用于测试渲染平铺地图,并设置带有视口和一些简单输入处理的摄影机,以便我可以使用WASD“平移”地图。问题是,当我尝试在地图周围平移时,我会在地图上得到奇怪的效果。这些措施包括:

  • 瓦片“波动”。我的意思是,当我向上/向下滚动或穿过屏幕时,屏幕将显示“波动”
  • 故障/口吃屏幕。相机有时看起来并不平滑
  • 分幅变化(例如,移动相机时,黄色分幅上的黑色条的侧面或顶部将有一个不同颜色的黄色像素。这些“额外”像素位于哪一侧取决于相机移动的方式)。我想这叫做纹理出血,但我不确定
我尝试过的事情:

  • 在所有边上用相同颜色的像素填充所有瓷砖(这样可以去除地图上的黑色水平线)
  • 将过滤器设置为线性/最近(尝试所有组合)
  • 在视口中玩转
  • 改变相机的速度
有人知道会出什么问题吗?我只是不想在继续之前确保我了解如何正确地渲染地图和移动相机,而不会出现任何问题

确切代码:

public class GameScreen implements Screen {
final Alpha game;

private OrthographicCamera camera;
private FitViewport viewport;
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private Rectangle player;

public GameScreen(final Alpha game) {
    this.game = game;

    camera = new OrthographicCamera();
    viewport = new FitViewport(800, 480, camera);

    TmxMapLoader.Parameters params = new TmxMapLoader.Parameters();
    params.textureMinFilter = Texture.TextureFilter.Nearest;
    params.textureMagFilter = Texture.TextureFilter.Linear;
    map = new TmxMapLoader().load("simple_padded_same_color.tmx");
    renderer = new OrthogonalTiledMapRenderer(map);

    player = new Rectangle(32,32,32,32);
}

@Override
public void render(float delta) {
    camera.update();
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    // handle input
    if (Gdx.input.isKeyPressed(Input.Keys.A)) {
        player.setX(player.getX() - 200 * delta);
    }
    if (Gdx.input.isKeyPressed(Input.Keys.D)) {
        player.setX(player.getX() + 200 * delta);
    }
    if (Gdx.input.isKeyPressed(Input.Keys.W)) {
        player.setY(player.getY() + 200 * delta);
    }
    if (Gdx.input.isKeyPressed(Input.Keys.S)) {
        player.setY(player.getY() - 200 * delta);
    }

    camera.position.set(player.getX(), player.getY(), 0);

    renderer.setView(camera);
    renderer.render();
}

@Override
public void resize(int width, int height) {
    viewport.update(width, height);
}

@Override
public void show() {
}

@Override
public void hide() {
}

@Override
public void pause() {
}

@Override
public void resume() {
}

@Override
public void dispose() {
    map.dispose();
    renderer.dispose();
}
}

下面是渲染函数的外观

@Override
public void render(float delta) {

    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    // force a constant delta
    float gameDelta = 0.1f;

    // handle input
    if (Gdx.input.isKeyPressed(Input.Keys.A)) {
        player.setX(player.getX() - 200 * gameDelta);
    }
    if (Gdx.input.isKeyPressed(Input.Keys.D)) {
        player.setX(player.getX() + 200 * gameDelta);
    }
    if (Gdx.input.isKeyPressed(Input.Keys.W)) {
        player.setY(player.getY() + 200 * gameDelta);
    }
    if (Gdx.input.isKeyPressed(Input.Keys.S)) {
        player.setY(player.getY() - 200 * gameDelta);
    }

    // set camera position first
    camera.position.set(player.getX(), player.getY(), 0);
    // update camera
    camera.update();

    // then set the view
    renderer.setView(camera);
    // last render
    renderer.render();
}
首先,您需要在设置新位置后更新相机。然后,尝试使用一个恒定的增量,而不是实际的增量,因为libgdx增量表示两帧之间的时间量,并且不是恒定的,这将导致奇怪的相机移动。这将消除游戏中的波浪效果

为了理解您的delta问题,我建议您阅读本文

理想情况下,您可以使用实体系统框架和特定的
物理系统
运动系统
来计算玩家的移动,并将玩家位置计算与渲染循环分离


Libgdx随附,你也可以看看这是一个很棒的项目,在我看来比Ashley更完整。

对于任何遇到这个问题的人,我已经在谷歌上搜索和尝试了大约一周。我终于把它修好了,所以我将分享我所做的

  • 将填充添加到平铺集,可能还有角色。我还使用了重复填充
  • 检查插值函数,确保它们不是问题所在(在一个例子中,我使用的插值方法之一使效果更糟)
  • 更改正交摄影机初始化。最初我把相机设置成画25x19块瓷砖。更改此数字有时会解决问题,但随后地图会扭曲。以下是我使用的:
  • camera.setToOrTo(false,Gdx.graphics.getWidth()/TILE\u SIZE/2f,Gdx.graphics.getHeight()/TILE\u SIZE/2f);
    
    TILE\u SIZE
    是您的TILE(PPU?)。我的磁贴是16x16,因此值是16。我的地图渲染器已初始化为
    1/16.0f

    如果使用的是视口,也可以在“调整大小”方法中应用此选项

    @覆盖
    公共空心调整大小(整型宽度、整型高度){
    viewport.update(宽度、高度、假);
    相机。设置为(假,宽/16f/2f,高/16f/2f);
    }
    
    我为调试问题所做的工作:

  • 分析,实际上没有显示任何东西
  • 确保我没有在渲染/更新循环中创建任何对象
  • 多次更改我的时间步长
  • 将代码剥离到基本级别

  • 首先,您应该在设置新位置后调用
    camera.update()
    。接下来,试着使用一个常量delta,而不是libgdx提供的delta,它依赖于你的计算机能力。不幸的是,所有这些都不会对问题产生任何影响。