有問題的可以再來詢問我們!
李育衡:hank93513@gmail.com
劉哲佑:
在本系統中 地圖 的儲存分為:
後端有對 Map List 做 pagnation
所以先 Get Map List by offset & limit
原本的 Get Map List 只會有 map_id , 還需要前端重新 loop 過所有 map_id 去打 S3 presigned Url
後來改為後端 Get Map List 也會順便回傳 Image 的 presigend Url
以 UI / UX 角度,比較難在 3D 空間編輯地圖
所以可以在 上視圖 ( 2D ) 會比較好編輯
以滑鼠從 A 拖到 B 點(還沒放開時):顯示 Preview
放開後:再實際畫在地圖中
Features:
原本掃出來的 Map 是非常破碎的,所以需要這些工具來把地圖完善
Tool:
Three.js !
Why Three.js : 擴充性 -> Eg: 未來 MiniMap 要改成 3D 呈現
所有看到的 「東西」 在 Three.js 都是 物件
包括 輔助網格、半透明遮罩、畫上去的方塊 都是一個個 物件
intro to render 、 scene 與 plane
場景
我們所有 Three.js 的物件都加在 場景 中
在接下來 renderer 會用到
也可以想成鏡頭
Three.js 有提供
相機成像的結果來比較:
Camera Scene VS Image
https://medium.com/@gopisaikrishna.vuta/exploring-cameras-in-three-js-32e268a6bebd
可以看到 PerspectiveCamera
會有透視的效果
而 OrthographicCamera
對無論距離遠近的物件,成像大小都相同
因為我們要實作的是 2D Editor
需要使用 OrthographicCamera
來避免 raycast 位置與 滑鼠座標換算差異 的問題
Camera Error Image
選染器
在更新畫面時,我們需要 call renderer.render
來依據相機 和 場景
renderer.render(this.scene, this.camera);
如果 scene 多了 A 方塊,跑完
renderer.render
後
畫面就會多生成 A 方塊
Trois.js 是為 Vue 包裝好 Three.js 的 Package
這邊採用 Trois.js 的好處是:
接著只需要在 script 中以 ref 來直接引用
以滑鼠從 A 拖到 B 點(還沒放開時):顯示 Preview
放開後:再實際畫在地圖中
Features:
startPosition : set when onMouseDown
currentPosition : set when onPointerMove
endPosition : set when onMouseUp
當遇到以上 3 個 event 時 (onMouseDown
, onPointerMove
, onMouseUp
)
都會更新畫面中的物件
再 call render
來 實際更新畫面
function render() {
renderer.render(scene, camera);
}
Why Preview Utility ?
一開始沒有預覽功能: 完全不知道畫到哪裡
在一開始有說到 所有東西 都是 Object
所以我們可以先將 半透明的預覽方塊 加入 previewList
當要下次要 render 前,先清除 previewList
中的物件
再重新加入該輪新的預覽方塊!
這邊是開一個 Map
( 這邊叫他 currentState
)
以 {x},{y}
作為 Key
如果 {x},{y}
不是 None
代表
x,y
座標有物件
當遇到 onMouseUp
事件
在 pop 出所有 previewList
中的物件時
可以順便取得物件的座標,就可以加上實際的方塊
同樣也是 onMouseUp
事件
會把剛剛提到的 currentState
( 紀錄座標是否有物件的 Map
)
存到 historyList
中
By codpilot XD
要在網格座標中從 A 畫一條直線到 B 可以使用
Bresenham's line algorithm
主要是透過計算 A , B 兩點之間的斜率達成
Bresenham's line algorithm 圖
https://zh.wikipedia.org/wiki/布雷森漢姆直線演算法
GIF of fill tool
要在封閉區塊中填滿方格
可以使用 BFS
By setTimeout
接著會將 plane 中的 物件 依據座標建成 List
再向後端更新
後端會再向 S3 更新 Map 的 json
我們同樣是透過 renderer.render
來更新畫面的
在更新主要 Editor 畫面時,同時 call MiniMap 的 renderScene
那要如何把 MiniMap 的縮圖存成 png
打向後端呢?
可以透過
抓到 Three.js 生成的 canva
使用 canvas.toDataURL("image/png");
再將 URI 轉成 blob 即可
這邊使用 Vuex 來處理跨 Conpoent 共享狀態的問題
有空會嘗試把 使用 Three.js 實作 2D 畫布編輯器 包成 NPM Package !