简体   繁体   English

如何在等距 libgdx 中获得平铺位置

[英]How to get tile position on touching it in isometric libgdx

I'm creating 2d game, it's just an isometric map in libgdx it's 64x32我正在创建 2d 游戏,它只是 libgdx 中的等距图,它是 64x32

   public class MyGdxGame extends ApplicationAdapter implements InputProcessor
{


    public static float zoom=0.3f;
    Texture img;
    TiledMap tiledMap;
    OrthographicCamera camera;
    TiledMapRenderer tiledMapRenderer;
    final Matrix4 matrix = new Matrix4();
    public static float lastx,lasty;
    private IsometricTiledMapRenderer renderer;
    SpriteBatch sb;
    Texture texture;
    Sprite sprite;


    TextureRegion textureRegion;

    public static float translate,pick;

    float mapWidth;
    float mapHeight;
    static String c;
    TiledMapTileLayer.Cell cell;
    TiledMapTileLayer tileLayer;

    private Matrix4 isoTransform;

    private Matrix4 invIsotransform;

    @Override
    public void create () {
        float w = Gdx.graphics.getWidth();
        float h = Gdx.graphics.getHeight();

        camera = new OrthographicCamera();
        camera.setToOrtho(false,w,h);
        tiledMap = new TmxMapLoader().load("iso.tmx");//iso
        renderer = new IsometricTiledMapRenderer(tiledMap);
        camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());


        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();

        camera.update();


        Gdx.input.setInputProcessor(this);

        sb = new SpriteBatch();
        texture = new Texture(Gdx.files.internal("sand_128x64.png"));
        sprite = new Sprite(texture);
        sprite.setSize(50,50);



         mapWidth = tiledMap.getProperties().get("width",Integer.class);
         mapHeight = tiledMap.getProperties().get("height",Integer.class);



    }

    @Override
    public void render () {
        Gdx.gl.glClearColor(.5f, .7f, .9f, 1);
        Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        camera.zoom = zoom;




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

        sb.setProjectionMatrix(camera.combined);
        sb.begin();
        //sprite.draw(sb);

        sb.end();



    }


    public Vector2 worldToCell(float x, float y) {
        float halfTileWidth = mapWidth * 0.5f;
        float halfTileHeight = mapHeight * 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 -= mapHeight *0.5f;
        return worldToCell(world.x,world.y);
    }

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
        Vector2 cell = screenToCell(screenX,screenY);

        TiledMapTileLayer layer = (TiledMapTileLayer)tiledMap.getLayers().get("Layer1");

        TiledMapTileLayer.Cell tileCell = layer.getCell((int) cell.x, (int) cell.y);
        TiledMapTile  tile = tileCell.getTile();

        tileCell.setFlipHorizontally(!tileCell.getFlipHorizontally());

        System.out.println("selectedCell = "+cell.toString());
        c=cell.toString();
        tileCell.setTile(tile);



        lastx=-screenX;
        lasty=screenY;
        Vector3 clickCoordinates = new Vector3(screenX,screenY,0);
        Vector3 position = camera.unproject(clickCoordinates);

        translate=position.x;



        return true;
    }





    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
        lastx=0;
        lasty=0;
        return false;
    }

    @Override
    public boolean touchDragged(int screenX, int screenY, int pointer) {

        if (lastx != 0) {
            camera.translate(-screenX - lastx, screenY - lasty);
            lastx = -screenX;
            lasty = screenY;




        }

        return false;
    }

    @Override
    public boolean mouseMoved(int screenX, int screenY) {

        return false;
    }

    @Override
    public boolean scrolled(int amount) {

        return false;
    }

    @Override
    public boolean keyDown(int p1)
    {
        // TODO: Implement this method
        return false;
    }

    @Override
    public boolean keyUp(int p1)
    {
        // TODO: Implement this method
        return false;
    }

    @Override
    public boolean keyTyped(char p1)
    {
        // TODO: Implement this method
        return false;
    }

}

And now I want to pick the tile on touching it, so I get the tile (x, y) , I tried many ways to do this but I couldn't find a good solution, and I tried this现在我想在触摸它时选择瓷砖,所以我得到了瓷砖 (x, y) ,我尝试了很多方法来做到这一点,但我找不到一个好的解决方案,我尝试了这个

LibGDX: How to make tiled map tiles clickable? LibGDX:如何使平铺地图图块可点击?

But it didn't work, so what can I do?但它不起作用,那我该怎么办?

The problem is that you can't put clickable squares as isometric maps are rotated squares问题是你不能放置可点击的方块,因为等轴测图是旋转方块

See this article.看到这篇文章。 Or you can use a rotated matrix...或者您可以使用旋转矩阵...

In create init the Matrixes...create初始化矩阵...


    @Override
    public void create () {
        //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();
        ...
        ...
        ...
        ...

    }

Add this methods....添加此方法....


    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);
        cam.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);
    }

And finally you would get the tile like this....最后你会得到这样的瓷砖......

@Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
        Vector2 cell = screenToCell(screenX,screenY);
        System.out.println("selectedCell = "+cell.toString());

        //if you want to get the tile and the cell 
        TiledMapTileLayer layer = (TiledMapTileLayer)tiledMap.getLayers().get("Tile Layer 1");

        TiledMapTileLayer.Cell tileCell = layer.getCell((int) cell.x, (int) cell.y);
        TiledMapTile           tile     =  tileCell.getTile();

        //flip the tile just so you have a visual to make sure your selected the right tile
        tileCell.setFlipHorizontally(!tileCell.getFlipHorizontally());

        return true;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM