做游戏的最重要的是要与用户有交互,怎样与用户交互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