iT邦幫忙

0

ActionScript 撞擊測式問題!!!

  • 分享至 

  • xImage

Hi ALL

小弟最近在做砲台射擊
但遇到一個問題, 射擊出的砲彈, 無法有效執行碰撞, 只有第一發有用
之後射擊的都無法產生碰撞
請大大指點一下, 到底是那邊有問題, 讓我無法正確產生碰撞

原始檔如下
for CS5.5
https://www.asuswebstorage.com/navigate/share/GYYI459SIY

如果是 CS5.0 用戶請開這個檔案
https://www.asuswebstorage.com/navigate/share/GYYQUS9SIY

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

4
wordsmith
iT邦高手 1 級 ‧ 2012-02-24 17:55:52
最佳解答

稍微看過一下你的code,看看錯誤是不是發生在此。

首先關於砲彈,除了第一發放在舞台上有用之外,其它用click產生出來的砲彈就沒有用了。所以關鍵在於你用click產生出來的砲彈沒有辦法偵測到撞擊。

你是用飛出的ball01、02、03來偵測是否撞擊,然後偵測的方法是去測試myroot.ball是否與和這些發生撞擊,但是myroot.ball這個實體物件,在第一次撞擊之後,就已經被移除了。所以之後的myroot.ball就不存在了。

所以現在改進的方法,一個是將ball這個實體名稱再指定給滑鼠生出的ball,不然就是用一個變數如currentBall來記住砲彈,然後在ball01、02、02中去存取這個值。

我想這樣應該就可以解決問題了。

另外,寫actionscript最好能將程式用外部文件的方式獨立出來,這樣子比較容易維護。寫在flash的影片物件中,放一段時間後,你自己要debug就會覺得痛苦了。

看更多先前的回應...收起先前的回應...
ck123 iT邦新手 5 級 ‧ 2012-02-24 23:48:37 檢舉

感謝大大指點, 小弟有機會會報達~

ck123 iT邦新手 5 級 ‧ 2012-02-25 01:52:28 檢舉

有個問題, 這點我知到
但我的問題在於, 小弟用addChild出來的物件, 我不知到有那個指令可以指定它的名稱
所以我也很疑惑~
至於用變數記住砲彈這招, 更是沒聽說過這要怎做
這幾天一直在google上面找範例, 貌似台灣不討論這個問題似的, 沒發現
國外對岸比較多, 但也沒找到可以參考的範例或指令可用
可能偶太笨吧 = =

wordsmith iT邦高手 1 級 ‧ 2012-02-25 13:15:43 檢舉

要動態指定砲彈的名稱很簡單,例如我們可以利用reaction這個物件,給他一個ballCounter的變數:
reaction.ballCounter =0
然後在生成砲彈的froth函式中,讓counter+1
reaction.ballCounter++
再指定給砲彈:
amissile.name = "ball"+reaction.ballCounter;
這樣就可以動態給予每個砲彈不同的實體名稱

wordsmith iT邦高手 1 級 ‧ 2012-02-25 13:20:22 檢舉

至於我原本建議指定砲彈名稱的作法,後來發現不合用,原因在於舞台上可以一次出現多個砲彈,如果是這樣,就不能指定唯一的instance name。

所以我想應該用一個陣列來放生成的砲彈,然後碰撞測試時,去檢查是否撞擊在這陣列中的物件。

wordsmith iT邦高手 1 級 ‧ 2012-02-25 13:23:52 檢舉

首先我把舞台上的ball移掉,只用以滑鼠生成的ball。接下來就是在生成砲彈時,放進陣列中。以你的code來改的話,就是這樣:

<pre class="c" name="code">import flash.events.MouseEvent;
import flash.events.Event;

stage.addEventListener(Event.ENTER_FRAME,rotatee);
//增加一個放砲彈的陣列
reaction.allBalls = [];

function rotatee(e:Event)
{
	var theX:int = mouseX - theArrow.x;
	var theY:int = (mouseY - theArrow.y) * -1;
	var angle = Math.atan(theY/theX)/(Math.PI/180);
	if (theX<0)
	{
		angle +=  180;
	}
	if (theX>=0 && theY<0)
	{
		angle +=  360;
	}
	theArrow.rotation = (angle * -1) + 1;

}

reaction.addEventListener(MouseEvent.CLICK, froth)

function froth(MouseEvent){
	var amissile:missile=new missile();
	amissile.x = 18;
	amissile.y = 158;
	amissile.rotation = theArrow.rotation;
        //把砲彈放進陣列
	reaction.allBalls.push(amissile);
	addChild(amissile);
}
wordsmith iT邦高手 1 級 ‧ 2012-02-25 13:26:24 檢舉

接下來,原本碰撞測試的元件3、5、6的go函式改成這樣:

<pre class="c" name="code">function go(e)
{
	this.x -=  1;
//取得放砲彈陣列的長度	
	var total = myroot.reaction.allBalls.length;
//檢查是否撞擊到
	for(var i=0; i<total;i++)
	{
		if (this.hitTestObject(myroot.reaction.allBalls[i]))
		{
			myroot.score += 10;
			this.removeEventListener(Event.ENTER_FRAME,go);
			myroot.removeChild(this);
		}	
	}


}

這樣就可以運作了。

wordsmith iT邦高手 1 級 ‧ 2012-02-25 13:32:39 檢舉

上面只是在解決碰撞的問題,至於架構、效能面等東西就沒有多加考量。像是砲彈如果飛出舞台後,應該把它移除,一方面一直增加砲彈會佔用記憶體,另外陣列裡面放一些沒有用到的砲彈,也會增加檢測的時間。

簡單來說,就是用Array.splice的方法,移除掉陣列中已經飛出舞台的砲彈。

wordsmith iT邦高手 1 級 ‧ 2012-02-25 13:37:00 檢舉

我把修改過的檔案放在:
https://docs.google.com/open?id=0B-4_2_Uw2gP-UUpNYVctd3RUOGlrRjB3aWF1MWR5dw

可以從[檔案][下載]

我要發表回答

立即登入回答