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 );



範例下載

沒有留言:

張貼留言