5

我已经制作了我的 rpg 的 alpha 版本,现在我想实现一个带有多个选项卡的菜单。当您在游戏中并按 Tab 或 Escape 时,我想显示一个用户界面,该界面将有一个带有 3 个按钮(如主菜单、技能树和库存)的顶部栏。问题是,当您切换选项卡时,我需要停止绘制先前选择的选项卡并从中禁用演员,因此当您从当前选项卡单击某些内容时,它不会同时单击未绘制的选项卡上的按钮,而是它就在那里......我怎样才能禁用演员、按钮,这样我就可以绘制一个新标签,而不必担心当前标签与前一个标签重叠?

编辑:我想避免制作多个阶段。我想要一个定义每个选项卡的阶段。

4

2 回答 2

12

不可见的 Actor 不会接收触摸事件,这是完成选项卡式界面的最简单方法,只需适当地设置选项卡内容 Actor 的可见性。

以下是我在 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. 简化的生命周期管理。当另一个屏幕正在运行时暂停一个屏幕。
    3. 其他屏幕被隐藏:(

  • 如果你想保持相同的屏幕,最简单的方法是不同的阶段。
    1. 只需禁用前一阶段的输入侦听器并停止在冻结阶段调用更新。
    2. 手动管理:(

  • 如果您想使用同一阶段,则必须由您实现整个逻辑,因为您拒绝使用框架定义的类。
    1. 完全可定制。
    2. 难以管理。(需要进行不必要的测试。Libgdx 库类已经过测试。)
    3. 实施起来可能很有趣。

怎么做:

  • 为菜单和游戏对象使用不同的父顶级组。
  • 一次手动禁用一组事件处理并停止更新。
  • 可能需要覆盖Stage类中的少数方法。(不建议)。

通常 HUD 和暂停菜单是在不同的阶段实现的。

我想避免制作多个阶段

这一定来自“阶段重”。

相反,阶段并不重,但spritebatches 很重

如果您制作共享单个 spritebatch 的多个阶段,则可以轻松创建多个阶段而无需太多开销。

希望这可以帮助。
祝你好运。

于 2014-06-09T09:00:04.010 回答