libgdx等距平铺地图屏幕到带有视口的世界

问题描述 投票:0回答:1

我想创建一个简单的30x30等距图块地图,并添加一个侦听器以能够单击图块。我在这里查找了很多文章和帖子,但没有一个对我有帮助。我的问题是,我有一个视口,30x17,一个摄像头,一个舞台和一个带有tileWidth = 32和tileHeight = 16像素的平铺地图。现在,当我渲染平铺的地图时,它看起来还不错。当我在舞台上单击并尝试获取世界坐标时,我看到了一些非常奇怪的坐标。这是代码:

private static final float TILE_WIDTH = 32;
private static final float TILE_HEIGHT = 16;

private OrthographicCamera camera;

private Viewport viewport;

private Stage stage;
private IsometricTiledMapRenderer isometricTiledMapRenderer;

private Matrix4 isoTransform;
private Matrix4 invIsotransform;

public void load(AssetManagerLoaderV2 assetManagerLoader) {

    assetManagerLoader.load();

    init();

    camera = new OrthographicCamera();

    viewport = new FitViewport(30, 17, camera);

    stage = new Stage(viewport);

    TiledMap tiledMap = new TiledMapGenerator(assetManagerLoader).generate(30, 30);

    isometricTiledMapRenderer = new IsometricTiledMapRenderer(tiledMap, 1/32f);

    stage.addListener(new InputListener() {

        @Override
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
            System.out.println(screenToCell(x, y));
            return true;
        }
    });
}

@Override
public void show() {
    Gdx.input.setInputProcessor(stage);
}


@Override
public void render(float delta) {

    DrawUtils.clearScreen();

    viewport.apply();

    isometricTiledMapRenderer.setView(camera);
    isometricTiledMapRenderer.render();

}

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

@Override
public void pause() {

}

@Override
public void resume() {

}

@Override
public void hide() {

}

@Override
public void dispose() {
    isometricTiledMapRenderer.dispose();
    stage.dispose();
}


public void init () {
    //create the isometric transform
    isoTransform = new Matrix4();
    isoTransform.idt();
    isoTransform.translate(0.0f, 0.25f, 0.0f);
    isoTransform.scale((float)(Math.sqrt(2.0) / 2.0), (float)(Math.sqrt(2.0) / 4.0), 1.0f);
    isoTransform.rotate(0.0f, 0.0f, 1.0f, -45.0f);

    //... and the inverse matrix
    invIsotransform = new Matrix4(isoTransform);
    invIsotransform.inv();

}

public Vector2 worldToCell(float x, float y) {
    float halfTileWidth = TILE_WIDTH * 0.5f;
    float halfTileHeight = TILE_HEIGHT * 0.5f;

    float row = (1.0f/2) * (x/halfTileWidth + y/halfTileHeight);
    float col = (1.0f/2) * (x/halfTileWidth - y/halfTileHeight);

    return  new Vector2((int)col,(int)row);
}

public Vector2 screenToWorld(float x, float y){
    Vector3 touch = new Vector3(x,y,0);
    camera.unproject(touch);
    touch.mul(invIsotransform);
    touch.mul(isoTransform);
    return  new Vector2(touch.x,touch.y);
}


public Vector2 screenToCell(float x, float y) {
    Vector2 world = screenToWorld(x,y);
    world.y -= TILE_HEIGHT *0.5f;
    return worldToCell(world.x,world.y);
}

有人知道如何编写worldToCell以获得正确的坐标吗?

libgdx isometric
1个回答
0
投票

我发现了问题,我错过了一步。这就是touchDown的外观:

@Override
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
            Vector2 newCoords = stage.stageToScreenCoordinates(new Vector2(x, y));
            System.out.println(screenToCell(newCoords.x, newCoords.y));
            return true;
        }

我需要将舞台坐标转换为屏幕坐标,现在此代码正在运行。

© www.soinside.com 2019 - 2024. All rights reserved.