LibGDX:如何在有和没有缩放的图块的平铺地图中获得相同的坐标

时间:2014-11-14 08:54:00

标签: java libgdx tiled

我是LibGDX的初学者。我正在尝试创建一个基于固定大小的平铺地图(33x21瓷砖)的Android游戏。我使用的瓷砖是32x32px。到目前为止,我设法加载了使用Tiled创建的地图,并添加了放大/缩小和平移等触摸手势。游戏角色移动将逐个平铺,因此我需要有可能选择特定的平铺以执行某些操作。我从这里尝试了解决方案:LibGDX: How to make tiled map tiles clickable?并且它完全正常,直到屏幕没有放大。

没有缩放,左下角坐标显示它是(0,0),这是正确的。当我放大地图的可见部分的左下角而不是保持它的正确坐标(即(480,320))时,它再次变为(0,0)。我试图使用camera.unproject(Vector3),但我没有成功。可能用错了。我也不是很确信,我试图获得瓷砖的方式是最合适的。你能帮我正确地找到瓷砖坐标吗?以下是我正在使用的代码:

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

}

}

2 个答案:

答案 0 :(得分:3)

所以你想把屏幕坐标转移到世界坐标 例如:

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

    }
}

答案 1 :(得分:2)

上面点击的功能对我不起作用,但是你引导我找到答案。我为tile分配了整个分配actor,并在touchDown中的MyGestureListener中使用了camera.unproject。

如果有人有兴趣我就把它留在这里:)

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