前端瓦片地圖加載之塞爾達傳說曠野之息

聲明:本文涉及圖文和模型素材僅用于個人學習、研究和欣賞,請勿二次修改、非法傳播、轉(zhuǎn)載、出版、商用、及進行其他獲利行為。

原項目地址:https://bbs.a9vg.com/forum.php?mod=viewthread&tid=5207596&page=1&authorid=951893

背景
玩了《曠野之息》整整三年,《王國之淚》都發(fā)布了,都還沒有救出公主???
。 最近公司有地圖加載的需求,于是想以?曠野之息
?地圖為例,學習實踐一下前端開發(fā)相關(guān)的地圖知識,本文內(nèi)容主要介紹通過使用瓦片地圖加載原理,實現(xiàn)?塞爾達曠野之息
?地圖加載并添加交互錨點。
實現(xiàn)效果

在線預(yù)覽:https://dragonir.github.io/zelda-map
基礎(chǔ)知識
瓦片地圖 `??`
在游戲開發(fā)過程中,經(jīng)常會遇到超過屏幕大小的地圖,例如在即時戰(zhàn)略游戲中,它使得玩家可以在地圖中滾動游戲畫面。這類游戲通常會有豐富的背景元素,如果直接使用背景圖切換的方式,需要為每個不同的場景準備一張背景圖,但是每個背景圖都不小,這樣會造成資源浪費。
瓦片地圖就是為了解決此類問題產(chǎn)生的,一張大的世界地圖或者背景圖可以由幾種地形來表示,每種地形對應(yīng)一張小的的圖片,我們稱這些小的地形圖片為瓦片。把這些瓦片拼接在一起,一個完整的地圖就組合出來了,這就是瓦片地圖的原理。

瓦片地圖金字塔模型是一種多分辨率層次模型,從瓦片金字塔的底層到頂層,分辨率越來越低,但表示的地理范圍不變。?首先確定地圖服務(wù)平臺所要提供的縮放級別的數(shù)量?N
,把縮放級別最高、地圖比例尺最大的地圖圖片作為金字塔的底層,即第?0
?層,并對其進行分塊,從地圖圖片的左上角開始,從左至右、從上到下進行切割,分割成相同大小的正方形地圖瓦片,形成第?0
?層瓦片矩陣;在第?0
?層地圖圖片的基礎(chǔ)上,按每像素分割為?2×2
?個像素的方法生成第?1
?層地圖圖片,并對其進行分塊,分割成與下一層相同大小的正方形地圖瓦片,形成第1層瓦片矩陣;采用同樣的方法生成第?2
?層瓦片矩陣;…… 如此下去,直到第?N-1
?層,構(gòu)成整個瓦片金字塔
。

瓦片地圖一般采用
ZXY規(guī)范
的地圖瓦片。(瓦片層級
、瓦片?x坐標
、瓦片?y坐標
)
墨卡托投影
瓦片地圖采用的都是墨卡托投影,即正軸等角圓柱投影,又稱等角圓柱投影, 是圓柱投影的一種,由荷蘭地圖學家墨卡托(Gerhardus Mercator
)擬定?;驹硎羌僭O(shè)地球被圍在一中空的圓柱里,其基準緯線與圓柱相切(赤道)接觸,然后再假想地球中心有一盞燈,把球面上的圖形投影到圓柱體上,再把圓柱體展開,這就是一幅選定基準緯線上的?墨卡托投影
?繪制出的地圖。百度地圖、高德地圖及?Google Maps
?使用的投影方法都是墨卡托投影。

瓦片地圖不用自己生成,有很多工具可以用來制作瓦片地圖,
Tiled
、Arcgis
?等都是非常流行的制作工具。

實現(xiàn)
在本例中,塞爾達曠野之息
瓦片地圖來源網(wǎng)絡(luò)開源地圖,加載瓦片地圖使用?Leaflet
?web
?地圖庫,開發(fā)之前簡要了解一下。
Leaflet.js
Leaflet ?? (https://leafletjs.com)
?是一個為建設(shè)交互性好適用于移動設(shè)備地圖,而開發(fā)的現(xiàn)代的、開源的 JavaScript 庫。使用它我們可以部署簡單,交互式,輕量級的Web地圖。
代碼僅?
33 KB
,但它具有開發(fā)在線地圖的大部分功能。允許使用圖層,
WMS
,標記,彈出窗口,矢量圖層(折線,多邊形,圓形等),圖像疊加層和?GeoJSON
?等圖層。可以通過拖動地圖,縮放(通過雙擊或滾輪滾動),使用鍵盤,使用事件處理以及拖動標記來與?
Leaflet
?地圖進行交互。瀏覽器支持桌面端?
Chrome
、Firefox
、Safari 5+
、Opera 12+
、IE 7-11
?以及?Safari
、Android
、Chrome
、Firefox
等手機瀏覽器。
代碼實現(xiàn)
在頁面的?head
?標簽中引入?Leaflet
的?css
?文件和?js
?文件。在想要創(chuàng)建地圖的地方創(chuàng)建一個帶有?id
?的?div
,示例中用?#mapContainer
?元素承載地圖。
需要確保地圖有一個明確的高度, 可以在?CSS
?中添加如下全屏顯示的樣式。
現(xiàn)在地圖的初始化已經(jīng)完成了,這一步進行瓦片地圖加載。
L.LatLngBounds(西南角點,東北角點)
:通過定義矩形西南角點和東北角點來創(chuàng)建經(jīng)緯度的矩形框。setView
:初始化地圖,并將其視圖設(shè)置為我們所選擇的地理坐標和縮放級別。L.tileLayer
:加載瓦片圖層。addTo
:顯示地圖。

確保所有代碼都在用于顯示地圖的?
div
?和?leaflet.js
?包含之后調(diào)用。默認情況下(因為我們在創(chuàng)建地圖實例時沒有設(shè)置任何參數(shù)),地圖上的所有鼠標事件和觸摸交互功能都是開啟的,并且它具有縮放和屬性控件。
此時我們在頁面中對地圖進行拖動、縮放等操作,并打開瀏覽器控制臺查看?network
?中的?img
?選項,隨著操作的觸發(fā),不同的地圖瓦片被瀏覽器加載顯示。

塞爾達曠野之息
?地圖非常大,據(jù)國外?油管阿婆主
?測試,林克從最北走到地圖最南端需要?20
?多分鐘。在如此宏大的地圖上進行游戲,探索的神廟、地圖塔、人馬等怪物點等位置需要花很大精力,如果使用已有數(shù)據(jù)進行標注,可以節(jié)省很多精力(但也失去了探索的樂趣???
)。此時可以利用?Leaflet
?的地圖標注功能,在地圖上進行標記。其中標注數(shù)據(jù)來源于網(wǎng)絡(luò)資料。以下內(nèi)容以神廟???
?為例,實現(xiàn)在瓦片地圖上的標注和交互功能。
L.marker([x, y])
:除了瓦片之外,可以輕松地在地圖中添加其他東西,包括標記、折線、多邊形、圓圈和彈出窗口。L.divIcon
: 自定義圖標。bindPopup
: 彈出窗口通常用于將某些信息附加到地圖上的特定對象上。
至此,通過遍歷,將數(shù)據(jù)中神廟的坐標點添加到了地圖上,同時在dom結(jié)構(gòu)中添加了點擊事件,點擊神廟可以進行交互。

使用同樣的方法,可以將地圖塔、村莊、人馬、呀哈哈???
、回憶點、子任務(wù)點等位置信息標注在地圖中方便查找。


總結(jié)
使用瓦片地圖,可以做到地圖的整體和局部都能高清展示,并且能夠做到按需加載,需要注意的是,分層較多的地圖瓦片圖片也會指數(shù)增長,需要做好緩存處理,這樣就能提升地圖頁面加載速度,提升用戶體驗。leaflet.js
?雖然很輕量,但是功能非常強大,本例中只用到它的一些基礎(chǔ)功能,其他高級用法還要在后續(xù)開發(fā)中繼續(xù)探索。
想了解其他前端知識或其他未在本文中詳細描述的Web 3D開發(fā)技術(shù)相關(guān)知識,可閱讀我往期的文章。如果有疑問可以在評論中留言,如果覺得文章對你有幫助,不要忘了一鍵三連哦 ??。
附錄
[1].??? Three.js 打造繽紛夏日3D夢中情島
[2].??? Three.js 實現(xiàn)炫酷的賽博朋克風格3D數(shù)字地球大屏
[3].??? Three.js 實現(xiàn)2022冬奧主題3D趣味頁面,含冰墩墩
[4].??? Three.js 實現(xiàn)3D開放世界小游戲:阿貍的多元宇宙
[5].??? Three.js 進階之旅:全景漫游-高階版在線看房
…
【Three.js 進階之旅】系列專欄訪問 ??
更多往期【3D】專欄訪問 ??
更多往期【前端】專欄訪問 ??
參考
塞爾達曠野之息地圖標注來源:https://github.com
瓦片地圖生成工具?
Tiled
?項目:https://www.mapeditor.org瓦片地圖生成工具?
arcgis
:https://developers.arcgis.com開放地理空間實驗室?
Leaflet.js
:?http://webgis.cn/leaflet-index.html墨卡托投影:https://baike.baidu.com/item/%E5%A2%A8%E5%8D%A1%E6%89%98%E6%8A%95%E5%BD%B1
https://www.cnblogs.com/fwc1994/p/6519229.html
ZXY標準瓦片?http://support.supermap.com.cn/DataWarehouse/WebDocHelp/iServer/Subject_introduce/Cache/MapCache/TileFormat/ZXY_format.htm
