5

RPG のアルファ版を作成したので、複数のタブを持つメニューを実装したいと考えています。ゲーム中にタブまたはエスケープを押すと、メイン メニュー、スキル ツリー、インベントリなどの 3 つのボタンを備えたバー トップを持つユーザー インターフェイスを表示したいと考えています。問題は、タブを切り替えるときに、以前に選択したタブの描画を停止し、そこからアクターを無効にする必要があるため、現在のタブから何かをクリックすると、描画されていないタブのボタンもクリックされませんが、そこにあります...現在のタブが前のタブと重なることを心配せずに新しいタブを描画できるように、アクター、ボタンを無効にするにはどうすればよいですか?

編集:複数のステージを作成することは避けたいです。すべてのタブが定義されている単一のステージが必要です。

4

2 に答える 2

12

インビジブル アクターはタッチ イベントを受信しないため、タブ コンテンツ アクターの可視性を適切に設定するだけで、タブ付きインターフェイスを実現する最も簡単な方法になります。

libgdx でタブ付きインターフェイスを実装する方法は次のとおりです。

package com.badlogic.gdx.tests.lwjgl;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.ButtonGroup;
import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Stack;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.viewport.ScreenViewport;

class Game3 extends ApplicationAdapter {

    Skin skin;
    Stage stage;

    @Override
    public void create () {
        skin = new Skin(Gdx.files.internal("data/uiskin.json"));
        stage = new Stage(new ScreenViewport());

        Table main = new Table();
        main.setFillParent(true);

        // Create the tab buttons
        HorizontalGroup group = new HorizontalGroup();      
        final Button tab1 = new TextButton("Tab1", skin, "toggle");
        final Button tab2 = new TextButton("Tab2", skin, "toggle");
        final Button tab3 = new TextButton("Tab3", skin, "toggle");
        group.addActor(tab1);
        group.addActor(tab2);
        group.addActor(tab3);
        main.add(group);
        main.row();

        // Create the tab content. Just using images here for simplicity.
        Stack content = new Stack();
        final Image content1 = new Image(skin.newDrawable("white", 1,0,0,1)); 
        final Image content2 = new Image(skin.newDrawable("white", 0,1,0,1));
        final Image content3 = new Image(skin.newDrawable("white", 0,0,1,1));   
        content.addActor(content1);
        content.addActor(content2);
        content.addActor(content3);

        main.add(content).expand().fill();

        // Listen to changes in the tab button checked states
        // Set visibility of the tab content to match the checked state
        ChangeListener tab_listener = new ChangeListener(){
            @Override
            public void changed (ChangeEvent event, Actor actor) {
                content1.setVisible(tab1.isChecked());
                content2.setVisible(tab2.isChecked());
                content3.setVisible(tab3.isChecked());
            }
        };
        tab1.addListener(tab_listener);
        tab2.addListener(tab_listener);
        tab3.addListener(tab_listener);

        // Let only one tab button be checked at a time
        ButtonGroup tabs = new ButtonGroup();
        tabs.setMinCheckCount(1);
        tabs.setMaxCheckCount(1);
        tabs.add(tab1);
        tabs.add(tab2);
        tabs.add(tab3);

        stage.addActor(main);       
        Gdx.input.setInputProcessor(stage);
    }

    @Override
    public void render () {
        stage.act();
        stage.draw();
    }

    @Override
    public void dispose () {
        stage.dispose();
        skin.dispose();
    }

    public static void main (String[] args) {
        new LwjglApplication(new Game3(), new LwjglApplicationConfiguration());
    }
}
于 2014-06-09T14:49:14.230 に答える
0
  • メニューを処理するための最良のアプローチは、別のを使用することScreenです。
    1. 管理が簡単。クラスを分けます。関心事の分離。
    2. シンプルなライフサイクル管理。別の画面が実行されているときに、1 つの画面を一時停止します。
    3. 他の画面は非表示です:(

  • 同じ画面を維持したい場合、最も簡単な方法は異なる段階です。
    1. 前のステージの inputlistener を無効にし、凍結されたステージで update の呼び出しを停止するだけです。
    2. 手動管理:(

  • 同じステージを使用する場合は、フレームワークで定義されたクラスの使用を拒否したため、ロジック全体を実装する必要があります。
    1. 完全にカスタマイズ可能。
    2. 管理が難しい。(不要なテストが必要です。Libgdx ライブラリ クラスがテストされます。)
    3. 実装するのは楽しいかもしれません。

どうやってするの:

  • メニューとゲーム オブジェクトには、異なる親トップ レベル グループを使用します。
  • 一度に 1 つのグループのイベント処理を手動で無効にし、更新を停止します。
  • クラス内のいくつかのメソッドをオーバーライドする必要がある場合がありますStage。(非推奨)。

通常、HUD とポーズ メニューは異なる段階で実装されます。

多段化は避けたい

これは「ステージが重い」から来ているに違いない。

逆にステージは重くないけどスプライトバッチは重い

1 つの spritebatch を共有する複数のステージを作成すると、オーバーヘッドが少なく簡単に複数のステージを作成できます。

お役に立てれば。
幸運を。

于 2014-06-09T09:00:04.010 に答える