如何製作圖磚地圖 — 搭配免費編輯器的逐步指南
打造你自己的圖磚地圖
從零開始學習如何製作圖磚地圖 — 圖磚集、網格、圖層、碰撞與自動拼接。跟著步驟操作,接著在瀏覽器中免費打造並遊玩你自己的作品。
學習製作圖磚地圖,重點多半在於依正確順序做出四項決定:格子大小、圖磚集的排列方式、圖層堆疊,以及碰撞要放在哪裡。這些決定只需做一次,之後繪製地圖就會變成機械化的流程。
以下步驟採用我們在 Neta Studio 中,把一段文字描述變成可遊玩世界時所用的順序:挑選或生成圖磚集、固定網格、先鋪出地形再處理細節、切分圖層,最後交由自動拼接處理邊緣。這裡的一切都不需要安裝。編輯器在瀏覽器中執行,而且下方每個數值之後都能修改,不必重畫地圖。
什麼是圖磚地圖?(清楚定義 + 圖解)
圖磚地圖是一張索引網格,而不是一張圖片網格。每個格子儲存一個整數,指向圖磚集裡的某一張圖磚;渲染器會查出該索引,並在格子位置繪製那張圖磚。一張 20 乘 12、格子為 32 px 的地圖,就是 240 個整數,涵蓋 640 乘 384 像素。
這種間接參照正是關鍵所在。一張草地圖磚在圖磚表裡只存一次,卻能被數百個格子引用,因此地圖檔案能維持精簡並快速載入。由於圖磚地圖是資料而非美術成品,你可以用雜訊函式生成它、把它當成文字編輯、在 Git 中比對兩個版本,或隨著攝影機移動分區串流載入。
本頁最上方的圖解,是用我們自己的圖磚,在 12 乘 8、每格 32 px 的網格上組成。草地填滿內部,沙地沿著左側與底部邊緣延伸,水則位於沙地結束處的右下角。把它當成資料來讀:第 3 欄、第 0 列的格子存放草地索引;第 0 欄、第 7 列的格子存放水的角落索引;其餘每個格子都存放單純的沙地索引。原點在左上角,x 向右遞增,y 向下遞增。如果你的引擎使用左下角原點,地圖會上下顛倒,直到你把列索引改為總列數減 1 再減 y。
- 網格欄與列,在地圖建立時就固定下來。20 乘 12 的地圖與 40 乘 24 的地圖,在相同的攝影機縮放下,行為差異極大。
- 格子大小單一格子所佔的像素範圍:16、32、48 或 64。它必須與圖磚集的圖磚大小完全一致,否則取樣會落在圖磚中間。
- 圖磚的集合索引所指向的圖片,以及它有多少欄與多少列的定義。
- 索引圖層每個圖層的每個格子各有一個整數。地面圖層是密集的,細節圖層大多為空,而碰撞圖層存放的是標記而非美術圖。
什麼是圖磚集?(以及它有何不同)
圖磚集是那本圖畫書;圖磚地圖則是引用它的那一頁。圖磚集擁有像素:一張圖磚表,加上一條規則說明這張表例如是 8 欄、每欄 32 px 的圖磚。圖磚地圖擁有的則是配置:哪個索引位於每個圖層的每個格子裡。
這兩個詞經常被混用,因為大多數編輯器把它們並排顯示在同一個面板中,也因為單一檔案格式可能隱藏了這道區分。在 Tiled 中,這道區分是明確的,圖磚集檔案與地圖檔案各自獨立。在 Unity 中,Tile 資產存放精靈圖,Tilemap 元件存放格子。在 Godot 中,TileSet 與圖磚地圖圖層是各自獨立的資源。
實際後果是:更動圖磚集會改變所有引用它的地圖,而更動圖磚地圖只會改變一個關卡。把 32 px 的圖磚表換成 48 px 的圖磚表,每個索引仍然能解析,但所有地圖現在都會以不同比例繪製,並可能在邊緣取樣到相鄰的圖磚。請把圖磚集視為一個附有版本號的已發佈介面。
| 項目 | 圖磚集 | 圖磚地圖 |
|---|---|---|
| 存放的內容 | 每張圖磚的像素資料 | 每個圖層的每個格子一個索引 |
| 磁碟上的是什麼 | 一張圖片加上格子大小的定義 | 一串整數加上對圖磚集的引用 |
| 由誰編輯 | 美術人員 | 關卡設計師或生成器 |
| 何時會變動 | 美術風格或比例改變時 | 版面改變時,包括每一次試玩調整 |
步驟 1:挑選或製作圖磚集
你有兩條路:沿用現成的圖磚表,或自行生成一張。現成的圖磚表較快,但你得沿用它的色盤、格子大小與授權條款。在它之上建了四十張地圖之前,先檢查授權,並確認它是網格式圖磚表,而不是打包式圖集。圖集儲存的是每張圖磚的矩形座標,而非統一的格子,這會讓索引更困難,自動拼接也變得彆扭。
如果地形必須符合特定色盤,就生成它。Agent Sprite Forge 能依文字描述產出格子大小一致的圖磚表,藉此消除最常見的錯位來源:某張圖磚寬達 33 px,只因美術人員在格子外多加了亮部。
無論走哪條路,第一遍都不是在畫圖,而是在量測。以 100% 縮放開啟圖磚表,數一數欄與列,並把格子大小寫在團隊其他成員找得到的地方。
- 單一格子大小每張圖磚的寬高都相同,包括大部分為空的圖磚。若匯出工具依閱讀順序打包,32 px 圖磚表中只要有一張 33 px 的圖磚,就會使其後每個索引全部位移。
- 真正的透明要用透明通道,而不是白色。帶有不透明白色背景的圖磚表,會在瀏覽器中於你的天空上畫出白色方塊。
- 有文件記錄的網格記錄欄數、列數,以及是否有內距。索引計算是列乘以欄再加欄,從零起算,由左至右、由上至下讀取。
- 間隙的決定帶有內距的圖磚表會在格子之間加入 1 或 2 px,以減少材質滲透,代價是取樣計算中多了一個位移量。在下第一筆之前,先決定你要用哪一種。
步驟 2:設定你的圖磚大小與網格
格子大小取決於三件事:玩家實際遊玩時的縮放、你的目標渲染解析度,以及你願意繪製多少美術。在 1920 px 寬的視埠上,16 px 的圖磚可橫向容納 120 格,每螢幕涵蓋大量關卡,卻幾乎沒有空間表現細節。64 px 的圖磚可容納 30 格,並有足夠像素畫出一棵辨識度良好的樹。
硬性限制在於算術。格子大小必須能整除圖磚表。一張 256 px 寬的圖磚表,在 32 px 下正好是 8 欄;在 48 px 下則是 5.33 欄,因此最後一欄只是圖磚的一小部分,其後每個索引都會偏移。圖磚表的尺寸不是美感選擇,而是格子大小的倍數。
使用整數縮放。如果視埠不是網格的整數倍,格子就會落在半像素上,篩選會取樣到兩張相鄰圖磚,整張地圖便會出現一條像素的接縫。請從兩端修正:在引擎中使用最近鄰居篩選,並讓攝影機縮放為整數。
| 格子大小 | 適合什麼 | 要注意什麼 |
|---|---|---|
| 16 px | 小型角色、每螢幕高格子數、以程式生成的地圖 | 幾乎沒有空間表現細節;三色的樹看起來像一團色塊 |
| 32 px | 俯瞰與平台遊戲地形的折衷選擇 | 美術必須畫在 32 px 網格上,否則放在其他圖磚旁會顯得突兀 |
| 48 px | 較為厚實的俯瞰外觀,道具辨識度高 | 每螢幕格子較少,因此稀疏的地圖會顯得空洞 |
| 64 px | 細節豐富的美術、低格子數、擠出成 3D 的地圖 | 若每個格子只用一個碰撞器,碰撞會顯得粗糙 |
步驟 3:先繪製地面,再處理細節
分階段繪製,而且永遠先畫地形。地形是你會改動的部分;裝飾則是你不想移動的部分。先放置六十棵樹,接著把海岸線往左移四格,那些樹就會突然全部站在水裡。
從單一圖磚開始。用一個草地索引鋪滿整張地圖,以遊玩縮放檢視整體輪廓,然後才讓自動拼接處理邊緣。細節要等形狀定案後再處理,碰撞則在細節之後,因為發現某個道具可以走過去,是碰撞設定的修改,而不是重畫。
玩家看得見的一切都要繪製。空白格子會顯示渲染器在地圖後方所繪製的內容,而那通常不是你想要的背景。在攝影機上設定背景顏色,比依賴清空的畫布更保險。
01
建立地面圖層,並用一個地形索引填滿整張地圖。先不要做自動拼接。
02
鋪出形狀:先畫水,再畫懸崖,每一種都只用單一圖磚。完全先不管邊緣。
03
以遊玩縮放檢視輪廓,而不是 400% 放大。如果形狀現在看不出來,之後也一樣看不出來。
04
輪廓定案後,為每種地形執行自動拼接,並在每次編輯地形後重新執行。
05
加入細節圖層:道具、貼花、草叢。保持稀疏,因為稀疏看起來才像刻意安排的。
06
最後再繪製碰撞圖層,依據你實際保留的細節,而不是你原先規劃的細節。
步驟 4:加入圖層、深度與碰撞
圖磚地圖一旦拆分成圖層,就不再扁平。最小可用的堆疊是三層:密集的地面圖層、稀疏的細節圖層,以及完全不含美術的碰撞圖層。如果地圖中有任何東西應該遮住玩家,就值得及早加上一層位於角色上方的覆蓋圖層。
深度來自同一套網格。在俯瞰地圖中,依每個物件的底邊排序:腳底位置最低者最後繪製。對圖磚而言這不費功夫,因為格子的 y 已經編碼了位置。對會移動的角色,你需要逐物件排序,並加上一個確定性的平手處理規則,通常是物件的 y 再加上它在格子內的小數位移。少了這個規則,同一列上的兩個物件會在不同影格之間閃爍。
碰撞會以一個相同尺寸的平行陣列對應到網格上。在圖磚集裡給每張圖磚一個實心標記,這樣繪製一道牆時也會把它標為實心,並用碰撞圖層做逐地圖的覆寫。逐格標記無法表達斜坡、單向平台,或位於格子內部的薄牆。那些屬於疊在網格之上的獨立物件,而不是圖磚地圖。
- 地面圖層密集:每個格子都存放一個索引。這是唯一能安全進行自動拼接的圖層。
- 細節圖層稀疏,且空白處為透明。樹木、岩石、貼花。這裡的任何東西都不該意外阻擋移動。
- 覆蓋圖層繪製在角色上方:樹冠、橋樑、屋頂。任何應該遮住玩家的東西。
- 碰撞圖層不含美術。一個與地圖同大小的布林陣列,初始由圖磚集的實心標記填入,並針對例外情況手動編輯。
步驟 5:自動拼接與 47 圖磚集
自動拼接是那種會悄悄出錯的部分。一張有八個鄰居的地形圖磚,有 2 的 8 次方,也就是 256 種可能的鄰居組態。只有在兩個相鄰邊都填滿時,角落才有意義,而這個對稱性把 256 種情況收斂成 47 張獨特的圖磚。這就是為什麼大多數引擎與編輯器每種地形都使用一套 47 圖磚集,並依文件化的版面排列。
你也會遇到 16 圖磚集,它只讀取四個側邊鄰居而忽略角落;以及 2x2 迷你圖磚集,其中每個格子都由四分之一圖磚拼成,因此 13 到 16 張迷你圖磚就能涵蓋所有情況。16 圖磚集較容易繪製,但產生的角落較為生硬。迷你圖磚做法所需的圖片較少,卻強迫你以四分之一為單位來製作每種地形,這會讓像素藝術變得柔和。
如何製作能自動拼接且不留縫隙的圖磚地圖
遮罩就是整套機制。對每個格子,用它的八個鄰居組成一個 8 位元整數:位元 0 代表北、位元 1 代表東北、位元 2 代表東,依此類推順時針排列。挑一個順序,把它寫在程式碼旁邊,並且永遠不要更動。差一個位元的遮罩仍會產生看似合理的地形,這就是為什麼不一致的慣例能潛伏數個月,才有人發現角落是錯的。
接著把遮罩轉換成圖磚索引。有兩種做法:完整的 256 筆查表,容易生成,也容易除錯,因為你可以把那一列印出來;或是 47 筆的查表加上一個對稱函式。除非目標平台記憶體受限,否則請採用完整查表。它能消除整整一類的角落錯誤。
在接上自動拼接之前,值得先了解的自動拼接失敗模式
地圖邊緣的接縫,來自對超出範圍的格子處理不一致。一次決定好地圖外的世界是空的、還是相同地形,並把這條規則套用到每種地形。
第二個常見的失敗是覆寫。自動拼接會重寫它負責的格子,因此任何你為了特定外觀手繪的單一圖磚,都會在下一輪消失。你要嘛在自動拼接後鎖定地形圖層,要嘛把手動覆寫存到另一份最後才執行的清單中。
01
在圖磚表中為每種地形保留一個 47 圖磚的區塊,並讓各種地形各自成塊,而不要交錯排列。
02
定義鄰居位元順序,並把它記錄在使用它的程式碼旁邊的註解裡。
03
對每個格子,從八個鄰居計算遮罩,並依你選定的規則處理超出範圍的格子。
04
在 256 筆的查表中查找該遮罩,取得該地形的 47 個索引之一。
05
當某個格子改變時,只重新計算它與它的八個鄰居。每次筆刷落下就重建整張地圖,是常見的效能錯誤。
06
當你對地形圖層滿意時就凍結它,否則你手動放置的圖磚會在下一輪被覆寫。
可以打開來玩的圖磚地圖範例
閱讀一張能運作的地圖,比閱讀關於它的描述學到更多。The Cyclops' Island 是一張可遊玩的地圖,建立在單一地形集上,並有獨立的碰撞圖層。沿著海岸線走,觀察沙地轉為水的交界處在哪裡更換圖磚:那些就是實際使用中的 47 種組合情況。
Mini World 是較小的範例。打開它來看看圖層堆疊——地面、細節與覆蓋——並看看只需多麼少的細節圖磚,就能讓一張地圖讀起來像完成品,而不是空洞。
3D 遊戲建構器採用同一套網格並將其擠出。每個格子變成一個方塊,碰撞圖層變成垂直的牆,而 y 排序則在 Three.js 場景中成為真正的深度。如果你的 2D 地圖條理一致,3D 版本幾乎不費成本;如果圖層混雜,擠出後會立刻暴露出來。
- The Cyclops' Island一張可步行的地圖,用來在遊玩速度下,而非編輯器縮放下,研究自動拼接的地形邊緣。
- Mini World一張小網格,讓你不必捲動就能檢視圖層堆疊。
- 3D 遊戲建構器同一張圖磚地圖擠出成方塊,其中碰撞圖層成為幾何,而深度也成為真實。
圖磚集範本下載(PS / Aseprite 網格)
範本只是繪圖輔助,並非必要。它是一張透明畫布,每一格都有參考線,安全區域有 1 像素的內縮標記,頂列與左欄沿邊有索引編號,讓你在繪製時看得出索引會落在哪裡。在它上方作畫,匯出前再把它隱藏。
讓範本符合專案。一張 512 乘 512 的畫布,可容納 16 乘 16、每格 32 px 的網格。在 16 px 的格子下,同一個檔案可容納 32 乘 32 的網格,這時你應該降低參考線的不透明度,因為在那樣的密度下,參考線會蓋住圖。
01
以格子大小的倍數建立畫布:32 px 格子用 512 乘 512,16 px 格子用 256 乘 256。
02
在 Aseprite 中,把網格大小設為你的格子大小,並啟用貼齊,讓圖磚落在完整的格子上。
03
在 Photoshop 中,使用欄數與你的圖磚表相符的參考線版面,間隙為零、邊界為零,或每隔 32 px 手動放置一條參考線。
04
把範本保留為獨立圖層,包含參考線、1 px 內縮外框與索引標籤,在你工作時置於圖稿上方。
05
關閉反鋸齒與工具平滑。以反鋸齒匯出的像素藝術,在邊緣無法乾淨地拼貼。
06
隱藏範本圖層,並以含透明度的 PNG-24 匯出,同時保留分層檔案,讓範本能在下一次編輯時繼續使用。
走進它所屬的世界
精靈圖是一個無處可站的角色。最後這一步是其他人都不提供的:把你剛做好的圖磚表放進一個有人可以走動的世界——一座小島、一顆行星、一個下雨的街角。本網站上的每個世界,都由一段文字描述製作而成,並發佈成一個可以遊玩的頁面。
FAQ
什麼是圖磚地圖? +
一張索引網格,每個格子指向圖磚集中的一張圖磚。渲染器查出該索引,並在格子位置繪製那張圖磚,因此一張 20 乘 12、32 px 的地圖就是 240 個整數,涵蓋 640 乘 384 像素。
圖磚地圖與圖磚集有什麼不同? +
圖磚集是圖片加上它的格子大小;圖磚地圖則是引用它的配置資料。更動圖磚集會改變所有使用它的地圖,而更動圖磚地圖只會改變一個關卡。
圖磚地圖最理想的圖磚大小是多少? +
任何能整除你的圖磚表、並以整數縮放的大小都行。32 px 是 2D 地形常見的折衷選擇,16 px 適合小型角色與高格子數,而 64 px 則適合細節豐富、每螢幕格子較少的美術。
什麼是自動拼接?我需要 47 圖磚集嗎? +
自動拼接會依格子的鄰居,挑選要用的邊緣與角落圖磚。一套 47 圖磚集在套用對稱性後涵蓋全部 256 種八鄰居情況,而只考慮側邊的 16 圖磚集較容易繪製,但角落較為生硬。
我可以在瀏覽器中免費製作圖磚地圖嗎? +
可以。Neta Studio 的編輯器在瀏覽器中執行,因此你可以依文字描述生成地圖,或親手繪製一張並直接遊玩,完全不需要安裝任何東西。
我要如何把圖磚地圖匯入我的引擎? +
把圖磚表匯出成 PNG,並把配置資料匯出成索引的 JSON 或 CSV,然後確認格子大小、欄數與原點都符合引擎的預期。使用左下角原點而非左上角,會讓地圖上下翻轉。
圖磚地圖可以是等角的嗎? +
可以。格子會變成菱形,而你要依列加欄排序,而不是依 y 排序。高度需要第二個圖層,碰撞則變成一個交錯的網格,不再對應單純的矩形陣列。
我要如何從零開始製作圖磚? +
以最終的格子大小繪製,絕不要放大,並在繪製圖磚表其餘部分之前,先用每張圖磚組成 3 乘 3 的區塊測試它。把邊緣重疊維持在一個像素,並使用一組固定的少數色盤作畫,這樣在不同時間點製作的圖磚仍能彼此搭配。
回到 3D 遊戲建構器
全部 31 個完成的 3D 世界、遊戲與場景都在同一頁——每一個都能遊玩。