首页 > 解决方案 > 如何在等距 libgdx 中触摸它时获得平铺位置

问题描述

我正在创建 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;
    }

}

现在我想在触摸它时选择瓷砖,所以我得到了瓷砖 (x, y) ,我尝试了很多方法来做到这一点,但我找不到一个好的解决方案,我尝试了这个

LibGDX:如何使平铺地图图块可点击?

但它不起作用,那我该怎么办?

标签: javaandroidlibgdxtileisometric

解决方案


问题是您不能放置可点击的正方形,因为等轴测图是旋转的正方形

这篇文章。或者您可以使用旋转矩阵...

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

    }

添加此方法....


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

最后你会得到这样的瓷砖......

@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;
    }

推荐阅读