Libgdx之监听用户输入

做游戏的最重要的是要与用户有交互,怎样与用户交互Ligdx提供了2种方式。

Libgdx事件查询(Event Polling)

这种方式主要是Libgdx主动查询当前的状态,通过这种方式我们可以查询键盘输入,鼠标事件,加速器等状态
事实上主动查询事件是在render()方法中调用,意味每一帧我们都会来查询事件状态。

在Libgdx上我们可以获得屏幕点击坐标 Gdx.input.getX() 和 Gdx.input.getY(),注意这时获取的坐标为Touch坐标,我们要通过函数camera.unproject()将其转换为World坐标。我们在查阅文档时unproject方法为将screen坐标转换为World坐标,其实在unproject方法中是先讲Touch坐标转换为Screen坐标再转换为World坐标。

其实有些设备是不支持一些输入的,比如desktop工程就不支持加速器,这时我们可以先通过下面方法来查询设备是否可用,然后再处理

Gdx.input.isPeripheralAvailable(Peripheral.Accelerometer);
Gdx.input.isPeripheralAvailable(Peripheral.Compass);
Gdx.input.isPeripheralAvailable(Peripheral.HardwareKeyboard);
Gdx.input.isPeripheralAvailable(Peripheral.MultitouchScreen);
Gdx.input.isPeripheralAvailable(Peripheral.OnscreenKeyboard);
Gdx.input.isPeripheralAvailable(Peripheral.Vibrator);

下面是一些测试代码来帮助大家理解

private static final float scene_width = 640f;
    private static final float scene_height = 480f;

    SpriteBatch batch;
    BitmapFont font;

    @Override
    public void create() {
        batch = new SpriteBatch();
        font = new BitmapFont();
    }

    @Override
    public void render() {
        Gdx.gl.glClearColor(0.39f, 0.58f, 0.92f, 1.0f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.begin();

        // Mouse / touch
        int mouseX = Gdx.input.getX();
        int mouseY = Gdx.input.getY();
        boolean leftPressed = Gdx.input.isButtonPressed(Buttons.LEFT); // 鼠标左键触发事件
        boolean rightPressed = Gdx.input.isButtonPressed(Buttons.RIGHT); // 鼠标右键触发事件
        boolean middlePressed = Gdx.input.isButtonPressed(Buttons.MIDDLE); // 鼠标中键触发事件

        font.draw(batch, "Mouse/Touch: x=" + mouseX + " y=" + mouseY, 20.0f,
                scene_height - 20.0f);
        font.draw(batch, leftPressed ? "Mouse left button pressed"
                : "Mouse left button not pressed", 20.0f, scene_height - 50.0f);
        font.draw(batch, rightPressed ? "Mouse right button pressed"
                : "Mouse right button not pressed", 20.0f, scene_height - 80.0f);
        font.draw(batch, middlePressed ? "Mouse middle button pressed"
                : "Mouse middle button not pressed", 20.0f,
                scene_height - 110.0f);

        boolean wPressed = Gdx.input.isKeyPressed(Keys.W);
        boolean aPressed = Gdx.input.isKeyPressed(Keys.A);
        boolean sPressed = Gdx.input.isKeyPressed(Keys.S);
        boolean dPressed = Gdx.input.isKeyPressed(Keys.D);

        // Keys
        font.draw(batch, wPressed ? "W is pressed" : "W is not pressed", 20.0f,
                scene_height - 160.0f);
        font.draw(batch, aPressed ? "A is pressed" : "A is not pressed", 20.0f,
                scene_height - 190.0f);
        font.draw(batch, sPressed ? "S is pressed" : "S is not pressed", 20.0f,
                scene_height - 220.0f);
        font.draw(batch, dPressed ? "D is pressed" : "D is not pressed", 20.0f,
                scene_height - 250.0f);

        batch.end();
    }

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

测试结果,其实移动鼠标就会发现Touch的坐标原点是在左上角

Libgdx事件监听

上面介绍的方法是主动查询,那么接下来介绍的这种方法可以说是事件监听,是被动触发。
Libgdx之监听用户输入_第1张图片
InputProcessor用于接听键盘和鼠标输入。要想Libgdx监听它,需要使用setInputProcessor(InputProcessor)来注册,之后再render()方法中即每一帧中自动监听调用。

    public static final int MESSAGE_MAX = 10;

    private Array<String> messages;
    private BitmapFont font;
    SpriteBatch batch;
    InputProcessorEvent processorEvent;

    @Override
    public void create() {
        batch = new SpriteBatch();
        font = new BitmapFont();
        messages = new Array<String>();

        processorEvent = new InputProcessorEvent();
        Gdx.input.setInputProcessor(processorEvent); // 此方法一次只能是一个Input processor有效

        /*** 可以下面方法设置几个InputPorcessor * Gdx.input.setInputProcessor(multiplexer); * multiplexer.addProcessor(new InputHandlerA()); * multiplexer.addProcessor(new InputHandlerB()); */

        // 监听返回键和菜单键
        Gdx.input.setCatchBackKey(true);
        Gdx.input.setCatchMenuKey(true);
    }

    @Override
    public void render() {
        Gdx.gl.glClearColor(0.39f, 0.58f, 0.92f, 1.0f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.begin();
        for (int i = 0; i < messages.size; ++i) {
            font.draw(batch, messages.get(i), 20.0f, 480 - 40.0f * (i + 1));
        }
        batch.end();
    }

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

    class InputProcessorEvent implements InputProcessor {

        @Override
        public boolean keyDown(int keycode) {
            addMessage("keyDown: keycode(" + keycode + ")");

            if (keycode == Keys.BACK) {
                // TODO: 处理返回事件
            } else if (keycode == Keys.MENU) {
                // TODO: 处理菜单事件
            }

            return true;  // 如果此处设置为false那么不会执行key up
        }

        @Override
        public boolean keyUp(int keycode) {
            addMessage("keyUp: keycode(" + keycode + ")");
            return true;
        }
          @Override
            public boolean keyTyped(char character) {  // 可以输出按键的字母和数字,不过貌似不好使
                addMessage("keyTyped: character(" + character + ")");
                return true;
            }

            @Override
            public boolean touchDown(int screenX, int screenY, int pointer, int button) {
                addMessage("touchDown: screenX(" + screenX + ") screenY(" + screenY + ") pointer(" + pointer + ") button(" + button + ")");
                return true;
            }

            @Override
            public boolean touchUp(int screenX, int screenY, int pointer, int button) {
                addMessage("touchUp: screenX(" + screenX + ") screenY(" + screenY + ") pointer(" + pointer + ") button(" + button + ")");
                return true;
            }

            @Override
            public boolean touchDragged(int screenX, int screenY, int pointer) {
                addMessage("touchDragged: screenX(" + screenX + ") screenY(" + screenY + ") pointer(" + pointer + ")");
                return true;
            }

            @Override
            public boolean mouseMoved(int screenX, int screenY) {
// addMessage("mouseMoved: screenX(" + screenX + ") screenY(" + screenY + ")");
                return true;
            }

            @Override
            public boolean scrolled(int amount) {
                addMessage("scrolled: amount(" + amount + ")");
                return true;
            }

        private void addMessage(String message) {
            messages.add(message + "time: " + System.currentTimeMillis());

            if (messages.size > MESSAGE_MAX) {
                messages.removeIndex(0);
            }
        }
    }

Libgdx之监听用户输入_第2张图片

你可能感兴趣的:(libgdx)