LibGDX - GestureListener触摸坐标以屏幕像素返回,如何转换为游戏中的世界单位?

时间:2016-08-15 00:17:06

标签: java android libgdx touch

如何将从GestureListener(例如TouchDown方法)返回的坐标转换为世界单位坐标。

EG。我的设备屏幕是1080p,我的游戏设置为使用540x960(人像)。 在我当前的示例项目(下面的代码)中,桨叶沿着x轴移动两倍于我的手指,因此设置的位置以屏幕像素给出。

当然在这个确切的例子中,我可以很容易地将它除以2,因为我知道游戏世界单位正好是设备像素的一半,但是如果我想让我的世界大小为150x150单位 - 或者如果我正在测试具有不同屏幕尺寸的设备吗?

package com.moneylife.breakingass;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.math.Vector2;


public class BreakingAss extends ApplicationAdapter {
    SpriteBatch batch;
    Sprite bgSprite, bgCoverSprite, menu1Sprite;
    Paddle paddle;


    enum ScreenState { StartScreen, PlayScreen, GameOverScreen }
    ScreenState currentScreenState;

    public int DeviceScreenWidth, DeviceScreenHeight;
    public int WorldWidth = 540, WorldHeight = 960;
    public OrthographicCamera camera;
    int zAxis = 0;

    MyGestureDetector myGestureDetector;

    @Override
    public void create () {
        currentScreenState = ScreenState.StartScreen;
        batch = new SpriteBatch();
        DeviceScreenWidth = Gdx.graphics.getWidth();
        DeviceScreenHeight = Gdx.graphics.getHeight();
        myGestureDetector = new MyGestureDetector();

        bgSprite = new Sprite(new Texture("bentoverass.jpg"));
        bgCoverSprite = new Sprite(new Texture("half1080coverup.png"));
        menu1Sprite = new Sprite(new Texture("menu1.jpg"));

        menu1Sprite.setSize(WorldHeight * DeviceScreenWidth / DeviceScreenHeight,WorldHeight);
        menu1Sprite.setPosition(0,0);

        camera = new OrthographicCamera(WorldWidth, WorldHeight);
        camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, zAxis);
        camera.update();

        paddle = new Paddle(WorldWidth, WorldHeight);
        Gdx.input.setInputProcessor(new GestureDetector(myGestureDetector));
    }

    @Override
    public void render () {
        Gdx.gl.glClearColor(1, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        paddle.update();
        camera.update();



        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        if (currentScreenState == ScreenState.StartScreen){
            menu1Sprite.draw(batch);
        }
        if (currentScreenState == ScreenState.PlayScreen){
            paddle.draw(batch);
        }


        batch.end();
    }

    @Override
    public void dispose () {
        batch.dispose();

    }

    public class MyGestureDetector implements GestureDetector.GestureListener {
        @Override
        public boolean touchDown(float x, float y, int pointer, int button) {
            if (currentScreenState == ScreenState.StartScreen) {
                if (x > 0) {
                    currentScreenState = ScreenState.PlayScreen;
                }
            }

            if (currentScreenState == ScreenState.PlayScreen){
                paddle.position = new Vector2(x - paddle.texture.getWidth() / 2, paddle.fixedYPosition);
            }
            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) {
            if (currentScreenState == ScreenState.PlayScreen){
                paddle.position = new Vector2(x - paddle.texture.getWidth() / 2, paddle.fixedYPosition);
            }
            return false;
        }

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

        @Override
        public boolean zoom(float initialDistance, float distance) {
            return false;
        }

        @Override
        public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2) {
            return false;
        }

        @Override
        public void pinchStop() {

        }
    }

}

1 个答案:

答案 0 :(得分:0)

获取输入坐标始终产生屏幕的坐标。从逻辑上讲,因为输入不需要(需要)知道您的游戏世界。相机负责绘制屏幕的内容,相机可用于将屏幕坐标转换为您的世界坐标。

//Get screen coordinates
Vector3 mousePosition = new Vector3(Gdx.input.getX, Gdx.input.getY, 0);
//Transform to world coordinates using the correct camera
camera.unproject(mousePosition);
//The mousePosition vector is changed in the above method and now contains the game world coordinates of the camera you used.

PS。 对于您的球拍,您可以制作变换方法,以便在deltaX方法中使用deltaYpan。由于三角洲向你提供了“平移”的变化,因此根本不需要在屏幕和世界之间进行转换。