大家好,我是猫狗喵
一步步教你在地图中套用名条动画
1. 首先下载 Font Animation Creator 这个程序
度的我写的,这两天才赶工把他改写成图形接口的程序所以写得很丑
原码都附在里面了,想改写请注明原作,然后如果有 BUG 可以跟我说但我不见得会修
2. 解压缩到文件夹后会看到下面四个文件,运行 Font Animation Creator.exe 就对了
3. 点开后等他一段时间会出现下面这个画面
功能解释:
- A:动画要导入哪一个资源包文件夹内,右边的按钮可以选择文件夹
- B:添加一张图片列表 E 时,该画格缺省的停留时间
- C:列表 E 中目前选择的画格停留的时间
- D:选择一个 GIF 档导入列表 E
- E:动画画格列表,顺序由上到下,可以用拖曳的方式调整画格顺序
- F:添加一张图片到列表 E,要注意所有图片都会置中对齐
- G:移除列表 E 选择中的画格
- H:清空列表 E 的内容
- I:预览动画效果,在游戏中会显示原本的大小,但分辨率最高就是如预览的这样
- J:当你在游戏里绕着图片跑的时候,他会以哪边为旋转轴面向你
- K:如何把当前动画间隔转换成 minecraft 中的动画间隔,不懂就用默认值就好
- L:把列表 E 的内容转换成 minecraft 的名条动画,并在目标资源包内保存相关素材
4. 全部设置好后按「创建」按钮,他会叫你帮动画文件取一个名字,高兴取什么都行
5. 创建完成后会跳出字体档存放的文件夹,里面有一个 mcfunction 文件,就是用来生成名条动画的
6. 下载倒退字符资源包,把它的内容全部丢进你自己的资源包里面
要注意使用这个资源包是需要原作表示的,不过内容的修改等等就完全没有限制
7. 在这里下载 Font Animation datapack 这个数据报,或是在 Font Animation Creator 的文件夹里面也有。把它丢到你地图的 datapacks 文件夹里面
8. 上一步的数据报有安装成功的话,进去游戏应该会看到安装成功的消息。
这时候就可以把上面的 summon.mcfunction 丢到自己的数据报里面,并且运行来看看效果了!
如何?是不是真的超简单?这次大家总该把这技术拿来用了吧?
如果大家有使用这套工具的话希望可以在地图中注明一下,不过真的没标注我也不会咬你就是了
如果你想知道其中的一些选项实际有什么功能,可以跳到最后选项效果解说的部分来看
动画名条的原理教学
============== 正文开始 ===============
- 如何让文本图片照顺序更替?
(如果你在这边想到用 list 的作法的人不要急,这作法我后面再讲)在过去版本中最直觉的想法应该是:透过分数穷举对应的文本图片。不过穷举这种东西就是浪费性能,又没有泛用性,每次做新的动画就要再穷举一次、多做一套连闪侦测不过到了 1.16 出了自订字体档后就不一样了,在游戏中我们可以不用穷举自动依串行出文本的方式就是数字显示,不管是记分板还是 nbt 数值,我们可以轻易的运算然后用 json 格式显示出来。如果还不清楚如何把分数写进 json 字符串可以看这篇,我过去都是用 loot table 法不过听说告示牌法比较省,所以现在也换成告示牌法了。有了依串行出文本的方式后,我们只要把图片对应的数字文本写进自订字体档,然后在我们的 json 字符串声明使用的字体就可以了。
那这边又会遇到两个问题:
1. 要怎么声明我们 json 字符串要用哪个字体?
声明字体好像很单纯,只要把 font 写进 json 里面就好了,然而问题在于怎么知道要写什么 font 进去。如果每个动画个别使用不同的 json 声明,那还是没有解决穷举法一个动画需要一套连闪的问题
这时候就要用一点小技巧了,那就是利用 json 解析的特性
常用 json 生成器的人应该会发现,生成器产生的中括号 […] 的内容,开头第一个对象基本上都是空字符串,以前我也一直觉得意义不明,后来才知道它的功能是什么。在 WIKI 页面中也有提到格式的继承关系。如果你用 data get 把中括号解析后的新字符串抓出来看会发现,中括号其实就是被解析成第一个对象 extra 其它对象的格式
利用这个特性,我们只要把字符串以中括号或 extra 形式写好,第一个对象填入我们要的字体格式的空字符串,第二个对象填入我们要显示的数字就完成了。不过这里又会遇到一个小问题
怎么针对每个不同的动画填入不同字体的空字符串?
我的作法是事先写好,以字符串形式存在显示名条的实体身上,例如 ‘{“text”:””,”font”:”test:main”}’。然后当要解析 json 的时候,只要用 json 当中的 nbt 搭配 interpret 的效果就可以还原出那个有字体的空字符串了。
2. 数字只有 10 个,动画画格数超过 10 个怎么办?
要想打破数字的数量限制,势必得使用更多的字体档。在上一个问题我们已经知道要把有字体的空字符串存在名条实体身上,那接下来的问题就是
要怎么存更多的字体,并且依序替换?
我的作法很简单,就是使用 list 来保存那些字符串,解析 json 时固定填入 list 的第一项,然后每显示完 10 个一组的数字就把 list 第一个对象移除掉。
听到这里,一开始就想到 list 法的人应该已经按耐不住了 我这不是来了吗.jpg
我也是在打这篇文章的时候才想到,其实还有一套不需要数字,也不需要多个字体档的作法。那就是事先把每个画格的图片存成自订字体档中的各个文本,然后把那些文本全部依序存在 list 里面,这样我们只要每个画格显示 list 的第一个字,然后移除第一个 list 的对象就搞定了
说到这里,感觉好像制作名条动画的工具都已经俱备了,但其实还有一个小问题还没解决
每个画格的停留时间该怎么设置?
我们刚刚说的「每次」更换一个显示的文本,原则上就是每 tick 运行一次。但是 1 tick 就是 50 毫秒,先不考虑实际动画中每个画格的停留时间常常不是 50 毫秒的整数倍的问题,假设现在同一个动画中有的画格停留 100 毫秒,有的停留 200 毫秒,我们要怎么处理呢?
或许你会想到另外再开一个 list 保存每个画格的停留 tick 数量,不过这个方法有点复杂,也需要比较多的运算。这里我采用的方法是:一个画格不够,那不会再一个吗?
以我的显示数字的作法来说,假设第一个画格会停留 200 毫秒,那我就把 0123 四个数字全部都设置成同样的图片不就搞定了吗(茶
那如果你用 list 法原理也是一样,同样的一个字塞四次就解决了
到这里一套优雅的,免穷举的名条动画显示系统就完成了。只需要一套连闪,召唤的时候填入不同的字符串就会自动显示不同的动画。下一步要提到的则是进一步优化相关的技巧,如果对系统性能不在意的可以跳到下个分隔线后,关于 Font Animation Creator 部分选项效果解说的部分
- 如何透过 药水云(area_effect_cloud) 来当显示名条的实体?
或许有些人还不清楚,不过药水云在性能上比起盔甲架或掉落物等实体节省了 10 倍左右,因此非必要的情况下使用药水云作为实体可以大幅节省资源于是我就在想这个功能是不是可以只用药水云来达成,显示名条的部分只要是实体就能做到,用药水云绝对没问题。问题出在字体的 list 该存在哪里盔甲架或掉落物可以透过道具字段的虚拟 nbt 轻松创建一个字符串的 list 来访问字体 (还不知道虚拟 nbt 是什么的自己回去看这篇),但是药水云可就没有那种方便的东西了。翻遍药水云的 nbt 数据不要说是字符串 list 了,就连字符串都找不到几个。撇除 CustomName 是我们要用的,剩下的字符串数据就只有 Particle 而已,设成原版没有的 particle 还会被强制改回去。就在打算放弃的时候突然想到还有一个东西可以用,那就是所有实体都可以有的 Tags不过如果你直接开开心心的把那些字体的 json 字符串丢进 Tags 你会发现,那个顺序是在哈啰?如果他是单纯的单个数字的字符串,看起来好像又会照顺序,但只要加上其他字以后整个顺序就找不出规律了。这时候有点程序 sense 的人应该就会猜到,结合这个摸不着头绪的顺序,以及内容不能重复的特性,答案就是……没错 Tags 是用 HashSet 去存的,没学过程序的只要知道他会经过一串数学公式去得出他所属的位置就好了那因为 Java Edition 的 Minecraft 是用 Java 写的(废话),可是我又查不到 Java 的 Hash 公式是什么,为了验证我把人生第一次写 Java 的经验就用在这上面了。(后来听强者我同学说 Java String 的 Hash 公式是把第一个字符乘以 31 再加下一个字符,重复以上动作到最后一个字。不过不知道溢出的话怎么处理,我也懒得验证所以就算了)而 Font Animation Creator 当中我给 Tags 排序的方法就是先丢进 Java 程序存到 HashSet 再吐回来给我,想要的可以直接运行 PrintSet.exe 那个文件,输入几个字符串然后用空格隔开,他就会回传 Hash 后的顺序了,或是你直接开 Minecraft 把 Tags 写进去再抓结果也可以知道顺序。那知道 Tags 的顺序之后我们就可以像一般字符串 list 那样使用 Tags 来访问数据了,要注意的只有不能给它乱加其他的 tag 进去,要不然你不知道他被排到哪,哪天他就被拿来当成字体格式字符串你都不知道另外前面提到的完全用 list 来保存每个画格要显示内容的方法,在这边也需要一些调整。前面提到如果一个画格要显示 4 tick 那你就要把同样的图片文本塞 4 个进去,但是 Tags 是不可重复的,也就是说你没办法塞 4 个相同的字进去 Tags 里面,这时候你就必须同一张图片用 4 个不同的字来显示,而且这 4 个字的顺序要排在一起,在计算顺序的时候相对来说麻烦了一点
Font Animation Creator 部分选项效果解说
- 图片分辨率与大小关系
- 图片锚点功能解说
- 帧分割公式解说
- 时间门槛法
这个算法的逻辑非常直觉,就是我每个 50 毫秒(红线位置)都个别判断现在处于哪个原始画格的范围内(包含开头,不含结束),以上图来说,红色的 0, 50, 100 都属于第一个画格,150, 200 属于第二个画格,以此类推直到 600 毫秒的瞬间就消失了,也不用再切换画格了一般情况下都建议使用这个算法,虽然偶尔会有画格延迟的感觉出现,但是 50 毫秒的间距并不会让这个感觉太明显。使用这个算法的优点是可以较还原原始动画的速度,并且在很多画格的停留时间小于 50 毫秒的时候,可以节省一些未使用到的画格图片的文件时间门槛法还原枫谷天怒特效(每个画格固定 120 毫秒),偶尔有卡顿的感觉但不明显
- 最小间距差法
这个算法其实也很直觉,只是有些特殊状况需要处理。这个算法的结果就如上图绿线所示最小间距差,顾名思义就是最小化「显示的画格停留时间」,与「实际画格停留时间」的差距以上图来说,各个画格停留的时间依序为 120, 90, 120, 90, 150 毫秒在以 50 毫秒为最小单位的情况下,最接近的停留时间依序为 100, 100, 100, 100, 150 毫秒,也就是上图中绿线的分布情形这个算法的优点是,当原始动画的各个画格停留时间很稳定,但并不是 50 毫秒的整数倍时,它可以有效的保持原始动画的流畅度,而不会有画格延迟的感觉出现然而相对来说它就会导致动画的播放有变速的感觉,假设原始画格停留时间固定是 60 毫秒,用这个算法跑出来的动画就会有快进 1.2 倍的效果(显示的画格停留时间都是 50 毫秒)而所谓的的特殊状况就是,当原始画格停留时间小于 25 毫秒时,这个画格最接近的停留时间就会变成「0」,没错毫无悬念直接死去。这就代表假如你把 40 FPS 以上的动画丢进这个算法里面,你会发现就跟把钱丢进枫谷的金苹果一样,噗通一声就不见了为了避免这样的状况,所以我的程序在运行这个算法的时候,有限制每个画格最小的停留时间就是 50 毫秒,虽然这样就不会丢东西进去然后什么都没跑出来,不过你会体会到什么叫做「世界越快,心则慢」的超级慢动作特效最小间距差法还原枫谷天怒特效(每个画格固定 120 毫秒),有了快进 1.2 倍的效果