大家好,我是貓狗喵
一步步教你在地圖中套用名條動畫
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 倍的效果