サイトのトップへ戻る

libGDX ドキュメント 日本語訳

サイト内検索

Scene2d.ui



概要

scene2d とは、 libgdxの 2D シーングラフです。 その中枢では、アクター、 グループ、 描写、イベント、アクションといった基本的な 2D シーングラフを提供しています。 アプリケーションで使用できるユーティリティがたくさんありますが、それらは適度にローレベルのものです。 ゲームの場合、アプリケーション固有のactorを実装するので特に問題はありません。 UIを作成する場合、scene2d.uiパッケージでは一般的なUIウィジットと、scene2d上に構築されたその他のクラスを使用できます。

以降のページへ進む前に、scene2d のドキュメントを読むことを強くお勧めします。 少なくとも該当ページのskimの項目については読んでおいてください。



Widgetクラス と WidgetGroupクラス

UIでは大抵の場合、画面上でサイズや位置を設定するための多くのUIウィジットを持っています。 これらの実装を手動で行うと、時間がかかり、コードの可読性や保守性が下がり、異なる画面サイズへの対応が難しくなってしまいます。 Layout インタフェースには、actorをより高度に配置することができるメソッドが実装されています。

Widget クラスとWidgetGroup クラスは、それぞれActorクラスと Group クラスを継承しており、両方とも Layoutインタフェースを実装しています。 これら二つのクラスは、layout上に配置するactorにとって基本的なものになります。 子actorを持つUIウィジットはWidgetGroupを継承し、子actorを持たないUIウィジットはWidgetを継承すると良いでしょう。



Layout

UI ウィジットは自分自身のサイズと位置は設定しません。 その代わり親ウィジットが子ウィジットのサイズと位置を設定します。 ウィジットは、親が使用することができる最小サイズ、推奨サイズ、最大サイズをヒントとして提供します。 TableやContainerのような一部の親ウィジットでは、子ウィジットのサイズと位置の設定方法に制約があります。 To give a widget a specific size in a layout, the widget's minimum, preferred, and maximum size are left alone and size constraints are set in the parent.

各ウィジットが描写される前に、まず最初に validateが呼び出されます。 ウィジットのlayoutが無効状態の場合は、ウィジット(とその子ウィジット)の現在のサイズで描写するために必要な情報をキャッシュするために、layout メソッドが呼び出されます。 invalidateメソッドとinvalidateHierarchyメソッドは、両方ともウィジットのlayoutを無効にします。

ウィジットの状態が変わったりキャッシュされているレイアウト情報を再計算する必要がある場合はinvalidateを呼び出しますが、 それによってウィジットの最小サイズと推奨サイズと最大サイズは影響を受けません。 つまり、ウィジットは再度配置する必要がありますが、ウィジットの希望サイズは変わらないので親ウィジットは影響を受けません。

ウィジット状態が変わることによってその最小サイズ、推奨サイズ、最大サイズに影響するような場合はinvalidateHierarchyを呼び出します。 つまり、ウィジットの新しい希望サイズによって親のレイアウトが影響を受ける可能性があります。 ウィジットのinvalidateHierarchy メソッドを呼び出すと、自身のinvalidateに加えてルートに至るまでの全ての親のinvalidateを呼び出します。



Stage の設定

scene2d.ui でウィジットを配置する場合、ほとんどの場合はstageと同じサイズのtable を使用します。その他全てのウィジットと内部tableは、このtable内に設置されます。

以下は、最上位にtableを設置した最も基本的な scene2d.ui アプリケーションの例です:

private Stage stage;
private Table table;

public void create () {
    stage = new Stage();
    Gdx.input.setInputProcessor(stage);

    table = new Table();
    table.setFillParent(true);
    stage.addActor(table);

    table.setDebug(true); // This is optional, but enables debug lines for tables.

    // Add widgets to the table here.
}

public void resize (int width, int height) {
    stage.getViewport().update(width, height, true);
}

public void render () {
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    stage.act(Gdx.graphics.getDeltaTime());
    stage.draw();
}

public void dispose() {
    stage.dispose();
}

setFillParentを最上位のtableで使用すると、tableが有効になった時にそのサイズが親(今回の場合はstage)のサイズに合わせられるので、覚えておいて下さい。 通常だとウィジットのサイズはその親によって設定されるので、setFillParentを使用する必要はありません。 setFillParent は、ウィジットの親がその子のサイズを設定しない場合(stageのような)にのみ使用します。

Tableは様々な画面解像度に自動的に対応するので、これでピクセル座標を使用するstageの設定は完了です。 stageのスケール設定についてはstage のビューポート設定を参照してください。



Skin

ほとんどの UI ウィジットは、画像、フォント、色などのいくつかの設定可能なリソースで構成されています。 ウィジットの描写に必要なリソースは全て、"style"と呼ばれます。 各ウィジットは自身のstyleクラス(通常はstaicメンバークラス)を定義し、初期styleを設定するためのコンストラクタを持ち、後でstyleを変更するためのsetStyleメソッドも持っています。

とりあえず最初は、libgdx testsのSkinファイルを使用できます。 これには、 uiskin.png, uiskin.atlas, uiskin.json, default.fntといったファイルが必要です このSkinファイルを使用することでscene2d.uiを素早く使い始めることができ、後からskin素材を置き換えることもできます。

Styles は、JSONを使用するか、もしくはコード上から設定できます:

TextureRegion upRegion = ...
TextureRegion downRegion = ...
BitmapFont buttonFont = ...

TextButtonStyle style = new TextButtonStyle();
style.up = new TextureRegionDrawable(upRegion);
style.down = new TextureRegionDrawable(downRegion);
style.font = buttonFont;

TextButton button1 = new TextButton("Button 1", style);
table.add(button1);

TextButton button2 = new TextButton("Button 2", style);
table.add(button2);

同一の style を複数のウィジットに使用することができるので覚えておいて下さい。 また、UIウィジトに必要な全てのimageはDrawable インタフェースを実装しているということも覚えておいて下さい。

Skinクラスを使用することで、UIウィジット用のstyleやその他リソースの定義がより簡単に行えます。 詳細については Skin のドキュメント を参照してください。 JSONを使ってstyleを定義しない場合であっても、利便性の観点からSkinを使用することを強く推奨します。



Drawable

Drawable インタフェースには、SpriteBatchと位置とサイズを引数として受け取るdrawメソッドが用意されています。 Drawable を実装することで、 TextureRegionやSpriteやAnimationなど任意のものを描写できるようになります。 Drawableは、ウィジットを構成する全ての画像で広く使用されています。 実装すると テクスチャ領域、 Sprite、 NinePatche、タイル型テクスチャ領域を描写できます。 Custom implementations can draw anything they like.

Drawable はminimum 値を提供します。minimum 値は、描写可能な最も小さいサイズを測るためのヒントとして使用されます。 また、top値、right値、bottom値、left値も提供します。これらは、drawable上で描写されるコンテンツの周りにどれくらいのパディングが必要かを測るためのヒントとして使用されます。

既定では、NinePatchDrawableはナインパッチテクスチャ領域に対応するtop値, right値, bottom値, left値を使用します。 しかし、drawableのサイズとナインパッチのサイズは別のものです。 The drawable sizes can be changed to draw content on the nine patch with more or less padding than the actual nine patch regions.

drawableを作成するのはとても単調な作業のため、やや冗長だと感じるかもしれません。 skin メソッドを使用すると適切なタイプのdrawableを自動的に取得できるので、お勧めです。



ChangeEvents

ほとんどのウィジットでは、何らかの変更があった時にChangeEventを起動します。 このChangeEventというのはあくまで一般的な呼称であって、実際のイベントは各ウィジットによって異なります。 例えば、ボタンの場合はボタンが押された時に変更イベントが発生し、スライダーの場合はスライダーの位置が変わったときに変更イベントが発生する、など。

ChangeListener を使ってこれらのイベントを検知します:

actor.addListener(new ChangeListener() {
    public void changed (ChangeEvent event, Actor actor) {
        System.out.println("Changed!");
    }
});

例えばボタンの場合、可能な限りClickListenerではなくChangeListenerを使ったほうが良いでしょう。 ClickListener はウィジット上の入力イベントに反応し、そのウィジットがクリックされたかどうかのみを感知します。 The click will still be detected if the widget is disabled and doesn't handle the widget being changed by a key press or programmatically. また、ほとんどのウィジットの場合でChangeEventをキャンセルすることができ、これによってウィジットの変更を元に戻すことができます。



クリッピング処理

クリッピング処理を最も簡単に行うには、Tableの setClip(true) メソッドを使用します。 table内のActorは、そのtableの境界内がクリッピング範囲対象となります。 カリング処理が行われるので、完全にtableの境界外にいるactorは一切描写されません。

Tableのadd メソッドを使ってtableに追加されたActorは、tableのセルを一つ与えられて、tableによってサイズと位置が設定されます。 他のgroupのように、addActorメソッドを使ってtableにactorを追加することもできます。 この方法でactorが追加された場合、tableはそのactorのサイズや位置を設定しません。 このaddActorは、クリッピング処理のためだけにtableを使用する場合に便利です。



回転と拡大縮小

以前説明したように、 scene2dでtransform 設定が有効になっている groupでは、子が描写される前にSpriteBatchのフラッシュ処理が発生します。 UIはしばしば、数百とは言わないまでも数十のgroupを持つことがあります。 各groupごとにフラッシュ処理を行うとパフォーマンスが著しく低下するため、既定ではほとんどのscene2d.uiグループではtransform設定はfalseになっています。 groupのtransform設定が無効になっている場合、回転や拡大縮小といった処理は無視されます。

必要に応じてTransform設定を有効にできますが、いくつか注意点があります。 回転や拡大縮小といった処理を適用した場合、全てのウィジットがこの機能を全てサポートしている訳ではありません。 例えば、Tableの場合はtransform設定を有効にすることができるので、回転や拡大縮小と行った処理が可能です。 Tableの子は回転や拡大縮小が適用された状態で描写され、入力は正しく割り振られます、といった具合に。 しかし、他のウィジットの場合は回転や拡大縮小を考慮せずに描写を行うことがあります。 この問題の解決策は、該当ウィジットをtableやcontainer内に格納し、そのウィジットではなくtableやcontaierに対して回転や拡大縮小を設定することです。:

TextButton button = new TextButton("Text Button", skin);
Container wrapper = new Container(button);
wrapper.setTransform(true);
wrapper.setOrigin(wrapper.getPrefWidth() / 2, wrapper.getPrefHeight() / 2);
wrapper.setRotation(45);
wrapper.setScaleX(1.5f);

レイアウトを行うscene2d.uiの group(Tableなど)では、transform処理が適用されたウィジットのレイアウトの計算をする際に、そのウィジットの拡大縮小や回転が適用されていない境界を使用して計算を行うので注意してください。

ScrollPaneのようなクリッピング処理を行うウィジットは glScissorを使用しています。 このglScissorでは aligned rectangleの画面を使用しています。こうしたウィジットは回転を行うことができません。

多くのgroupでtransform設定が有効になっていることによりbatchのフラッシュ処理が頻発している場合は、 CpuSpriteBatchを使用することができます。 これはbatchのフラッシュ処理を避けるために、CPUを使ってtransformation処理を行います。



Layout ウィジット



Table

Table クラス (コード)はHTMLのテーブルと同様に、ロジカルテーブルを使って子のサイズと位置を設定します。 Tableは簡単に使用できてウィジットのサイズと位置を手動で設定するよりも強力なので、scene2d.uiにおいてウィジットの配置で広く使われるよう意図されています。 Tableベースのレイアウトは絶対位置に依存せず、したがって異なるウィジットサイズと画面解像度に対して自動的に調整を行います。

scene2d.uiを使ってUIを構築する前に、Table のドキュメントを読むことを強く推奨します。



Container

Container クラス (コード) は子を一つしか持たない Table と同等ですが、より軽量です。 Containerはテーブルセルが持つ全ての制限を同じ様に持っており、一つのウィジットのサイズや位置を設定する場合に便利です。



Stack

Stack (コード) は、各子ウィジットをstackと同じサイズにして配置するWidgetGroup です。 これは、ウィジットを他のウィジットの上に重ねる必要がある場合に便利です。 stackに最初に追加されたウィジットは一番下に描写され、最後に追加されたウィジットは一番上に描写されます。



ScrollPane

ScrollPane (コード) では、スクロールバーやマウスやタッチドラッグを使って子ウィジットをスクロールします。 子ウィジットがScrollPaneよりも大きい場合に、スクロールが自動的に有効になります。 ウィジットの上下左右いずれかの側が scroll paneより小さい場合は、その側のサイズはscroll paneのサイズに合わせられます。 ScrollPane では、スクロールのタッチ制御をするかどうか、制御する場合はどのように制御するか、しばらく使用しないスクロールバーを非表示にするかどうか、非表示にする場合はどのように非表示にするか、など多くの設定を行うことができます。 ScrollPane は、背景・横スクロールバーとそのつまみ・縦スクロールバーとそのつまみ、といったもののdrawableを持っています。 タッチ制御が有効な場合(既定では有効になっています)、各drawableを設定するかどうかはあくまで任意です。

The ScrollPane preferred width



SplitPane

SplitPane (コード) は内部に二つのウィジットを持っており、水平方向もしくは垂直方向で二画面に分割されます。 ユーザーは分割線をドラッグして各ウィジットのサイズを変更することができます。 小ウィジットはそれぞれ、常にsplitpaneの半分になるようサイズが変更されます。 SplitPane は、ドラッグ可能な分割線のdrawableを持っています。



Tree

Tree (コード) はノードの階層を表示します。 各ノードは小ノードを持つことができ、展開したり折り畳んだりできます。 各ノードはActorを持ち、それにより各項目の表示を柔軟に行うことができます。 Tree は各ノードのActorの隣にあるプラスアイコンとマイナスアイコンのdrawableを持っています。



VerticalGroup

VerticalGroup (コード)は列が一つしかない Table と同等ですが、より軽量です。 VerticalGroup では途中にウィジットを挿入したり削除したりできますが、Table ではそれができません。



HorizontalGroup

A HorizontalGroup (コード) は行が一つしかない Table と同等ですが、より軽量です。 HorizontalGroup では途中にウィジットを挿入したり削除したりできますが、Table ではそれができません。



ウィジット



Label

Label (コード) はビットマップフォントと色を使ってテキストを表示します。 テキストには改行を含むことができます。labelの横幅が親によって設定されている場合は、ワードラップを有効にできます。 テキストの各行は他の行との相対位置で並べられ、またテキストは全てlabelウィジット内に並べられます。

同じフォントを使用しているlabelは、違う色を使用していたとしても同じサイズになります。 ビットマップフォントでは、一般的な拡大縮小が上手く行えません。サイズが小さい場合はそれが特に顕著です。 そのため、異なるフォントサイズごとに別々のビットマップフォントを使用することを推奨します。 テクスチャバインドを減らすために、ビットマップフォントの画像はskinのatlasに入れます。



Image

Image (コード) drawableを表示するだけです。 drawable というのは、 texture, texture region, ninepatch, sprite, などのことです。 様々な方法を使って、drawableのサイズを変更してimageウィジットの境界内に配置することができます。



Button

Button (コード) それ自体は単なる空のボタンですが、 table を継承しているので他のウィジットをボタン内に追加することができます。 Buttonには通常時に表示されるup用背景と、ボタンが押された時に表示される down用背景があります。 Buttonはクリックされる度に切り替わり後の状態を確認し、その状態確認時にはup用背景ではなくchecked用背景を使用します(checked用背景が定義されているのであれば)。 It also has pressed/unpressed offsets, which offset the entire button contents when pressed/unpressed.



TextButton

TextButton (コード) は Button を継承しており、内部にlabelを持っています。 TextButton は、ビットマップフォントとup時・down時・状態確認時のテキストの色をButtonに追加します。

TextButton はButtonを継承し、Buttonは Tableを継承しているので、Tableのメソッドを使ってTextButtonにウィジットを追加できます。



ImageButton

ImageButton (コード) は Button を継承しており、内部に image ウィジットを持っています。 ImageButton は、up時・down時・状態確認時のimageウィジット用drawableをButtonに追加します。

ImageButtonはButtonを継承しており、そのButtonはup時・down時・状態確認時のdrawableを既に持っているので覚えておいて下さい。 ImageButton は、ボタン背景の上にdrawable(アイコンのような)を持たせたい場合にのみ必要になります。

ImageButton はButtonを継承し、Buttonは Tableを継承しているので、Tableのメソッドを使ってImageButtonにウィジットを追加できます。



CheckBox

CheckBox (コード) は TextButton を継承しており、labelの左に image ウィジットを追加します。 CheckBoxはチェック状態と非チェック状態を表すimageウィジット用のdrawableを持っています。



ButtonGroup

ButtonGroup (コード) は actor ではなく、目に見えません。 ButtonをButtonGroupに追加すると、ButtonGroupによってチェックできるボタンの最小値と最大値が決められます。 これを使うことで、ボタン(ボタン、テキストボタン、チェックボックス、など)を"ラジオ"ボタンとして使用することができます。



TextField

TextField (コード) は一行のテキスト入力フィールドです。 TextFieldは、背景・テキストカーソル・テキスト選択で使用するdrawable、入力された文字のフォントとフォントカラー、テキストフィールドが空の時に表示されるメッセージのフォントとフォントカラー、といったものを持っています。 パスワードモードを有効にすることができ、有効にすると入力された文字の代わりにアスタリスクが表示されます。



TextArea

TextArea (コード) は TextFieldと似ていますが、複数行のテキスト入力が可能です。



List

List (コード) は、テキストの項目一覧を表示して選択状態の項目は強調するリストボックスです。 List は、フォント、選択状態の項目の背景用 drawable、選択状態の項目のフォントカラー、非選択状態のフォントカラーを持っています。 List は自身ではスクロールはしませんが、たいていはscrollpane内に設置します。



SelectBox

SelectBox (コード) とはドロップダウンリストのことで、これを使うことでリストの中にあるいくつかの値から一つを選ぶことができます。 クリックされていない状態では、SelectBoxには選択された値が表示されます。クリックすると、SelectBoxには選択可能な値の一覧が表示されます。 SelectBox は、背景・一覧の背景・選択された項目の背景で使用するdrawable、フォントとフォントカラー、項目と項目の間でどれくらいのスペースを使用するかの設定、といったものを持っています。



ProgressBar

ProgressBar (コード) とは、ある処理の進捗状況や、指定した範囲内の様々な値を視覚的に表示するウィジットです。プログレスバーは、範囲(最小値、最大値)とそれらの間の進捗度合いを設定値として持っています。 完了割合は通常、空のプログレスバーとして開始され、作業や値が完了に近づくにつれて徐々にバーが埋まっていきます。

プログレスバーは水平向きや垂直向きに設定できますが、バーの増加方向は常に同じになります。 水平向きのプログレスバーの場合は左へ進み、垂直向きの場合は上向きへ進みます。 プログレスバーの設定値を変更することで、時間経過ごとにバーが埋まっていくアニメーションをよりスムーズにすることができます。



Slider

Slider (コード) とは、ユーザーが値を設定することができる、水平向きのインジケータです。 Sliderは、範囲(最小値、最大値)とそれらの間の進捗度合いを設定値として持っています。 Slider は、背景・スライダーのつまみ・つまみの前と後ろに表示されるスライダー部分、で使用されるdrawableを持っています。

ProgressBarとSliderは両方とも同じコードと視覚Styleを使用しているので、A slider with touches disabled, a drawable before the knob, and without the knob can be used as a substitute for progress bar。 Sliderの設定値を変更することで、バーが埋まっていくアニメーションをよりスムーズにすることができます。



Window

Window (コード) はコンテンツの上にタイトルを表示するタイトルバー領域を持つtable のことです。 これは必要であればモーダルウィンドウとして動作し、下にあるウィジットでタッチイベントが発生するのを防ぎます。 Window は背景用の drawable とタイトル用のフォント・フォントカラーを持っています。



Touchpad

Touchpad (コード) とは、画面上に表示されるジョイスティックのことで、円形範囲内を動かして操作します。 Touchpadは、背景用のdrawableとユーザーがドラッグ操作に使うノブ用のdrawableを持っています。



Dialog

Dialog (コードは) とは、コンテンツ用のtableと、その下にボタン用のtableを持つ window です。 任意のものをdialogへ追加することができますが、labelをコンテンツ用tableへ追加してbuttonをボタン用tableへ追加するための便利なメソッドが用意されています。



scene2d.uiのレイアウトを使わないウィジット

scene2dのウィジットは、tableやその他 scene2d.uiのレイアウトを使わずに、ただのActorとして使うことができます。 actorと同様に、ウィジットは既定サイズを持っており、絶対位置で位置指定ができます。 ウィジットが変更された場合は、そのウィジットが新しいサイズで再配置されるので、ウィジットのinvalidateメソッドを呼び出す必要があります。

Tableのようないくつかのウィジットでは、推奨サイズが自身を内包する親ウィジットに基づいて決められるため、作成された後でも既定サイズを持ちません。 ウィジットが追加された後、packメソッドを使ってウィジットの幅と高さを推奨の幅と高さに設定できます。 このメソッドではウィジットのサイズが変更されていた場合はinvalidateも呼び出され、その後ウィジットが自身を新しいサイズへ調節するために validateが呼び出されます。



ドラッグアンドドロップ (DragAndDrop クラス)

It should be noted that to make a drag start/source actor, a table and to have that table and all of its contents trigger a drag, one must enable Table.setTouchable(Enabled). It is set to ChildrenOnly by default.



今のところは、以下のテストプログラムを参照してください: