2009年7月17日 星期五

DisplayObject上層擋到下層滑鼠事件問題


有一個常遇到但是一但遇到老是不求甚解的就把它解決掉的問題,這幾天在處理一個案子的時候又遇到了。
在AS3裡,位於上層的DisplayObject會阻擋滑鼠事件,所以會導致較下層的物件無法接收到滑鼠事件。這理論上看起來是合理的,只是問題的發生點通常都是在我們常會忽略掉的地方,那就是透明圖層。
設計師們常常會利用PNG的透明背景來處理一些效果,而我們也常常忘了這個PNG其實是一個方形的存在,因此就會在Runtime時遇到明明看起來沒東西的地方但是滑鼠事件就是不會work的狀況。

Ok,解決的方法就是將擋到的DisplayObjec的mouseChildren及mouseEnabled設為false。通常這樣也都可以解決問題。
但是這次我遇到的狀況比較不一樣,才發現事實沒這麼簡單。
我這次的狀況是,場景上一個MovieClip(簡稱MC_A)裡面有動畫,其中有一個按鈕。但是很不幸的這些動畫擋到了場景上的另一個MovieClip(簡稱MC_B)裡的按鈕。(請注意MC_A及MC_B是位於同一個DisplayObjectContainer裡)
很直覺的我用一個迴圈將所有MC_A裡除了按鈕以外的DisplayObject的mouseChildren及mouseEnabled都設為false,感覺這樣就可以解決問題,但是很遺憾發佈後MC_B還是一樣被MC_A的一些東西擋住(這些東西我都已經設成mouseChildren及mouseEnalbed為false了)。
於是我做了一些實驗,我在MC_A裡把MC_A的按鈕都放到最低的層級裡,把動畫都拉上來,如果我沒跑迴圈去將動畫的mouseChildren及mouseEnalbed設為false的話,MC_A裡的按鈕及MC_B裡的按鈕都不能work。但如果我有跑迴圈,那麼只有MC_B裡的按鈕會無法work。
有些人也許已經知道是怎麼回事了。

照這種情況看起來,MC_A裡面的DisplayObject其mouseChildren及mouseEnabled屬性只會在MC_A這個DisplayObjectContainer裡生效,對於MC_B這個與MC_A存在於同樣一個層級的物件來說,MC_A的「滑鼠有效範圍」仍然是整個MC_A的所有範圍。
因此在MC_A裡不管怎樣的最裡面的mouseChildren或mouseEnabled做操作,對於MC_A以外的物件來說,它們只認識MC_A自己的mouseChilren及mouseEnabled。

在這個案例裡,由於我的MC_A裡還有按鈕,所以我不可能將整個MC_A自己的mouseChilren及mouseEnabled設為false,因為這樣一來我MC_A裡的按鈕也跟著廢掉了。
最後我才知道我忽略了一個很簡單的解決方法,那就是直接將MC_A的hitArea屬性設為按鈕實際的感應區域就好了。這樣子對MC_B來說,MC_A的實際「滑鼠有效範圍」就會被改變了。

2 則留言: