LibGDX输入模块之鼠标、触摸屏及键盘

libgdx支持的主要输入设备是桌面/浏览器上的鼠标,Android上的触摸屏以及键盘。 我们来看看libgdx如何抽象这些输入设备。

键盘

键盘通过生成用于按下和释放键的事件来指示用户输入了哪个键。 每个事件带有一个键代码,用于标识被按下/释放的键。 这些密钥代码在平台之间有所不同。 Libgdx尝试通过提供自己的密钥代码表来隐藏这个差异性,参见Keys (source) 类了解更多。 您可以通过轮询查询当前正在被按下的键。

Key-codes alone do not give us information about which character the user actually entered. This information is often derived from the state of multiple keys, e.g. the character 'A' is generated by the keys 'a' and 'shift' being pressed simultaneously. In general, deriving characters from the keyboard's state (which keys are down) is non-trivial. Thankfully, the operating system usually has a means to hook up an event listener that not only reports key-code events (key pressed/key released), but also characters. Libgdx uses this mechanism under the hood to provide you with character information. See Event Handling.

鼠标和触摸屏

鼠标和触摸输入允许用户指向屏幕上的东西。 两个输入机制将相互作用的位置报告为相对于屏幕左上角的2D坐标,正x轴指向右侧,y轴指向下方。

鼠标输入附带附加信息,即哪个按钮被按下。 大多数鼠标都有一个左键和一个鼠标右键以及一个鼠标中键。 此外,通常有一个滚轮可用于许多应用中的缩放或滚动。

触摸输入不具有按钮的概念,并且由于硬件的差异性导致监听多点触摸变得复杂。 第一代Android手机只支持单触。 从摩托罗拉Droid手机开始,多点触控成为大多数Android手机的标准功能。

触摸在不同的设备上有完全不同的实现方式,这关系到指针索引的指定和释放以及触发事件的方式,确保用尽可能多的设备来测试你的控制方案是否可行,市面上也有 很多的输入测试应用程序,它可以帮忙确定特定的设备如何处理触摸事件,并帮助设计一种在多设备上运行的控制方案。

LibGDX统一处理鼠标和触摸事件,对于鼠标事件,LibGDX会把它看做是一种特殊的触摸事件,它只有一个手指被跟踪,处理报告坐标外,它还会上报是是左键还是右键被按下了,对于触摸输入,我们支持跟踪多个手指(指针),并报告所有事件的按键是鼠标左键。

注意,在Android系统中,坐标系统相对于纵向或横向模式,取决于您为应用程序设置的内容。
鼠标事件或者触摸事件都可以被轮训polled 或者通过事件进行监听Event Handling

接触点

获得正确的世界坐标的接触点或鼠标光标要转换原屏幕坐标与摄像机在世界坐标。下面是一个简单的例子。

public class SimplerTouchTest extends ApplicationAdapter implements InputProcessor {
    // we will use 32px/unit in world
    public final static float SCALE = 32f;
    public final static float INV_SCALE = 1.f/SCALE;
    // this is our "target" resolution, not that the window can be any size, it is not bound to this one
    public final static float VP_WIDTH = 1280 * INV_SCALE;
    public final static float VP_HEIGHT = 720 * INV_SCALE;

    private OrthographicCamera camera;
    private ExtendViewport viewport;        
    private ShapeRenderer shapes;
    
    @Override public void create () {
        camera = new OrthographicCamera();
        // pick a viewport that suits your thing, ExtendViewport is a good start
        viewport = new ExtendViewport(VP_WIDTH, VP_HEIGHT, camera);
        // ShapeRenderer so we can see our touch point
        shapes = new ShapeRenderer();
        Gdx.input.setInputProcessor(this);
    }
    
    @Override public void render () {
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        shapes.setProjectionMatrix(camera.combined);
        shapes.begin(ShapeRenderer.ShapeType.Filled);
        shapes.circle(tp.x, tp.y, 0.25f, 16);
        shapes.end();
    }
    
    Vector3 tp = new Vector3();
    boolean dragging;
    @Override public boolean mouseMoved (int screenX, int screenY) {
        // we can also handle mouse movement without anything pressed
//      camera.unproject(tp.set(screenX, screenY, 0));
        return false;
    }
    
    @Override public boolean touchDown (int screenX, int screenY, int pointer, int button) {
        // ignore if its not left mouse button or first touch pointer
        if (button != Input.Buttons.LEFT || pointer > 0) return false;
        camera.unproject(tp.set(screenX, screenY, 0));
        dragging = true;
        return true;
    }
    
    @Override public boolean touchDragged (int screenX, int screenY, int pointer) {
        if (!dragging) return false;
        camera.unproject(tp.set(screenX, screenY, 0));
        return true;
    }
    
    @Override public boolean touchUp (int screenX, int screenY, int pointer, int button) {
        if (button != Input.Buttons.LEFT || pointer > 0) return false;
        camera.unproject(tp.set(screenX, screenY, 0));
        dragging = false;
        return true;
    }
    
    @Override public void resize (int width, int height) {
        // viewport must be updated for it to work properly
        viewport.update(width, height, true);
    }
    
    @Override public void dispose () {
        // disposable stuff must be disposed
        shapes.dispose();
    }
    
    @Override public boolean keyDown (int keycode) {
        return false;
    }
    
    @Override public boolean keyUp (int keycode) {
        return false;
    }
    
    @Override public boolean keyTyped (char character) {
        return false;
    }
    
    @Override public boolean scrolled (int amount) {
        return false;
    }
    
    public static void main (String[] arg) {
        LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
        config.width = 1280;
        config.height = 720;
        config.useHDPI = true;
        new LwjglApplication(new SimplerTouchTest(), config);
    }
}

//TODO 待续

你可能感兴趣的:(LibGDX输入模块之鼠标、触摸屏及键盘)