GUI
当你想要用户不只是对着方块左键右键就完成互动的时候,就会需要游戏内用户界面。与其他教程可能略有不同,我们将使用T88的GUI部分来完成GUI编写。
如果你更想要使用原版GUI进行编写,或是想要了解原版GUI的原理,你可以查看Fledge的Boson教程。
由于MC原版GUI代码实在是不怎么简便,故开发者们通常更喜欢使用一些GUI库。但是有一个不一定准确,又有点不幸的印象是,Forge模组的开发者往往更倾向于造一个自己的GUI轮子——T88亦是如此。
总体来讲,T88(的GUI部分)是一个对原版GUI的简单抽象层、倾向于原版美术风格、代码结构类似Swing。作为抽象层,跨版本兼容性也是T88的追求之一,尽力减少在版本变化时所需的代码改动。
- 如果你想要更加炫酷和专业的界面,你可以考虑BCL的ModernUI。
目前T88的组件功能并不十分完善。欢迎你提交自己的新组件。
由是否直接含有ItemStack区分,GUI可以被分为container-GUI和non-container-GUI。前者通常需要涉及到物品的两端同步问题而略微复杂,我们讲先从后者开始讲起;由GUI展示时机区分,有以Screen为代表的世界外GUI(例如暂停菜单)和抬头显示HUD(例如血条和盔甲条),以下的“GUI”默认都指前者。
T88的有关内容随版本可能有变化但未及时在此处更新,请自行注意。
- 1.20
在1.20之后,GUI代码中的绝大多数使用PoseStack的地方都被包装成为了GuiGraphics,而原来的GuiComponent中的一堆画图相关的方法也被移到了GuiGraphics中,TComponent也不再继承GuiComponent。
TComponent现在提供几个静态的blitById方法,以此能够继续方便地使用ID而不是ResourceLocation来绑定绘图。
non-container-GUI
请注意,GUI只在客户端存在。
地基:自定义TScreen
简单来讲,GUI各组件就是有不同渲染方法和响应方法的类。他们需要最终依附于一个Screen, 在其统筹之下进行渲染和响应。
要展示你的GUI,你需要一个自己的Screen类。我们将以MadParticle的辅助设计工具DesignerScreen为例进行讲解,其大体结构如图:

蓝色框即为这一整个Screen,里面是一个典型的卡片结构:在左侧DesignerModeSelectList选择想要看到的是HelperModePanel、LineModePanel、还是SettingPanel。
以下DesignerScreen代码均为GPLv3许可。
public class DesignerScreen extends TScreen {
public static final int GAP = 5;
private static DesignerScreen designerScreen = null;
private final DesignerModeSelectList designerModeSelectList = new DesignerModeSelectList();
private final HelperModePanel helperModePanel = new HelperModePanel();
private final LineModePanel lineModePanel = new LineModePanel();
private final SettingPanel settingPanel = new SettingPanel();
public DesignerScreen() {
super(Component.translatable("gui.mp.designer.title"));
this.add(designerModeSelectList);
this.add(helperModePanel);
this.add(lineModePanel);
this.add(settingPanel);
if (designerScreen == null) {
designerScreen = this;
}
}
...
首先你需要继承TScreen来创建你自己的类。TScreen的构造函数会要求你填入一个title,它在多数情况下没有实用意义,填写只是为了备用。
然后实例化你需要的组件,用add(TWidget tWidget)方法来添加进DesignerScreen