Help us understand the problem. What is going on with this article?

libGDXの基礎7 イベント

More than 5 years have passed since last update.

libGDXとはWindows、Linux、Mac、Android、iPhone、HTMLに対応したクロスプラットフォームゲームライブラリです。有名なIngressでも利用されています。欧米ではわりとメジャーどころです。

入力イベントとは

タッチやクリック、キーボードなどの入力に応じてよばれる仕組みです。と書くと難しそうですが、仕組みは簡単です。

Scene2Dには各種Actorにイベントリスナーを設定することが可能です。ちゃんと重なった場所も優先度の高い(手前に表示されているもの)Actorがそのイベントを受け取ります。

イベント登録に利用するメソッドは1つだけ

イベントの登録メソッドはActor#addListener()のみです。

イベントリスナーはいくつか用意されていますが、一番単純なクリックイベントをここでは実装してみます。

ソース

package test.libgdx;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;

public class MainListener7 implements ApplicationListener{

    TextureAtlas atlas;
    Stage stage;

    @Override
    public void create() {

        FileHandle fh = Gdx.files.internal("atlas/data.txt");
        atlas = new TextureAtlas(fh);

        stage = new Stage();
        Gdx.input.setInputProcessor(stage);//ここがポイント1

        {   
            TextureAtlas.AtlasRegion region = atlas.findRegion("001");
            Image image = new Image(region);
            image.setPosition(0, 0);

            ClickListener listener = new ClickListener(){//ここがポイント2

                @Override
                public void clicked(InputEvent event, float x, float y) {
                    System.out.println("001がクリックされた!");
                }

            };
            image.addListener(listener);//ここがポイント3


            stage.addActor(image);
        }

        {   
            TextureAtlas.AtlasRegion region = atlas.findRegion("002");
            Image image = new Image(region);
            image.setPosition(50, 50);

            ClickListener listener = new ClickListener(){

                @Override
                public void clicked(InputEvent event, float x, float y) {
                    System.out.println("002がクリックされた!");
                }

            };
            image.addListener(listener);

            stage.addActor(image);
        }


    }

    @Override
    public void resize(int w, int h) {
    }

    @Override
    public void render() {

        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        Gdx.gl.glClearColor(0, 0, 0, 1);


        stage.act(Gdx.graphics.getDeltaTime());
        stage.draw();
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }

    @Override
    public void dispose() {
    }

    //起動部分
    public static void main(String[] args) {
        new LwjglApplication(new MainListener7());
    }
}

軽く解説をすると、コメントにある「ポイント1」のところが各種入力イベントをScene2Dへ処理をさせるという宣言です。ここがないとイベントは発生していてもイベントリスナーへはまともに飛んできません。

「ポイント2」でリスナーの作成。GUI系ではこう言ったインナークラスはよく使うので覚えておいてください。

「ポイント3」でリスナーをActorへ登録します。今回はImageですが、Image以外のActorでも構いません。

実行!

20141011-01.png

クリックやタッチした場合、重なっている部分は上にある画像(002)のが優先されている・・・と思います。

思うというのは、いまいち余白の部分がどの辺までなのか微妙にわかりにくいからです。どこまでがイベントの範囲、Actorのサイズなのかがわからないですね。

クリック判定をわかりやすく

そこで以下の一行をそれぞれのImageのインスタンスの初期化のところに追加します。positionの設定の直後のところにでもおいてください。

image.setDebug(true);

なお、この機能が使えるのはバージョンが比較的新しめのものが必要になるので、古いバージョンを利用している人はバージョンを上げましょう。

Gradleを利用している場合はバージョンを1.4.1に設定、そうでない場合は以下のところから直接とってこれます。置き換えましょう。
http://libgdx.badlogicgames.com/releases/

実行すると以下のようになります。

20141011-02.png

これで判定がばっちりですね。重なっている部分は上の方が優先されてクリックされているのがわかると思います。

さらに回転と拡大縮小を加える

回転や拡大縮小をした場合はどうなるでしょうか?以下のコードを002のイメージにのみ追加して実行してみます。

image.setRotation(-45);
image.setScale(0.75f);

20141011-03.png

境目を重点的にクリックしてみてください。ちゃんと回転後、拡大縮小後のサイズで計算されているのがわかりますね。

キーボードを使いたい場合はInputListenerをstageに設定してkeyupやkeydownのイベントを利用するとよいでしょう。

ここまでの記事で、画像の描画、クリック(タッチ)イベントの実装ときました。アドベンチャーやRPGはもう作れますね。

shinsan68k
MSX, X68000, C, Java, Android, libGDX, C#, Unity
http://d.hatena.ne.jp/shin/
abby
少数精鋭の会社です!
https://www.abby.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした