Libgdx之監聽用戶輸入


教程總目錄: http://blog.csdn.net/zqiang_55/article/details/50878524

做游戲的最重要的是要與用戶有交互,怎樣與用戶交互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);
}
}
}

這里寫圖片描述


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com