ActionScript3.0 - 2D 彈幕講座
相信各位都玩過類以下這張圖(早期遊戲:雷電)的平面2D遊戲,
除了本身畫面之外,最重要的部份也是我們最好奇是,它的子
彈,我這邊介紹稱為"彈幕",到底是怎麼做出來的?,或許你
沒有想過這問題,或是看過沒有去多想它,或是把它當成理所
當然的一部份!事實上一點也不!
要做彈幕首先必須知道一些基礎:
1.基本的物件座標操作(敵人與子彈移動座標相關)
2.Math.sin() cos()參數應用
3.new物件與addChild後name的運用
4.removeChild相關
一樣廢話不多說馬上開始!
註:如果以下基礎觀念都不想看的話,那..請拉到最後下載範例!
1.子彈的建立
請在元件庫隨意畫一個子彈,以下圖為例為它類別命名,在此是
命名為 enemy_bullet
2.子彈的排列
子彈的排列考量到以下幾點:
2.1 子彈的旋轉角
2.2 繞半圓路線排列
2.1子彈旋轉角解說:
eb.rotation=-(90-i*(180/20));//每一個子彈旋轉角
簡單說就我們希望把rotation角度 從 90 變化到-90
180是總度數,20是你要產生的子彈數(同迴圈數)
2.2 繞半圓路線排列
到底要怎麼動態讓子彈排成一個弧形?
註:不想看數學邏輯及廢話的人請跳過此步驟!!
很簡單,我們從兩個方向去討論它的邏輯!(參考下圖)
我們若只看 y 軸,實際上它只是先往下再往上的一個路逕
我們若只看 x 軸,其實它只是一個平移一段距離的路逕
你說那有什麼演算法可以剛好符合這兩個需求?
有,非常好的是我們高中數學三角函數又派上用場,這時候
也許你又想回去重學你的數學了,在這裡分別應用sin跟cos
兩個簡單特性讓它們完成這項工作!!
參考以下兩張圖
(以下是sin的參數,我用紅圈標起來,當參數0-3點多的位置
剛好可以形成一個先往下再往上的函數)
對flash座標來說,數值座標越大就是往下跑.
(以下是cos,當參數是0-3.多,它的位置從1下降到-1)
剛好可以拿來當x平移距離
r*Math.cos(i*3.2/20)+enemy.x;
r*Math.sin(i*3.2/20)+enemy.y;
很簡單吧? 看不懂自己開個新檔把Math.sin拿參數進去try數據!!
這裡 r是半逕,你產生的子彈用以上參數產生的位置充其量也不過
是在-1 到1的距離在跑,這時候你只要乘上一個倍數,子彈就會擴
展開來!
3.彈幕如何散開?
以上我們製作好的彈幕是不會動的,因為實際上數據是固定的,但
我們發現,實際上子彈擴散時,變動的其實只是半逕的大小,因此
我們只要動態的改變半逕讓它不斷的增加,子彈便會射出去!
(r<300)? r+=5:r=0; //讓r半逕不斷增加超過300 則又重新開始
4.多重彈幕?
多重彈幕實計上只是發射的時間延後一個時間點而已
timer_var=getTimer()/1000;
if(timer_var>=0.3){ //希望晚0.3秒後 發射第二波彈幕
(r2<300)? r2+=5:r2=0;
ger_bullet2();
}
//當然了 如果你要一直發射很多重彈幕,你可以改進更好的寫法!
5.最重要的部份,子彈的移除!
上面的部份都理所當然的被建立發射,可是實際上在flash裡被建
立的物件並不會因此而消失.以下是建立與移除的邏輯過程!
半逕1子彈被建立 --> 半逕2子彈被建立(此時半逕1子彈仍存在) --->
於是我們在這之中加了removeChild
var tmp_eb:MovieClip = MovieClip(root).getChildByName("eb" + i);
if( tmp_eb != null ){
MovieClip(root).removeChild(tmp_eb );
}//if
}//for
6.補充說明
所建立的子彈在上述說明要被移除, 我們裡是使用.name的方法
來移除,當然你也可以使用removeChildAt ,指定深度,可是這樣
會太麻煩了,建議還是給它.name後再來移除name即可!
var eb:enemy_bullet=new enemy_bullet();
MovieClip(root).addChild(eb);
eb.name = "eb" + String( i );
範例下載
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言