diff --git a/.gitignore b/.gitignore
index 5173a93..dba7df0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
package-lock.json
package.json
.DS_Store
+.idea
diff --git a/mcguide/10-新内容/1-开发工作台/933-1.1.44.md b/mcguide/10-新内容/1-开发工作台/933-1.1.44.md
new file mode 100644
index 0000000..7a24788
--- /dev/null
+++ b/mcguide/10-新内容/1-开发工作台/933-1.1.44.md
@@ -0,0 +1,34 @@
+---
+front: https://nie.res.netease.com/r/pic/20250709/095c3bb4-eb58-4444-811f-76be2b94eedf.jpg
+hard: 入门
+time: 2分钟
+selection: 23
+---
+
+# 2025.7.08 版本1.1.44
+
+## 地图编辑器
+
+替换和填充界面增加方块收藏功能
+
+- 点击所有方块列表中的方块后,会出现收藏按钮,点击按钮即可将方块放入收藏列表
+
+
+
+- 点击在收藏方块列表中的方块后,会出现取消收藏按钮,点击按钮即可将方块移出收藏列表
+
+
+
+## 配置编辑器
+
+- 对新建文件中"生成规则"描述文字优化为"实体生成规则",避免和特征规则造成混淆
+
+## 问题修复
+
+- 修复多结构生成规则字段"is multi sub editor"检测会删除文件问题
+
+- 修复原版模型转fbx工具0帧处理问题
+
+- 修复文本输入框控件调整输入文本颜色属性后,再改属性在编辑器内消失问题
+
+- 修复地图编辑器替换、填充弹出界面位置UI会遮挡的问题
\ No newline at end of file
diff --git a/mcguide/10-新内容/1-开发工作台/934-1.1.43.md b/mcguide/10-新内容/1-开发工作台/934-1.1.43.md
new file mode 100644
index 0000000..105221d
--- /dev/null
+++ b/mcguide/10-新内容/1-开发工作台/934-1.1.43.md
@@ -0,0 +1,34 @@
+---
+front: https://nie.res.netease.com/r/pic/20250625/93d00c93-a3de-43e2-86d2-8128f8c467aa.jpg
+hard: 入门
+time: 2分钟
+selection: 23
+---
+
+# 2025.6.25 版本1.1.43
+
+## 编辑器
+
+### 编辑器升级3.4
+
+新增支持1.21.0的新物品、方块、实体等
+
+### 贴图压缩工具
+
+工具箱新增资源包贴图压缩工具,可根据JSON配置自动压缩资源包贴图并生成报告,帮助开发者减少包体体积
+
+详细使用链接请前往官方Github仓库[https://github.com/MCNeteaseDevs/Image-AutoCompress](https://github.com/MCNeteaseDevs/Image-AutoCompress)
+
+
+
+### Java版组件-本地导入-适用版本,新增支持Java1.21
+
+
+
+## 配置编辑器
+
+- 新建页签优化
+
+现在新建配置会根据当前所在页面打开对应的配置选择界面。如在**界面编辑器界面**,新建文件向导会默认**选择界面选项**(见下图)
+
+
\ No newline at end of file
diff --git a/mcguide/10-新内容/1-开发工作台/935-1.1.42.md b/mcguide/10-新内容/1-开发工作台/935-1.1.42.md
new file mode 100644
index 0000000..562112c
--- /dev/null
+++ b/mcguide/10-新内容/1-开发工作台/935-1.1.42.md
@@ -0,0 +1,26 @@
+---
+front: https://nie.res.netease.com/r/pic/20250609/61c838c0-4e9e-49a0-8555-403f760039ad.jpg
+hard: 入门
+time: 2分钟
+selection: 23
+---
+
+# 2025.6.10 版本1.1.42
+
+## 编辑器
+
+- 组件名称发布适配特殊字符
+
+现在支持特殊字符的作品名,并一键发布到开发者内容管理平台
+
+
+
+## 地图编辑器
+
+- **按住Ctrl键**点击可以多选所需要替换/填充的方块行,再次点击右侧方块即可全部**预选**该方块进行替换/填充
+
+
+
+## 问题修复
+
+- 修复界面编辑器使用原版贴图会复制问题
\ No newline at end of file
diff --git a/mcguide/10-新内容/1-开发工作台/936-1.1.41.md b/mcguide/10-新内容/1-开发工作台/936-1.1.41.md
new file mode 100644
index 0000000..10dd761
--- /dev/null
+++ b/mcguide/10-新内容/1-开发工作台/936-1.1.41.md
@@ -0,0 +1,22 @@
+---
+front: https://nie.res.netease.com/r/pic/20250528/cb9ff22d-2b87-4c3a-9114-4f2e947d9f1e.jpg
+hard: 入门
+time: 2分钟
+selection: 23
+---
+
+# 2025.5.27 版本1.1.41
+
+## 编辑器
+
+- 版本升级优化
+
+点击版本升级后,也会升级modules字段的version
+
+
+
+
+
+## 问题修复
+
+- 修复方块易测获取测试端游戏进程失败问题
\ No newline at end of file
diff --git a/mcguide/10-新内容/1-开发工作台/937-1.1.40.md b/mcguide/10-新内容/1-开发工作台/937-1.1.40.md
new file mode 100644
index 0000000..d5c8de3
--- /dev/null
+++ b/mcguide/10-新内容/1-开发工作台/937-1.1.40.md
@@ -0,0 +1,38 @@
+---
+front: https://nie.res.netease.com/r/pic/20250513/d83d9999-e1e2-4f29-870d-a50582e47cfc.jpg
+hard: 入门
+time: 2分钟
+selection: 23
+---
+
+# 2025.5.13 版本1.1.40
+
+## 配置编辑器
+
+- 新增自定义锻造转换配方选项
+
+## 界面编辑器
+
+- 界面编辑器生成控件键值对源码排序,方便开发者进行阅读
+
+排序规则如下
+```bash
+控件类:type、renderer
+变量(按字母顺序):$变量1: xxx
+变量初始化:variables
+尺寸和位置相关:offset、size等
+可见性和状态视觉相关:layer、alpha等
+动画相关: anims、animation_reset_name等
+数据绑定相关:modifications、property_bag、bindings
+最后为controls
+```
+
+## UI调试工具
+
+- UI调试工具仅顶部分割线才可拖动 变为 右侧分割线均可拖动
+
+## 问题修复
+
+- 方块易测连接失败问题修复
+
+- 修复贴图资源复制问题
\ No newline at end of file
diff --git a/mcguide/10-新内容/1-开发工作台/938-1.1.39.md b/mcguide/10-新内容/1-开发工作台/938-1.1.39.md
new file mode 100644
index 0000000..df14b6d
--- /dev/null
+++ b/mcguide/10-新内容/1-开发工作台/938-1.1.39.md
@@ -0,0 +1,26 @@
+---
+front: https://nie.res.netease.com/r/pic/20250422/45cbbcc5-1c8e-43de-b011-cf822f273031.jpg
+hard: 入门
+time: 2分钟
+selection: 23
+---
+
+# 2025.4.22 版本1.1.39
+
+## 启动器
+
+- 性能诊断工具优化,优化采集服务的CPU消耗、优化获取进程列表的效率等
+- 组件编辑界面优化,编辑界面排布与配置界面一致
+- 日志与调试工具,保存窗口位置和大小以及字号大小为配置,下次打开工具使用保存配置
+
+## 编辑器
+
+- 自定义指令支持参数变体配置
+
+
+
+- 支持批量导入原版方块模型,点击导入-原版方块模型后打开模型所在文件夹,可以选择多个文件导入
+
+## 问题修复
+
+- 编辑功能对橡木方块进行旋转操作后变为白桦木方块
\ No newline at end of file
diff --git a/mcguide/10-新内容/1-开发工作台/939-1.1.33.md b/mcguide/10-新内容/1-开发工作台/939-1.1.33.md
new file mode 100644
index 0000000..8c6498a
--- /dev/null
+++ b/mcguide/10-新内容/1-开发工作台/939-1.1.33.md
@@ -0,0 +1,22 @@
+---
+front: https://nie.res.netease.com/r/pic/20250310/dd8f038a-fd2a-497f-861a-5b36dd238bf0.jpg
+hard: 入门
+time: 2分钟
+selection: 23
+---
+
+# 2025.3.11 版本1.1.33
+
+## 启动器
+
+新增性能诊断模块,具体教程见[性能监测与调试工具](../../30-测试/5-性能监测与调试工具.md)。
+
+## 编辑器
+
+自定义配方支持锻造转换配方。
+
+## 问题修复
+
+- 修复地图附带mod在第二次开发测试后无法热重载
+- 修复山羊实体配置模板为空问题
+- Java版作品测试支持1.19.2
\ No newline at end of file
diff --git a/mcguide/10-新内容/1-开发工作台/940-1.1.31.md b/mcguide/10-新内容/1-开发工作台/940-1.1.31.md
new file mode 100644
index 0000000..e4aabe4
--- /dev/null
+++ b/mcguide/10-新内容/1-开发工作台/940-1.1.31.md
@@ -0,0 +1,37 @@
+---
+front: https://nie.res.netease.com/r/pic/20250220/984b86ef-d9a4-4cb4-bf3b-c89d86a96b7c.jpg
+hard: 入门
+time: 2分钟
+selection: 23
+---
+
+# 2025.2.20 版本1.1.31
+
+## 启动器
+
+组件导入功能优化,支持选择文件类型。
+
+
+
+## 界面编辑器
+
+界面编辑器支持预览新触控界面。
+
+
+
+界面编辑器补充字段。
+
+- 文本控件:补充锁定颜色、锁定透明度、隐藏连字符、启用本地化
+- 图片控件:补充平铺类型、平铺缩放比例、双线性缩放
+- 按钮控件:补充按钮声音、声音音量、声音音调
+
+## 配置编辑器
+
+- 自定义配方:支持配方解锁配置
+- 自定义盔甲:补充盔甲韧性、击退抗性配置
+- 掉落表:支持战利品表配置和空配置
+
+## 问题修复
+
+- 修复打开含雕纹书架的结构体后编辑器崩溃
+- 修复netease:weapon、netease:render_layer部分字段与实际配置不符
\ No newline at end of file
diff --git a/mcguide/10-新内容/1-开发工作台/941-1.1.30.md b/mcguide/10-新内容/1-开发工作台/941-1.1.30.md
new file mode 100644
index 0000000..997683b
--- /dev/null
+++ b/mcguide/10-新内容/1-开发工作台/941-1.1.30.md
@@ -0,0 +1,33 @@
+---
+front: https://nie.res.netease.com/r/pic/20250122/8dfbddfe-aa1f-4d82-a802-68fcdac73c78.jpg
+hard: 入门
+time: 2分钟
+selection: 23
+---
+
+# 2025.1.23 版本1.1.30
+
+## 启动器
+
+新建作品时支持配置命名空间。
+
+
+
+## 编辑器
+
+自定义物品新增自定义盾牌模板和相关属性。
+
+
+
+编辑器属性面板排版优化,部分控件支持自适应宽度,分割线改为白色,并支持更大范围拖动。
+
+
+
+## 其他
+
+- 修复地形功能放置结构池属性点击无反应
+- 修复编辑器内的村庄结构无法正常生成
+- 修复fbx/obj导入地图编辑器后方块颜色错误
+- 修复放置带有箱子的结构体时内嵌游戏崩溃
+- 修复配方配置的结果选择自定义物品后属性栏不显示
+- 修复物品选择器部分物品贴图错误问题
\ No newline at end of file
diff --git a/mcguide/10-新内容/1-开发工作台/942-1.1.29.md b/mcguide/10-新内容/1-开发工作台/942-1.1.29.md
new file mode 100644
index 0000000..3e2b048
--- /dev/null
+++ b/mcguide/10-新内容/1-开发工作台/942-1.1.29.md
@@ -0,0 +1,35 @@
+---
+front: https://nie.res.netease.com/r/pic/20250108/9c1b2703-8a0d-4126-9ffd-3c55e17e0a9a.jpg
+hard: 入门
+time: 2分钟
+selection: 23
+---
+
+# 2025.1.9 版本1.1.29
+
+## 编辑器
+
+新增自定义指令配置,开发者可以更方便地为作品添加自定义指令。
+
+
+
+支持新版物品和方块注册逻辑,不仅支持配置两种新的获取方式,并且能够指定自定义分页。
+
+
+
+编辑器目录生成优化,减少了大量不必要的文件夹和文件。
+
+
+
+## 启动器
+
+配置界面重新排布,现在右侧搜索框更大更容易操作。
+
+
+
+## 其他
+
+- 修复界面编辑器快速切换自定义控件导致Json数据丢失问题
+- 修复导出功能会删除二级目录同名非空文件夹的问题
+- 云端列表增加对无主包的demo模组标记
+- 编辑器升级基岩版1.20.50和Java版1.20.6
\ No newline at end of file
diff --git a/mcguide/10-新内容/1-开发工作台/943-1.1.28.md b/mcguide/10-新内容/1-开发工作台/943-1.1.28.md
new file mode 100644
index 0000000..3fab260
--- /dev/null
+++ b/mcguide/10-新内容/1-开发工作台/943-1.1.28.md
@@ -0,0 +1,58 @@
+---
+front: https://nie.res.netease.com/r/pic/20241219/5a620c8c-c7c7-4d80-8f36-137e1edc2db2.jpg
+hard: 入门
+time: 2分钟
+selection: 23
+---
+
+# 2024.12.19 版本1.1.28
+
+## 导出功能
+
+作品导出的zip中会移除无用的空文件夹和文件。
+
+导出前:
+
+
+
+导出后:
+
+
+
+## 界面编辑器
+
+- 缩进调整为4个空格
+- 保留键值对顺序,新键插入末尾
+- 移除无用文件和键值对
+
+```json
+在生成image控件时,不生成:
+"clip_direction": "left",
+"clip_ratio": 0.0,
+"controls": [],
+```
+- 不再生成netease_editor_template_namespace.json
+- 浮点数生成优化
+
+```json
+原本:"color": [0.2352941176470588, 0.3176470588235294, 0.9764705882352941],
+修改后:"color": [0.2353, 0.3176, 0.9765],
+
+原本:"offset": [20.0, 0.0],
+修改后:"offset": [20, 0],
+
+原本:"font_scale_factor": 2.000000000000001,
+修改后:"font_scale_factor": 2,
+```
+
+## 测试配置
+
+开发测试的配置界面支持搜索作品,方便测试同时加载多个作品的情况。
+
+
+
+## 新建作品
+
+新建空白地图和空白附加包支持仅创建。
+
+
\ No newline at end of file
diff --git a/mcguide/10-新内容/1-开发工作台/images/241219/1.png b/mcguide/10-新内容/1-开发工作台/images/241219/1.png
new file mode 100644
index 0000000..8070dcb
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/241219/1.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/241219/2.png b/mcguide/10-新内容/1-开发工作台/images/241219/2.png
new file mode 100644
index 0000000..72e6a22
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/241219/2.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/241219/3.png b/mcguide/10-新内容/1-开发工作台/images/241219/3.png
new file mode 100644
index 0000000..3aec4e8
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/241219/3.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/241219/4.png b/mcguide/10-新内容/1-开发工作台/images/241219/4.png
new file mode 100644
index 0000000..ba17c20
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/241219/4.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250109/1.png b/mcguide/10-新内容/1-开发工作台/images/250109/1.png
new file mode 100644
index 0000000..a1e2009
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250109/1.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250109/2.png b/mcguide/10-新内容/1-开发工作台/images/250109/2.png
new file mode 100644
index 0000000..c162a36
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250109/2.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250109/3.png b/mcguide/10-新内容/1-开发工作台/images/250109/3.png
new file mode 100644
index 0000000..a8c624e
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250109/3.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250109/4.png b/mcguide/10-新内容/1-开发工作台/images/250109/4.png
new file mode 100644
index 0000000..ec346f3
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250109/4.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250123/1.png b/mcguide/10-新内容/1-开发工作台/images/250123/1.png
new file mode 100644
index 0000000..62a00db
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250123/1.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250123/2.png b/mcguide/10-新内容/1-开发工作台/images/250123/2.png
new file mode 100644
index 0000000..e297660
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250123/2.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250123/3.png b/mcguide/10-新内容/1-开发工作台/images/250123/3.png
new file mode 100644
index 0000000..ddd6331
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250123/3.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250220/1.png b/mcguide/10-新内容/1-开发工作台/images/250220/1.png
new file mode 100644
index 0000000..a48351f
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250220/1.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250220/2.png b/mcguide/10-新内容/1-开发工作台/images/250220/2.png
new file mode 100644
index 0000000..c119c32
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250220/2.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250422/0_0.png b/mcguide/10-新内容/1-开发工作台/images/250422/0_0.png
new file mode 100644
index 0000000..9bc8eb4
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250422/0_0.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250527/0_0.png b/mcguide/10-新内容/1-开发工作台/images/250527/0_0.png
new file mode 100644
index 0000000..ced42a6
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250527/0_0.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250527/0_1.png b/mcguide/10-新内容/1-开发工作台/images/250527/0_1.png
new file mode 100644
index 0000000..e02ab8d
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250527/0_1.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250610/0_0.png b/mcguide/10-新内容/1-开发工作台/images/250610/0_0.png
new file mode 100644
index 0000000..d1f543d
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250610/0_0.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250610/0_1.png b/mcguide/10-新内容/1-开发工作台/images/250610/0_1.png
new file mode 100644
index 0000000..e86be52
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250610/0_1.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250625/0_0.png b/mcguide/10-新内容/1-开发工作台/images/250625/0_0.png
new file mode 100644
index 0000000..85b503f
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250625/0_0.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250625/0_1.png b/mcguide/10-新内容/1-开发工作台/images/250625/0_1.png
new file mode 100644
index 0000000..0e9ae73
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250625/0_1.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250625/0_2.png b/mcguide/10-新内容/1-开发工作台/images/250625/0_2.png
new file mode 100644
index 0000000..d981eee
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250625/0_2.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250708/0_0.png b/mcguide/10-新内容/1-开发工作台/images/250708/0_0.png
new file mode 100644
index 0000000..8bfd8f7
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250708/0_0.png differ
diff --git a/mcguide/10-新内容/1-开发工作台/images/250708/0_1.png b/mcguide/10-新内容/1-开发工作台/images/250708/0_1.png
new file mode 100644
index 0000000..3b7399f
Binary files /dev/null and b/mcguide/10-新内容/1-开发工作台/images/250708/0_1.png differ
diff --git a/mcguide/16-美术/6-模型和动作/12-动作优化规范.md b/mcguide/16-美术/6-模型和动作/12-动作优化规范.md
new file mode 100644
index 0000000..3636f2e
--- /dev/null
+++ b/mcguide/16-美术/6-模型和动作/12-动作优化规范.md
@@ -0,0 +1,143 @@
+---
+front: 进阶
+time: 15分钟
+---[2-地图编辑器使用说明.md](../../14-%E5%9C%B0%E5%9B%BE%E5%88%B6%E4%BD%9C/2-%E5%9C%B0%E5%9B%BE%E7%BC%96%E8%BE%91%E5%99%A8%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md)
+
+# 模型规范指南
+## 前言
+在当前模组开发实践中,部分开发者所采用的 Blockbench.
+
+模型与官方标准模型存在差异,因此换了BlockBench模型的Mod,会导致官方皮肤时出现贴图错位、模型消失等兼容性问题,影响了玩家的视觉体验.
+因此,我们现已开放官方模型规范,开发者们请参考并遵循。新作品通过规范指南进行UV、动画等的制作,已有作品则可以通过API判断是否需要修改Blockbench
+模型,确保模组能够与官方皮肤良好配合,为玩家带来更加一致、流畅的游戏体验。
+
+## 兼容分类
+
+根据模组与官方皮肤的兼容程度,分为:
+1. **完全兼容**:未更换bb模型。表现为:皮肤模型贴图,以及穿戴外观,模组动画等表现都正常。
+2. **部分兼容**:更换了bb模型,但按照官方规范制作。表现为:皮肤挂件以及穿戴外观正常,但是模型样式改变及贴图错乱。
+3. **不兼容**:更换了bb模型,且未按照官方规范制作。表现为:模型样式改变,皮肤挂件错乱,穿戴外观错乱,以及动作异常。
+
+## 规范概要
+
+1. 玩法模组:非必要不改bb模型
+2. 动作优化类模组:`人形角色,非必要不修改bb结构,即无需使用AddPlayerGeometry的Api`
+* 未增加关节:仅增加和优化动画的 ,不替换bb模型(属于“完全兼容”)
+* 增加关节:
+ - 中高级别多关节官方皮肤:不替换模型与贴图,动画按照官方骨骼层级制作进而保证皮肤表现正常(属于“完全兼容”)
+ - 其他官方皮肤:可根据各模组对动画的修改程度选择是否替换bb模型。如果选择替换bb模型,则需按官方规范制作(属于“部分兼容”)
+3. 人形角色,涉及“动作优化”等必须修改bb模型的,遵守以下规范即可(可参考 官方人物模型.json 模板)
+4. 不建议直接修改 player.entity.json 和 player.render_controllers.json,如果改了请务必在官方的规范下进行拓展
+
+## 美术制作规范
+
+### 必要骨骼
+
+1. 常规骨骼:常作为挂件的挂点
+> root, waist, body, leftArm, leftArmDown, rightArm, rightArmDown, head, bodyDown, leftLeg, leftLegDown, rightLeg, rightLegDown, rightLeg, cape
+2. 会员盔甲挂点:
+> hat, jacket, jacketDown, leftSleeve, leftSleeveDown, rightSleeve, rightSleeveDown, leftPants, leftPantsDown, rightPants, rightPantsDown
+
+**【注意】**
+
+共计26个骨骼,开发者请不要随意删除
+必要骨骼中,红色字体的骨骼为相比原版Steve新增的关节
+
+
+### 骨骼层级一览
+
+| 节点名称 | 枢纽点 | 备注 |
+|---------------------------|----------------| --- |
+| root | (0,0,0) | |
+| —waist | (0, 12, 0) | |
+| ——body | (0, 24, 0) | |
+| ———head | (0, 24, 0) | |
+| —————hat | (0, 24, 0) | |
+| ———cape | (0, 24, 3) | |
+| ———leftArm | (-5, 22, 0) | |
+| **—————leftArmDown** | (-5, 18, 0) | 新增必要骨骼 |
+| **———————leftSleeveDown** | (-5, 18.25, 0) | 新增盔甲骨骼 |
+| ———————leftItem | (-6, 15, 0) | |
+| —————leftSleeve | (-5, 22, 0) | |
+| ———rightArm | (5, 22, 0) | |
+| **—————rightArmDown** | (5, 18, 0) | 新增必要骨骼 |
+| **———————rightSleeveDown** | (5, 18.25, 0) | 新增盔甲骨骼 |
+| ———————rightItem | (6, 15, 0) | |
+| —————rightSleeve | (5, 22, 0) | |
+| ———jacket | (0, 24, 0) | |
+| **——bodyDown** | (0, 16, 0) | 新增必要骨骼 |
+| **———jacketDown** | (0, 16.25, 0) | 新增盔甲骨骼 |
+| —leftLeg | (-1.9, 12, 0) | |
+| ——leftPants | (-1.9, 12, 0) | |
+| **——leftLegDown** | (-1.9, 6, 0) | 新增必要骨骼 |
+| **————leftPantsDown** | (-1.9, 6.25, 0) | 新增盔甲骨骼 |
+| —rightLeg | (1.9, 12, 0) | |
+| ——rightPants | (1.9, 12, 0) | |
+| **——rightLegDown** | (1.9, 6, 0) | 新增必要骨骼 |
+| **————rightPantsDown** | (1.9, 6.25, 0) | 新增盔甲骨骼 |
+
+**【注意】**
+* 骨骼层级:影响官方动画兼容
+* 骨骼命名:影响官方挂件兼容
+
+### 骨骼层级说明
+* body 和 bodyDown 层级并列
+* 新增的切分关节
+ - 5个骨骼节点:`leftArmDown, rightArmDown, bodyDown, leftLegDown, rightLegDown `
+ - 5个骨骼节点:`jacketDown, leftSleeveDown, rightSleeveDown, leftPantsDown, [12-动作优化规范.md](12-%E5%8A%A8%E4%BD%9C%E4%BC%98%E5%8C%96%E8%A7%84%E8%8C%83.md)rightPantsDown`
+
+### UV贴图制作
+如下图所示,需要按照Steve规范进行制作
+
+
+### 其余注意事项
+
+1. 除盔甲骨骼以外,其他骨骼下必须有同名cube。例如:
+
+
+
+## 新增支持
+
+### MOD SDK
+
+为了方便开发者们在脚本中判断当前玩家皮肤状态,新增了三个接口和一个事件。
+开发者可在事件当中判定**当前皮肤是否是官方,从而决定是否修改模型。**
+
+也请开发者注意[**规范概要**](#规范概要),**非必要情况不修改模型。如需修改,也遵循照官方模型规范**
+
+**【接口和事件】**
+1. IsOfficialSkin 是否为官方皮肤
+2. IsHighLevelOfficialSkin 是否为官方史诗级以上皮肤
+3. IsHighLevelMultiJointOfficialSkin 是否为官方史诗级以上的多关节皮肤
+4. UpdatePlayerSkinClient 更新模型皮肤事件
+
+**【注意】**
+
+上述三个接口在收到 Minecraft:EngineScripts:UpdatePlayerSkinClient 事件后进行调用。更多详细说明,见官网文档
+
+使用示例
+```python
+# 这里以IsHighLevelMultiJointOfficialSkin为例
+
+self.ListenForEvent('Minecraft', "EngineScripts", "UpdatePlayerSkinClient', self, self onUpdatePlayerSkinClient)
+def onUpdatePlayerSkinClient(self,args):
+ import mod.client.extraClientApi as clientApi
+ comp = clientApi.GetEngineCompFactory().CreateGame(levelId)
+ comp.IsHighLevelMultiJointOfficialSkin(args['playerId']) # 返回bool:为官方史诗级以上的多关节皮肤
+```
+
+### 模型模板下载
+当前官方提供的“多关节”结构已经能满足大部分的模组开发者,请开发者下载官方规范模型文件
+
+[standard_steve.geo.json](./resources/standard_steve.geo.json)
+
+[standard_steve.png](./resources/standard_steve.png)
+
+
+
+### 测试服测试
+为方便开发者测试4D皮肤与模组本身的兼容性,官方在开发者测试服提供了测试用4D皮肤,可通过邮件领取
+
+
+
+
diff --git a/mcguide/16-美术/6-模型和动作/resources/0_1.png b/mcguide/16-美术/6-模型和动作/resources/0_1.png
new file mode 100644
index 0000000..5fc04fe
Binary files /dev/null and b/mcguide/16-美术/6-模型和动作/resources/0_1.png differ
diff --git a/mcguide/16-美术/6-模型和动作/resources/0_2.jpg b/mcguide/16-美术/6-模型和动作/resources/0_2.jpg
new file mode 100644
index 0000000..8cd0564
Binary files /dev/null and b/mcguide/16-美术/6-模型和动作/resources/0_2.jpg differ
diff --git a/mcguide/16-美术/6-模型和动作/resources/standard_steve.geo.json b/mcguide/16-美术/6-模型和动作/resources/standard_steve.geo.json
new file mode 100644
index 0000000..044139d
--- /dev/null
+++ b/mcguide/16-美术/6-模型和动作/resources/standard_steve.geo.json
@@ -0,0 +1,473 @@
+{
+ "format_version": "1.12.0",
+ "minecraft:geometry": [
+ {
+ "description": {
+ "identifier": "geometry.standard_steve",
+ "texture_width": 64,
+ "texture_height": 64,
+ "visible_bounds_width": 3,
+ "visible_bounds_height": 4,
+ "visible_bounds_offset": [0, 1, 0]
+ },
+ "bones": [
+ {
+ "name": "root",
+ "pivot": [0, 0, 0]
+ },
+ {
+ "name": "waist",
+ "parent": "root",
+ "pivot": [0, 12, 0]
+ },
+ {
+ "name": "body",
+ "parent": "waist",
+ "pivot": [0, 24, 0],
+ "cubes": [
+ {
+ "origin": [-4, 16, -2],
+ "size": [8, 8, 4],
+ "uv": {
+ "north": {"uv": [20, 20], "uv_size": [8, 8]},
+ "east": {"uv": [16, 20], "uv_size": [4, 8]},
+ "south": {"uv": [32, 20], "uv_size": [8, 8]},
+ "west": {"uv": [28, 20], "uv_size": [4, 8]},
+ "up": {"uv": [20, 16], "uv_size": [8, 4]},
+ "down": {"uv": [28, 20], "uv_size": [8, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "head",
+ "parent": "body",
+ "pivot": [0, 24, 0],
+ "cubes": [
+ {
+ "origin": [-4, 24, -4],
+ "size": [8, 8, 8],
+ "uv": {
+ "north": {"uv": [8, 8], "uv_size": [8, 8]},
+ "east": {"uv": [0, 8], "uv_size": [8, 8]},
+ "south": {"uv": [24, 8], "uv_size": [8, 8]},
+ "west": {"uv": [16, 8], "uv_size": [8, 8]},
+ "up": {"uv": [8, 0], "uv_size": [8, 8]},
+ "down": {"uv": [16, 8], "uv_size": [8, -8]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "hat",
+ "parent": "head",
+ "pivot": [0, 24, 0],
+ "cubes": [
+ {
+ "origin": [-4, 24, -4],
+ "size": [8, 8, 8],
+ "inflate": 0.25,
+ "uv": {
+ "north": {"uv": [40, 8], "uv_size": [8, 8]},
+ "east": {"uv": [32, 8], "uv_size": [8, 8]},
+ "south": {"uv": [56, 8], "uv_size": [8, 8]},
+ "west": {"uv": [48, 8], "uv_size": [8, 8]},
+ "up": {"uv": [40, 0], "uv_size": [8, 8]},
+ "down": {"uv": [48, 8], "uv_size": [8, -8]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "cape",
+ "parent": "body",
+ "pivot": [0, 24, 3]
+ },
+ {
+ "name": "leftArm",
+ "parent": "body",
+ "pivot": [5, 22, 0],
+ "cubes": [
+ {
+ "origin": [4, 18, -2],
+ "size": [4, 6, 4],
+ "uv": {
+ "north": {"uv": [36, 52], "uv_size": [4, 6]},
+ "east": {"uv": [32, 52], "uv_size": [4, 6]},
+ "south": {"uv": [44, 52], "uv_size": [4, 6]},
+ "west": {"uv": [40, 52], "uv_size": [4, 6]},
+ "up": {"uv": [36, 48], "uv_size": [4, 4]},
+ "down": {"uv": [40, 52], "uv_size": [4, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "leftArmDown",
+ "parent": "leftArm",
+ "pivot": [5, 18, 0],
+ "cubes": [
+ {
+ "origin": [4, 12, -2],
+ "size": [4, 6, 4],
+ "uv": {
+ "north": {"uv": [36, 58], "uv_size": [4, 6]},
+ "east": {"uv": [32, 58], "uv_size": [4, 6]},
+ "south": {"uv": [44, 58], "uv_size": [4, 6]},
+ "west": {"uv": [40, 58], "uv_size": [4, 6]},
+ "up": {"uv": [40, 48], "uv_size": [4, 4]},
+ "down": {"uv": [40, 52], "uv_size": [4, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "leftSleeveDown",
+ "parent": "leftArmDown",
+ "pivot": [5, 18.25, 0],
+ "cubes": [
+ {
+ "origin": [4, 12, -2],
+ "size": [4, 6, 4],
+ "inflate": 0.25,
+ "uv": {
+ "north": {"uv": [52, 58], "uv_size": [4, 6]},
+ "east": {"uv": [48, 58], "uv_size": [4, 6]},
+ "south": {"uv": [60, 58], "uv_size": [4, 6]},
+ "west": {"uv": [56, 58], "uv_size": [4, 6]},
+ "up": {"uv": [56, 48], "uv_size": [4, 4]},
+ "down": {"uv": [56, 52], "uv_size": [4, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "leftItem",
+ "parent": "leftArmDown",
+ "pivot": [6, 15, 1]
+ },
+ {
+ "name": "leftSleeve",
+ "parent": "leftArm",
+ "pivot": [5, 22, 0],
+ "cubes": [
+ {
+ "origin": [4, 18, -2],
+ "size": [4, 6, 4],
+ "inflate": 0.25,
+ "uv": {
+ "north": {"uv": [52, 52], "uv_size": [4, 6]},
+ "east": {"uv": [48, 52], "uv_size": [4, 6]},
+ "south": {"uv": [60, 52], "uv_size": [4, 6]},
+ "west": {"uv": [56, 52], "uv_size": [4, 6]},
+ "up": {"uv": [52, 48], "uv_size": [4, 4]},
+ "down": {"uv": [56, 52], "uv_size": [4, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "rightArm",
+ "parent": "body",
+ "pivot": [-5, 22, 0],
+ "cubes": [
+ {
+ "origin": [-8, 18, -2],
+ "size": [4, 6, 4],
+ "uv": {
+ "north": {"uv": [40, 52], "uv_size": [-4, 6]},
+ "east": {"uv": [44, 52], "uv_size": [-4, 6]},
+ "south": {"uv": [48, 52], "uv_size": [-4, 6]},
+ "west": {"uv": [36, 52], "uv_size": [-4, 6]},
+ "up": {"uv": [40, 48], "uv_size": [-4, 4]},
+ "down": {"uv": [44, 52], "uv_size": [-4, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "rightArmDown",
+ "parent": "rightArm",
+ "pivot": [-5, 18, 0],
+ "cubes": [
+ {
+ "origin": [-8, 12, -2],
+ "size": [4, 6, 4],
+ "uv": {
+ "north": {"uv": [40, 58], "uv_size": [-4, 6]},
+ "east": {"uv": [44, 58], "uv_size": [-4, 6]},
+ "south": {"uv": [48, 58], "uv_size": [-4, 6]},
+ "west": {"uv": [36, 58], "uv_size": [-4, 6]},
+ "up": {"uv": [44, 48], "uv_size": [-4, 4]},
+ "down": {"uv": [44, 52], "uv_size": [-4, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "rightISleeveDown",
+ "parent": "rightArmDown",
+ "pivot": [-5, 18.25, 0],
+ "cubes": [
+ {
+ "origin": [-8, 12, -2],
+ "size": [4, 6, 4],
+ "inflate": 0.25,
+ "uv": {
+ "north": {"uv": [48, 42], "uv_size": [-4, 6]},
+ "east": {"uv": [52, 42], "uv_size": [-4, 6]},
+ "south": {"uv": [56, 42], "uv_size": [-4, 6]},
+ "west": {"uv": [44, 42], "uv_size": [-4, 6]},
+ "up": {"uv": [52, 32], "uv_size": [-4, 4]},
+ "down": {"uv": [52, 36], "uv_size": [-4, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "rightItem",
+ "parent": "rightArmDown",
+ "pivot": [-6, 15, 1],
+ "locators": {
+ "lead_hold": [-6, 15, 1]
+ }
+ },
+ {
+ "name": "rightSleeve",
+ "parent": "rightArm",
+ "pivot": [-5, 22, 0],
+ "cubes": [
+ {
+ "origin": [-8, 18, -2],
+ "size": [4, 6, 4],
+ "inflate": 0.25,
+ "uv": {
+ "north": {"uv": [48, 36], "uv_size": [-4, 6]},
+ "east": {"uv": [52, 36], "uv_size": [-4, 6]},
+ "south": {"uv": [56, 36], "uv_size": [-4, 6]},
+ "west": {"uv": [44, 36], "uv_size": [-4, 6]},
+ "up": {"uv": [48, 32], "uv_size": [-4, 4]},
+ "down": {"uv": [52, 36], "uv_size": [-4, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "jacket",
+ "parent": "body",
+ "pivot": [0, 24, 0],
+ "cubes": [
+ {
+ "origin": [-4, 16, -2],
+ "size": [8, 8, 4],
+ "inflate": 0.25,
+ "uv": {
+ "north": {"uv": [20, 36], "uv_size": [8, 8]},
+ "east": {"uv": [16, 36], "uv_size": [4, 8]},
+ "south": {"uv": [32, 36], "uv_size": [8, 8]},
+ "west": {"uv": [28, 36], "uv_size": [4, 8]},
+ "up": {"uv": [20, 32], "uv_size": [8, 4]},
+ "down": {"uv": [28, 36], "uv_size": [8, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "bodyDown",
+ "parent": "waist",
+ "pivot": [0, 16, 0],
+ "cubes": [
+ {
+ "origin": [-4, 12, -2],
+ "size": [8, 4, 4],
+ "uv": {
+ "north": {"uv": [20, 28], "uv_size": [8, 4]},
+ "east": {"uv": [16, 28], "uv_size": [4, 4]},
+ "south": {"uv": [32, 28], "uv_size": [8, 4]},
+ "west": {"uv": [28, 28], "uv_size": [4, 4]},
+ "up": {"uv": [28, 16], "uv_size": [8, 4]},
+ "down": {"uv": [28, 20], "uv_size": [8, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "jacketDown",
+ "parent": "bodyDown",
+ "pivot": [0, 16.25, 0],
+ "cubes": [
+ {
+ "origin": [-4, 12, -2],
+ "size": [8, 4, 4],
+ "inflate": 0.25,
+ "uv": {
+ "north": {"uv": [20, 44], "uv_size": [8, 4]},
+ "east": {"uv": [16, 44], "uv_size": [4, 4]},
+ "south": {"uv": [32, 44], "uv_size": [8, 4]},
+ "west": {"uv": [28, 44], "uv_size": [4, 4]},
+ "up": {"uv": [0, 4], "uv_size": [8, 4]},
+ "down": {"uv": [0, 4], "uv_size": [8, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "leftLeg",
+ "parent": "root",
+ "pivot": [1.9, 12, 0],
+ "cubes": [
+ {
+ "origin": [-0.1, 6, -2],
+ "size": [4, 6, 4],
+ "uv": {
+ "north": {"uv": [20, 52], "uv_size": [4, 6]},
+ "east": {"uv": [16, 52], "uv_size": [4, 6]},
+ "south": {"uv": [28, 52], "uv_size": [4, 6]},
+ "west": {"uv": [24, 52], "uv_size": [4, 6]},
+ "up": {"uv": [20, 48], "uv_size": [4, 4]},
+ "down": {"uv": [24, 52], "uv_size": [4, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "leftPants",
+ "parent": "leftLeg",
+ "pivot": [1.9, 12, 0],
+ "cubes": [
+ {
+ "origin": [-0.1, 6, -2],
+ "size": [4, 6, 4],
+ "inflate": 0.25,
+ "uv": {
+ "north": {"uv": [4, 52], "uv_size": [4, 6]},
+ "east": {"uv": [0, 52], "uv_size": [4, 6]},
+ "south": {"uv": [12, 52], "uv_size": [4, 6]},
+ "west": {"uv": [8, 52], "uv_size": [4, 6]},
+ "up": {"uv": [4, 48], "uv_size": [4, 4]},
+ "down": {"uv": [8, 52], "uv_size": [4, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "leftLegDown",
+ "parent": "leftLeg",
+ "pivot": [1.9, 6, 0],
+ "cubes": [
+ {
+ "origin": [-0.1, 0, -2],
+ "size": [4, 6, 4],
+ "uv": {
+ "north": {"uv": [20, 58], "uv_size": [4, 6]},
+ "east": {"uv": [16, 58], "uv_size": [4, 6]},
+ "south": {"uv": [28, 58], "uv_size": [4, 6]},
+ "west": {"uv": [24, 58], "uv_size": [4, 6]},
+ "up": {"uv": [24, 48], "uv_size": [4, 4]},
+ "down": {"uv": [24, 52], "uv_size": [4, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "leftPantsDown",
+ "parent": "leftLegDown",
+ "pivot": [1.9, 6.25, 0],
+ "cubes": [
+ {
+ "origin": [-0.1, 0, -2],
+ "size": [4, 6, 4],
+ "inflate": 0.25,
+ "uv": {
+ "north": {"uv": [4, 58], "uv_size": [4, 6]},
+ "east": {"uv": [0, 58], "uv_size": [4, 6]},
+ "south": {"uv": [12, 58], "uv_size": [4, 6]},
+ "west": {"uv": [8, 58], "uv_size": [4, 6]},
+ "up": {"uv": [8, 48], "uv_size": [4, 4]},
+ "down": {"uv": [8, 52], "uv_size": [4, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "rightLeg",
+ "parent": "root",
+ "pivot": [-1.9, 12, 0],
+ "cubes": [
+ {
+ "origin": [-3.9, 6, -2],
+ "size": [4, 6, 4],
+ "uv": {
+ "north": {"uv": [24, 52], "uv_size": [-4, 6]},
+ "east": {"uv": [28, 52], "uv_size": [-4, 6]},
+ "south": {"uv": [32, 52], "uv_size": [-4, 6]},
+ "west": {"uv": [20, 52], "uv_size": [-4, 6]},
+ "up": {"uv": [24, 48], "uv_size": [-4, 4]},
+ "down": {"uv": [28, 52], "uv_size": [-4, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "rightPants",
+ "parent": "rightLeg",
+ "pivot": [-1.9, 12, 0],
+ "cubes": [
+ {
+ "origin": [-3.9, 6, -2],
+ "size": [4, 6, 4],
+ "inflate": 0.25,
+ "uv": {
+ "north": {"uv": [8, 36], "uv_size": [-4, 6]},
+ "east": {"uv": [12, 36], "uv_size": [-4, 6]},
+ "south": {"uv": [16, 36], "uv_size": [-4, 6]},
+ "west": {"uv": [4, 36], "uv_size": [-4, 6]},
+ "up": {"uv": [8, 32], "uv_size": [-4, 4]},
+ "down": {"uv": [12, 36], "uv_size": [-4, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "rightLegDown",
+ "parent": "rightLeg",
+ "pivot": [-1.9, 6, 0],
+ "cubes": [
+ {
+ "origin": [-3.9, 0, -2],
+ "size": [4, 6, 4],
+ "uv": {
+ "north": {"uv": [24, 58], "uv_size": [-4, 6]},
+ "east": {"uv": [28, 58], "uv_size": [-4, 6]},
+ "south": {"uv": [32, 58], "uv_size": [-4, 6]},
+ "west": {"uv": [20, 58], "uv_size": [-4, 6]},
+ "up": {"uv": [28, 48], "uv_size": [-4, 4]},
+ "down": {"uv": [28, 52], "uv_size": [-4, -4]}
+ }
+ }
+ ]
+ },
+ {
+ "name": "rightPantsDown",
+ "parent": "rightLegDown",
+ "pivot": [-1.9, 6.25, 0],
+ "cubes": [
+ {
+ "origin": [-3.9, 0, -2],
+ "size": [4, 6, 4],
+ "inflate": 0.25,
+ "uv": {
+ "north": {"uv": [8, 42], "uv_size": [-4, 6]},
+ "east": {"uv": [12, 42], "uv_size": [-4, 6]},
+ "south": {"uv": [16, 42], "uv_size": [-4, 6]},
+ "west": {"uv": [4, 42], "uv_size": [-4, 6]},
+ "up": {"uv": [12, 32], "uv_size": [-4, 4]},
+ "down": {"uv": [12, 36], "uv_size": [-4, -4]}
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/mcguide/16-美术/6-模型和动作/resources/standard_steve.png b/mcguide/16-美术/6-模型和动作/resources/standard_steve.png
new file mode 100644
index 0000000..fefd1bd
Binary files /dev/null and b/mcguide/16-美术/6-模型和动作/resources/standard_steve.png differ
diff --git a/mcguide/16-美术/7-材质与着色器/images/netease_outline.png b/mcguide/16-美术/7-材质与着色器/images/netease_outline.png
new file mode 100644
index 0000000..76ad24e
Binary files /dev/null and b/mcguide/16-美术/7-材质与着色器/images/netease_outline.png differ
diff --git a/mcguide/16-美术/7-材质与着色器/images/netease_outline2.png b/mcguide/16-美术/7-材质与着色器/images/netease_outline2.png
new file mode 100644
index 0000000..482526b
Binary files /dev/null and b/mcguide/16-美术/7-材质与着色器/images/netease_outline2.png differ
diff --git a/mcguide/18-界面与交互/19-控件属性动画.md b/mcguide/18-界面与交互/19-控件属性动画.md
index 256ad7d..7e9996d 100644
--- a/mcguide/18-界面与交互/19-控件属性动画.md
+++ b/mcguide/18-界面与交互/19-控件属性动画.md
@@ -187,12 +187,12 @@ uv动画和序列帧动画都是uv起点属性的动画,不同于其他属性
要表现一个属性动画,需要先写一个Json数据块,透明度动画举例如下(相关参数会在下文详细描述):
```json
- {
- "anim_type" : "alpha",
- "duration" : 1.0,
- "from" : 0.0,
- "to" : 1.0
- }
+{
+ "anim_type" : "alpha",
+ "duration" : 1.0,
+ "from" : 0.0,
+ "to" : 1.0
+}
```
这段代码块代表一个控件在1秒钟内alpha值从0线性变化到1的属性动画,为了将这个动画绑定到控件上,一共有两种写法。
@@ -200,38 +200,38 @@ uv动画和序列帧动画都是uv起点属性的动画,不同于其他属性
一种是将Json数据块直接赋给alpha属性:
```json
- {
- "alphaImg" : {
- "alpha" : {
- "anim_type" : "alpha",
- "duration" : 0.30,
- "from" : 0.0,
- "to" : 1.0
- },
- "texture" : "textures/netease/common/image/default",
- "type" : "image",
- "visible" : true
- }
- }
-```
-
-另一种则是将属性动画写成自定义控件的形式写在UIjson文件的最外层,在alpha属性值以 “@”+动画名 的形式进行赋值:
-
-```json
- {
- "alphaImg" : {
- "alpha" : "@show_alpha_ani",
- "texture" : "textures/netease/common/image/default",
- "type" : "image",
- "visible" : true
- },
- "show_alpha_ani": {
+{
+ "alphaImg" : {
+ "alpha" : {
"anim_type" : "alpha",
"duration" : 0.30,
"from" : 0.0,
"to" : 1.0
},
- }
+ "texture" : "textures/netease/common/image/default",
+ "type" : "image",
+ "visible" : true
+ }
+}
+```
+
+另一种则是将属性动画写成自定义控件的形式写在UIjson文件的最外层,在alpha属性值以 “@”+动画名 的形式进行赋值:
+
+```json
+{
+ "alphaImg" : {
+ "alpha" : "@show_alpha_ani",
+ "texture" : "textures/netease/common/image/default",
+ "type" : "image",
+ "visible" : true
+ },
+ "show_alpha_ani": {
+ "anim_type" : "alpha",
+ "duration" : 0.30,
+ "from" : 0.0,
+ "to" : 1.0
+ }
+}
```
两种写法都能达成相同的效果,不同的是第二种写法能够被复用。
@@ -259,33 +259,34 @@ uv动画和序列帧动画都是uv起点属性的动画,不同于其他属性
* 注2
```json
- "alphaImg" : {
- "alpha" : "@show_alpha_ani",
- "texture" : "textures/netease/common/image/default",
- "type" : "image",
- "visible" : true
- },
- "show_alpha_ani": {
- "anim_type" : "alpha",
- "duration" : 0.30,
- "from" : 0.0,
- "next" : "@hold_alpha_ani",
- "to" : 1.0
- },
- "hold_alpha_ani" : {
- "anim_type" : "alpha",
- "duration" : 1,
- "from" : 1.0,
- "next" : "@hide_alpha_ani",
- "to" : 1.0
- },
- "hide_alpha_ani" : {
- "anim_type" : "alpha",
- "duration" : 0.30,
- "from" : 1.0,
- "to" : 0.0
- },
-
+{
+ "alphaImg" : {
+ "alpha" : "@show_alpha_ani",
+ "texture" : "textures/netease/common/image/default",
+ "type" : "image",
+ "visible" : true
+ },
+ "show_alpha_ani": {
+ "anim_type" : "alpha",
+ "duration" : 0.30,
+ "from" : 0.0,
+ "next" : "@hold_alpha_ani",
+ "to" : 1.0
+ },
+ "hold_alpha_ani" : {
+ "anim_type" : "alpha",
+ "duration" : 1,
+ "from" : 1.0,
+ "next" : "@hide_alpha_ani",
+ "to" : 1.0
+ },
+ "hide_alpha_ani" : {
+ "anim_type" : "alpha",
+ "duration" : 0.30,
+ "from" : 1.0,
+ "to" : 0.0
+ }
+}
```
### 透明度动画
@@ -301,33 +302,34 @@ uv动画和序列帧动画都是uv起点属性的动画,不同于其他属性

```json
- "alphaImg" : {
- "alpha" : "@show_alpha_ani",
- "texture" : "textures/netease/common/image/default",
- "type" : "image",
- "visible" : true
- },
- "show_alpha_ani": {
- "anim_type" : "alpha",
- "duration" : 0.30,
- "from" : 0.0,
- "next" : "@hold_alpha_ani",
- "to" : 1.0
- },
- "hold_alpha_ani" : {
- "anim_type" : "alpha",
- "duration" : 1,
- "from" : 1.0,
- "next" : "@hide_alpha_ani",
- "to" : 1.0
- },
- "hide_alpha_ani" : {
- "anim_type" : "alpha",
- "duration" : 0.30,
- "from" : 1.0,
- "to" : 0.0
- },
-
+{
+ "alphaImg" : {
+ "alpha" : "@show_alpha_ani",
+ "texture" : "textures/netease/common/image/default",
+ "type" : "image",
+ "visible" : true
+ },
+ "show_alpha_ani": {
+ "anim_type" : "alpha",
+ "duration" : 0.30,
+ "from" : 0.0,
+ "next" : "@hold_alpha_ani",
+ "to" : 1.0
+ },
+ "hold_alpha_ani" : {
+ "anim_type" : "alpha",
+ "duration" : 1,
+ "from" : 1.0,
+ "next" : "@hide_alpha_ani",
+ "to" : 1.0
+ },
+ "hide_alpha_ani" : {
+ "anim_type" : "alpha",
+ "duration" : 0.30,
+ "from" : 1.0,
+ "to" : 0.0
+ }
+}
```
### 裁剪动画
@@ -343,18 +345,19 @@ uv动画和序列帧动画都是uv起点属性的动画,不同于其他属性

```json
- "clipImg" : {
- "clip_ratio" : {
- "anim_type" : "clip",
- "duration" : 1.0,
- "from" : 0.0,
- "to" : 1.0
- },
- "texture" : "textures/netease/common/image/default",
- "type" : "image",
- "visible" : true
- },
-
+{
+ "clipImg" : {
+ "clip_ratio" : {
+ "anim_type" : "clip",
+ "duration" : 1.0,
+ "from" : 0.0,
+ "to" : 1.0
+ },
+ "texture" : "textures/netease/common/image/default",
+ "type" : "image",
+ "visible" : true
+ }
+}
```
### 颜色动画
@@ -370,19 +373,20 @@ uv动画和序列帧动画都是uv起点属性的动画,不同于其他属性

```json
- "colorImg" : {
- "color": "@color_ani",
- "texture" : "textures/netease/common/image/default",
- "type" : "image",
- "visible" : true
- },
- "color_ani": {
- "anim_type" : "color",
- "duration" : 1.0,
- "from" : [1,0,0],
- "to" : [0,0,1]
- },
-
+{
+ "colorImg" : {
+ "color": "@color_ani",
+ "texture" : "textures/netease/common/image/default",
+ "type" : "image",
+ "visible" : true
+ },
+ "color_ani": {
+ "anim_type" : "color",
+ "duration" : 1.0,
+ "from" : [1,0,0],
+ "to" : [0,0,1]
+ }
+}
```
### 序列帧动画
@@ -402,20 +406,22 @@ uv动画和序列帧动画都是uv起点属性的动画,不同于其他属性

```json
- "flipbookImg" : {
- "texture" : "textures/ui/my_eating_apple",
- "type" : "image",
- "uv" : "@flipbook_ani",
- "uv_size" : [ 64.0, 64.0 ],
- "visible" : true
- },
- "flipbook_ani": {
- "anim_type": "flip_book",
- "initial_frame": 10,
- "frame_count": 36,
- "fps": 10,
- "reversible": false
- },
+{
+ "flipbookImg" : {
+ "texture" : "textures/ui/my_eating_apple",
+ "type" : "image",
+ "uv" : "@flipbook_ani",
+ "uv_size" : [ 64.0, 64.0 ],
+ "visible" : true
+ },
+ "flipbook_ani": {
+ "anim_type": "flip_book",
+ "initial_frame": 10,
+ "frame_count": 36,
+ "fps": 10,
+ "reversible": false
+ }
+}
```
当一个图片控件被用作序列帧的载体时,该控件的属性配置有以下规则需要遵守:
@@ -441,19 +447,20 @@ uv动画和序列帧动画都是uv起点属性的动画,不同于其他属性

```json
- "offsetImg" : {
- "offset" : "@offset_ani",
- "texture" : "textures/netease/common/image/default",
- "type" : "image",
- "visible" : true
- },
- "offset_ani": {
- "anim_type" : "offset",
- "duration" : 1.0,
- "from" : [0, 0],
- "to" : [0, 50]
- },
-
+{
+ "offsetImg" : {
+ "offset" : "@offset_ani",
+ "texture" : "textures/netease/common/image/default",
+ "type" : "image",
+ "visible" : true
+ },
+ "offset_ani": {
+ "anim_type" : "offset",
+ "duration" : 1.0,
+ "from" : [0, 0],
+ "to" : [0, 50]
+ }
+}
```
**注**
@@ -477,19 +484,20 @@ uv动画和序列帧动画都是uv起点属性的动画,不同于其他属性

```json
- "sizeImg" : {
- "size" : "@size_ani",
- "texture" : "textures/netease/common/image/default",
- "type" : "image",
- "visible" : true
- },
- "size_ani": {
- "anim_type" : "size",
- "duration" : 1.0,
- "from" : [100, 100],
- "to" : [150, 150]
- },
-
+{
+ "sizeImg" : {
+ "size" : "@size_ani",
+ "texture" : "textures/netease/common/image/default",
+ "type" : "image",
+ "visible" : true
+ },
+ "size_ani": {
+ "anim_type" : "size",
+ "duration" : 1.0,
+ "from" : [100, 100],
+ "to" : [150, 150]
+ }
+}
```
**注**
@@ -513,19 +521,20 @@ uv动画和序列帧动画都是uv起点属性的动画,不同于其他属性

```json
- "sizeImg" : {
- "uv" : "@uv_ani",
- "texture" : "textures/netease/common/image/default",
- "type" : "image",
- "visible" : true
- },
- "uv_ani": {
- "anim_type" : "uv",
- "duration" : 5,
- "from" : [0, 0],
- "to" : [2240, 0]
- },
-
+{
+ "sizeImg" : {
+ "uv" : "@uv_ani",
+ "texture" : "textures/netease/common/image/default",
+ "type" : "image",
+ "visible" : true
+ },
+ "uv_ani": {
+ "anim_type" : "uv",
+ "duration" : 5,
+ "from" : [0, 0],
+ "to" : [2240, 0]
+ }
+}
```
diff --git a/mcguide/18-界面与交互/2-从零开始创建UI.md b/mcguide/18-界面与交互/2-从零开始创建UI.md
index 582892f..ee13072 100644
--- a/mcguide/18-界面与交互/2-从零开始创建UI.md
+++ b/mcguide/18-界面与交互/2-从零开始创建UI.md
@@ -248,20 +248,20 @@ shootButton的锚点,位移XY,尺寸XY的参考属性如下。按照这种
3. 然后激活(显示)对应的界面预设
```python
- def InitClient(self):
- import mod.client.extraClientApi as clientApi
- self.ListenForEngineEvent(UiInitFinishedEvent, self, self.OnUIInitFinished)
+def InitClient(self):
+ import mod.client.extraClientApi as clientApi
+ self.ListenForEngineEvent(UiInitFinishedEvent, self, self.OnUIInitFinished)
```
```python
- def OnUIInitFinished(self, args):
- import mod.client.extraClientApi as clientApi
- if clientApi.GetPlatform() == 0:
- uiNodePreset = self.GetParent().GetChildPresetsByName("PC版UI界面")[0]
- else:
- uiNodePreset = self.GetParent().GetChildPresetsByName("PE版UI界面")[0]
- if uiNodePreset:
- uiNodePreset.SetUiActive(True)
+def OnUIInitFinished(self, args):
+ import mod.client.extraClientApi as clientApi
+ if clientApi.GetPlatform() == 0:
+ uiNodePreset = self.GetParent().GetChildPresetsByName("PC版UI界面")[0]
+ else:
+ uiNodePreset = self.GetParent().GetChildPresetsByName("PE版UI界面")[0]
+ if uiNodePreset:
+ uiNodePreset.SetUiActive(True)
```
我们利用[UI API文档](40-UIAPI文档.html)中对各个控件的接口和游戏原生支持的格式化,可以在python代码中动态的改变界面的表现,具体可以参考[样式代码](https://minecraft-zh.gamepedia.com/index.php?title=%E6%A0%B7%E5%BC%8F%E4%BB%A3%E7%A0%81&variant=zh)
diff --git a/mcguide/18-界面与交互/30-UI说明文档.md b/mcguide/18-界面与交互/30-UI说明文档.md
index 2144611..3cd3002 100644
--- a/mcguide/18-界面与交互/30-UI说明文档.md
+++ b/mcguide/18-界面与交互/30-UI说明文档.md
@@ -12,13 +12,12 @@ time: 分钟
* 示例中为"myUIName"
-```json
- myUIName.json
+```html
+myUIName.json
- "namespace" : "myUIName"
-
- myUIName.py
+"namespace": "myUIName"
+myUIName.py
```
## JSON编写说明
@@ -32,7 +31,9 @@ Json是UI界面的显示内容和绑定的集合,UI是一种树状的组织结
命名空间是这个界面的名称,我们规定json文件名和namespace一致。
```json
- "namespace" : "myUIName"
+{
+ "namespace" : "myUIName"
+}
```
### Main Screen
@@ -42,10 +43,12 @@ main是这个界面名称,我们规定使用main,即一个json文件是一
controls中的内容是该界面下的树状节点,即子节点。
```json
- "main@common.base_screen" : {
+{
+ "main@common.base_screen" : {
"controls" : [
]
}
+}
```
| 变量 | 解释 |
@@ -87,7 +90,8 @@ path = "/panel0/text0"
为了适配异形屏,我们可以展示screen中的内容通过引用的形式写在screen的$screen_content属性中。
```json
- "main@common.base_screen" : {
+{
+ "main@common.base_screen" : {
"$screen_content":"myUIName.panel0"
},
"panel0":{
@@ -99,10 +103,11 @@ path = "/panel0/text0"
"type" : "panel"
},
"text0" : {
- "text" : "Hello World!",
- "type" : "label",
- "visible" : true
+ "text" : "Hello World!",
+ "type" : "label",
+ "visible" : true
}
+}
```
被$screen_content引用的内容,其显示内容的范围不会被异形屏遮挡。此时text0的路径为
@@ -121,45 +126,47 @@ path = base_path + "/text0"
screen,即画布控件,是游戏中一个UI界面的根节点,所有其他控件只有挂在画布下才能被正确显示出来。
```json
-"main1" : {
- "absorbs_input" : true,
- "always_accepts_input" : false,
- "controls" : [
- {
- "label0@test.label0" : {}
- }
- ],
- "force_render_below" : false,
- "is_showing_menu" : true,
- "render_game_behind" : true,
- "render_only_when_topmost" : true,
- "should_steal_mouse" : false,
- "type" : "screen"
+{
+ "main1" : {
+ "absorbs_input" : true,
+ "always_accepts_input" : false,
+ "controls" : [
+ {
+ "label0@test.label0" : {}
+ }
+ ],
+ "force_render_below" : false,
+ "is_showing_menu" : true,
+ "render_game_behind" : true,
+ "render_only_when_topmost" : true,
+ "should_steal_mouse" : false,
+ "type" : "screen"
},
"main2@common.base_screen" : {
- "$screen_content" : "test.netease_editor_root_panel_base_screen0",
- "absorbs_input" : true,
- "always_accepts_input" : false,
- "force_render_below" : false,
- "is_showing_menu" : true,
- "render_game_behind" : true,
- "render_only_when_topmost" : true,
- "should_steal_mouse" : false
+ "$screen_content" : "test.netease_editor_root_panel_base_screen0",
+ "absorbs_input" : true,
+ "always_accepts_input" : false,
+ "force_render_below" : false,
+ "is_showing_menu" : true,
+ "render_game_behind" : true,
+ "render_only_when_topmost" : true,
+ "should_steal_mouse" : false
},
"netease_editor_root_panel_base_screen0" : {
- "anchor_from" : "top_left",
- "anchor_to" : "top_left",
- "controls" : [
- {
- "label1@test.label1" : {}
- }
- ],
- "layer" : 1,
- "offset" : [ 0, 0 ],
- "size" : [ "100%", "100%" ],
- "type" : "panel",
- "visible" : true
+ "anchor_from" : "top_left",
+ "anchor_to" : "top_left",
+ "controls" : [
+ {
+ "label1@test.label1" : {}
+ }
+ ],
+ "layer" : 1,
+ "offset" : [ 0, 0 ],
+ "size" : [ "100%", "100%" ],
+ "type" : "panel",
+ "visible" : true
}
+}
```
|
变量
| 解释 |
@@ -196,21 +203,21 @@ absorbs_input暂时无法生效,等待后续修复。
### 通用属性
通用属性是每个控件都支持编辑的属性,对每个控件的位置、大小等基本属性进行设置。
-| 变量
| 解释 |
-| :------------: | ----------------------------------------------------------- |
-| anchor_from | 挂接在父节点锚点的位置,取值范围["top_left", "top_middle", "top_right", "left_middle", "center", "right_middle", "bottom_left", "bottom_middle", "bottom_right"] |
-| anchor_to | 自身挂接锚点的位置,取值同anchor_from |
-| layer | 当前控件相对父节点的层级,最终显示层级取决于父节点到该节点的layer之和 |
-| offset | 自身相对父节点的偏移,值为百分比+像素(1个像素等于屏幕上3个像素) |
-| size | 相对父节点的大小,取值同offset |
-| max_size | 最大尺寸,取值同offset。当该控件尺寸可变时,最大不能超过该属性配置的尺寸 |
-| min_size | 最小尺寸,取值同offset。当该控件尺寸可变时,最小不能小于该属性配置的尺寸 |
-| clips_children | 裁剪子控件,取值bool值,开启后该控件范围外的子控件将不会被渲染 |
-| clip_offset | 裁剪偏移,取值[x,y]。当开启裁剪子控件后,用来调整裁剪范围的偏移 |
-| alpha | 透明度,取值0-1.0。调整控件的透明度 |
+| 变量
| 解释 |
+| :------------: | ----------------------------------------------------------- |
+| anchor_from | 挂接在父节点锚点的位置,取值范围["top_left", "top_middle", "top_right", "left_middle", "center", "right_middle", "bottom_left", "bottom_middle", "bottom_right"] |
+| anchor_to | 自身挂接锚点的位置,取值同anchor_from |
+| layer | 当前控件相对父节点的层级,最终显示层级取决于父节点到该节点的layer之和 |
+| offset | 自身相对父节点的偏移,值为百分比+像素(1个像素等于屏幕上3个像素) |
+| size | 相对父节点的大小,取值同offset |
+| max_size | 最大尺寸,取值同offset。当该控件尺寸可变时,最大不能超过该属性配置的尺寸 |
+| min_size | 最小尺寸,取值同offset。当该控件尺寸可变时,最小不能小于该属性配置的尺寸 |
+| clips_children | 裁剪子控件,取值bool值,开启后该控件范围外的子控件将不会被渲染 |
+| clip_offset | 裁剪偏移,取值[x,y]。当开启裁剪子控件后,用来调整裁剪范围的偏移 |
+| alpha | 透明度,取值0-1.0。调整控件的透明度 |
| propagate_alpha | 透明度传递,取值bool。该控件的透明度是否会影响子控件 |
-| enable | 是否可交互,取值bool。关闭该属性后按钮等控件变得不可交互 |
-| type | 当前控件类型 |
+| enable | 是否可交互,取值bool。关闭该属性后按钮等控件变得不可交互 |
+| type | 当前控件类型 |
| visible | 默认是否显示,true为显示,false为不显示 |
下图为UI编辑器中控件的通用属性编辑面板
@@ -250,24 +257,26 @@ absorbs_input暂时无法生效,等待后续修复。
### Label
Label 是文本框控件,用来显示文本信息,默认的字体是MC字体,如果有中文会变成中文字体格式,暂时不支持换字体,可以通过接口统一设置字体,如果需要设置后续有介绍。
-```json
- "label0" : {
- "anchor_from" : "center",
- "anchor_to" : "center",
- "color" : [ 1, 1, 1 ],
- "font_scale_factor" : 1.0,
- "font_size" : "normal",
- "font_type" : "smooth",
- "layer" : 1,
- "offset" : [ 0, 0 ],
- "shadow" : false,
- "size" : [ 100, 100 ],
- "text" : "Hello World!",
- "text_alignment" : "center",
- "line_padding" : 0.0,
- "type" : "label",
- "visible" : true
- },
+```json
+{
+ "label0" : {
+ "anchor_from" : "center",
+ "anchor_to" : "center",
+ "color" : [ 1, 1, 1 ],
+ "font_scale_factor" : 1.0,
+ "font_size" : "normal",
+ "font_type" : "smooth",
+ "layer" : 1,
+ "offset" : [ 0, 0 ],
+ "shadow" : false,
+ "size" : [ 100, 100 ],
+ "text" : "Hello World!",
+ "text_alignment" : "center",
+ "line_padding" : 0.0,
+ "type" : "label",
+ "visible" : true
+ }
+}
```
| 变量
| 解释 |
| :------------: | ----------------------------------------------------------- |
@@ -315,30 +324,32 @@ Label 是文本框控件,用来显示文本信息,默认的字体是MC字体
Image是指图片控件,具有图片裁剪,图片九宫格,颜色叠加,uv偏移,旋转显示的额外属性。
```json
- "image0" : {
- "anchor_from" : "center",
- "anchor_to" : "center",
- "is_new_nine_slice" : false,
- "layer" : 2,
- "nine_slice_buttom" : 0,
- "nine_slice_left" : 0,
- "nine_slice_right" : 0,
- "nine_slice_top" : 0,
- "offset" : [ 0, 0 ],
- "size" : [ 100, 100 ],
- "texture" : "textures/netease/common/image/default",
- "nineslice_size" : [ 0, 0, 0, 0 ],
- "grayscale" : false,
- "keep_ratio" : true,
- "clip_direction" : "left",
- "clip_ratio" : 0.0,
- "type" : "image",
- "uv" : [ 0, 0 ],
- "uv_size" : [ 107, 107 ],
- "rotate_pivot": [0.5, 0.5],
- "rotate_angle": 0,
- "visible" : true
- },
+{
+ "image0" : {
+ "anchor_from" : "center",
+ "anchor_to" : "center",
+ "is_new_nine_slice" : false,
+ "layer" : 2,
+ "nine_slice_buttom" : 0,
+ "nine_slice_left" : 0,
+ "nine_slice_right" : 0,
+ "nine_slice_top" : 0,
+ "offset" : [ 0, 0 ],
+ "size" : [ 100, 100 ],
+ "texture" : "textures/netease/common/image/default",
+ "nineslice_size" : [ 0, 0, 0, 0 ],
+ "grayscale" : false,
+ "keep_ratio" : true,
+ "clip_direction" : "left",
+ "clip_ratio" : 0.0,
+ "type" : "image",
+ "uv" : [ 0, 0 ],
+ "uv_size" : [ 107, 107 ],
+ "rotate_pivot": [0.5, 0.5],
+ "rotate_angle": 0,
+ "visible" : true
+ }
+}
```
| 变量
| 解释 |
@@ -397,33 +408,33 @@ json如下:
"type" : "screen"
},
"image" : {
- "layer": 3,
- "size": [ 100, 100 ],
- "offset": "@UIDemo.animation_in",
- "texture": "textures/netease/common/image/default",
- "is_new_nine_slice": false,
- "nine_slice_buttom" : 0,
- "nine_slice_left" : 0,
- "nine_slice_right" : 0,
- "nine_slice_top" : 0,
- "nineslice_size" : [0, 0, 0, 0],
- "type": "image"
+ "layer": 3,
+ "size": [ 100, 100 ],
+ "offset": "@UIDemo.animation_in",
+ "texture": "textures/netease/common/image/default",
+ "is_new_nine_slice": false,
+ "nine_slice_buttom" : 0,
+ "nine_slice_left" : 0,
+ "nine_slice_right" : 0,
+ "nine_slice_top" : 0,
+ "nineslice_size" : [0, 0, 0, 0],
+ "type": "image"
},
"animation_in": {
- "anim_type": "offset",
- "duration": 1.5,
- "from": [ -100, 0 ],
- "to": [ 100, 0 ],
- "next": "@UIDemo.animation_out"
+ "anim_type": "offset",
+ "duration": 1.5,
+ "from": [ -100, 0 ],
+ "to": [ 100, 0 ],
+ "next": "@UIDemo.animation_out"
},
"animation_out": {
- "anim_type": "offset",
- "duration": 1.5,
- "from": [ 100, 0 ],
- "to": [ -100, 0 ],
- "next": "@UIDemo.animation_in"
+ "anim_type": "offset",
+ "duration": 1.5,
+ "from": [ 100, 0 ],
+ "to": [ -100, 0 ],
+ "next": "@UIDemo.animation_in"
},
- "namespace" : "UIDemo"
+ "namespace" : "UIDemo"
}
```
@@ -456,101 +467,103 @@ Button 是按钮控件,同时含有Image和Label。按钮有三种状态,分
* controls表示控制的子节点,
```json
- "button0@common.button" : {
- "$default_texture" : "textures/netease/common/button/default",
- "$hover_texture" : "textures/netease/common/button/hover",
- "$is_new_nine_slice" : false,
- "$label_color" : [ 1, 1, 1 ],
- "$label_font_scale_factor" : 1.0,
- "$label_font_size" : "large",
- "$label_layer" : 3,
- "$label_offset" : [ 0, 0 ],
- "$label_text" : "Button",
- "$nine_slice_buttom" : 0,
- "$nine_slice_left" : 0,
- "$nine_slice_right" : 0,
- "$nine_slice_top" : 0,
- "$nineslice_size" : [ 0, 0, 0, 0 ],
- "$pressed_button_name" : "%fpsBattle.click",
- "$pressed_texture" : "textures/netease/common/button/pressed",
- "$texture_layer" : 2,
- "anchor_from" : "center",
- "anchor_to" : "center",
- "is_handle_button_move_event" : true,
- "button_mappings" : [],
- "bindings" : [
- {
- "binding_collection_name" : "",
- "binding_condition" : "always_when_visible",
- "binding_type" : "collection_details"
- }
- ],
- "controls" : [
- {
- "default@fpsBattle.default" : {}
- },
- {
- "hover@fpsBattle.hover" : {}
- },
- {
- "pressed@fpsBattle.pressed" : {}
- },
- {
- "button_label@fpsBattle.button_label" : {}
- }
- ],
- "default_control" : "default",
- "hover_control" : "hover",
- "layer" : 3,
- "offset" : [ 0, 0 ],
- "pressed_control" : "pressed",
- "size" : [ 100, 50 ],
- "type" : "button",
- "visible" : true
+{
+ "button0@common.button" : {
+ "$default_texture" : "textures/netease/common/button/default",
+ "$hover_texture" : "textures/netease/common/button/hover",
+ "$is_new_nine_slice" : false,
+ "$label_color" : [ 1, 1, 1 ],
+ "$label_font_scale_factor" : 1.0,
+ "$label_font_size" : "large",
+ "$label_layer" : 3,
+ "$label_offset" : [ 0, 0 ],
+ "$label_text" : "Button",
+ "$nine_slice_buttom" : 0,
+ "$nine_slice_left" : 0,
+ "$nine_slice_right" : 0,
+ "$nine_slice_top" : 0,
+ "$nineslice_size" : [ 0, 0, 0, 0 ],
+ "$pressed_button_name" : "%fpsBattle.click",
+ "$pressed_texture" : "textures/netease/common/button/pressed",
+ "$texture_layer" : 2,
+ "anchor_from" : "center",
+ "anchor_to" : "center",
+ "is_handle_button_move_event" : true,
+ "button_mappings" : [],
+ "bindings" : [
+ {
+ "binding_collection_name" : "",
+ "binding_condition" : "always_when_visible",
+ "binding_type" : "collection_details"
+ }
+ ],
+ "controls" : [
+ {
+ "default@fpsBattle.default" : {}
+ },
+ {
+ "hover@fpsBattle.hover" : {}
+ },
+ {
+ "pressed@fpsBattle.pressed" : {}
+ },
+ {
+ "button_label@fpsBattle.button_label" : {}
+ }
+ ],
+ "default_control" : "default",
+ "hover_control" : "hover",
+ "layer" : 3,
+ "offset" : [ 0, 0 ],
+ "pressed_control" : "pressed",
+ "size" : [ 100, 50 ],
+ "type" : "button",
+ "visible" : true
},
"button_label" : {
- "color" : "$label_color",
- "font_scale_factor" : "$label_font_scale_factor",
- "font_size" : "$label_font_size",
- "font_type" : "smooth",
- "layer" : "$label_layer",
- "max_size" : [ "100%", "100%" ],
- "offset" : [ 0, 0 ],
- "shadow" : false,
- "text" : "$label_text",
- "text_alignment" : "center",
- "type" : "label"
+ "color" : "$label_color",
+ "font_scale_factor" : "$label_font_scale_factor",
+ "font_size" : "$label_font_size",
+ "font_type" : "smooth",
+ "layer" : "$label_layer",
+ "max_size" : [ "100%", "100%" ],
+ "offset" : [ 0, 0 ],
+ "shadow" : false,
+ "text" : "$label_text",
+ "text_alignment" : "center",
+ "type" : "label"
},
"default" : {
- "is_new_nine_slice" : "$is_new_nine_slice",
- "layer" : "$texture_layer",
- "nine_slice_buttom" : "$nine_slice_buttom",
- "nine_slice_left" : "$nine_slice_left",
- "nine_slice_right" : "$nine_slice_right",
- "nine_slice_top" : "$nine_slice_top",
- "texture" : "$default_texture",
- "type" : "image"
+ "is_new_nine_slice" : "$is_new_nine_slice",
+ "layer" : "$texture_layer",
+ "nine_slice_buttom" : "$nine_slice_buttom",
+ "nine_slice_left" : "$nine_slice_left",
+ "nine_slice_right" : "$nine_slice_right",
+ "nine_slice_top" : "$nine_slice_top",
+ "texture" : "$default_texture",
+ "type" : "image"
},
"hover" : {
- "is_new_nine_slice" : "$is_new_nine_slice",
- "layer" : "$texture_layer",
- "nine_slice_buttom" : "$nine_slice_buttom",
- "nine_slice_left" : "$nine_slice_left",
- "nine_slice_right" : "$nine_slice_right",
- "nine_slice_top" : "$nine_slice_top",
- "texture" : "$hover_texture",
- "type" : "image"
+ "is_new_nine_slice" : "$is_new_nine_slice",
+ "layer" : "$texture_layer",
+ "nine_slice_buttom" : "$nine_slice_buttom",
+ "nine_slice_left" : "$nine_slice_left",
+ "nine_slice_right" : "$nine_slice_right",
+ "nine_slice_top" : "$nine_slice_top",
+ "texture" : "$hover_texture",
+ "type" : "image"
},
"pressed" : {
- "is_new_nine_slice" : "$is_new_nine_slice",
- "layer" : "$texture_layer",
- "nine_slice_buttom" : "$nine_slice_buttom",
- "nine_slice_left" : "$nine_slice_left",
- "nine_slice_right" : "$nine_slice_right",
- "nine_slice_top" : "$nine_slice_top",
- "texture" : "$pressed_texture",
- "type" : "image"
- },
+ "is_new_nine_slice" : "$is_new_nine_slice",
+ "layer" : "$texture_layer",
+ "nine_slice_buttom" : "$nine_slice_buttom",
+ "nine_slice_left" : "$nine_slice_left",
+ "nine_slice_right" : "$nine_slice_right",
+ "nine_slice_top" : "$nine_slice_top",
+ "texture" : "$pressed_texture",
+ "type" : "image"
+ }
+}
```
| 变量
| 解释 |
@@ -587,15 +600,17 @@ Button 是按钮控件,同时含有Image和Label。按钮有三种状态,分
panel为面板控件,主要是用来将控件进行分类和管理,类似文件夹。
```json
- "panel" : {
- "anchor_from" : "center",
- "anchor_to" : "center",
- "layer" : 0,
- "offset" : [ 0, 0 ],
- "size" : [ "50.000000%+0 px", "50.000000%+0px" ],
- "type" : "panel",
- "visible" : true
+{
+ "panel" : {
+ "anchor_from" : "center",
+ "anchor_to" : "center",
+ "layer" : 0,
+ "offset" : [ 0, 0 ],
+ "size" : [ "50.000000%+0 px", "50.000000%+0px" ],
+ "type" : "panel",
+ "visible" : true
}
+}
```
| 变量 | 解释 |
@@ -609,25 +624,27 @@ panel为面板控件,主要是用来将控件进行分类和管理,类似文
input_panel与panel类似,可以用来放置其他控件,但除此之外还可以用来拖动,或实现“模态框”功能。
```json
-"InputPanel" : {
- "anchor_from" : "top_left",
- "anchor_to" : "top_left",
- "button_mappings": [
- {
- "from_button_id": "button.menu_select",
- "to_button_id": "#netease_to_button_id",
- "mapping_type": "pressed"
- }
- ],
- "layer" : 10,
- "modal" : true,
- "is_swallow": true,
- "contained": true,
- "draggable": "both",
- "offset" : [ 0.0, 0.0 ],
- "size" : [ 198.0, 137.0 ],
- "type" : "input_panel",
- "visible" : true
+{
+ "InputPanel" : {
+ "anchor_from" : "top_left",
+ "anchor_to" : "top_left",
+ "button_mappings": [
+ {
+ "from_button_id": "button.menu_select",
+ "to_button_id": "#netease_to_button_id",
+ "mapping_type": "pressed"
+ }
+ ],
+ "layer" : 10,
+ "modal" : true,
+ "is_swallow": true,
+ "contained": true,
+ "draggable": "both",
+ "offset" : [ 0.0, 0.0 ],
+ "size" : [ 198.0, 137.0 ],
+ "type" : "input_panel",
+ "visible" : true
+ }
}
```
@@ -681,23 +698,28 @@ InputPanel维护着一个拖拽偏移量,它代表着在整个拖拽过程中
布局面板,用于自动布局该控件的子控件
```json
-"stack_panel0": {
- "layer": 1,
- "orientation": "horizontal",
- "size": [100, 100],
- "type": "stack_panel",
- "controls": [{
- "panel_0": {
- "type": "panel",
- "size": [2, 2]
- }
- }, {
- "fill_0": {
- "type": "panel",
- "size": ["fill", 1]
- }
- }]
-},
+{
+ "stack_panel0": {
+ "layer": 1,
+ "orientation": "horizontal",
+ "size": [100, 100],
+ "type": "stack_panel",
+ "controls": [
+ {
+ "panel_0": {
+ "type": "panel",
+ "size": [2, 2]
+ }
+ },
+ {
+ "fill_0": {
+ "type": "panel",
+ "size": ["fill", 1]
+ }
+ }
+ ]
+ }
+}
```
| 变量 | 解释 |
@@ -725,51 +747,53 @@ InputPanel维护着一个拖拽偏移量,它代表着在整个拖拽过程中
TextEditBox是输入框控件,用来输入文字信息,可以获取输入内容,设置输入框内容,触发输入中和输入完成事件,设置最大输入值等。下面的示例展示了一个搜索框的信息。
```json
- "text_edit_box0@common.text_edit_box" : {
- "$edit_box_default_texture" : "textures/ui/edit_box_indent",
- "$edit_box_hover_texture" : "textures/ui/edit_box_indent_hover",
- "$font_size" : "normal",
- "$is_new_nine_slice" : false,
- "$nine_slice_buttom" : 0,
- "$nine_slice_left" : 0,
- "$nine_slice_right" : 0,
- "$nine_slice_top" : 0,
- "$nineslice_size" : [ 0, 0, 0, 0 ],
- "$place_holder_text" : "请输入内容",
- "$place_holder_text_color" : [ 0.50, 0.50, 0.50 ],
- "$text_background_default" : "fpsBattle.edit_box_background_default",
- "$text_background_hover" : "fpsBattle.edit_box_background_hover",
- "$text_box_name" : "%fpsBattle.message_text_box",
- "$text_box_text_color" : [ 1, 1, 1 ],
- "$text_edit_box_content_binding_name" : "#fpsBattle.message_text_box_content",
- "anchor_from" : "center",
- "anchor_to" : "center",
- "enabled_newline" : false,
- "layer" : 5,
- "max_length" : 512,
- "offset" : [ 0, 0 ],
- "size" : [ 300, 27 ],
- "type" : "edit_box",
- "visible" : true
+{
+ "text_edit_box0@common.text_edit_box" : {
+ "$edit_box_default_texture" : "textures/ui/edit_box_indent",
+ "$edit_box_hover_texture" : "textures/ui/edit_box_indent_hover",
+ "$font_size" : "normal",
+ "$is_new_nine_slice" : false,
+ "$nine_slice_buttom" : 0,
+ "$nine_slice_left" : 0,
+ "$nine_slice_right" : 0,
+ "$nine_slice_top" : 0,
+ "$nineslice_size" : [ 0, 0, 0, 0 ],
+ "$place_holder_text" : "请输入内容",
+ "$place_holder_text_color" : [ 0.50, 0.50, 0.50 ],
+ "$text_background_default" : "fpsBattle.edit_box_background_default",
+ "$text_background_hover" : "fpsBattle.edit_box_background_hover",
+ "$text_box_name" : "%fpsBattle.message_text_box",
+ "$text_box_text_color" : [ 1, 1, 1 ],
+ "$text_edit_box_content_binding_name" : "#fpsBattle.message_text_box_content",
+ "anchor_from" : "center",
+ "anchor_to" : "center",
+ "enabled_newline" : false,
+ "layer" : 5,
+ "max_length" : 512,
+ "offset" : [ 0, 0 ],
+ "size" : [ 300, 27 ],
+ "type" : "edit_box",
+ "visible" : true
},
"edit_box_background_default" : {
- "is_new_nine_slice" : "$is_new_nine_slice",
- "nine_slice_buttom" : "$nine_slice_buttom",
- "nine_slice_left" : "$nine_slice_left",
- "nine_slice_right" : "$nine_slice_right",
- "nine_slice_top" : "$nine_slice_top",
- "texture" : "$edit_box_default_texture",
- "type" : "image"
+ "is_new_nine_slice" : "$is_new_nine_slice",
+ "nine_slice_buttom" : "$nine_slice_buttom",
+ "nine_slice_left" : "$nine_slice_left",
+ "nine_slice_right" : "$nine_slice_right",
+ "nine_slice_top" : "$nine_slice_top",
+ "texture" : "$edit_box_default_texture",
+ "type" : "image"
},
"edit_box_background_hover" : {
- "is_new_nine_slice" : "$is_new_nine_slice",
- "nine_slice_buttom" : "$nine_slice_buttom",
- "nine_slice_left" : "$nine_slice_left",
- "nine_slice_right" : "$nine_slice_right",
- "nine_slice_top" : "$nine_slice_top",
- "texture" : "$edit_box_hover_texture",
- "type" : "image"
- },
+ "is_new_nine_slice" : "$is_new_nine_slice",
+ "nine_slice_buttom" : "$nine_slice_buttom",
+ "nine_slice_left" : "$nine_slice_left",
+ "nine_slice_right" : "$nine_slice_right",
+ "nine_slice_top" : "$nine_slice_top",
+ "texture" : "$edit_box_hover_texture",
+ "type" : "image"
+ }
+}
```
| 变量
| 解释 |
@@ -788,22 +812,26 @@ TextEditBox是输入框控件,用来输入文字信息,可以获取输入内
* 注1
```python
+import mod.client.extraClientApi as clientApi
+ViewBinder = clientApi.GetViewBinderCls()
+ViewRequest = clientApi.GetViewViewRequestCls()
+ScreenNode = clientApi.GetScreenNodeCls()
+
class TestScreen(ScreenNode):
- def __init__(self, namespace, name, param):
- ScreenNode.__init__(self, namespace, name, param)
+ def __init__(self, namespace, name, param):
+ ScreenNode.__init__(self, namespace, name, param)
self.text = ""
self.holder = str("请输入姓名")
-
+
@ViewBinder.binding(ViewBinder.BF_EditChanged | ViewBinder.BF_EditFinished)
- def TextBox(self, args):
- print "SearchTextBox ", args
- self.text = args["Text"]
- return ViewRequest.Refresh
-
- @ViewBinder.binding(ViewBinder.BF_BindString)
- def ReturnTextString(self):
- return self.text
+ def TextBox(self, args):
+ print "SearchTextBox ", args
+ self.text = args["Text"]
+ return ViewRequest.Refresh
+ @ViewBinder.binding(ViewBinder.BF_BindString)
+ def ReturnTextString(self):
+ return self.text
```
* 注2
@@ -843,21 +871,23 @@ PC和IOS平台没有这个问题
该控件可以用于在ui上显示骨骼模型
```json
-"paper_doll0" : {
- "anchor_from" : "center",
- "anchor_to" : "center",
- "animation" : "",
- "animation_looped": true,
- "layer" : 7,
- "modelname" : "",
- "modelsize" : 1.0,
- "offset" : [ 0, 0 ],
- "renderer" : "paper_doll_renderer",
- "size" : [ 100, 100 ],
- "type" : "custom",
- "visible" : true,
- "enable_scissor_test" : false,
- },
+{
+ "paper_doll0" : {
+ "anchor_from" : "center",
+ "anchor_to" : "center",
+ "animation" : "",
+ "animation_looped": true,
+ "layer" : 7,
+ "modelname" : "",
+ "modelsize" : 1.0,
+ "offset" : [ 0, 0 ],
+ "renderer" : "paper_doll_renderer",
+ "size" : [ 100, 100 ],
+ "type" : "custom",
+ "visible" : true,
+ "enable_scissor_test" : false,
+ }
+}
```
| 变量
| 解释 |
| :----------: | ----------------------------------------------------------- |
@@ -891,19 +921,21 @@ PC和IOS平台没有这个问题
3)生物类型原版模型展示。
```json
-"paper_doll0" : {
- "anchor_from" : "center",
- "anchor_to" : "center",
- "layer" : 22,
- "offset" : [ 0.0, 0.0 ],
- "renderer" : "netease_paper_doll_renderer",
- "init_rot_y": 60.0,
- "rotation": "gesture_x",
- "screen_scale": 1.0,
- "size" : [ 100, 100 ],
- "type" : "custom",
- "visible" : true,
- "enable_scissor_test" : false,
+{
+ "paper_doll0" : {
+ "anchor_from" : "center",
+ "anchor_to" : "center",
+ "layer" : 22,
+ "offset" : [ 0.0, 0.0 ],
+ "renderer" : "netease_paper_doll_renderer",
+ "init_rot_y": 60.0,
+ "rotation": "gesture_x",
+ "screen_scale": 1.0,
+ "size" : [ 100, 100 ],
+ "type" : "custom",
+ "visible" : true,
+ "enable_scissor_test" : false
+ }
}
```
@@ -934,7 +966,7 @@ param = {
"init_rot_y": 60, # 初始朝向
"molang_dict": {"variable.liedownamount": 1} # molang变量dict,其中key为字符串,value为float类型
}
-uiNode.RenderPaperDoll(path, param)
+self.GetBaseUIControl(path).asNeteasePaperDoll().RenderEntity(param)
```
2)渲染骨骼模型
@@ -947,7 +979,7 @@ param = {
"animation": "fengxi", # 动画名称
"animation_looped": False, # 是否循环播放
}
-uiNode.RenderPaperDoll(path, param)
+self.GetBaseUIControl(path).asNeteasePaperDoll().RenderSkeletonModel(param)
```
3)渲染原版生物模型(不需要生物实例)
@@ -960,7 +992,7 @@ param = {
"init_rot_y": 60,
"molang_dict": {"variable.state": 2, "variable.liedownamount": 1} # 通过molang变量来调整渲染效果(坐下的猫)
}
-uiNode.RenderPaperDoll(path, param)
+self.GetBaseUIControl(path).asNeteasePaperDoll().RenderEntity(param)
```
使用注意事项:
@@ -981,19 +1013,21 @@ uiNode.RenderPaperDoll(path, param)
该控件可以用于在ui上显示物品
```json
-"item_renderer0" : {
- "anchor_from" : "center",
- "anchor_to" : "center",
- "layer" : 1,
- "offset" : [ 0, 0 ],
- "property_bag" : {
- "#item_id_aux" : 131072
- },
- "renderer" : "inventory_item_renderer",
- "size" : [ 100, 100 ],
- "type" : "custom",
- "visible" : true
- },
+{
+ "item_renderer0" : {
+ "anchor_from" : "center",
+ "anchor_to" : "center",
+ "layer" : 1,
+ "offset" : [ 0, 0 ],
+ "property_bag" : {
+ "#item_id_aux" : 131072
+ },
+ "renderer" : "inventory_item_renderer",
+ "size" : [ 100, 100 ],
+ "type" : "custom",
+ "visible" : true
+ }
+}
```
| 变量
| 解释 |
| :----------: | ----------------------------------------------------------- |
@@ -1026,42 +1060,44 @@ uiNode.RenderPaperDoll(path, param)
该控件是可以滑动的窗口,需要有其他控件附属。
```json
- "scroll_view0@common.scrolling_panel" : {
- "$background_nine_slice_buttom" : 0,
- "$background_nine_slice_left" : 0,
- "$background_nine_slice_right" : 0,
- "$background_nine_slice_top" : 0,
- "$background_nineslice_size" : [ 0, 0, 0, 0 ],
- "$box_nine_slice_buttom" : 0,
- "$box_nine_slice_left" : 0,
- "$box_nine_slice_right" : 0,
- "$box_nine_slice_top" : 0,
- "$box_nineslice_size" : [ 0, 0, 0, 0 ],
- "$is_background_nine_slice" : false,
- "$is_box_nine_slice" : false,
- "$is_track_nine_slice" : false,
- "$scroll_background_image_control" : "fpsBattle.scroll_background_image",
- "$scroll_background_texture" : "textures/ui/ScrollRail",
- "$scroll_box_mouse_image_control" : "fpsBattle.scroll_box_image",
- "$scroll_box_texture" : "textures/ui/newTouchScrollBox",
- "$scroll_box_touch_image_control" : "fpsBattle.scroll_box_image",
- "$scroll_track_image_control" : "fpsBattle.scroll_track_image",
- "$scroll_track_texture" : "textures/ui/ScrollRail",
- "$scrolling_content" : "fpsBattle.image",
- "$show_background" : true,
- "$track_nine_slice_buttom" : 0,
- "$track_nine_slice_left" : 0,
- "$track_nine_slice_right" : 0,
- "$track_nine_slice_top" : 0,
- "$track_nineslice_size" : [ 0, 0, 0, 0 ],
- "anchor_from" : "center",
- "anchor_to" : "center",
- "layer" : 9,
- "offset" : [ 0, 0 ],
- "size" : [ 100, 80 ],
- "type" : "scroll_view",
- "visible" : true
- },
+{
+ "scroll_view0@common.scrolling_panel" : {
+ "$background_nine_slice_buttom" : 0,
+ "$background_nine_slice_left" : 0,
+ "$background_nine_slice_right" : 0,
+ "$background_nine_slice_top" : 0,
+ "$background_nineslice_size" : [ 0, 0, 0, 0 ],
+ "$box_nine_slice_buttom" : 0,
+ "$box_nine_slice_left" : 0,
+ "$box_nine_slice_right" : 0,
+ "$box_nine_slice_top" : 0,
+ "$box_nineslice_size" : [ 0, 0, 0, 0 ],
+ "$is_background_nine_slice" : false,
+ "$is_box_nine_slice" : false,
+ "$is_track_nine_slice" : false,
+ "$scroll_background_image_control" : "fpsBattle.scroll_background_image",
+ "$scroll_background_texture" : "textures/ui/ScrollRail",
+ "$scroll_box_mouse_image_control" : "fpsBattle.scroll_box_image",
+ "$scroll_box_texture" : "textures/ui/newTouchScrollBox",
+ "$scroll_box_touch_image_control" : "fpsBattle.scroll_box_image",
+ "$scroll_track_image_control" : "fpsBattle.scroll_track_image",
+ "$scroll_track_texture" : "textures/ui/ScrollRail",
+ "$scrolling_content" : "fpsBattle.image",
+ "$show_background" : true,
+ "$track_nine_slice_buttom" : 0,
+ "$track_nine_slice_left" : 0,
+ "$track_nine_slice_right" : 0,
+ "$track_nine_slice_top" : 0,
+ "$track_nineslice_size" : [ 0, 0, 0, 0 ],
+ "anchor_from" : "center",
+ "anchor_to" : "center",
+ "layer" : 9,
+ "offset" : [ 0, 0 ],
+ "size" : [ 100, 80 ],
+ "type" : "scroll_view",
+ "visible" : true
+ }
+}
```
|变量
| 解释 |
@@ -1126,32 +1162,34 @@ mouse_path = scroll_view_path + "/scroll_mouse/scroll_view/stack_panel/backgroun
Grid组件属于网格型的排列,可以依附在滚动条中,用来实现背包等功能。
```json
- "grid0" : {
- "anchor_from" : "center",
- "anchor_to" : "center",
- "collection_name" : "test_grid",
- "grid_dimensions" : [ 2, 2 ],
- "grid_item_template" : "fpsBattle.netease_editor_template_image",
- "grid_rescaling_type" : "none",
- "maximum_grid_items" : 0,
- "layer" : 1,
- "offset" : [ 0, 0 ],
- "size" : [ 200, 200 ],
- "type" : "grid",
- "visible" : true
+{
+ "grid0" : {
+ "anchor_from" : "center",
+ "anchor_to" : "center",
+ "collection_name" : "test_grid",
+ "grid_dimensions" : [ 2, 2 ],
+ "grid_item_template" : "fpsBattle.netease_editor_template_image",
+ "grid_rescaling_type" : "none",
+ "maximum_grid_items" : 0,
+ "layer" : 1,
+ "offset" : [ 0, 0 ],
+ "size" : [ 200, 200 ],
+ "type" : "grid",
+ "visible" : true
},
"netease_editor_template_image" : {
- "anchor_from" : "center",
- "anchor_to" : "center",
- "layer" : 1,
- "offset" : [ 0, 0 ],
- "size" : [ "50%", "50%" ],
- "texture" : "textures/netease/common/image/default",
- "type" : "image",
- "uv" : [ 0, 0 ],
- "uv_size" : [ 107, 107 ],
- "visible" : true
- },
+ "anchor_from" : "center",
+ "anchor_to" : "center",
+ "layer" : 1,
+ "offset" : [ 0, 0 ],
+ "size" : [ "50%", "50%" ],
+ "texture" : "textures/netease/common/image/default",
+ "type" : "image",
+ "uv" : [ 0, 0 ],
+ "uv_size" : [ 107, 107 ],
+ "visible" : true
+ }
+}
```
| 变量
| 解释 |
@@ -1186,43 +1224,49 @@ Grid组件属于网格型的排列,可以依附在滚动条中,用来实现
3. grid控件不建议使用其子控件路径对其动态生成的格子控件直接进行SetVisible等操作,因为在每次界面刷新时grid控件会对所有的格子做一次数据更新,更新的过程中会强制将格子可见性置True。如果有需要对格子进行操作,可以使用数据绑定的方式,如下代码和json。需要注意的是在数据绑定的回调函数中需要明确grid本身是否可见,否则会造成grid子节点控件的可见性数据异常,从而影响界面操作逻辑。
```json
- "grid1" : {
- "anchor_from" : "center",
- "anchor_to" : "center",
- "collection_name" : "gridDemo",
- "grid_dimensions" : [ 2, 2 ],
- "grid_item_template" : "UIDemo.scrollviewBtn0",
- "layer" : 39,
- "offset" : [ 0, 0 ],
- "size" : [ 200, 200 ],
- "type" : "grid",
- "visible" : true
+{
+ "grid1" : {
+ "anchor_from" : "center",
+ "anchor_to" : "center",
+ "collection_name" : "gridDemo",
+ "grid_dimensions" : [ 2, 2 ],
+ "grid_item_template" : "UIDemo.scrollviewBtn0",
+ "layer" : 39,
+ "offset" : [ 0, 0 ],
+ "size" : [ 200, 200 ],
+ "type" : "grid",
+ "visible" : true
},
"scrollviewBtn0@UIDemo.scrollviewBtn": {
- "bindings" : [
- {
- "binding_collection_name" : "gridDemo",
- "binding_condition" : "always",
- "binding_name" : "#UIDemo.visible",
- "binding_name_override" : "#visible",
- "binding_type" : "collection"
- }
- ],
- "visible" : "#UIDemo.visible"
- },
+ "bindings" : [
+ {
+ "binding_collection_name" : "gridDemo",
+ "binding_condition" : "always",
+ "binding_name" : "#UIDemo.visible",
+ "binding_name_override" : "#visible",
+ "binding_type" : "collection"
+ }
+ ],
+ "visible" : "#UIDemo.visible"
+ }
+}
```
```python
+import mod.client.extraClientApi as clientApi
+ViewBinder = clientApi.GetViewBinderCls()
+ViewRequest = clientApi.GetViewViewRequestCls()
+ScreenNode = clientApi.GetScreenNodeCls()
+
class UIDemoScreen(ScreenNode):
def __init__(self, namespace, name, param):
- self.demoGridControl = None
- ......
+ ScreenNode.__init__(self, namespace, name, param)
+ self.demoGridControl = None
+
+ def Create(self):
+ self.demoGridControl = self.GetBaseUIControl("/grid1")
- def Create(self):
- self.demoGridControl = self.GetBaseUIControl("/grid1")
- ......
-
- @ViewBinder.binding_collection(ViewBinder.BF_BindBool, "gridDemo", "#UIDemo.visible")
+ @ViewBinder.binding_collection(ViewBinder.BF_BindBool, "gridDemo", "#UIDemo.visible")
def GridItemVisible(self, index):
return index < self.showNum and self.demoGridControl.GetVisible()
```
@@ -1233,55 +1277,57 @@ class UIDemoScreen(ScreenNode):
ProgressBar进度条控件,用于百分比显示进度
```json
- "progress_bar0" : {
- "$clip_direction" : "left",
- "$clip_ratio" : 0.0,
- "$is_new_nine_slice" : false,
- "$nine_slice_buttom" : 0,
- "$nine_slice_left" : 0,
- "$nine_slice_right" : 0,
- "$nine_slice_top" : 0,
- "$nineslice_size" : [ 0, 0, 0, 0 ],
- "$progress_bar_empty_texture" : "textures/ui/empty_progress_bar",
- "$progress_bar_filled_texture" : "textures/ui/filled_progress_bar",
- "anchor_from" : "center",
- "anchor_to" : "center",
- "controls" : [
- {
- "empty_progress_bar@fpsBattle.empty_progress_bar" : {}
- },
- {
- "filled_progress_bar@fpsBattle.filled_progress_bar" : {}
- }
- ],
- "layer" : 8,
- "offset" : [ 0, 0 ],
- "size" : [ 100, 10 ],
- "type" : "panel",
- "visible" : true
- },
- "empty_progress_bar" : {
- "is_new_nine_slice" : "$is_new_nine_slice",
- "layer" : 1,
- "nine_slice_buttom" : "$nine_slice_buttom",
- "nine_slice_left" : "$nine_slice_left",
- "nine_slice_right" : "$nine_slice_right",
- "nine_slice_top" : "$nine_slice_top",
- "texture" : "$progress_bar_empty_texture",
- "type" : "image"
- },
- "filled_progress_bar" : {
- "clip_direction" : "$clip_direction",
- "clip_ratio" : "$clip_ratio",
- "is_new_nine_slice" : "$is_new_nine_slice",
- "layer" : 2,
- "nine_slice_buttom" : "$nine_slice_buttom",
- "nine_slice_left" : "$nine_slice_left",
- "nine_slice_right" : "$nine_slice_right",
- "nine_slice_top" : "$nine_slice_top",
- "texture" : "$progress_bar_filled_texture",
- "type" : "image"
- },
+{
+ "progress_bar0" : {
+ "$clip_direction" : "left",
+ "$clip_ratio" : 0.0,
+ "$is_new_nine_slice" : false,
+ "$nine_slice_buttom" : 0,
+ "$nine_slice_left" : 0,
+ "$nine_slice_right" : 0,
+ "$nine_slice_top" : 0,
+ "$nineslice_size" : [ 0, 0, 0, 0 ],
+ "$progress_bar_empty_texture" : "textures/ui/empty_progress_bar",
+ "$progress_bar_filled_texture" : "textures/ui/filled_progress_bar",
+ "anchor_from" : "center",
+ "anchor_to" : "center",
+ "controls" : [
+ {
+ "empty_progress_bar@fpsBattle.empty_progress_bar" : {}
+ },
+ {
+ "filled_progress_bar@fpsBattle.filled_progress_bar" : {}
+ }
+ ],
+ "layer" : 8,
+ "offset" : [ 0, 0 ],
+ "size" : [ 100, 10 ],
+ "type" : "panel",
+ "visible" : true
+ },
+ "empty_progress_bar" : {
+ "is_new_nine_slice" : "$is_new_nine_slice",
+ "layer" : 1,
+ "nine_slice_buttom" : "$nine_slice_buttom",
+ "nine_slice_left" : "$nine_slice_left",
+ "nine_slice_right" : "$nine_slice_right",
+ "nine_slice_top" : "$nine_slice_top",
+ "texture" : "$progress_bar_empty_texture",
+ "type" : "image"
+ },
+ "filled_progress_bar" : {
+ "clip_direction" : "$clip_direction",
+ "clip_ratio" : "$clip_ratio",
+ "is_new_nine_slice" : "$is_new_nine_slice",
+ "layer" : 2,
+ "nine_slice_buttom" : "$nine_slice_buttom",
+ "nine_slice_left" : "$nine_slice_left",
+ "nine_slice_right" : "$nine_slice_right",
+ "nine_slice_top" : "$nine_slice_top",
+ "texture" : "$progress_bar_filled_texture",
+ "type" : "image"
+ }
+}
```
| 变量
| 解释 |
@@ -1312,28 +1358,30 @@ ProgressBar进度条控件,用于百分比显示进度
开关控件,用于两个状态之间的切换
```json
-"switch_toggle0@common_toggles.switch_toggle_collection" : {
- "$default_texture" : "textures/ui/toggle_off",
- "$hover_texture" : "textures/ui/toggle_on",
- "$pressed_no_hover_texture" : "textures/ui/toggle_on_hover",
- "$pressed_texture" : "textures/ui/toggle_off_hover",
- "$toggle_name" : "#fpsBattle.toggle_name",
- "$toggle_state_binding_name" : "#fpsBattle.toggle_state",
- "anchor_from" : "center",
- "anchor_to" : "center",
- "bindings" : [
- {
- "binding_collection_name" : "",
- "binding_condition" : "always_when_visible",
- "binding_type" : "collection_details"
- }
- ],
- "layer" : 6,
- "offset" : [ 0, 0 ],
- "size" : [ 100, 100 ],
- "type" : "panel",
- "visible" : true
- },
+{
+ "switch_toggle0@common_toggles.switch_toggle_collection" : {
+ "$default_texture" : "textures/ui/toggle_off",
+ "$hover_texture" : "textures/ui/toggle_on",
+ "$pressed_no_hover_texture" : "textures/ui/toggle_on_hover",
+ "$pressed_texture" : "textures/ui/toggle_off_hover",
+ "$toggle_name" : "#fpsBattle.toggle_name",
+ "$toggle_state_binding_name" : "#fpsBattle.toggle_state",
+ "anchor_from" : "center",
+ "anchor_to" : "center",
+ "bindings" : [
+ {
+ "binding_collection_name" : "",
+ "binding_condition" : "always_when_visible",
+ "binding_type" : "collection_details"
+ }
+ ],
+ "layer" : 6,
+ "offset" : [ 0, 0 ],
+ "size" : [ 100, 100 ],
+ "type" : "panel",
+ "visible" : true
+ }
+}
```
| 变量
| 解释 |
@@ -1348,9 +1396,14 @@ ProgressBar进度条控件,用于百分比显示进度
* 注1
```python
+import mod.client.extraClientApi as clientApi
+ViewBinder = clientApi.GetViewBinderCls()
+ViewRequest = clientApi.GetViewViewRequestCls()
+ScreenNode = clientApi.GetScreenNodeCls()
+
class TestScreen(ScreenNode):
- def __init__(self, namespace, name, param):
- ScreenNode.__init__(self, namespace, name, param)
+ def __init__(self, namespace, name, param):
+ ScreenNode.__init__(self, namespace, name, param)
self.currentToggleShow = True
@ViewBinder.binding(ViewBinder.BF_ToggleChanged)
@@ -1358,7 +1411,7 @@ class TestScreen(ScreenNode):
self.currentToggleShow = args["state"]
return ViewRequest.Refresh
- @ViewBinder.binding(ViewBinder.BF_BindBool)
+ @ViewBinder.binding(ViewBinder.BF_BindBool)
def ReturnToggleState(self):
return self.currentToggleShow
@@ -1381,32 +1434,34 @@ class TestScreen(ScreenNode):
滑动条控件,用于拖动设置进度或百分比。
```json
-"slider0@common.slider": {
- "$slider_tts_text_value": "#netease_tts_text_value",
- "$slider_name": "#UIDemoScreen.OnDemoSliderChange",
- "$slider_value_binding_name":"#UIDemoScreen.ReturnSliderValue",
- "$slider_steps_binding_name": "#UIDemoScreen.ReturnSliderStep",
- "$background_default_control": "common.slider_background",
- "$progress_default_control": "common.slider_progress",
- "$progress_default_clip_direction": "left",
- "$background_hover_control": "common.slider_background_hover",
- "$progress_hover_control": "common.slider_progress_hover",
- "$progress_hover_clip_direction": "left",
- "$slider_direction": "horizontal",
- "$slider_box_layout": "common.slider_button_layout",
- "$slider_box_hover_layout": "common.slider_button_hover_layout",
- "$slider_box_locked_layout": "common.slider_button_locked_layout",
- "$slider_box_indent_layout": "common.slider_button_indent_layout",
- "$slider_box_size": [ 10, 16 ],
- "size": [ 100, 10 ],
- "offset": [ 0, 0 ],
- "$slider_step_factory_control_ids": {
- "slider_step": "@common.slider_step",
- "slider_step_hover": "@common.slider_step_hover",
- "slider_step_progress": "@common.slider_step_progress",
- "slider_step_progress_hover": "@common.slider_step_progress_hover"
- },
- }
+{
+ "slider0@common.slider": {
+ "$slider_tts_text_value": "#netease_tts_text_value",
+ "$slider_name": "#UIDemoScreen.OnDemoSliderChange",
+ "$slider_value_binding_name": "#UIDemoScreen.ReturnSliderValue",
+ "$slider_steps_binding_name": "#UIDemoScreen.ReturnSliderStep",
+ "$background_default_control": "common.slider_background",
+ "$progress_default_control": "common.slider_progress",
+ "$progress_default_clip_direction": "left",
+ "$background_hover_control": "common.slider_background_hover",
+ "$progress_hover_control": "common.slider_progress_hover",
+ "$progress_hover_clip_direction": "left",
+ "$slider_direction": "horizontal",
+ "$slider_box_layout": "common.slider_button_layout",
+ "$slider_box_hover_layout": "common.slider_button_hover_layout",
+ "$slider_box_locked_layout": "common.slider_button_locked_layout",
+ "$slider_box_indent_layout": "common.slider_button_indent_layout",
+ "$slider_box_size": [10, 16],
+ "size": [100, 10],
+ "offset": [0, 0],
+ "$slider_step_factory_control_ids": {
+ "slider_step": "@common.slider_step",
+ "slider_step_hover": "@common.slider_step_hover",
+ "slider_step_progress": "@common.slider_step_progress",
+ "slider_step_progress_hover": "@common.slider_step_progress_hover"
+ }
+ }
+}
```
| 变量
| 解释 |
@@ -1436,27 +1491,32 @@ class TestScreen(ScreenNode):
* 注1
```python
+import mod.client.extraClientApi as clientApi
+ViewBinder = clientApi.GetViewBinderCls()
+ViewRequest = clientApi.GetViewViewRequestCls()
+ScreenNode = clientApi.GetScreenNodeCls()
+
class UIDemoScreen(ScreenNode):
- def __init__(self, namespace, name, param):
- ScreenNode.__init__(self, namespace, name, param)
+ def __init__(self, namespace, name, param):
+ ScreenNode.__init__(self, namespace, name, param)
self.sliderPercentValue = 0.5 # 百分比值
# self.sliderAbsValue = 5.0 # 固定值
@ViewBinder.binding(ViewBinder.BF_SliderChanged | ViewBinder.BF_SliderFinished)
- def OnDemoSliderChange(self, value, isFinish, _unused):
- self.sliderPercentValue = value # 百分比类型滑动条保存值
- # self.sliderAbsValue = value # 固定格类型滑动条保存值
- return ViewRequest.Refresh
+ def OnDemoSliderChange(self, value, isFinish, _unused):
+ self.sliderPercentValue = value # 百分比类型滑动条保存值
+ # self.sliderAbsValue = value # 固定格类型滑动条保存值
+ return ViewRequest.Refresh
- @ViewBinder.binding(ViewBinder.BF_BindFloat)
- def ReturnSliderValue(self):
- return self.sliderPercentValue # 百分比类型滑动条返回值
- # return self.sliderAbsValue # 固定格类型滑动条返回值
+ @ViewBinder.binding(ViewBinder.BF_BindFloat)
+ def ReturnSliderValue(self):
+ return self.sliderPercentValue # 百分比类型滑动条返回值
+ # return self.sliderAbsValue # 固定格类型滑动条返回值
@ViewBinder.binding(ViewBinder.BF_BindInt)
- def ReturnSliderStep(self):
- return 1 # 百分比类型滑动条
- # return 10 # 固定格类型滑动条
+ def ReturnSliderStep(self):
+ return 1 # 百分比类型滑动条
+ # return 10 # 固定格类型滑动条
```
下图为Slider在游戏中的控件表现
@@ -1527,37 +1587,37 @@ def getFirstItemRange(itemNum):
"controls": [
{
"state_default@custom_wheel_namespace.wheel_state": {
- "texture" : "textures/ui/circle/custom_wheel_selection_default"
+ "texture" : "textures/ui/circle/custom_wheel_selection_default"
}
},
{
"state_0@custom_wheel_namespace.wheel_state": {
- "texture" : "textures/ui/circle/custom_wheel_selection_0"
+ "texture" : "textures/ui/circle/custom_wheel_selection_0"
}
},
{
"state_1@custom_wheel_namespace.wheel_state": {
- "texture" : "textures/ui/circle/custom_wheel_selection_1"
+ "texture" : "textures/ui/circle/custom_wheel_selection_1"
}
},
{
"state_2@custom_wheel_namespace.wheel_state": {
- "texture" : "textures/ui/circle/custom_wheel_selection_2"
+ "texture" : "textures/ui/circle/custom_wheel_selection_2"
}
},
{
"state_3@custom_wheel_namespace.wheel_state": {
- "texture" : "textures/ui/circle/custom_wheel_selection_3"
+ "texture" : "textures/ui/circle/custom_wheel_selection_3"
}
},
{
"state_4@custom_wheel_namespace.wheel_state": {
- "texture" : "textures/ui/circle/custom_wheel_selection_4"
+ "texture" : "textures/ui/circle/custom_wheel_selection_4"
}
},
{
"state_5@custom_wheel_namespace.wheel_state": {
- "texture" : "textures/ui/circle/custom_wheel_selection_5"
+ "texture" : "textures/ui/circle/custom_wheel_selection_5"
}
}
]
@@ -1630,11 +1690,13 @@ hover事件的触发本质上是与鼠标悬浮相关,在PC模式中,当鼠
```json
- "main" : {
- "controls" : [],
- "type" : "screen",
- "gamepad_cursor_deflection_mode": true
- },
+{
+ "main" : {
+ "controls" : [],
+ "type" : "screen",
+ "gamepad_cursor_deflection_mode": true
+ }
+}
```
@@ -1644,38 +1706,40 @@ hover事件的触发本质上是与鼠标悬浮相关,在PC模式中,当鼠
网易版单选下拉框,可以在给定的选项中进行选择。
```json
-"comboBoxPanel@combo_box.comboBoxPanel" : {
- "$content_size":[ "100.0%+0.0px", 100 ],
- "$item_size":[ "100.0%+0.0px", "10.0%x+0.0px" ],
- "$title_label":"combo_box.titleLabel",
- "$content_label":"combo_box.label",
- "$title_down_image":"combo_box.dropdownImage",
- "$title_up_image":"combo_box.dropupImage",
- "$default_title_texture" : "textures/ui/button_borderless_light",
- "$hover_title_texture" : "textures/ui/button_borderless_lighthover",
- "$pressed_title_texture" : "textures/ui/button_borderless_lightpressed",
- "$title_nineslice_size|default" : [ 0.0, 0.0, 0.0, 0.0 ],
- "$default_item_texture" : "textures/ui/button_borderless_light",
- "$hover_item_texture" : "textures/ui/button_borderless_lighthover",
- "$pressed_item_texture" : "textures/ui/button_borderless_lightpressed",
- "$item_nineslice_size|default" : [ 0.0, 0.0, 0.0, 0.0 ],
- "$scroll_background_texture" : "textures/ui/ScrollRail",
- "alpha" : 1.0,
- "anchor_from" : "center",
- "anchor_to" : "center",
- "clip_offset" : [ 0, 0 ],
- "clips_children" : false,
- "enabled" : true,
- "layer" : 0,
- "max_size" : [ 0, 0 ],
- "min_size" : [ 0, 0 ],
- "offset" : [ 0.0, 0.0 ],
- "priority" : 0,
- "propagate_alpha" : false,
- "size" : [ 120, 20 ],
- "type" : "panel",
- "visible" : true
- }
+{
+ "comboBoxPanel@combo_box.comboBoxPanel" : {
+ "$content_size":[ "100.0%+0.0px", 100 ],
+ "$item_size":[ "100.0%+0.0px", "10.0%x+0.0px" ],
+ "$title_label":"combo_box.titleLabel",
+ "$content_label":"combo_box.label",
+ "$title_down_image":"combo_box.dropdownImage",
+ "$title_up_image":"combo_box.dropupImage",
+ "$default_title_texture" : "textures/ui/button_borderless_light",
+ "$hover_title_texture" : "textures/ui/button_borderless_lighthover",
+ "$pressed_title_texture" : "textures/ui/button_borderless_lightpressed",
+ "$title_nineslice_size|default" : [ 0.0, 0.0, 0.0, 0.0 ],
+ "$default_item_texture" : "textures/ui/button_borderless_light",
+ "$hover_item_texture" : "textures/ui/button_borderless_lighthover",
+ "$pressed_item_texture" : "textures/ui/button_borderless_lightpressed",
+ "$item_nineslice_size|default" : [ 0.0, 0.0, 0.0, 0.0 ],
+ "$scroll_background_texture" : "textures/ui/ScrollRail",
+ "alpha" : 1.0,
+ "anchor_from" : "center",
+ "anchor_to" : "center",
+ "clip_offset" : [ 0, 0 ],
+ "clips_children" : false,
+ "enabled" : true,
+ "layer" : 0,
+ "max_size" : [ 0, 0 ],
+ "min_size" : [ 0, 0 ],
+ "offset" : [ 0.0, 0.0 ],
+ "priority" : 0,
+ "propagate_alpha" : false,
+ "size" : [ 120, 20 ],
+ "type" : "panel",
+ "visible" : true
+ }
+}
```
@@ -1712,38 +1776,40 @@ UI编辑器暂时不支持编辑
其中官方封装了地图界面基类 MiniMapBaseScreen 供开发者扩展。
```json
-"mainPanel@mini_map.mini_map_wrapper" : {
- "anchor_from" : "top_right",
- "anchor_to" : "top_right",
- "layer" : 1,
- "offset" : [ -10.0, 10.0 ],
- "$enable_live_update": false,
- "$live_update_interval": 5,
- "$use_default_face_icon": true,
- "$face_icon_size": [4,4],
- "$face_icon_bg_color": "white",
- "$highest_y": 0
- // 如果希望小地图能够被裁剪,请继承后修改controls如下:
- "controls":[
- {
- "mini_map_bg@mini_map.mini_map_bg": {}
- },
- {
- "netease_mini_map@mini_map.netease_mini_map": {
- "allow_clipping":true,
- "enable_scissor_test" : true
- }
- },
- {
- "icon@mini_map.icon": {}
- },
- {
- "head_lbl@mini_map.head_label": {}
- },
- {
- "text_lbl@mini_map.text_label": {}
- }
- ]
+{
+ "mainPanel@mini_map.mini_map_wrapper" : {
+ "anchor_from" : "top_right",
+ "anchor_to" : "top_right",
+ "layer" : 1,
+ "offset" : [ -10.0, 10.0 ],
+ "$enable_live_update": false,
+ "$live_update_interval": 5,
+ "$use_default_face_icon": true,
+ "$face_icon_size": [4,4],
+ "$face_icon_bg_color": "white",
+ "$highest_y": 0,
+ // 如果希望小地图能够被裁剪,请继承后修改controls如下:
+ "controls":[
+ {
+ "mini_map_bg@mini_map.mini_map_bg": {}
+ },
+ {
+ "netease_mini_map@mini_map.netease_mini_map": {
+ "allow_clipping":true,
+ "enable_scissor_test" : true
+ }
+ },
+ {
+ "icon@mini_map.icon": {}
+ },
+ {
+ "head_lbl@mini_map.head_label": {}
+ },
+ {
+ "text_lbl@mini_map.text_label": {}
+ }
+ ]
+ }
}
```
@@ -1764,12 +1830,14 @@ UI编辑器暂时不支持编辑
该控件可以用于在ui上绘制渐变颜色
```json
-"gradient": {
- "color1": [1, 0, 1, 1],
- "color2": [0, 0, 1, 1],
- "gradient_direction": "vertical",
- "renderer": "gradient_renderer",
- "type": "custom"
+{
+ "gradient": {
+ "color1": [1, 0, 1, 1],
+ "color2": [0, 0, 1, 1],
+ "gradient_direction": "vertical",
+ "renderer": "gradient_renderer",
+ "type": "custom"
+ }
}
```
@@ -1874,6 +1942,10 @@ ScreenNode = clientApi.GetScreenNodeCls()
### UI界面初始化
```python
+import mod.client.extraClientApi as clientApi
+
+ScreenNode = clientApi.GetScreenNodeCls()
+
class TestScreen(ScreenNode):
def __init__(self, namespace, name, param):
ScreenNode.__init__(self, namespace, name, param)
@@ -1884,32 +1956,32 @@ ScreenNode是我们的UI节点基类,必须继承。
```python
# Bind Type
class ViewBinder(object):
- ButtonFilter = 0x10000000
- BF_ButtonClickUp = 0 | ButtonFilter
- BF_ButtonClickDown = 1 | ButtonFilter
- BF_ButtonClick = 2 | ButtonFilter
- BF_ButtonClickCancel= 3
- BF_InteractButtonClick = 4
- BindFilter = 0x01000000
- BF_BindBool = 5 | BindFilter
- BF_BindInt = 6 | BindFilter
- BF_BindFloat = 7 | BindFilter
- BF_BindString = 8 | BindFilter
- BF_BindGridSize = 9 | BindFilter
- BF_BindColor = 10 | BindFilter
- EditFilter = 0x00100000
- BF_EditChanged = 11 | EditFilter
- BF_EditFinished = 12 | EditFilter
+ ButtonFilter = 0x10000000
+ BF_ButtonClickUp = 0 | ButtonFilter
+ BF_ButtonClickDown = 1 | ButtonFilter
+ BF_ButtonClick = 2 | ButtonFilter
+ BF_ButtonClickCancel = 3
+ BF_InteractButtonClick = 4
+ BindFilter = 0x01000000
+ BF_BindBool = 5 | BindFilter
+ BF_BindInt = 6 | BindFilter
+ BF_BindFloat = 7 | BindFilter
+ BF_BindString = 8 | BindFilter
+ BF_BindGridSize = 9 | BindFilter
+ BF_BindColor = 10 | BindFilter
+ EditFilter = 0x00100000
+ BF_EditChanged = 11 | EditFilter
+ BF_EditFinished = 12 | EditFilter
ToggleFilter = 0x00010000
- BF_ToggleChanged = 13 | ToggleFilter
+ BF_ToggleChanged = 13 | ToggleFilter
+
# Return Type
class ViewRequest(object):
- Nothing = 0
- Refresh = 1 << 0
- PointerHeldEventsRequest = 1 << 1
- PointerHeldEventsCancel = 1 << 2
- Exit = 1 << 3
-
+ Nothing = 0
+ Refresh = 1 << 0
+ PointerHeldEventsRequest = 1 << 1
+ PointerHeldEventsCancel = 1 << 2
+ Exit = 1 << 3
```
### UI绑定和返回
@@ -1940,19 +2012,25 @@ bind_flag为上文中绑定类型,binding_name为绑定名称。
binding_name为脚本绑定变量,binding_name_override为引擎变量,json格式如下
```json
- "bindings" : [
- {
+{
+ "bindings": [
+ {
"binding_condition" : "always",
"binding_name" : "#scoreboard_grid.item_count",
"binding_name_override" : "#StackGridItemsCount"
- }
- ]
+ }
+ ]
+}
```
对应的Python代码如下
```python
- @ViewBinder.binding(ViewBinder.BF_BindInt, "#scoreboard_grid.item_count")
- def OnStarkGridResize(self):
- return len(self.scoreBoardList)
+import mod.client.extraClientApi as clientApi
+
+ViewBinder = clientApi.GetViewBinderCls()
+
+@ViewBinder.binding(ViewBinder.BF_BindInt, "#scoreboard_grid.item_count")
+def OnStarkGridResize(self):
+ return len(self.scoreBoardList)
```
**binding_collection(bind_flag, collection_name, binding_name = None)**
@@ -1962,38 +2040,46 @@ bind_flag为上文中的绑定类型,collection_name为集合名称,binding_
集合的json如下:
```json
-"collection_name" : "scoreboard_stackgrid"
+{
+ "collection_name" : "scoreboard_stackgrid"
+}
```
在集合的子控件中,binding_collection_name为集合名,binding_condition为绑定条件,binding_name为绑定名称,binding_type为collection绑定,property_bag设置他的初始值,text为它的绑定值。
```json
- "label_score_board" : {
- "bindings" : [
- {
- "binding_collection_name" : "scoreboard_stackgrid",
- "binding_condition" : "always",
- "binding_name" : "#label_score_board.text",
- "binding_type" : "collection"
- }
- ],
- "offset" : [ "0%+0 px", "0%+0px" ],
- "property_bag" : {
- "#label_score_board.text" : "666666666666"
- },
- "text" : "#label_score_board.text",
- "text_alignment" : "left",
- "type" : "label",
- "visible" : true
- },
+{
+ "label_score_board" : {
+ "bindings" : [
+ {
+ "binding_collection_name" : "scoreboard_stackgrid",
+ "binding_condition" : "always",
+ "binding_name" : "#label_score_board.text",
+ "binding_type" : "collection"
+ }
+ ],
+ "offset" : [ "0%+0 px", "0%+0px" ],
+ "property_bag" : {
+ "#label_score_board.text" : "666666666666"
+ },
+ "text" : "#label_score_board.text",
+ "text_alignment" : "left",
+ "type" : "label",
+ "visible" : true
+ }
+}
```
对应的Python代码如下,其中index表示在集合中的哪一元素。
```python
- @ViewBinder.binding_collection(ViewBinder.BF_BindString, "scoreboard_stackgrid", "#label_score_board.text")
- def OnRefreshScoreBoardLabel(self, index):
- return self.scoreBoardList[index] if len(self.scoreBoardList) > index else ""
+import mod.client.extraClientApi as clientApi
+
+ViewBinder = clientApi.GetViewBinderCls()
+
+@ViewBinder.binding_collection(ViewBinder.BF_BindString, "scoreboard_stackgrid", "#label_score_board.text")
+def OnRefreshScoreBoardLabel(self, index):
+ return self.scoreBoardList[index] if len(self.scoreBoardList) > index else ""
```
## 接口调用说明
@@ -2009,10 +2095,11 @@ bind_flag为上文中的绑定类型,collection_name为集合名称,binding_
假设设置Mod名称为"myModName",示例:
```python
- @Mod.Binding(name = "myModName", version = "0.1")
- class MyModClass(object):
- def __init__(self):
- pass
+from mod.common.mod import Mod
+@Mod.Binding(name = "myModName", version = "0.1")
+class MyModClass(object):
+ def __init__(self):
+ pass
```
### 界面创建流程及生命周期
@@ -2089,7 +2176,7 @@ bind_flag为上文中的绑定类型,collection_name为集合名称,binding_
使用方法如下所示
-```json
+```html
// 定制化文本控件
```
-```json
+```html
// 在非标签的内容
Dear player,
welcome to Minecraft,
where you can build your own world
```
-```json
+```html
// 按钮控件
// 注意:如果按钮控件空间不足以显示该字符串,多余部分将以"..."显示