4-2 为插件设计交互系统
和任何其它的功能一样,在编写功能性代码前,我们需要设计交互系统的功能。在继续之前,让我们来看看『开始菜单』的功能设计:
开始菜单(Start Menu)
为用户提供一个小巧的菜单界面,提供下列操作:
重新部署:令玩家死亡并在出生点重生。
快速起飞:给玩家赋予一个较大的向上动量
原地升天。查询延迟:查询服务器上测得的玩家 Ping 延迟。
执行命令:以玩家身份,执行一条在插件配置中写好的命令,这个按钮的名称应当能在插件配置中设置。
许多插件都提供这样的『执行自定义命令』功能,以方便与其它插件集成。
菜单需要能通过命令
/menu打开。
这就牵涉到图形界面交互(显示按钮,处理点击事件等)和命令交互(处理 menu 命令,执行自定义命令等)两部分的设计。事实上,绝大多数与玩家交互的插件,都会包含这两部分,以获得较好的交互性和灵活性。
图形界面交互
理论上,各种能由服务器控制物品信息的容器界面(酿造台、铁砧等)都可以用来制作 GUI,但最常使用的还是箱子的 GUI,因为其形状规整,而且可以做得很大(最大 6×9 格),也能放进任意的物品。在插件开发社区里,基于物品栏的 GUI 也常被称为『箱子 GUI』。
在制作箱子 GUI 时,通常用一个物品来代表一个按钮,并通过自定义这个物品的信息来显示按钮的『文字』。一般来说,使用什么物品并没有严格的限制,选取外观上与其代表功能相近的物品即可(例如『返回基地』功能就经常使用床,而本例中的『快速起飞』就可以使用烟花火箭)。在这个项目里,我们将使用一个 1×9 的箱子 GUI,并将四个按钮排在最左侧,分别使用屏障、烟花火箭、指南针和命令方块代表它们的功能。
当玩家点击物品栏中的物品时,服务器会收到相关的事件,这个事件是 InventoryClickEvent,它提供了几个方法来获取『到底哪个物品被点击了』这样的信息,我们将在稍后介绍如何从中获取物品信息,并将它对应到我们的操作。
命令交互
相比图形界面交互,命令交互相对简单一些,我们仅需要定义每条命令的功能和参数,有些参数或许是可选的,或者有默认值,这都需要在设计时就考虑好。在这个项目里,我们的插件只有一个 menu 命令,它不接受任何参数,唯一的作用是打开菜单 GUI。
与图形界面交互不同,命令交互不使用常规的事件系统,而需要通过一个名为 CommandExecutor 的接口来实现。等等,什么是接口?哈,这又是一个微妙的关于面向对象编程的概念,也许是时候再多介绍一点关于 Kotlin 的知识了……