將你的 sprite hitArea 套上完美的 polygons 吧!
PixiJS 很好玩,你一定要試試!
1. 前言
PixiJS 是個很龐大的 2D 渲染引擎,使用後,你會發現更多美麗的事物。
2. 動機
最近使用 PixiJS 時,在 sprite 的滑鼠事件上遇到了點問題。
情境說明:
我們隨意找一張圖,下圖為 PixiJS 範例圖。
該圖大小為 119x181 且為透明背景的可愛河童。
如果你為它寫一個 pointertap 觸碰事件,會發生什麼事?
const app = new PIXI.Application({
width: 200,
height: 200,
});
document.body.appendChild(app.view);
const sprite = PIXI.Sprite.from('https://pixijs.io/examples/examples/assets/flowerTop.png');
sprite.buttonMode = true;
sprite.interactive = true;
sprite.addListener('pointertap', () => {
alert('Hola');
});
app.stage.addChild(sprite);
- buttonMode:為了方便辨識,在此設定讓滑鼠移入可觸發範圍時的指標為 pointer 樣式
點選了河童,看起來沒問題!
但接下來,你試著將滑鼠移動到右下角的 「黑色區域」 ...!?
居然能夠觸發觸碰事件,而且滑鼠指標也呈現 pointer 樣式。
為什麼會這樣?
因為 sprite 預設 hitArea 為圖片本身的大小,包含了那些透明區域。
在理想上,當然會希望僅在 「看得見」的地方 trigger!
因此,如何鎖定在看得見的圖片是個問題!
接下來開始撰寫解決的辦法!
2. 工具
目前找到的工具是 PhysicsEditor,不過他只有七天的試用期。
如果有長期需求,當然建議可以給他買下去,約台幣 $800/year 不到~
安裝完畢後啟動,試著加入圖片吧!
[ Add sprites ]
接著使用如同魔術棒的輪廓偵測工具,捕捉圖形邊框。
[ Shape tracer ]
由於我們使用 PixiJS,在右側 Exporter 中,請選擇 Phaser (P2)。
[ Exporter ]
最後將多邊形匯出成 JSON 格式。
[ Publish ]
仔細看看它的 JSON 結構:
它是由數個多邊形組合而成的喲!
{
"flowerTop": [
{
"shape": [ 27.5,145, 32.5,138, 30.5,152, 27.5,149 ]
},
{
"shape": [ 41.5,176, 32.5,138, 89.5,141, 92.5,150, 90.5,152, 61.5,176, 54,180.5, 44,180.5 ]
},
]
}
- flowerTop:根據你的圖片而命名。
- shape:該集合為其中一個多邊形的座標點。
3. 套件
接下來可使用套件 hitarea-shapes 將該輪廓套至 sprite 中。
3.1 安裝
npm install --save pixi.js hitarea-shapes
# 或者
yarn add pixi.js hitarea-shapes
當然,你也可以在 html 中使用 CDN:
<script src="https://unpkg.com/hitarea-shapes"></script>
如果你不想使用該套件,你可以參考 pixi-poly 是如何實踐出輪廓問題的。
因為 hitarea-shapes 是筆者參考並調整一些程式碼後發佈出來的~
3.2 載入模組與多邊形
如果你是以模組化架構開發,那就直接 import 或 require 進來~
import HitAreaShapes from 'hitarea-shapes';
import data from 'flowerTop.json';
如果你的環境選擇使用 cdn,也沒有 babel ,
那你可以參考 hiarea-shapes example,先用 fetch 將多邊形 JSON 檔案載入。
然後再實例一個 HitAreaShapes。
3.3 實例與套用
直接把 sprite.hitArea 設為剛剛建立好的實例即可!
// Your sprite
// ...
const hitAreaShapes = new HitAreaShapes(data);
sprite.hitArea = hitAreaShapes;
3.4 結果
再次看看網頁結果!
當滑鼠在黑色區域進行觸碰 (click/tap) ,並不會 trigger 囉~
同時指標也不會呈現 pointer ~
4. 後記
大家也來學學 PixiJS 吧~
本篇方法也許不是最好,誤打誤撞學習道路上有你有我。
也歡迎提出更棒的做法!!
有勘誤之處,不吝指教。ob'_'ov