昨天聊到碰撞是什麼,又如何在 Matter.js 中發生,相關函式扮演的角色等等。不知道大家還記不記得一個廣告:
https://www.youtube.com/watch?v=o6Yn6HzP2bM
我們之前的碰撞,都是讓引擎自然發生處理的,我們也沒有對物體做事情,就好像腳踏車壓到阿嬤的腳,阿嬤你怎麼沒感覺?我們今天要讓阿嬤,喔不是,物體知道他被撞到了,或是他撞到人了,不再沒感覺!
今天要來聊的是實作面一點的 ─ 如何知道兩物體發生碰撞,收到碰撞資訊後我們怎麼從訊號中得到我們需要的內容。
大家看到熟悉的場景,應該會發覺,沒錯,這裡又是我們的範例程式碼。
今天的Demo有針對 render 的 options 做一些設置,讓大家可以看到一些細節。
目前碰撞我預設行為是任何碰撞事件都會讓 Runner 暫停,暫停後請持續按 Run the Runner 的按鈕來讓 Runner 繼續運行。
那我們可以先跑一次現在狀態,總共有兩個方形一個地面。
第一個是注意左上角的 Pair 數量的變動,也就是我們上篇提到的碰撞對, Pair 的變化如下:
透過這個觀察,相信大家有更了解Pair。
我們會用 Matter.js 中的 Event 模組來讓 Mater.js 在指定事件發生時執行指定的 Callback 函式。
Events 模組就三個方法,on 來掛上指定的 Event, off 來移除指定的 Event,trigger 針對物件觸發指定的事件。
Events 模組相對簡單,會在下面的例子直接讓大家看實際應用,想再確認 API 文件的讀者可以點上面的連結。
那我們來看一下我們是如何偵測碰撞的。
function AttachEvents()
{
Events.on(engine, "collisionStart", CollisionTriggered);
Events.on(engine, "collisionActive", CollisionTriggered);
Events.on(engine, "collisionEnd", CollisionTriggered);
}
在API文件 Engine 模組中的事件,我們可以看到範例代碼的這三個事件。
分別是 collisionStart, collisionActive, collisionEnd。
發生順序也是 collisionStart, collisionActive, collisionEnd。
除了碰撞到會暫停 Runner 以外,我們的 Callback 函式還會把當下丟進來的 event 印在 console.log,可以打開網頁中的開發者工具來應證這件事。
我們稍微看一下 Event 丟進來內容我們可以怎麼讀。
首先會看到第一層有三個物件:name, pairs, source。
name就是碰撞事件本身是哪個事件被觸發,這應該不用多說,型別會是字串。
source會是一些和 engine 或物體本身相關的參數內容,我們也不會特別讀取裡面的資料。
最重要的會是 pairs 這個陣列,裡面的 collision 就是我們的目標,可以透過 bodyA, bodyB 了解是哪兩個物體參與到這次的碰撞裡。
可以看看這段加在碰撞後 callback 函式中的範例代碼:
if(e.name == 'collisionStart' && e.pairs.length > 0 && e.pairs[0].bodyA.id == 1 && e.pairs[0].bodyB.id == 2)
{
e.pairs[0].bodyB.render.fillStyle = "green"
}
if(e.name == 'collisionStart' && e.pairs.length > 0 && e.pairs[0].bodyA.id == 2 && e.pairs[0].bodyB.id == 3)
{
e.pairs[0].bodyA.render.fillStyle = "#7DB4A2"
}
做的事情就是偵測碰撞事件、碰撞對象,當方塊 2 碰到 方塊1,則將方塊2 變色,而方塊2 再碰到地板時再進行二次變色。
參考這段代碼以及上面的解說,讀者應該能夠理解碰撞事件中的事件資訊回傳與對物體本身的操作。
碰撞的單元到此告一個段落,希望大家對碰撞都有所了解了,明天會來實作彈珠台中的球體碰撞後變色的部分。