高拓展性的树结构菜单,玩家操作简单方便
预览
菜单操作方式
- 长按近战键打开菜单,再次按下关闭
- A后退,D前进或确认
- WS上下切换选项,长按WS快速翻页
代码详解
变量 | 描述 |
---|---|
menu_tree | 树结构本体,储存每层选择的索引,无法查询更深层 |
menu_treename | 储存每层选择的内容 |
menu_text | 当前页面所有的选项内容 |
menu_content | 当前页面所有的选项备注,与menu_text对应 |
menu_treeindex | 储存每层选择的索引,可以查询更深层。如果页面查询它的子页面选择的索引需要使用该变量 |
menu_state[3] | 当前页面的深度 |
menu_state[4] | 当前页面标题,有默认值生成方式,也可自行定义 |
menu_state[5] | 当前页面每页最大行数,取值1~6;默认6 |
menu_state[12] | 定义当前页面选项的前进操作(D),为0则打开新页面,为1则返回上级,其他值为无动作,或者可以自行定义其他动作,对当前页面所有选项生效;默认0 |
menu_state[17] | 打开当前页面时,往回后退menu_state[17]个页面,可用于不需要页面的动作型选项 |
菜单的编写都在最后一条规则html子程序中,联合menu_trees和menu_state[3]来定位每个选项位置,用menu_text和menu_content定义页面内容,并使用相关参数和动作来控制页面和选项行为
其他
该菜单选项的内容绑定数组变量为menu_text和menu_content,对于这两个数组的修改会直接更新到菜单上,如果某些场景下需要更新当前页面,直接调用refresh_menu子程序或者直接修改这两个变量都可以
编程思想是当打开一个页面前,定义页面的属性并执行相应代码,再最后呈现该页面,所以如果你希望为某个选项添加动作,需要打开它的子页面下并在子页面下编写代码,按照需要是否退回之前的页面
全部代码如下,需要自行理解子程序html的编写方式
变量
{
玩家:
0: menu_content
1: menu_state
2: menu_text
3: menu_dqtext
4: menu_tree
5: menu_treename
6: menu_treeindex
}
子程序
{
0: html
1: refresh_menu
2: default_page
3: refresh_menupage
}
规则("老王不在橱柜 玩家初始化 不需要修改")
{
事件
{
持续 - 每名玩家;
队伍1;
全部;
}
动作
{
事件玩家.menu_tree = 数组(0);
事件玩家.menu_treename = 数组(自定义字符串("主菜单"));
事件玩家.menu_state[20] = 自定义字符串("打开菜单");
事件玩家.menu_state[21] = 自定义字符串("长按");
事件玩家.menu_state[22] = 自定义字符串("————————————————————————————————————————————————————————————————————————————————————————————");
创建HUD文本(事件玩家, 自定义字符串("{0}", 自定义字符串("{1}{0}{2}", 输入绑定字符串(按钮(近身攻击)), 事件玩家.menu_state[21], 事件玩家.menu_state[20])), 无, 无, 左边, 9, 颜色(橙色),
颜色(白色), 颜色(白色), 可见和字符串, 默认可见度);
事件玩家.menu_state[14] = 上一个文本ID;
中止;
事件玩家.menu_tree[0] = 0;
事件玩家.menu_tree[1] = 2;
事件玩家.menu_treename[1] = 自定义字符串("说明");
}
}
规则("老王不在橱柜 打开背包 不需要修改")
{
事件
{
持续 - 每名玩家;
队伍1;
全部;
}
条件
{
按钮被按下(事件玩家, 按钮(近身攻击)) == 真;
}
动作
{
If(事件玩家.menu_state[0] == 真);
事件玩家.menu_state[20] = 自定义字符串("打开菜单");
事件玩家.menu_state[21] = 自定义字符串("长按");
停止限制阈值(事件玩家);
事件玩家.menu_state[0] = 假;
消除HUD文本(事件玩家.menu_state[1]);
消除HUD文本(事件玩家.menu_state[2]);
中止;
End;
等待(0.500, 当为“假”时中止);
If(事件玩家.menu_state[0] == 假);
事件玩家.menu_state[20] = 自定义字符串("关闭菜单\r\nWS上下 A返回 D确认");
事件玩家.menu_state[21] = 自定义字符串("按下");
开始限制阈值(事件玩家, 0, 0.010, 0, 0.010, 0, 0.010);
事件玩家.menu_state[0] = 真;
事件玩家.menu_state[13] = 1;
调用子程序(refresh_menu);
创建HUD文本(事件玩家, 事件玩家.menu_content[事件玩家.menu_state[6]] ? 事件玩家.menu_content[事件玩家.menu_state[6]] : 自定义字符串(""), 无, 无, 左边, 11, 颜色(橙色), 颜色(
白色), 颜色(白色), 可见和字符串, 默认可见度);
事件玩家.menu_state[2] = 上一个文本ID;
创建HUD文本(事件玩家, 自定义字符串("◇{0}\r\n——————————{1}{2}", 事件玩家.menu_state[4], 自定义字符串("{0}{1}", 自定义字符串("{0}{1}{2}",
事件玩家.menu_dqtext[0] ? 自定义字符串("\r\n{0}{1}", 事件玩家.menu_state[7] == 0 ? 自定义字符串("● ") : 自定义字符串("○ "), 事件玩家.menu_dqtext[0])
: 自定义字符串(""), 事件玩家.menu_dqtext[1] ? 自定义字符串("\r\n{0}{1}", 事件玩家.menu_state[7] == 1 ? 自定义字符串("● ") : 自定义字符串("○ "),
事件玩家.menu_dqtext[1]) : 自定义字符串(""), 事件玩家.menu_dqtext[2] ? 自定义字符串("\r\n{0}{1}", 事件玩家.menu_state[7] == 2 ? 自定义字符串("● ") : 自定义字符串(
"○ "), 事件玩家.menu_dqtext[2]) : 自定义字符串("")), 自定义字符串("{0}{1}{2}", 事件玩家.menu_dqtext[3] ? 自定义字符串("\r\n{0}{1}",
事件玩家.menu_state[7] == 3 ? 自定义字符串("● ") : 自定义字符串("○ "), 事件玩家.menu_dqtext[3]) : 自定义字符串(""), 事件玩家.menu_dqtext[4] ? 自定义字符串(
"\r\n{0}{1}", 事件玩家.menu_state[7] == 4 ? 自定义字符串("● ") : 自定义字符串("○ "), 事件玩家.menu_dqtext[4]) : 自定义字符串(""),
事件玩家.menu_dqtext[5] ? 自定义字符串("\r\n{0}{1}", 事件玩家.menu_state[7] == 5 ? 自定义字符串("● ") : 自定义字符串("○ "), 事件玩家.menu_dqtext[5])
: 自定义字符串(""))), 事件玩家.menu_state[9] > 1 ? 自定义字符串("\r\n◇◇第{0}/{1}页◇◇", 事件玩家.menu_state[8] + 1, 事件玩家.menu_state[9]) : 自定义字符串("")),
无, 无, 左边, 10, 颜色(橙色), 颜色(白色), 颜色(白色), 可见和字符串, 默认可见度);
事件玩家.menu_state[1] = 上一个文本ID;
End;
}
}
规则("老王不在橱柜 打开菜单操作 不需要修改")
{
事件
{
持续 - 每名玩家;
队伍1;
全部;
}
条件
{
事件玩家.menu_state[0] == 真;
阈值(事件玩家) != 矢量(0, 0, 0);
}
动作
{
"左"
If(X方向分量(阈值(事件玩家)) > 0);
If(数量(事件玩家.menu_tree) > 1);
修改玩家变量(事件玩家, menu_tree, 根据索引从数组中移除, 数量(事件玩家.menu_tree) - 1);
事件玩家.menu_state[13] = 1;
调用子程序(refresh_menu);
End;
"右"
Else If(X方向分量(阈值(事件玩家)) < 0);
事件玩家.menu_state[11] = 事件玩家.menu_state[6];
事件玩家.menu_state[16] = 事件玩家.menu_text[事件玩家.menu_state[11]];
事件玩家.menu_treename[事件玩家.menu_state[3] + 1] = 事件玩家.menu_state[16];
事件玩家.menu_treeindex[事件玩家.menu_state[3] + 1] = 事件玩家.menu_state[11];
"选择"
If(事件玩家.menu_state[12] == 0);
修改玩家变量(事件玩家, menu_tree, 添加至数组, 事件玩家.menu_state[11]);
事件玩家.menu_state[13] = 0;
调用子程序(refresh_menu);
"返回"
Else If(事件玩家.menu_state[12] == 1);
修改玩家变量(事件玩家, menu_tree, 根据索引从数组中移除, 数量(事件玩家.menu_tree) - 1);
事件玩家.menu_state[13] = 1;
调用子程序(refresh_menu);
"无动作"
Else If(事件玩家.menu_state[12] == -1);
End;
"上"
Else If(Z方向分量(阈值(事件玩家)) > 0);
事件玩家.menu_state[6] -= 1;
事件玩家.menu_state[7] -= 1;
If(事件玩家.menu_state[6] < 0);
事件玩家.menu_state[6] = 事件玩家.menu_state[10] - 1;
事件玩家.menu_state[7] = 事件玩家.menu_state[6] % 事件玩家.menu_state[5];
事件玩家.menu_state[8] = 事件玩家.menu_state[9] - 1;
调用子程序(refresh_menupage);
Else If(事件玩家.menu_state[7] < 0);
事件玩家.menu_state[7] = 事件玩家.menu_state[5] - 1;
事件玩家.menu_state[8] -= 1;
调用子程序(refresh_menupage);
End;
根据条件中止(事件玩家.menu_state[9] <= 1);
等待直到 (Z方向分量(阈值(事件玩家)) <= 0, 0.400);
While(Z方向分量(阈值(事件玩家)) > 0);
事件玩家.menu_state[8] -= 1;
事件玩家.menu_state[6] -= 事件玩家.menu_state[5];
If(事件玩家.menu_state[8] < 0);
事件玩家.menu_state[8] = 事件玩家.menu_state[9] - 1;
事件玩家.menu_state[6] = 事件玩家.menu_state[10] - 1;
事件玩家.menu_state[7] = 事件玩家.menu_state[6] % 事件玩家.menu_state[5];
End;
调用子程序(refresh_menupage);
等待直到 (Z方向分量(阈值(事件玩家)) <= 0, 0.400);
End;
"下"
Else If(Z方向分量(阈值(事件玩家)) < 0);
事件玩家.menu_state[6] += 1;
事件玩家.menu_state[7] += 1;
If(事件玩家.menu_state[6] >= 事件玩家.menu_state[10]);
事件玩家.menu_state[6] = 0;
事件玩家.menu_state[7] = 0;
事件玩家.menu_state[8] = 0;
调用子程序(refresh_menupage);
Else If(事件玩家.menu_state[7] >= 事件玩家.menu_state[5]);
事件玩家.menu_state[7] = 0;
事件玩家.menu_state[8] += 1;
调用子程序(refresh_menupage);
End;
根据条件中止(事件玩家.menu_state[9] <= 1);
等待直到 (Z方向分量(阈值(事件玩家)) >= 0, 0.400);
While(Z方向分量(阈值(事件玩家)) < 0);
事件玩家.menu_state[8] += 1;
事件玩家.menu_state[6] += 事件玩家.menu_state[5];
If(事件玩家.menu_state[8] > 事件玩家.menu_state[9] - 1);
事件玩家.menu_state[8] = 0;
事件玩家.menu_state[6] = 0;
事件玩家.menu_state[7] = 0;
Else If(事件玩家.menu_state[6] > 事件玩家.menu_state[10] - 1);
事件玩家.menu_state[6] = 事件玩家.menu_state[10] - 1;
事件玩家.menu_state[7] = 事件玩家.menu_state[6] % 事件玩家.menu_state[5];
End;
调用子程序(refresh_menupage);
等待直到 (Z方向分量(阈值(事件玩家)) >= 0, 0.400);
End;
End;
}
}
规则("老王不在橱柜 refresh_menu 更新背包页面 不需要修改")
{
事件
{
子程序;
refresh_menu;
}
动作
{
While(真);
事件玩家.menu_state[17] = 0;
事件玩家.menu_state[19] = 0;
"当前深度"
事件玩家.menu_state[3] = 数量(事件玩家.menu_tree) - 1;
调用子程序(default_page);
调用子程序(html);
"阻止打开新页面并刷新"
While(事件玩家.menu_state[17] > 0);
事件玩家.menu_state[17] -= 1;
事件玩家.menu_state[19] = 1;
修改玩家变量(事件玩家, menu_tree, 根据索引从数组中移除, 数量(事件玩家.menu_tree) - 1);
事件玩家.menu_state[13] = 1;
End;
If(事件玩家.menu_state[19] == 0);
中断;
End;
End;
"为空则添加返回上级选项"
If(事件玩家.menu_text == 空数组);
事件玩家.menu_text = 数组(自定义字符串("没有内容->返回"));
事件玩家.menu_state[12] = 1;
End;
事件玩家.menu_state[10] = 数量(事件玩家.menu_text);
"下标位置不能超出数量"
事件玩家.menu_state[6] = 较小(事件玩家.menu_state[6], 事件玩家.menu_state[10] - 1);
"总页数(从1开始)"
事件玩家.menu_state[9] = 取整(较大(0, 事件玩家.menu_state[10] - 0) / 事件玩家.menu_state[5], 上);
"当前页选中的行的下标(0~最大行数-1)"
事件玩家.menu_state[7] = 事件玩家.menu_state[6] % 事件玩家.menu_state[5];
"当前页数(从0开始)"
事件玩家.menu_state[8] = 取整((0 + 事件玩家.menu_state[6]) / 事件玩家.menu_state[5], 下);
"更新当前页面"
调用子程序(refresh_menupage);
}
}
规则("老王不在橱柜 default_page 默认页面属性 定义了页面的默认生成方式 按需要修改")
{
事件
{
子程序;
default_page;
}
动作
{
"每页最大行数,不能超过6"
事件玩家.menu_state[5] = 6;
"页面标题,这里提供了两种标题方法,如需切换,启用该动作并禁用下面6条动作"
禁用 事件玩家.menu_state[4] = 事件玩家.menu_treename[事件玩家.menu_state[3] + 0];
"生成页面标题"
事件玩家.menu_state[23] = 0;
事件玩家.menu_state[4] = 自定义字符串("主菜单");
While(事件玩家.menu_state[23] < 事件玩家.menu_state[3]);
事件玩家.menu_state[4] = 自定义字符串("{0}\r\n{1}{2}", 事件玩家.menu_state[4], 截取字符串(事件玩家.menu_state[22], 0, 1 * (事件玩家.menu_state[23] + 1)),
事件玩家.menu_treename[事件玩家.menu_state[23] + 1]);
事件玩家.menu_state[23] += 1;
End;
"当前页面是否为新打开"
If(事件玩家.menu_state[13] == 1);
"为1则光标置于记录点位置"
事件玩家.menu_state[6] = 事件玩家.menu_treeindex[事件玩家.menu_state[3] + 1];
事件玩家.menu_state[13] = 0;
Else;
"为0则将光标置于0"
事件玩家.menu_state[6] = 0;
End;
"文本数据数组"
事件玩家.menu_text = 空数组;
"右键的操作,0钻取 1返回上一级 2自定义 (对所有行生效)"
事件玩家.menu_state[12] = 假;
"文本备注数组"
事件玩家.menu_content = 空数组;
}
}
规则("老王不在橱柜 refresh_menupage 更新背包当前页面 不需要修改")
{
事件
{
子程序;
refresh_menupage;
}
动作
{
事件玩家.menu_dqtext = 数组分割(事件玩家.menu_text, 事件玩家.menu_state[8] * 事件玩家.menu_state[5], 事件玩家.menu_state[5]);
}
}
规则("老王不在橱柜 html 菜单界面 需要自己编写")
{
事件
{
子程序;
html;
}
动作
{
If(事件玩家.menu_state[3] == 0);
"选项文本"
事件玩家.menu_text = 字符串分割(自定义字符串("选项0\\选项1\\选项2\\关于"), 自定义字符串("\\"));
"备注文本"
事件玩家.menu_content = 字符串分割(自定义字符串("多级菜单示例\\动作类型选项示例\\树分叉优先写法"), 自定义字符串("\\"));
Else If(事件玩家.menu_state[3] >= 1);
"选项0 多级菜单示例"
If(事件玩家.menu_tree[1] == 0);
"深度为1"
If(事件玩家.menu_state[3] == 1);
事件玩家.menu_text = 字符串分割(自定义字符串("选项0-0\\选项0-1\\选项0-2"), 自定义字符串("\\"));
"深度为2"
Else If(事件玩家.menu_state[3] == 2);
"选项0-0-"
If(事件玩家.menu_tree[2] == 0);
"不钻取下一层"
事件玩家.menu_state[12] = -1;
事件玩家.menu_text = 字符串分割(自定义字符串("选项0-0-0\\选项0-0-1\\选项0-0-2"), 自定义字符串("\\"));
"选项0-1-"
Else If(事件玩家.menu_tree[2] == 1);
"继续钻取下一层,若没有内容则自动添加一个返回上级的选项,此为默认值"
事件玩家.menu_state[12] = 0;
事件玩家.menu_text = 字符串分割(自定义字符串("选项0-1-0\\选项0-1-1\\选项0-1-2"), 自定义字符串("\\"));
End;
End;
"选项1 动作类型选项示例"
Else If(事件玩家.menu_tree[1] == 1);
"深度为1"
If(事件玩家.menu_state[3] == 1);
事件玩家.menu_text = 字符串分割(自定义字符串("发送语音\\切换英雄\\添加机器人"), 自定义字符串("\\"));
"深度为2"
Else If(事件玩家.menu_state[3] == 2);
"发送你好动作"
If(事件玩家.menu_tree[2] == 0);
"打开该页面时,往回后退menu_state[17]即1个页面"
事件玩家.menu_state[17] = 1;
交流(事件玩家, 语音(上));
"切换英雄"
Else If(事件玩家.menu_tree[2] == 1);
事件玩家.menu_text = 全部英雄;
"添加机器人动作"
Else If(事件玩家.menu_tree[2] == 2);
"打开该页面时,往回后退menu_state[17]即1个页面"
事件玩家.menu_state[17] = 1;
生成机器人(英雄(D.Va), 所在队伍(事件玩家), -1, 所选位置(事件玩家), 所选位置(事件玩家));
End;
"深度为3"
Else If(事件玩家.menu_state[3] == 3);
"切换英雄动作,该定位的是深度为3,且tree[2]为1即“切换英雄”的子页面,这里的if判断可省略因为深度为3没有其他页面,但不建议,会导致语义理解困难,影响后续添加其他页面"
If(事件玩家.menu_tree[2] == 1);
"打开该页面时,往回后退menu_state[17]即2个页面,改成1也可以"
事件玩家.menu_state[17] = 2;
"menu_tree记录每层选择的选项索引,menu_treename记录每层选择的选项内容,这里的menu_treename[3]记录了上一级你选择的英雄"
开始强制玩家选择英雄(事件玩家, 事件玩家.menu_treename[3]);
End;
End;
"选项2 以上两个选项为深度优先写法,有时深度较大要使用树分叉优先写法"
Else If(事件玩家.menu_tree[1] == 2);
"深度为1"
If(事件玩家.menu_state[3] == 1);
事件玩家.menu_text = 字符串分割(自定义字符串("选项2-0\\选项2-1"), 自定义字符串("\\"));
"深度为2及以上"
Else;
"优先分叉 选项2-0-"
If(事件玩家.menu_tree[2] == 0);
"深度为2"
If(事件玩家.menu_state[3] == 2);
事件玩家.menu_text = 字符串分割(自定义字符串("选项2-0-0\\选项2-0-1"), 自定义字符串("\\"));
"深度为3及以上"
Else;
"选项2-0-0-"
If(事件玩家.menu_tree[3] == 0);
"深度为3 最末一层该If判断深度可省略"
If(事件玩家.menu_state[3] == 3);
事件玩家.menu_text = 字符串分割(自定义字符串("选项2-0-0-0\\选项2-0-0-1"), 自定义字符串("\\"));
End;
"选项2-0-1-"
Else If(事件玩家.menu_tree[3] == 1);
"深度为3 最末一层该If判断深度可省略"
If(事件玩家.menu_state[3] == 3);
事件玩家.menu_text = 字符串分割(自定义字符串("选项2-0-1-0\\选项2-0-1-1"), 自定义字符串("\\"));
End;
End;
End;
"优先分叉 选项2-1-"
Else If(事件玩家.menu_tree[2] == 1);
"深度为2"
If(事件玩家.menu_state[3] == 2);
事件玩家.menu_text = 字符串分割(自定义字符串("选项2-1-0\\选项2-1-1"), 自定义字符串("\\"));
"深度为3及以上"
Else;
"选项2-1-0-"
If(事件玩家.menu_tree[3] == 0);
"深度为3 最末一层该If判断深度可省略"
If(事件玩家.menu_state[3] == 3);
事件玩家.menu_text = 字符串分割(自定义字符串("选项2-1-0-0\\选项2-1-0-1"), 自定义字符串("\\"));
End;
"选项2-1-1-"
Else If(事件玩家.menu_tree[3] == 1);
"深度为3 最末一层该If判断深度可省略"
If(事件玩家.menu_state[3] == 3);
事件玩家.menu_text = 字符串分割(自定义字符串("选项2-1-1-0\\选项2-1-1-1"), 自定义字符串("\\"));
End;
End;
End;
End;
End;
Else If(事件玩家.menu_tree[1] == 3);
If(事件玩家.menu_state[3] == 1);
事件玩家.menu_state[12] = -1;
事件玩家.menu_text = 字符串分割(自定义字符串("作者:老王不在橱柜\\Q群:863964203\\更新时间:2021-11-19\\熔火工坊链接"), 自定义字符串("\\"));
事件玩家.menu_content = 字符串分割(自定义字符串("\\\\\\owmod.net/work/view/1859"), 自定义字符串("\\"));
End;
End;
End;
}
}
评论
这里空空如也~