教程:编写脚本API/server-ui模块基础

来自Minecraft基岩版开发Wiki
server-ui模块基础
系列教程
所属系列
难度
初级
实践设备
WindowsAndroid
所需软件

引言[编辑]

server-ui模块是 server 模块的一个支撑模块,它拥有强大的功能,我们将帮助您了解和使用此类。

导入[编辑]

在确保你已经导入了server模块的前提下,在清单文件中先导入server-ui模块(参见 Tutorial:编写脚本API/开始之前),像下面这个样子:

{
    "module_name": "@minecraft/server-ui",
    "version": "1.3.0-beta"
}

接下来你同样只需要一行就可以导入server-ui:

import * as ui from "@minecraft/server-ui";

构建ui[编辑]

@minecraft/server-ui 模块包含用于表达简单信息的ui,下面是目前提供的可用ui:

  • ActionFormData: 包含一个带有标题和图像的按钮列表,可用于向玩家呈现一组选项。
  • MessageFormData: 是简单的双按钮消息ui,适用于Yes/No或OK/Cancel问题。
  • ModalFormData: 允许更灵活的“浏览器风格”控件列表,可用于获取输入。

ActionFormData[编辑]

这是包含一堆按钮的表单。这个表单非常适合商店UI,小游戏选择等。
先看它的构造函数:

new ActionFormData()

let form = new ui.ActionFormData();

这个表单有三个属性:标题,主体,按钮。

标题[编辑]

标题是表单顶部的文本。

// title(titleText: minecraftserver.RawMessage | string): ActionFormData

form.title("Test");    //例

主体[编辑]

这是一段文字出现在标题的下方,按钮的上方,一般用于解释这个ui的功能(可以理解为正文)。

// body(bodyText: minecraftserver.RawMessage | string): ActionFormData

form.body("Body");    //例

按钮[编辑]

按钮是窗体的主要功能。表单可以有许多按钮供玩家选择。

// button(text: minecraftserver.RawMessage | string, iconPath?: string): ActionFormData

//例
form.button("Button 1");    //无图标仅文字
form.button("Button 2", "textures/items/compass");    //图标加文字

图标是从已应用的资源包(可以不是内置资源包)中获取。

MessageFormData[编辑]

消息表单是由2个按钮组成的表单,具有较大的描述(主体)。此表单适用于 是/否 问题或 确定/取消 表单。

let form = new ui.MessageFormData();

它拥有三个属性:标题,主体,双按钮。

标题[编辑]

// title(titleText: minecraftserver.RawMessage | string): MessageFormData

form.title("wiki");    //例

这和ActionFormData差不多。

主体[编辑]

// body(bodyText: minecraftserver.RawMessage | string): MessageFormData

form.body("Body");    //例

双按钮[编辑]

双按钮事实上是两个函数,这两个函数缺一不可,它们分别是:

/* button1:
button1(text: minecraftserver.RawMessage | string): MessageFormData */
form.button1("确定用按钮");
/* button2:
button2(text: minecraftserver.RawMessage | string): MessageFormData */
form.button2("否定用按钮");

ModalFormData[编辑]

这个表单在所有ui中拥有最多的输入类型。它有文本字段,滑块,下拉菜单和切换。

let form = new ModalFormData();

和别的ui不同的是它没有主体。

标题[编辑]

// title(titleText: minecraftserver.RawMessage | string): ModalFormData

form.title("wiki");    //例

提交按钮[编辑]

这个函数相对特殊,它不是必要的,就算没有它提交按钮也必然出现(显示文字采用玩家所选择的语言中的“提交”),它的主要功能是设置提交按钮的展现文字。

// submitButton(submitButtonText: minecraftserver.RawMessage | string): ModalFormData

form.submitButton("点这里提交");

下拉[编辑]

下拉是一个常见的ui,例如模式修改的ui就是下拉。

// dropdown(label: minecraftserver.RawMessage | string, options: (minecraftserver.RawMessage | string)[], defaultValueIndex?: number): ModalFormData

form.dropdown(["选项1","选项2"]);

var list = ["选项1"];

form.dropdown(list, 0);

滑块[编辑]

滑块并不常用,它用于展示一个仅返回数字的拉条。

// slider(label: minecraftserver.RawMessage | string, minimumValue: number, maximumValue: number, valueStep: number, defaultValue?: number): ModalFormData

form.slider("标题", 1, 100, 1);

form.slider("滑块标题", 0, 10, 2, 10);

输入框[编辑]

输入框允许您输入字符串,它比较方便,可以用来制作指定坐标的传送系统等。它返回一个字符串。

// textField(label: minecraftserver.RawMessage | string, placeholderText: minecraftserver.RawMessage | string, defaultValue?: minecraftserver.RawMessage | string): ModalFormData

form.textField("输入框", "提示文字");

form.textField("输入框标题", "提示文字", "默认值");

切换[编辑]

它看起来像一个开关,仅返回布尔值。

// toggle(label: minecraftserver.RawMessage | string, defaultValue?: boolean): ModalFormData

form.toggle("标题"); 

form.toggle("切换框标题", true);

扩展提示[编辑]

这里提供帮助您创建ui的一些想法。

展示ui[编辑]

在我们创建表单之后,我们需要向玩家显示表单并保存响应以运行其他任务。我们需要一些活动来展示我们的形式。
比较常用的是使用itemUse事件(具体参考请见server.itemUse)。

mc.world.beforeEvents.itemUse.subscribe(event => {
	if (event.itemStack.typeId === "minecraft:stick" && event.itemStack.nameTag === "打开用的工具名字") {
		// 打开窗口的函数
        uiShow(event.source);
    }
});

现在你可以使用一个叫 打开用的工具名字 的木棍来打开窗口。
这里推荐使用一个专门的函数来打开窗口。
下一步我们就需要进行反馈了。

基本展示[编辑]

我们需要一个专门的函数.show()来打开ui,这个函数每个form都有,它需要一个玩家(Player)类型的参数。
然后再使用.then()来做出响应。

function uiShow(target) {
    form.show(target)
        .then(r => {
        // 操作
    })
        .
    catch ((e) => {
        console.error(e, e.stack);
    });
};

当玩家关闭表单时,即使没有给出输入,其中的函数.then()也会运行。这可能会导致在播放器关闭窗体时运行意外代码。为防止这种情况,您需要使用.canceled取消脚本。

form.show(target)
    .then(r => {
        if (r.canceled) return;
        // 操作
    })
    // ...

部分情况下会有更复杂的取消要求:

form.show(target)
    .then(r => {
        if (r.canceled || r.selection === undefined) {
            // 关闭后的操作
            return;
        }
        // 操作
    })
    //...

或者是

function uiShow(target) {
    form.show(target)
        .then(r => {
        if (r.canceled) {
            if (r.cancelationReason === "UserBusy" || r.cancelationReason === undefined) {
                uiShow(target);    // 当玩家因已打开其他UI(即 "UserBusy")而无法打开此UI时,再此打开此UI,直至玩家正常打开
            } else {
                // 关闭后的操作
            }
            return;
        }
        // 操作
    })
    // ...
}

接下来为您介绍每种Form独有的操作数据。

ActionFormData[编辑]

r.selection是此Form玩家的选择按钮索引。

read-only selection?: number;

switch (r.selection) {
    case 0:
        break;
    case 1:
        break;
    default:
        return;    // 使用 return 而非 break
}

MessageFormData[编辑]

r.selection是此Form玩家所按按钮的索引。

   注意:虽然看上去此UI并没有关闭按钮,但事实上按“Escape”(手机版使用手机版退出页面的方法)即可退出。
if (r.selection === 0) {
    // ...
} else {
    // ...
}

ModalFormData[编辑]

r.formValues可能是最难懂的。他是指这个UI所有输入内容的有序列表。

read-only formValues?: (boolean | number | string)[];

let form = new ui.ModalFormData();
form.title(...);
form.textField(...);
form.dropdown(...);
form.slider(...);
form.toggle(...);
form.show(...).then(r => {
    // ...
    let [ textField, dropdown, slider, toggle ] = r.formValues;
    // ...
})

范例[编辑]

import * as mc from "@minecraft/server";
import * as ui from "@minecraft/server-ui";

mc.world.beforeEvents.itemUse.subscribe(event => {
	if (event.itemStack.typeId === "minecraft:stick" && event.itemStack.nameTag === "打开用的工具名字") {
		// 打开窗口的函数
        uiShow(event.source);
	}
});

function uiShow(target) {
    let form = new ui.ActionFormData()
        .title("测试用UI")
        .body("主体")
        .button("1")
        .button("2");
    
    form.show(target)
        .then(r => {
        if (r.canceled) {
            if (r.cancelationReason === "UserBusy" || r.cancelationReason === undefined) {
                uiShow(target);    // 当玩家因已打开其他UI(即 "UserBusy")而无法打开此UI时,再此打开此UI,直至玩家正常打开
            }
            return;
        }
        // 操作
    })
}

UI管理[编辑]

UIManager是本模块的一个类,它提供了一些方法来管理我们的UI。

closeAllForms[编辑]

这个函数可以用来关闭目前显示给玩家的所有窗口UI,它还能关闭其他的插件所打开的ui,同时被关闭的ui将不返回cancelationReason[需要验证]

// closeAllForms(player: minecraftserver.Player): void

ui.UIManager.closeAllForms(mc.world.getAllPlayers()[0]);

引用[编辑]

  1. 官方文档