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事件监听

上面介绍的方法是主动查询,那么接下来介绍的这种方法可以说是事件监听,是被动触发。

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

时间: 2024-09-29 22:33:45

Libgdx之监听用户输入的相关文章

迭代器 生成器 实时监听用户输入

def tail(filename): f = open(filename,encoding='utf-8') while True: line = f.readline() if line: yield line.strip() g = tail('file') for i in g: print(i) 原文地址:https://www.cnblogs.com/fate2048/p/9691609.html

11双向数据绑定和监听用户的输入

双向数据绑定 方向一:将数据绑定到视图 方向二:将视图用户操作的结果 绑定到 数据 语法:<input   type=" "       [(ngModule)] = " "> ①必须指定模块 依赖于 表单模块(ngModule指令并不属于ng核心模块的,属于表单模块) 在app.module.ts中,引入表单模块 import {FormsModule} from '@angular/forms' ②在数据的元数据 imports 数组中指定表单模块的

Android开发之EditText 详解(addTextChangedListener监听用户输入状态)

为了实现像qq或者微信输入框的效果,当在 EditText输入字符串时发送按钮显示,当输入框字符消除掉时按钮改变.所以这时候我就要用到addTextChangedListener 用它来监听用户输入状态.可以在监听中改变用户输入的内容或者提示用户输入内容不合法等等 EditText editText = (EditText)findViewById(R.id.monitor_edit_text0); editText.addTextChangedListener(new TextWatcher(

实时监听input输入

oninput 是 HTML5 的标准事件,对于检测 textarea, input:text, input:password 和 input:search 这几个元素通过用户界面发生的内容变化非常有用,在内容修改后立即被触发,不像 onchange 事件需要失去焦点才触发.oninput 事件在主流浏览器的兼容情况如下: 从上面表格可以看出,oninput 事件在 IE9 以下版本不支持,需要使用 IE 特有的 onpropertychange 事件替代,这个事件在用户界面改变或者使用脚本直接

Spring Boot实现一个监听用户请求的拦截器

项目中需要监听用户具体的请求操作,便通过一个拦截器来监听,并继续相应的日志记录 项目构建与Spring Boot,Spring Boot实现一个拦截器很容易. Spring Boot的核心启动类继承WebMvcConfigurerAdapter // 增加拦截器 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new RequestLog()); } //这

Android EditText的输入监听,输入字符的动态获取

http://itindex.net/detail/38974-android-edittext-%E7%9B%91%E5%90%AC 有时候我们可能会用到时时的监听EditText输入字符的时时监听,监听字符的个数,做一些正则表达式的处理等.如下方法可以实现: 我做的是时时的把EditeText输入的数据同步到TextView上 布局文件: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android&

微信小程序监听用户上滑下滑事件

今天做了一个要根据用户上滑或者下滑来显示不同内容的功能. 思路:先监听用户是上滑还是下滑,监听到结果后改变data数据中用来判断模块显示隐藏的变量,两个需要切换的模块使用两个hidden,data中定义两个变量来接受更改后的true或者false 页面 hidden='{{bottom}}' hidden='{{top}}' data{ //初始化状态 top:true, bottom:false, } //判断浏览器滚动条上下滚动 if (t.scrollTop > a.data.scroll

实时监听input输入的变化(兼容主流浏览器)

遇到如此需求,首先想到的是change事件,但用过change的都知道只有在input失去焦点时才会触发,并不能满足实时监测的需求,比如监测用户输入字符数. 在经过查阅一番资料后,欣慰的发现firefox等现代浏览器的input有oninput这一属性,可以用三种方式使用它: 1,内嵌元素方式(属性编辑方式) <input id="test" oninput="console.log('input');" type="text" />

[转] 实时监听input输入的变化(兼容主流浏览器)

遇到如此需求,首先想到的是change事件,但用过change的都知道只有在input失去焦点时才会触发,并不能满足实时监测的需求,比如监测用户输入字符数. 在经过查阅一番资料后,欣慰的发现firefox等现代浏览器的input有oninput这一属性,可以用三种方式使用它: 1,内嵌元素方式(属性编辑方式) <input id="test" oninput="console.log('input');" type="text" />