2016年11月11日 星期五

LimeJS : hitTest

最近寫了一個將物體拖曳到天平秤重的程式,原本的程序是利用 ['mousedown','touchstart'] 來觸發 Drag 事件,不過 LimeJS 預設會在最後將物體移到 DropTarget 上,也就是秤盤的中心點上,這樣的畫面實在很不自然,在不知道要將移動物體位置的程序安插在哪個事件中的情形下,只好放棄使用 drag 的相關事件,改在 ['mouseup','touchend', 'touchcancel'] 時用「hitTest」來判斷是否已將物體拖曳至秤盤上。

查看了 LimeJS 的 node.js 中的「hitTest」,它其實是抓參數的 .screenPosition 值(一般為滑鼠的所在位置),並利用 screenToLocal 轉換為要和要檢查是否碰撞物體同一系統的座標。

這下又產生新問題了,以將物體放到秤盤上來說,一般人的直覺會在滑鼠指標對準物體的中心左右按下滑鼠開始拖曳,然後當物體的邊緣碰到待測試的東西邊緣時可能就放開滑鼠按鍵,這樣一來,滑鼠指標的位置並不會在秤盤上,測試兩物體是否「碰撞」,理所當然就傳回 false。

為了解決上述的問題,只好修改測試碰撞的座標,改以物體邊緣的座標來測試。

LimeJS 裡, node.js 中的「hitTest」原本應該傳一個 lime.events.Event 型態的 e Event object 來當參數,不過,看 hitTest 的原始碼,它是要抓 e.screenPosition,所以我們只要傳一個物件,且帶有一個名為 screenPosition 的座標變數給它即可(記得先轉為 screen 的座標系統)。

以拖曳 sprite 這個物體為例,具體的程序如下:

var pos =  new Object();
pos.pos = sprite.getPosition();
pos.pos.y += sprite.getSize().height*2/3;
pos.screenPosition = sprite.getParent().localToScreen(pos.pos);

上面把測試的座標往下移 2/3 個 sprite 高度,因為我們起算的座標都是以 sprite 的觀點,而 sprite 是存在於它的 parent 中,所以我們用 sprite.getParent().localToScreen 來轉換座標,算出它的 screenPosition。

處理完座標後,我們就可以利用底下的語法來測試 targetObject 和 sprite 是否碰撞了

 targetObject.hitTest(pos) 


LimeJS 除了 localToScreen ,還有 localToNode 和 localToParent 可以用來轉換座標,滿值得研究的。


沒有留言:

張貼留言

 
© 2009. Design by Pocket