简体   繁体   English

LibGDX:如何在带有和不带有缩放的图块的图块地图中获取相同的坐标

[英]LibGDX: How to get the same coordinates in tiled map for tile with and without zoom

I am a beginner with LibGDX. 我是LibGDX的初学者。 I am trying to create an android game based fixed size tiled map (33x21 tiles). 我正在尝试基于固定大小的平铺地图(33x21平铺)创建一个Android游戏。 Tiles I am using are 32x32px. 我正在使用的图块是32x32px。 So far I managed to load the map created with Tiled and add touch gestures like zoom in/out and panning. 到目前为止,我设法加载了Tiled创建的地图,并添加了诸如放大/缩小和平移之类的触摸手势。 The game character movement will be turn based tile by tile, so I need to have a possibility to select specific tile in order to perform some action. 游戏角色的移动将逐个回合进行,因此我需要选择特定的回合以执行一些动作。 I tried solution from here: LibGDX: How to make tiled map tiles clickable? 我从这里尝试了解决方案: LibGDX:如何使平铺的地图图块可点击? and it works perfectly fine, until the screen is not zoomed in. 并且效果很好,直到没有放大屏幕为止。

Without zoom, the left-bottom corner coordinates shows that it is (0,0), which is correct. 如果没有缩放,则左下角坐标显示为(0,0),这是正确的。 When I zoom in, the left-bottom corner of the visible part of the map instead of keeping it's correct coordinates (ie (480, 320)) it becomes (0,0) again. 当我放大时,地图可见部分的左下角而不是保持正确的坐标(即(480,320)),而是再次变为(0,0)。 I tried to use camera.unproject(Vector3), but I was unsuccessful. 我尝试使用camera.unproject(Vector3),但未成功。 Probably used it wrong. 可能用错了。 I am also not really convinced, that the way in which I try to get tiles is the most appropriate one. 我也没有真正确信,我尝试获取瓷砖的方法是最合适的方法。 Can you help me get tiles coordinates properly? 您能帮我正确地获得瓷砖坐标吗? Below is the code that I am using: 下面是我正在使用的代码:

public class TiledTest extends ApplicationAdapter  {

public TiledMap tiledMap;
OrthographicCamera camera;
TiledMapRenderer tiledMapRenderer;

GestureDetector gesture;
InputMultiplexer myInputMultiplexer;

float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();

public static final float PAN_RATE = (float) 0.01;
private static final float ZOOM_SPEED = (float) 0.009;
int columns, rows;
TiledMapTileLayer grid_layer;

@Override
public void create () {

    gesture =new GestureDetector(new MyGestureListener());
    myInputMultiplexer = new InputMultiplexer();
    float unitScale = 1 / 32f;


    camera = new OrthographicCamera();
    camera.setToOrtho(true, 33,21);

    tiledMap = new TmxMapLoader().load("tiled_map.tmx");
    tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap, unitScale);
    grid_layer = (TiledMapTileLayer)tiledMap.getLayers().get(0);
    Stage stage = new TiledMapStage(tiledMap);
    myInputMultiplexer.addProcessor(gesture);
    myInputMultiplexer.addProcessor(stage);
    Gdx.input.setInputProcessor(myInputMultiplexer);
}

@Override
public void render () {

    tiledMapRenderer.setView(camera);
    tiledMapRenderer.render();
    camera.update();
}

public class TiledMapActor extends Actor {

    private TiledMapTileLayer.Cell cell;

    public TiledMapActor(TiledMap tileMap, TiledMapTileLayer tiledLayer, TiledMapTileLayer.Cell cell) {
        tiledMap = tileMap;
        grid_layer = tiledLayer;
        this.cell = cell;
    }

}

public class TiledMapClickListener extends ClickListener {

    private TiledMapActor actor;

    public TiledMapClickListener(TiledMapActor actor) {
        this.actor = actor;
    }

    @Override
    public void clicked(InputEvent event, float x, float y) {

    int a = (int) actor.getX();
        int b = (int) actor.getY();

        System.out.println(actor.cell + " has been clicked.");
        System.out.println("x =  " + a +  "y = " + b );
        }
}

public class TiledMapStage extends Stage {

    private TiledMap tiledMap;

    public TiledMapStage(TiledMap tiledMap) {
        this.tiledMap = tiledMap;

        for (MapLayer layer : tiledMap.getLayers()) {

            TiledMapTileLayer tiledLayer = (TiledMapTileLayer)layer;
            createActorsForLayer(tiledLayer);
        }
    }

    private void createActorsForLayer(TiledMapTileLayer tiledLayer) {
        for (int x = 0; x <= tiledLayer.getWidth(); x++) {
            for (int y = 0; y < tiledLayer.getHeight(); y++) {
                TiledMapTileLayer.Cell cell = tiledLayer.getCell(x, y);
                TiledMapActor actor = new TiledMapActor(tiledMap, tiledLayer, cell);
                actor.setBounds(x * tiledLayer.getTileWidth(), y * tiledLayer.getTileHeight(), tiledLayer.getTileWidth(),
                        tiledLayer.getTileHeight());
                addActor(actor);
                EventListener eventListener = new TiledMapClickListener(actor);
                actor.addListener(eventListener);
            }
        }
    }
}

public void resize(float width, float height) {

}

public class MyGestureListener implements GestureListener{

    @Override
    public boolean touchDown(float x, float y, int pointer, int button) {
        return false;
    }

    @Override
    public boolean tap(float x, float y, int count, int button) {
        return false;
    }

    @Override
    public boolean longPress(float x, float y) {
        return false;
    }

    @Override
    public boolean fling(float velocityX, float velocityY, int button) {
        return false;
    }

    @Override
    public boolean pan(float x, float y, float deltaX, float deltaY) {

        float effectiveViewportWidth = camera.viewportWidth * camera.zoom;
        float effectiveViewportHeight = camera.viewportHeight * camera.zoom;

        camera.position.x = MathUtils.clamp(camera.position.x, effectiveViewportWidth / 2f, 33 - effectiveViewportWidth / 2f);
        camera.position.y = MathUtils.clamp(camera.position.y, effectiveViewportHeight / 2f, 21 - effectiveViewportHeight / 2f);
        if (camera.zoom < 1) {

             camera.translate(-deltaX * PAN_RATE, -deltaY * PAN_RATE,   0);
             camera.update();
        } 
        return false;
    }

    @Override
    public boolean panStop(float x, float y, int pointer, int button) {
        //Gdx.app.log("Text", "panstop");
        return false;
    }


    @Override
    public boolean zoom (float originalDistance, float currentDistance){

         float ratio = originalDistance/currentDistance;

         camera.zoom += ZOOM_SPEED * ratio;

        if (camera.zoom < 0.3)
         {
            camera.zoom = (float) 0.3;
         }
         else if (camera.zoom > 1)
         {
            camera.zoom = 1;
         }
         System.out.println(camera.zoom);
    return false;
}

    @Override
    public boolean pinch (Vector2 initialFirstPointer, Vector2 initialSecondPointer, Vector2 firstPointer, Vector2 secondPointer){
         camera.zoom -= .01;
         camera.update();
       return false;
    }

}

} }

So you want to transfer the screen coordinates to world coordinates. 因此,您想将屏幕坐标转换为世界坐标。
For example: 例如:

@Override
public void clicked(InputEvent event, float x, float y) {

    Vector3 touch = new Vector3(x, y, 0);
    camera.unproject(touch);

    System.out.println("Screen coordinates translated to world coordinates: "
        + "X: " + touch.x + " Y: " + touch.y);

    }
}

Above clicked function does not worked for me, but you led me to the answer. 上面单击的功能不适用于我,但是您使我找到了答案。 I dumped whole assigning actors for tiles and used camera.unproject in MyGestureListener in touchDown. 我将整个分配角色丢弃为图块,并在touchDown的MyGestureListener中使用了camera.unproject。

If someone is interested I just leave it here :) 如果有人感兴趣,我就把它留在这里:)

@Override
    public boolean touchDown(float x, float y, int pointer, int button) {

         Vector3 temp_coord = new Vector3(x,y,0);
         Vector3  coords = camera.unproject(temp_coord);

            x =(int) coords.x;
            y =(int) coords.y;

            writerX = x;
            writerY = y;

            System.out.println("Screen coordinates translated to world coordinates: "
                    + "X: " + x + " Y: " + y);

        return false;
    }

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

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