Android StudioとlibGDXでアプリ開発 練習編3

前回の記事では描画に関する機能を紹介しました。
今回はタッチイベントなどのイベントハンドリングの紹介です。

メインループ内でタッチを検知する

サンプルコードを例に解説していきます。

core\src\com\mygdx\game\MyGdxGame.java

createメソッドとrenderメソッドを以下のように書き換えてアプリを実行します。
ただし、これは良い例ではありません。

    @Override
    public void create() {
        // 描画方法を自動に切り替え
        Gdx.graphics.setContinuousRendering(true);

        Gdx.app.setLogLevel(Logger.DEBUG);
        Gdx.app.debug("MyTag", "createメソッド");

        batch = new SpriteBatch();
        img = new Texture("badlogic.jpg");
    }
    @Override
    public void render() {
        Gdx.app.debug("MyTag", "renderメソッド");

        // タッチを検知する
        if (Gdx.input.isTouched()) {
            // タッチした座標をログ出力する
            Gdx.app.debug("MyTag", "Input occurred at x=" + Gdx.input.getX() + ", y=" + Gdx.input.getY());
        }

        Gdx.gl.glClearColor(1, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.begin();
        // タッチした座標に画像を表示
        batch.draw(img, Gdx.input.getX(), Gdx.input.getY());
        batch.end();
    }

実行するとタッチした際に座標が変化して画像が表示されますが、Y軸が違います。
libGDXのY軸は下から上方向ですがタッチ座標は上から下方向になるためずれてしまいます。
Y軸の座標を合わせるためには(画面の高さ – タッチしたY座標)の値へ変換が必要です。
batch.drawメソッドの引数を書き換え、アプリを実行します。

        batch.draw(img, Gdx.input.getX(), Gdx.graphics.getHeight() - Gdx.input.getY());

今度は正しい座標に表示できます。

タッチを検知する

メインループ内での検知は良くないです。
特にrenderメソッドは描画のためにあるので重いイベント処理をすると描画が止まったりします。
createメソッドとrenderメソッドを以下のように書き変えてアプリを実行します。

    @Override
    public void create() {
        // 描画方法を手動に切り替え
        Gdx.graphics.setContinuousRendering(false);

        Gdx.app.setLogLevel(Logger.DEBUG);
        Gdx.app.debug("MyTag", "createメソッド");

        batch = new SpriteBatch();
        img = new Texture("badlogic.jpg");

        // タッチイベントを検知した場合の処理を登録
        Gdx.input.setInputProcessor(new InputProcessor() {
            @Override
            public boolean keyDown(int keycode) {
                Gdx.app.debug("MyTag", "KeyDown : keycode = " + keycode);
                Gdx.graphics.requestRendering();
                return false;
            }

            @Override
            public boolean keyUp(int keycode) {
                Gdx.app.debug("MyTag", "KeyUp : keycode = " + keycode);
                Gdx.graphics.requestRendering();
                return false;
            }

            @Override
            public boolean keyTyped(char character) {
                Gdx.app.debug("MyTag", "keyTyped : character = " + character);
                Gdx.graphics.requestRendering();
                return false;
            }

            @Override
            public boolean touchDown(int screenX, int screenY, int pointer, int button) {
                Gdx.app.debug("MyTag", "touchDown : screenX = " + screenX + ", screenY = " + screenY + ", pointer = " + pointer + ", button = " + button);
                Gdx.graphics.requestRendering();
                return false;
            }

            @Override
            public boolean touchUp(int screenX, int screenY, int pointer, int button) {
                Gdx.app.debug("MyTag", "touchUp : screenX = " + screenX + ", screenY = " + screenY + ", pointer = " + pointer + ", button = " + button);
                Gdx.graphics.requestRendering();
                return false;
            }

            @Override
            public boolean touchDragged(int screenX, int screenY, int pointer) {
                Gdx.app.debug("MyTag", "touchDragged : screenX = " + screenX + ", screenY = " + screenY + ", pointer = " + pointer);
                Gdx.graphics.requestRendering();
                return false;
            }

            @Override
            public boolean mouseMoved(int screenX, int screenY) {
                Gdx.app.debug("MyTag", "mouseMoved : screenX = " + screenX + ", screenY = " + screenY);
                Gdx.graphics.requestRendering();
                return false;
            }

            @Override
            public boolean scrolled(int amount) {
                Gdx.app.debug("MyTag", "scrolled : amount = " + amount);
                Gdx.graphics.requestRendering();
                return false;
            }
        });
    }
    @Override
    public void render() {
        Gdx.app.debug("MyTag", "renderメソッド");

        Gdx.gl.glClearColor(1, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.begin();
        batch.draw(img, Gdx.input.getX(), Gdx.graphics.getHeight() - Gdx.input.getY());
        batch.end();
    }

Gdx.input.setInputProcessorで登録した処理はrenderメソッドの前に呼ばれます。
renderメソッド内でキーイベントの処理を行わない形になりました。
以下のページにイベントハンドリングに関する詳細が記載されています。

https://github.com/libgdx/libgdx/wiki/Event-handling

まとめ

タッチイベントの座標と画面の座標は異なるため変換が必要になります。
パフォーマンスを低下させないためにrenderメソッドにはイベントハンドリングさせず、描画に関する処理に専念するよう実装します。

カテゴリー: Android タグ: , パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です