読者です 読者をやめる 読者になる 読者になる

俺とプログラミング

某IT企業でエンジニアをしてます。このブログではプログラミングに関わることを幅広く発信します。

【libGDX入門】ユーザーから文字列の入力を受け取る

libGDXにおいてどうやってクロスプラットフォームにユーザーからの文字列の入力を受け取るかを紹介します。実現する方法は大きく3つあります。 1 , 2 , 3 の順に労力がかかります。 その代わり、 1 , 2 , 3の順に自由度が高まります。

1. TextInputListenerを使う方法

一つ目の方法はOS側で用意されている入力ダイアログを利用するやり方です。 この方法では、まずTextInputListenerインターフェースを実装します。実装するメソッドは、入力後に呼ばれるinput(String text)と、入力がキャンセルされた時に呼ばれるcanceled()です。

public class MyTextInputListener implements Input.TextInputListener {
    @Override
    public void input(String text) {
        System.out.println( text + "が入力されました");
    }

    @Override
    public void canceled() {
        System.out.println( "キャンセルボタンが押されました");
    }
}

実装したTextInputListenerの使いかたは下記のようになります。input.getTextInputが呼ばれると、ダイアログが現れます。 そしてOKもしくはCancelが押されると、消えます。

MyTextInputListener mtil = new MyTextInputListener();
Gdx.input.getTextInput(mtil,"タイトル","初めの値","ヒント");

4番目の引数は何も入力がないときに、背景に薄く表示される文字です。
現れるポップアップメニューはプラットフォーム毎に違います。DesktopではSwingのダイアログ、Androidでは標準のダイアログが表示されます。

Desktopでのダイアログ
Desktopでは、左上の×ボタンが押された時もcanceledが呼ばれます。
f:id:ttlg:20151014105435p:plain


Androidでのダイアログ
Androidでは、ダイアログの外をタッチすると、ダイアログが消え、canceledが呼ばれます。
f:id:ttlg:20151014105459p:plain


iOSでのダイアログ
iOSでは、OKかCancel以外の入力は受け付けません。
f:id:ttlg:20151014110423p:plain

marioさん(libGDX作者)も言及しているのですが、これらのダイアログはあまりかっこ良くないですね。しかし、日本語、特に漢字を含めた入力に関しては、現状ではこれが最善の方法かもしれません。

2. TextField(もしくはTextArea)を使う方法

2つ目の方法では、Scene2dに用意されている入力用ウィジェットのTextFieldを利用します。ただし、iOSでの日本語入力にはバグがあります。なのでiOSへの出力を考えていて、かつ日本語入力が必要な時はこの方法は使わないほうがいい。 英語入力のみならば問題ない。
以下のようにして使います。

/* BitmapFontを生成(fontに入ってない文字は入力できない) */
BitmapFont font = new BitmapFont(Gdx.files.internal("font.fnt"));

/* TextfieldStyleの定義 */
TextField.TextFieldStyle textFieldStyle = new TextField.TextFieldStyle(
    font,                           // BitmapFont
    Color.BLACK,                    // font color
    new TextureRegionDrawable(new TextureRegion(new Texture("cursor.png"))),      // cusor image 
    new TextureRegionDrawable(new TextureRegion(new Texture("selection.png"))),   // selectoin image 
    new TextureRegionDrawable(new TextureRegion(new Texture("background.png")))); // background image

/* textFieldの生成 */
TextField textField = new TextField(textFieldStyle);

/* 文字数を10に制限する */
textField.setMaxLength(10);

/* tabキーでTextField間をできなくする(デフォルトはtrue)   */
textField.setFocusTraversal(false);

/* TextFieldをStageに追加 */
stage.addActor(textField);

/* TextFieldをフォーカス状態にする(複数ある場合) */
stage.setKeyboardFocus(textField);

/* iOSもしくはAndroidの仮想キーボードを出現させる */
Gdx.input.setOnscreenKeyboardVisible(true);

………

/* 入力された文字列を取得する */
String text = textField.getText();

/* TextFieldに空文字列をセット */
textField.setText("");

/* TextFieldを見えないようにする */
textField.setVisible(false);

日本語で使うことを考えている場合、font.fntには入力を想定する全てのひらがな、漢字を含んでる必要があることに注意です。

フォントについては以下のサイトが詳しいです。

3. 仮想キーボードを自作する

3つ目の方法では自分でキーボードを作ります。 一番自由度が高いですが、一番大変です。
参考程度に擬似コードを載せておきます。

String currentText = new String("");

Table keyboard = new Table();

Label a = new Label("a", LabelStyle);
a.addListener( 
    new GestureActorListener(){
        @Override
        public void tap(InputEvent event, float x, float y, int p, int b) {
            currentText += a;
        }
    }
}
………
Label z = new Label("z", LabelStyle);
z.addListener( 
    new GestureActorListener(){
        @Override
        public void tap(InputEvent event, float x, float y, int p, int b) {
            currentText += z;
        }
    }
} 

keyboard.add(a);
………
keyboard.add(z);

stage.addActor( keyboard );


Androidゲームプログラミング A to Z

Copyright © 2016 ttlg All Rights Reserved.