明昀
Flash中碰撞檢測(cè)技術(shù)的研究與應(yīng)用
明昀
Flash是現(xiàn)今十分熱門的技術(shù),通過Flash可以實(shí)現(xiàn)動(dòng)畫、游戲和交互多媒體等應(yīng)用,功能強(qiáng)大。
本文重點(diǎn)討論采用Flash技術(shù)中使用actionscript進(jìn)行碰撞檢測(cè),并舉例說明其不同的使用方式,最后通過對(duì)一款平面飛行射擊游戲中碰撞檢測(cè)的設(shè)計(jì),來說明其具體應(yīng)用方法。
Flash; 碰撞檢測(cè)
在Flash actionscript 2.0中我們可以使用MovieClip 類的 hitTest() 方法來檢測(cè) SWF 文件中的沖突。它檢查某個(gè)對(duì)象是否與影片剪輯有沖突,然后返回一個(gè)布爾值(true 或 false)。我們可能想了解是否發(fā)生了沖突,以測(cè)試用戶是否已到達(dá)舞臺(tái)上的某個(gè)特定靜態(tài)區(qū)域,或確定一個(gè)影片剪輯何時(shí)到達(dá)另一個(gè)影片剪輯。利用hitTest() 方法,可以判定這些結(jié)果??梢允褂?hitTest() 的參數(shù)來指定舞臺(tái)上某個(gè)點(diǎn)擊區(qū)域的 x 和 y 坐標(biāo),或者使用另一個(gè)影片剪輯的目標(biāo)路徑作為點(diǎn)擊區(qū)域。在指定 x 和 y 時(shí),如果由 (x, y) 標(biāo)志的點(diǎn)是非透明點(diǎn),則 hitTest() 返回 true。當(dāng)目標(biāo)傳遞給 hitTest() 時(shí),會(huì)對(duì)兩個(gè)影片剪輯的邊框進(jìn)行比較。如果二者相交,則 hitTest() 返回 true。如果兩個(gè)邊框沒有相交,則 hitTest() 返回 false。hitTest具體用法為:
用法 1:根據(jù) shapeFlag 設(shè)置,將 x和 y 坐標(biāo)與指定實(shí)例的形狀或邊框進(jìn)行比較。如果 shapeFlag 設(shè)置為 true,則只計(jì)算在舞臺(tái)上的實(shí)例實(shí)際占據(jù)的區(qū)域,并且如果 x 和 y 在任意一點(diǎn)重疊,則返回true 值。此評(píng)估對(duì)于確定影片剪輯是否處于指定的點(diǎn)擊區(qū)域或熱點(diǎn)區(qū)域中很有用。參數(shù)x為舞臺(tái)上點(diǎn)擊區(qū)域的 x 坐標(biāo),y為舞臺(tái)上點(diǎn)擊區(qū)域的 y 坐標(biāo),x 和 y 坐標(biāo)都在全局坐標(biāo)空間中定義,shapeFlag為一個(gè)布爾值,指定是計(jì)算指定實(shí)例的整個(gè)形狀(true) 還是僅計(jì)算邊框 (false);只有當(dāng)用x 和 y 坐標(biāo)參數(shù)標(biāo)志點(diǎn)擊區(qū)域時(shí),才可以指定該參數(shù)。例如,鼠標(biāo)控制影片剪輯移動(dòng)。鼠標(biāo)在(坐標(biāo)_xmouse, _ymouse)影片剪輯test_mc上(與test_mc重疊或交叉)時(shí),test_mc向右移動(dòng)10個(gè)像素。此時(shí)可以在場(chǎng)景第1幀上使用test_mc執(zhí)行onEnterFrame事件處理函數(shù),并在函數(shù)中使用hitTest進(jìn)行判斷,即“if (this.hitTest (_xmouse, _ymouse, false))”,如果鼠標(biāo)坐標(biāo)與test_mc交叉或重疊(鼠標(biāo)在test_mc上),則test_mc橫坐標(biāo)增加10個(gè)像素“this. _x += 10”,test_mc橫坐標(biāo)大于或者等于500個(gè)像素時(shí)“if (this._x>=500)”,重新設(shè)置test_mc橫坐標(biāo)為0。
用法 2:計(jì)算target 和指定實(shí)例的邊框,如果它們?cè)谌我庖稽c(diǎn)上重疊或交叉,則返回 true。Target為可能與影片剪輯相交或重疊的點(diǎn)擊區(qū)域的目標(biāo)路徑。target 參數(shù)通常表示一個(gè)按鈕或一個(gè)文本輸入字段。例如,要把圓等6個(gè)圖形拖到上面對(duì)應(yīng)的文字上。6個(gè)圖形分別是tx1_mc~tx6_mc,6個(gè)對(duì)應(yīng)的文字都是動(dòng)態(tài)文本,名稱分別是wz1~wz6,每個(gè)mc拖動(dòng)的位置如果出錯(cuò)了能夠自動(dòng)回到原來的位置,當(dāng)6個(gè)mc都能正確拖到對(duì)應(yīng)位置上時(shí),主時(shí)間軸從第1幀跳到第2幀,并給予文字說明。顯然,此時(shí)我們只要在一個(gè)mc上的腳本寫對(duì)了,其他5個(gè)mc就可以很方便的寫出來;在主時(shí)間軸第1幀上寫的腳本“stop()”,設(shè)置用于記數(shù)的變量“i=0”,在圓(tx1_mc)上的腳本使用“on (press)”判斷鼠標(biāo)按下時(shí)進(jìn)行,并在on語(yǔ)句中把本mc的坐標(biāo)賦給本mc下的變量x、y,并拖動(dòng)這個(gè)mc,即“startDrag(this, true)”;使用“on (release)”判斷松開鼠標(biāo)時(shí)動(dòng)作,在做松開動(dòng)作時(shí)停止拖動(dòng)這個(gè)mc,并使用“if (this.hitTest(_root. wz1))”來判斷這個(gè)mc和動(dòng)態(tài)文本wz1重疊或相交;相交時(shí),判斷這時(shí)如果這個(gè)mc上的變量k不為1則主時(shí)間軸上的變量i加1,并在這個(gè)mc上設(shè)置變量k=1(使一個(gè)mc拖動(dòng)正確時(shí),主時(shí)間軸上的記數(shù)變量i只加1次);如相交時(shí),主時(shí)間軸上的記數(shù)變量i等于6(圖形都正確拖動(dòng)完畢),主時(shí)間軸跳到下1幀停下;但如果這個(gè)mc和動(dòng)態(tài)文本wz1不重疊或相交,那么把這個(gè)mc的坐標(biāo)設(shè)置為前面得到的這個(gè)mc的坐標(biāo)的數(shù)值;我們可以先檢測(cè)一個(gè)mc代碼的正確性,然后再把這代碼復(fù)制在其他5個(gè)mc上,只消把其中的wz1改為相應(yīng)的wz2~wz6即可。
通過上面研究了解了hitTest的基本用法后,下面就以一款平面飛行游戲中碰撞檢測(cè)為例,進(jìn)一步說明其實(shí)際應(yīng)用:
1、首先確定需要相互碰撞的對(duì)象。游戲中主角飛機(jī)與所有敵機(jī)機(jī)身會(huì)發(fā)生碰撞,被撞后雙方同歸于盡;主角子彈和其他友機(jī)子彈會(huì)與所有敵機(jī)機(jī)身發(fā)生碰撞,被撞后敵機(jī)生命將根據(jù)子彈威力扣減,為零則敵機(jī)被擊毀;敵機(jī)子彈與主角飛機(jī)發(fā)生碰撞,被撞后主角生命將根據(jù)子彈威力扣減,為零則主角被擊毀。
2、設(shè)置碰撞范圍。在Flash庫(kù)中雙擊子彈元件,進(jìn)入元件編輯,更改主角子彈圖形為“影片剪輯”,“實(shí)例名稱”為“body”,這就是子彈進(jìn)行碰撞判斷的范圍;同樣,重復(fù)此步驟,對(duì)其他元件也設(shè)置好碰撞范圍,對(duì)于飛機(jī)元件除了設(shè)置好碰撞范圍外,還可以加多一幀,把實(shí)例屬性“顏色”為“亮度100%”,這表示是飛機(jī)被擊中時(shí)進(jìn)行一次反白顯示。
3、子彈碰撞檢測(cè)。在庫(kù)中雙擊“敵機(jī)子彈(enemy_bullet)”元件,進(jìn)入元件編輯,新建一圖層,起名為“action”,在該層第1幀按
4、飛機(jī)碰撞檢測(cè)。在庫(kù)中雙擊“敵機(jī)(enemy)”元件,進(jìn)入元件編輯,先在最后一幀設(shè)置“幀標(biāo)簽”為“remove”,加入代碼“stop()”和“this.removeMovieClip()”,表示飛機(jī)消失處理;其次選擇飛機(jī)實(shí)例,按
10.3969/j.issn.1001-8972.2011.16.138