libgdx isometri c плиточный экран карты мира с окном просмотра - PullRequest
0 голосов
/ 10 марта 2020

Я хотел создать простую изометрическую карту размером 30x30 c и добавить слушателя, чтобы иметь возможность нажимать на плитки. Я просмотрел много статей и постов здесь, но ни одна из них не помогла мне. Моя проблема в том, что у меня есть окно просмотра, 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, чтобы получить правильные координаты?

1 Ответ

0 голосов
/ 10 марта 2020

Я нашел проблему, я пропустил один шаг. Вот как должен выглядеть 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;
        }

Мне нужно преобразовать координаты сцены в координаты экрана, теперь этот код работает.

...