Libgdx 如何仅渲染地图的一部分并仅显示其一部分?

Libgdx 如何仅渲染地图的一部分并仅显示其一部分?,libgdx,tiled,Libgdx,Tiled,我的贴图大小为40000X20000,我只想渲染2048X2048,在屏幕上只显示1200X600像素,我是如何做到的? 换句话说,假设我有一个大的贴图,我不想渲染所有的40000X20000,我只想渲染较小的贴图2048X2048 我的屏幕允许我显示1200X600像素 例如。 我的代码: public class LibgdxGame extends ApplicationAdapter { static final float WORLD_WIDTH = 40000.0f;

我的贴图大小为40000X20000,我只想渲染2048X2048,在屏幕上只显示1200X600像素,我是如何做到的?

换句话说,假设我有一个大的贴图,我不想渲染所有的40000X20000,我只想渲染较小的贴图2048X2048

我的屏幕允许我显示1200X600像素

例如。

我的代码:

public class LibgdxGame extends ApplicationAdapter {
    static final float WORLD_WIDTH = 40000.0f;
    static final float WORLD_HEIGHT = 20000.0f;

//  Define viewoport
    private static final float VIRTUAL_WIDTH = 1200.0f;
    private static final float VIRTUAL_HEIGHT = 600.0f;
    // Move camera around
    private static final float CAMERA_SPEED = 60.0f;

    private OrthographicCamera camera;
    private Viewport viewport;

    private TiledMap map;
    private TmxMapLoader loader;
    private OrthogonalTiledMapRenderer renderer;
    private Vector2 direction;


    @Override
    public void create () {



        camera = new OrthographicCamera(15000, 15000);

        viewport = new FitViewport(VIRTUAL_WIDTH, VIRTUAL_HEIGHT, camera);
        camera.position.set(10900, 10800, 0);
        loader = new TmxMapLoader();//
        map = loader.load("40000X20000.tmx");
        renderer = new OrthogonalTiledMapRenderer(map);

        direction = new Vector2();
    }

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

    @Override
    public void render () {
        System.out.println("Render.........");
        Gdx.gl.glClearColor(0.8f, 0.8f, 0.8f, 1.0f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        updateCamera();

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

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

    private void updateCamera() {
        direction.set(0.0f, 0.0f);

        int mouseX = Gdx.input.getX();
        int mouseY = Gdx.input.getY();
        int width = Gdx.graphics.getWidth();
        int height = Gdx.graphics.getHeight();

        if (Gdx.input.isKeyPressed(Keys.LEFT) || (Gdx.input.isTouched() && mouseX < width * 0.25f)) {
            direction.x = -1;
        }
        else if (Gdx.input.isKeyPressed(Keys.RIGHT) || (Gdx.input.isTouched() && mouseX > width * 0.25f)) {
            direction.x = 1;
        }

        if (Gdx.input.isKeyPressed(Keys.UP) || (Gdx.input.isTouched() && mouseY < height * 0.25f)) {
            direction.y = 1;
        }
        else if (Gdx.input.isKeyPressed(Keys.DOWN) || (Gdx.input.isTouched() && mouseY > height * 0.25f)) {
            direction.y = -1;
        }

        direction.nor().scl(CAMERA_SPEED * Gdx.graphics.getDeltaTime());;

        camera.position.x += direction.x;
        camera.position.y += direction.y;

        TiledMapTileLayer layer = (TiledMapTileLayer)map.getLayers().get(0);

        float cameraMinX = viewport.getWorldWidth() * 0.5f;
        float cameraMinY = viewport.getWorldHeight() * 0.5f;
        float cameraMaxX = layer.getWidth() * layer.getTileWidth() - cameraMinX;
        float cameraMaxY = layer.getHeight() * layer.getTileHeight() - cameraMinY;

        camera.position.x = MathUtils.clamp(camera.position.x, cameraMinX, cameraMaxX);
        camera.position.y= MathUtils.clamp(camera.position.y, cameraMinY, cameraMaxY);

        camera.update();
    }
}
公共类LibgdxGame扩展应用程序适配器{
静态最终浮动世界_宽度=40000.0f;
静态最终浮子世界_高度=20000.0f;
//定义视图端口
专用静态最终浮动虚拟_宽度=1200.0f;
专用静态最终浮动虚拟_高度=600.0f;
//移动摄像机
专用静态最终浮动摄像头\ U速度=60.0f;
私人正交摄影机;
私有视口;
私人平铺地图;
专用TMXMA装载机;
私有正交瓦片渲染器;
专用矢量2方向;
@凌驾
公共void创建(){
摄像机=新的正交摄像机(15000、15000);
视区=新视区(虚拟视区宽度、虚拟视区高度、相机);
摄像机位置设置(1090010800,0);
loader=新的TmxMapLoader()//
map=loader.load(“40000X20000.tmx”);
渲染器=新的正交平铺贴图渲染器(贴图);
方向=新矢量2();
}
@凌驾
公共空间处置(){
map.dispose();
renderer.dispose();
}
@凌驾
公共无效渲染(){
System.out.println(“渲染……);
Gdx.gl.glClearColor(0.8f、0.8f、0.8f、1.0f);
Gdx.gl.glClear(GL20.gl\u颜色\u缓冲\u位);
updateCamera();
渲染器.setView(摄像机);
render.render();
}
@凌驾
公共空心调整大小(整型宽度、整型高度){
视口。更新(宽度、高度);
系统输出打印长度(宽度);
系统输出打印LN(高度);
}
私有void updateCamera(){
方向设置(0.0f,0.0f);
int mouseX=Gdx.input.getX();
int mouseY=Gdx.input.getY();
int-width=Gdx.graphics.getWidth();
int height=Gdx.graphics.getHeight();
如果(Gdx.input.isKeyPressed(Keys.LEFT)| |(Gdx.input.isTouched()&&mouseXwidth*0.25f)){
方向x=1;
}
如果(Gdx.input.isKeyPressed(Keys.UP)| |(Gdx.input.isTouched()&&mouseYheight*0.25f)){
方向y=-1;
}
direction.nor().scl(CAMERA_SPEED*Gdx.graphics.getDeltaTime());;
摄像机.position.x+=方向.x;
camera.position.y+=方向.y;
TiledMattileLayer层=(TiledMattileLayer)map.getLayers().get(0);
float cameraMinX=viewport.getWorldWidth()*0.5f;
float cameraMinY=viewport.getWorldHeight()*0.5f;
float cameraMaxX=layer.getWidth()*layer.getTileWidth()-cameraMinX;
float cameraMaxY=layer.getHeight()*layer.getTileHeight()-cameraMinY;
camera.position.x=数学夹具(camera.position.x,cameraMinX,cameraMaxX);
camera.position.y=数学夹具(camera.position.y,cameraMinY,cameraMaxY);
camera.update();
}
}

有各种各样的方法可以做到这一点,尽管没有人是完全优化的。我几天前就试过了。我尝试使用:

  • Spritecache;如果您有一个静态贴图,且不更改平铺,那么哪一个是最佳选项。虽然缓冲区有一个限制,我猜是5640个瓷砖/纹理

  • 使用Scessior堆栈方法,这对我来说似乎很复杂,您可以简单地裁剪所需的纹理区域并将其显示为贴图。但这不是一个好的解决方案

  • 我最好采用这种方法。我拿了两个tmx文件,一个是大的_map.tmx,上面有所有详细的瓷砖和图层;然后拍摄了另一个小的_map.tmx,它只包含1/2层,没有平铺。然后使用两组加载程序和渲染器,只需将小区域(2048X2048)中的需求单元格从大地图复制到小地图,并仅渲染小地图。现在,您可以使用此贴图动态更改平铺并显示动画,因为它只加载小tmx文件


  • 我认为平铺贴图渲染器已经自动渲染了仅足以覆盖可见区域的平铺。如果2048x2048远大于摄影机的视图,则不确定您所说的渲染2048x2048是什么意思。@Tenfour04是正确的。您不需要使用scessior之类的工具。根据视口的不同,tiledmaprender将只渲染所需的部分,并且非常有效。但还是要尽量避免在视图中出现大量的瓷砖。增加平铺大小(例如,将4合并为1)。始终测试性能。