《DFQ》開發隨錄——圖集

  歡迎參與討論,轉載請註明出處。
  本文轉載自:https://musoucrow.github.io/2018/06/23/dfq_sheet/

前言

  在遊戲開發的領域裏,圖集(SpriteSheet)是一個很重要的概念,其好處在鏈接處也已言明。但若是引擎沒提供相關的支持,那麼便需要自己搞個解決方案了。而LÖVE也恰好是沒有提供相關支持的,那麼只好自己動手豐衣足食了,本文便記錄其中心得。

裝箱問題

  要實現圖集的核心便是對圖片進行拼合打包,其實類似的工具市面上亦有存在(如TexturePacker)。從功能上而論,TexturePacker完全可以滿足需求(有提供命令行模式,可實現自動化)。可惜TexturePacker的免費版根本不堪使用,而破解也相繼失敗。而其他類似的工具要麼無法滿足需求,要麼不支持macOS。只好自己手寫一套了。
  實現的圖集的難點無非在於拼合時圖片排列的算法,由Claris告知得這種屬於裝箱問題,目前並無最優解。由裝箱問題爲關鍵字進行展開搜索,發現一種名爲MaxRectsBinPack的算法可解決問題,我將之翻譯成了Python版。如此裝箱問題便解決了。

拼合問題

  接下來的問題便是“誰和誰拼合成一張圖”了,我對此立下三個原則:

  • 關聯性不高者不拼(拼成大圖的代價便是成爲資源共同體,如果關聯性不高的拼合一塊則會造成極大的內存浪費)
  • 黑底與透明者不拼(黑底圖拼成大圖必須得保證全圖無透明點,否則遊戲裏會出現奇怪的線條)
  • 拼合後過大者不拼(需保證圖片大小在4096*4096及以下,否則恐怕出現上限問題)

      以這三原則來看,是無法做到以文件夾爲單位進行粗暴的拼合了。所以採用了編寫配置的方式進行。

"effect": {
    "map": {
        "lorien": [
            "lorien",
            "/actor/article/lorien/pathgate",
            "/actor/article/lorien/largegrass"
        ]
    },
    "death": [
        "death",
        "dieFlash"
    ],
    "buff": {
        "freeze": "freeze"
    }
}

  配置以JSON形式存儲,配置中的key代表着合圖文件夾的層級,value則爲欲拼合的圖片文件夾,若無/開頭則代表以當前文件夾層級爲路徑,反之則爲全路徑。以這套方案便可很自由地選擇拼合的方案了。

配置問題

  圖片的拼合問題解決後,便是遊戲要如何以最低的代價去兼容新的圖片形式了。解決方案自然是爲原圖片生成路徑一致的配置文件,遊戲通過讀取配置文件以無縫對接新的圖片形式。配置文件格式如下:

return {
    image = "ui",
    x = 0,
    y = 151,
    w = 45,
    h = 41
}

  配置文件記錄了所屬合圖的路徑以及在合圖中的座標寬高,如此便可清晰無比地取得了。由於Python的lupa模塊裝不上,爲此還專門寫了個Lua與JSON的轉換器

大小問題

  一般而言,因爲光柵化需要對紋理採樣進行快速取值,圖片大小需要遵循2的N次冪(256、512、1024…)。這種符合的圖片被稱爲POT(Power-Of-Two),同理不滿足的稱爲NPOT(Non-Power-Of-Two)。在早期POT紋理可以說是必須的,而今在OpenGL ES2.0後支持了NPOT。但爲了能滿足ETC壓縮以及兼容性,個人推薦還是對合圖進行POT化。

後記

  其實從這個問題來看,選擇流行的大引擎的確會更爲方便。在Unity裏可以由後臺自動完成的事情現在卻要一篇文章來總結,不過賊船已經上了,就只能走到黑了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章