簡易地圖


有了 p5.js 的圖片載入與貼圖功能,可以用來製作簡易的地圖,簡易指的是沒有地形起伏,只要利用簡單的陣列標示可行走路線、障礙物,根據標示來繪圖的純平面地圖,適合作為認識、製作地圖的入門範例。

例如,底下使用木板圖片代表道路,岩石紋理圖片代表不可行走區域,製作出由上往下俯視的平面地圖:

如果你想要有些變化,可以嘗試做 45 度視角的地圖,這不必用到什麼 3D,在圖片處理上,可以將正方形的圖片轉 45 度,然後高度縮分為一半就能達到,例如,將以上範例的地板圖片改為斜角的版本就會是:

簡易地圖

p5.js 的 image 在繪製時支援透明度,也就是只要拼接以上的圖片,就可以繪製斜角地圖,那麼要怎麼拼接呢?也是利用轉動、平移公式來計算座標嗎?這也是可以啦!只不過還要旋轉感覺麻煩了些,簡單一些的方式是平移就可以,例如 yi 為 0 的第一列,可以如下平移:

簡易地圖

上圖的 wh 分別代表圖片的寬高,類似地,你可以計算第二列、第三列…只不過算寬高位移其實易出錯,更簡單的方式是基於座標的基向量(base vector)計算,例如在由上往下俯視的地圖繪製時,其實就是基於基向量 (w, 0) 與 (0, h) 在計算,只不過因為正好是直角,就不寫出 0 的分量罷了:

簡易地圖

如果由上往下俯視地繪製平面地圖時,使用向量來計算的話會是:

若現在要改為斜角地圖呢?基向量會是:

簡易地圖

因此只要修改上頭範例的圖片尺寸為斜角圖片尺寸,並修改基向量為 (w/2, h/2)、(-w/2, h/2)(順便調一下最左上角的圖片起點),就可以變成斜角地圖了:

基於向量來計算,可以簡化不少程式的撰寫,例如,若想判定滑鼠按下的位置,可以歸屬於哪一塊圖片範圍內,對於由上往上俯視的地圖來說,就算不是基於向量來實作,單純如這篇文章第一個範例數寬高的方式來實現也很容易,然而如果是斜角地圖呢?數寬高的方式在計算上就會複雜一些了!

若是基於向量的話就簡單多了,任意在一點按下的話:

簡易地圖

上圖中,(x, y) 與 (x', y') 間的關係為 (x, y) = x' * (w/2, h/2) + y' * (-w/2, h/2),整理一下並以用矩陣表示的話就是:

簡易地圖

接著求反矩陣可得到:

簡易地圖

知道 (x', y'),就可以知道滑鼠點選應該算在哪一格了,也就是格子索引可取 (floor(x'), floor(y')),實作為程式話就是:

範例中使用了 p5.js 的 tint 函式,這可以指定顏色與透明度等,為原圖「著色」,更精確點地說,指定的值會除以 255,再與對應的顏色值相乘,以上例 tint(255, 128, 255) 來說,就是將原圖的 r * 255/255,g * 128/255,b * 255/255,得到新的顏色後繪製,執行後可點選地圖中任一格,該格就會以不同的顏色顯示就是了。