libgdx がサポートしているメインの入力デバイスは、キーボードと、デスクトップ/ブラウザ環境ではマウス、Android環境ではタッチスクリーンです。 それでは、libgdx がどうやってこれらを抽象化しているか見てみましょう。
キーボードは、キーを押して離した際にイベントを生成して、ユーザーの入力信号を送信します。 各イベントには、押された/離されたキーを識別するためのキーコードも付いて来ます。 これらキーコードはプラットフォームごとに異なります。 Libgdx では、独自のキーコード表を用意することでそうしたプラットフォーム間に差異を意識させないようにします。 詳細はKeys (source) クラスを参照してください。 ポーリングを行って現在どのキーが押されているかを照会できます。
キーコードだけでは、ユーザーが実際にどのキーを入力したのかは分かりません。 キーコードの情報はしばしば、複数のキーの状態から発生します。例えば、文字'A'は'a' キーと 'shift'キーが同時に押されることで生成されます。 一般的には、キーボードの状態(キーが押されている状態)から文字を割り出すのはそこそこ重要なことです。 ありがたいことに、OSには通常、キーコードイベント(キーを押す/キーを離す)だけでなく押された文字も通知するイベントリスナを登録するための手段が用意されています。 Libgdx ではこの内部メカニズムを使ってあなたに文字情報を伝えます。詳細についてはイベント処理を参照してください。
マウス入力とタッチ入力を使うことで、ユーザーは画面上にあるものを指し示すことができます。 これらの入力メカニズムは両方とも、デバイスが指し示した位置を、画面の左上隅を開始点とした2D座標として通知します。 X軸は右へ行くほど座標の値が大きくなり、Y軸は下へ行くほど座標の値が大きくなります。
マウス入力では追加の情報が付いて来ます。すなわち、どのマウスボタンが押されたかです。 ほとんどのマウスでは、左ボタンと右ボタンだけでなく中央ボタンの機能があります。 さらに、多くのアプリケーションでズームやスクロールとして使用できるスクロールホイールもしばしば付いています。
タッチ入力にはボタンの概念が無く、またハードウェアによっては複数の指の動きを捕捉するので複雑になります。 第一世代のAndroid 携帯はシングルタッチのみサポートしていました。Motorola Droidのような携帯を皮切りに、ほとんどのAndroid携帯ではマルチタッチが標準機能になりました。
端末が違えばタッチ機能の実装も違ってくるので注意してください。This can affect how pointer indexes are specified and released and when touch events are fired. できるだけ多くの端末で、タッチ機能のテストをするようにして下さい。 また、マーケットには多くの入力テストアプリがあります。特定の端末でどのようにタッチ情報を通知するのか判別するのに役立ち、多くの端末で正しく動作するタッチ処理を設計する手助けになります。
Libgdx はマウス入力とタッチ入力を統一処理として抽象化します。マウス入力は、ちょっと変わったタッチ入力と見なします。 指は一つだけを捕捉し、座標に加えてどのマウスボタンが押されたかを通知します。 タッチ入力の場合は複数の指(ポインター)を捕捉でき、全てのイベントにおいてマウスの左ボタンが押されたものとして通知がされます。
Android環境において、座標系はあなたのアプリケーションの設定に応じて縦向きモードか横向きモードのいずれかになるので注意してください。
マウス入力とタッチ入力は、 ポーリングをするか、イベント処理を介して処理できます。
タッチポイントやマウスカーソルの正確な世界座標を取得するには、使用しているcameraのunprojectメソッドで画面座標を処理する必要があります。 以下はそれを行うための例です。
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); } }