
想要看代码高亮的可以去原文地址或者我的微信公众号(
)查看。
原文链接:https://wiki.mcjty.eu/modding/index.php?title=GUI-1.9
在这一教程中我们将向你解释如何制作一个能放9个物品的箱子,并且你可以打开图形界面(GUI)拿到这些物品。

下面是方块的代码。在这段代码中,我们也注册了我们的tile entity。在onBlockActivated()方法中,我们打开了GUI界面。需要注意的是这一步是在服务器端完成的因为一个tile entity的gui必须在前后端都处于“打开”,这样才有一个机制来同步里面的内容。player.openGui()在服务端调用,它会通过IGuiHandler接口(之后会说到)和客户端进行同步。也就是说如果你有一个箱子的GUI界面,你想要看到物品实时的出现或者消失:

tile entity是实际上存储物品的东西。在这个教程中,我们将不再使用原版的存储系统,而是用新的被推荐的容量系统(IItemHandler)来实现我们的存储。


下面是方块状态的json(blockstates/testcontainerblock.json)。需要注意的是在这个例子中我们没有使用我们自己的方块模型,而是使用了原生的cube_all模型:

然而上面这些还远远不够。要让一个GUI正常运转,我们需要GUI的代码并实现一个容器。而真正持有内容的是tile entity,容器是用来在GUI和服务器上的实际内容之间进行交互的。需要记住的是当你打开一个箱子(举个栗子),你看到的不仅仅是箱子本身的物品栏还有玩家的物品栏。所以在这种情况下,容器至少是两个存储空间的展示。
当我们在Minecraft中打开一个GUI,这个操作一般发生在服务端。一个容器的实现是用来表明我们打开了哪个存储。在客户端,容器的同步拷贝也会给到GUI。
下面是这个例子中的容器。关注一下物品槽是怎样被加到我们的tile entity和玩家物品栏的。
需要注意的是实现transferStackInSlot接口很重要。如果你不实现的话,当玩家对你的方块shift加点击方块就会崩溃。在这个例子中我们复制了原版箱子的实现。根据物品的起始位置和剩余空间,它会在玩家快捷栏/玩家背包/箱子之间切换。


现在我们还需要一个GUI。容器的GUI通常从GuiContainer拓展而来。在这个简单的例子中要使这个GUI运行起来不需要太多的代码。你可以像下面这样加入你自己自定义的渲染让GUI看起来更棒,也可以加入自定义的组件之类的:

最后一件你需要做的事是告诉Minecraft如何创建你的GUI和容器的实现。要做到这个,我们需要一个IGuiHandler接口,它包含服务端和客户端的代码来处理GUI。在下面的例子中,我们将TestContainerTileEntity和TestContainer固定下来。我建议不要在你自己的代码中这样做,而应该用一个简单的框架。比如说,你应该弄一个GenericTileEntity类,这样你可以用这个类来做“instanceof”这个操作,然后再通过类里面的方法来创建你的GUI或者容器(Container)。或者你可以运用那个给我们的ID,这个ID也给到了player.openGui(),因为它在之前被调用(GUI_ID)。 下面是代码。
狐狸注:这边作者用的是hardcode这个词。我查了下意思是指将可变变量用一个固定值来代替的方法。用这种方法编译后,如果以后需要更改此变量就非常困难了。大部分程序语言里;可以将一个固定数值定义为一个标记。在我的理解中,这边作者的意思是他把tile entity固定为他定义的TestContainerTileEntity,把container固定为他定义的TestContainer。如果我的理解有偏差欢迎大家指正~

最后你需要在CommonProxy类中注册这个GuiProxy类:

