跳到主要内容

阵法图形编辑器

一座阵法用 mxt:particle 模块描出来的图形,是一份独立的 mxt:formation_shape 定义:模块的 shape 指向它,客户端读自己那份定义去铺尘埃。这份定义存成 data/<命名空间>/mxt/formation_shape/<名字>.json。

下面这台编辑器画出那份定义的 strokes,Copy JSON 拿走整份定义(含 {"strokes": [...]} 外壳)。坐标是阵法半径的倍数:1 就是阵列自己的环,所以一份图形跟着每一座读它的阵法一起缩放。棋盘是俯视的阵列,+X 向右(东)、+Z 向下(南)、北朝上,两个轴的端头各写着方位字母与它所在的坐标(环上是 1,另一个方向是 -1)。

怎么画​

  • 折线:点出各个顶点,Enter、右键或双击收笔,Esc 丢掉这一笔。
  • 圆:按下的地方就是圆心,拖出半径。圆心不必在阵心,阵心自己有吸附点,所以想放阵心仍然是一次点击。之后拖圆心或它的起点可以改位置、半径与朝向。
  • 拖顶点改形状,列表里的 ⇄ 把一笔倒过来(生长方向也跟着倒),✕ 删掉一笔,Ctrl+Z / Ctrl+Y 撤销重做。
  • 吸附三件事让正多边形精确而不是"差不多":0.05 网格、环(r = 1)、以及圆的 N 等分——N 根从阵心射出的线,第 0 根正东、每 360/N 度一根。环与等分压过网格,所以正多边形的顶点不会被网格二次取整。
  • 生成器:Star N/K 按 FormationShape 的 {N/K} 规则写(每一步的首尾相接成一笔),5/2 就是本体自带的 mxt:five,6/2 是 mxt:six(两个三角),8/2 是 mxt:eight(两个方);K = 1 就是普通的 N 边形。N-gon 写一笔闭合折线,Rays 把 N 根射线写成 N 笔。三个生成器都能撤销。
  • 上色:每一笔自己带 color,写法是纯色十六进制或一串 {"at": …, "color": …} 的渐变(at 从那一笔的第一点到最后一点,必须升序,两端之外保持端点色)。文件里没有整体兜底色,所以一笔必须带色——新笔用 new strokes 那个颜色。工具条下面那条彩条就是选中的这一笔的渐变:点它加一个节点,拖标记移动节点,+ stop / − stop 增删节点。
  • 生长窗口:start / end 是这一笔占用的进度区间,图形的进度映射到它上面。所以 start: 0.5 就是"后半段才画这一笔",两笔一前一后写就能接力。窗口必须开(start < end),工具会让两个输入框互相避让,不会写出交叉的值。
  • 疏密与大小:spacing(每多少格一颗尘埃)与 size(尘埃画多大)也是每一笔自己的,默认 0.33 与 2。外环稀、内层密是可以的,等于默认值时这两个字段不进文件。

它在算什么​

  • 点数是游戏的算法:每一笔要 ceil(那一笔的格数 / 它自己的 spacing) + 1 个点,按你写的 radius 算,所以读数就是那一帧客户端被要求画的量。每一笔封顶 2048 点,超了远端被丢掉——工具会先把这件事报出来。
  • 生长不是工具设置:每一笔都按自己的窗口被截断,同一个窗口的几笔一起长。滑块就是那个进度,Play 按 duration_ticks(20 tick 一秒)从第一笔的起点演到最后一笔的终点。
  • speed 与 loop 只属于预览(默认 1× 就是游戏的节奏,duration_ticks: 24000 那种画法值得放慢,20 tick 的值得加快),以及旁边那个时钟读的是 已过 / duration_ticks。这三样都不会写进文件,duration_ticks 是模块的字段,也不是图形的。
  • 线也在动:lines 把每一笔从它的起点描到进度走到的地方(圆按角度扫,折线按弧长走),关掉 dust 就只看图形被写出来;还没走到的地方留着灰色的幽灵,所以半程的图仍然能改,进度 0 也不是一块空棋盘。

写出来的是什么​

{
"strokes": [
{"type": "mxt:circle", "radius": 1, "color": [{"at": 0, "color": "#80c0ff"}, {"at": 1, "color": "#ffffff"}]},
{"type": "mxt:polyline", "points": [[1, 0], [-0.809, 0.588], [0.309, -0.951], [0.309, 0.951], [-0.809, -0.588], [1, 0]], "color": "#ffd76a"}
]
}

type 是注册表 id,命名空间必须写全:写 "circle" 会被当成 minecraft:circle,整份定义加载失败。编辑器读得进不带命名空间的写法,读回来会补成 mxt:circle 再写出去。

只有 radius(阵法自己的半径)和预览开关不进文件——它们在这儿只是为了让点数和尘埃大小算得准。

接下来​