1. 程式人生 > >【四聖龍神錄的程式設計教室】第14章、來製作各種各樣的彈幕資料吧

【四聖龍神錄的程式設計教室】第14章、來製作各種各樣的彈幕資料吧

原文地址:

那些麻煩的設定終於搞定了,那麼這次我們就來做各種各樣的彈幕資料吧。

下面是一直髮射自機狙的彈幕函式001.

往 shotatan2 函式裡,傳入n,就可以返回自機和編號為n的敵機的角度,這樣很簡單就把射向自機的角度傳給angle 變量了。

——————————————————————————————————————————————————————————————————

//100個裡面有10發子彈、向自機的方向直線發射(始終瞄準自機)
void shot_bullet_H001(int n){
        int t=shot[n].cnt;
        int k;
        if(t>=0 && t<100 && t%10==0){//100次裡面,每10次出現1次
                if(shot[n].flag!=2 && (k=shot_search(n))!=-1){//敵人存在、並且子彈可以登入
                        shot[n].bullet[k].knd   =enemy[shot[n].num].blknd2;//子彈登入
                        shot[n].bullet[k].angle =shotatan2(n);//角度
                        shot[n].bullet[k].flag  =1;//標誌
                        shot[n].bullet[k].x     =enemy[shot[n].num].x;//座標
                        shot[n].bullet[k].y     =enemy[shot[n].num].y;
                        shot[n].bullet[k].col   =enemy[shot[n].num].col;//顏色
                        shot[n].bullet[k].cnt   =0;//計數
                        shot[n].bullet[k].spd   =3;//速度
                        se_flag[0]=1;
                }
        }
}

——————————————————————————————————————————————————————————————————

只是看各個變數的數值可能不是很明白,我們拿執行的結果來比較一下看看吧。

——————————————————————————————————————————————————————————————————

---- shotH.cpp的改動 ----


#include "../include/GV.h"

//只有一發子彈、向自機方向直線發射
void shot_bullet_H000(int n){
        int k;
        if(shot[n].cnt==0){
                if(shot[n].flag!=2 && (k=shot_search(n))!=-1){
                        shot[n].bullet[k].knd   =enemy[shot[n].num].blknd2;
                        shot[n].bullet[k].angle =shotatan2(n);
                        shot[n].bullet[k].flag  =1;
                        shot[n].bullet[k].x     =enemy[shot[n].num].x;
                        shot[n].bullet[k].y     =enemy[shot[n].num].y;
                        shot[n].bullet[k].col   =enemy[shot[n].num].col;
                        shot[n].bullet[k].cnt   =0;
                        shot[n].bullet[k].spd   =3;
                        se_flag[0]=1;
                }
        }
}

//100發中有10發、往自機方向直線發射(始終瞄準自機)
void shot_bullet_H001(int n){
        int t=shot[n].cnt;
        int k;
        if(t>=0 && t<100 && t%10==0){//在100發裡,每10發出現一次
                if(shot[n].flag!=2 && (k=shot_search(n))!=-1){//敵機存在,並且子彈可以註冊的話
                        shot[n].bullet[k].knd   =enemy[shot[n].num].blknd2;//子彈註冊
                        shot[n].bullet[k].angle =shotatan2(n);//角度
                        shot[n].bullet[k].flag  =1;//標誌
                        shot[n].bullet[k].x     =enemy[shot[n].num].x;//座標
                        shot[n].bullet[k].y     =enemy[shot[n].num].y;
                        shot[n].bullet[k].col   =enemy[shot[n].num].col;//顏色
                        shot[n].bullet[k].cnt   =0;//計數
                        shot[n].bullet[k].spd   =3;//速度
                        se_flag[0]=1;
                }
        }
}

//100發中有10發、往自機方向直線發射(角度記憶)
void shot_bullet_H002(int n){
        int t=shot[n].cnt;
        int k;
        if(t>=0 && t<100 && t%10==0){
                if(t==0)
                        shot[n].base_angle[0]=shotatan2(n);
                if(shot[n].flag!=2 && (k=shot_search(n))!=-1){
                        shot[n].bullet[k].knd   =enemy[shot[n].num].blknd2;
                        shot[n].bullet[k].angle =shot[n].base_angle[0];
                        shot[n].bullet[k].flag  =1;
                        shot[n].bullet[k].x     =enemy[shot[n].num].x;
                        shot[n].bullet[k].y     =enemy[shot[n].num].y;
                        shot[n].bullet[k].col   =enemy[shot[n].num].col;
                        shot[n].bullet[k].cnt   =0;
                        shot[n].bullet[k].spd   =3;
                        se_flag[0]=1;
                }
        }
}

//100發中有10發、往自機方向變速地直線發射
void shot_bullet_H003(int n){
        int t=shot[n].cnt;
        int k;
        if(t>=0 && t<100 && t%10==0){
                if(shot[n].flag!=2 && (k=shot_search(n))!=-1){
                        shot[n].bullet[k].knd   =enemy[shot[n].num].blknd2;
                        shot[n].bullet[k].angle =shotatan2(n);
                        shot[n].bullet[k].flag  =1;
                        shot[n].bullet[k].x     =enemy[shot[n].num].x;
                        shot[n].bullet[k].y     =enemy[shot[n].num].y;
                        shot[n].bullet[k].col   =enemy[shot[n].num].col;
                        shot[n].bullet[k].cnt   =0;
                        shot[n].bullet[k].spd   =1+5.0/100*t;
                        se_flag[0]=1;
                }
        }
}

//每0.5秒一次的圓形發射
void shot_bullet_H004(int n){
        int t=shot[n].cnt;
        int k;
        if(t>=0 && t<120 && t%20==0){
                double angle=shotatan2(n);
                for(int i=0;i<20;i++){
                        if(shot[n].flag!=2 && (k=shot_search(n))!=-1){
                                shot[n].bullet[k].knd   =enemy[shot[n].num].blknd2;
                                shot[n].bullet[k].angle =angle+PI2/20*i;
                                shot[n].bullet[k].flag  =1;
                                shot[n].bullet[k].x     =enemy[shot[n].num].x;
                                shot[n].bullet[k].y     =enemy[shot[n].num].y;
                                shot[n].bullet[k].col   =enemy[shot[n].num].col;
                                shot[n].bullet[k].cnt   =0;
                                shot[n].bullet[k].spd   =4;
                        }
                        se_flag[0]=1;
                }
        }
}

//散射
void shot_bullet_H005(int n){
        int t=shot[n].cnt;
        int k;
        if(t>=0 && t<120 && t%2==0){
                if(shot[n].flag!=2 && (k=shot_search(n))!=-1){
                        shot[n].bullet[k].knd   =enemy[shot[n].num].blknd2;
                        shot[n].bullet[k].angle =shotatan2(n)+rang(PI/4);
                        shot[n].bullet[k].flag  =1;
                        shot[n].bullet[k].x     =enemy[shot[n].num].x;
                        shot[n].bullet[k].y     =enemy[shot[n].num].y;
                        shot[n].bullet[k].col   =enemy[shot[n].num].col;
                        shot[n].bullet[k].cnt   =0;
                        shot[n].bullet[k].spd   =3+rang(1.5);
                        se_flag[0]=1;
                }
        }
}

//散射(減速)
void shot_bullet_H006(int n){
        int t=shot[n].cnt;
        int k;
        if(t>=0 && t<120 && t%2==0){
                if(shot[n].flag!=2 && (k=shot_search(n))!=-1){
                        shot[n].bullet[k].knd   =enemy[shot[n].num].blknd2;
                        shot[n].bullet[k].angle =shotatan2(n)+rang(PI/4);
                        shot[n].bullet[k].flag  =1;
                        shot[n].bullet[k].x     =enemy[shot[n].num].x;
                        shot[n].bullet[k].y     =enemy[shot[n].num].y;
                        shot[n].bullet[k].col   =enemy[shot[n].num].col;
                        shot[n].bullet[k].cnt   =0;
                        shot[n].bullet[k].spd   =4+rang(2);
                        se_flag[0]=1;
                }
        }
        for(int i=0;i<SHOT_BULLET_MAX;i++){//所有子彈進行迴圈
                if(shot[n].bullet[i].spd>1.5)//子彈的速度比1.5還要大的話
                        shot[n].bullet[i].spd-=0.04;//減速
        }
}

——————————————————————————————————————————————————————————————————

新增上面這些彈幕的同時,下面這裡也做一下改動

/カウンタ 移動パターン 敵の種類 x座標 y座標 スピード 発射時間 弾幕種類 弾の色 體力 弾種類 待機時間 アイテム1 2 3 4 5 6
/cnt pattern knd x y sp bltime blknd col hp blknd2 wait item_n
60 9 0 200 150 0 60 0 0 100 7 120 0 -1 -1 -1 -1 -1
200 9 0 180 150 0 60 1 0 100 8 120 0 -1 -1 -1 -1 -1
340 9 0 200 150 0 60 2 0 100 9 120 0 -1 -1 -1 -1 -1
480 9 0 180 150 0 60 3 0 100 0 120 0 -1 -1 -1 -1 -1
620 9 0 200 150 0 60 4 0 100 7 120 0 -1 -1 -1 -1 -1
760 9 0 180 150 0 60 5 0 100 8 120 0 -1 -1 -1 -1 -1
900 9 0 180 150 0 60 6 0 100 8 120 0 -1 -1 -1 -1 -1

移動模式9裡面,把上面的彈幕種類都包含進去了。

我們往【彈幕種類】裡,傳入0~6,代表這次製作的0~6的彈幕資料。

————————————————————————————————————————————————————————————————————

---- shot.cpp的exntern宣告部分和指標代入部分作如下修改 ----

extern void shot_bullet_H000(int);
extern void shot_bullet_H001(int);
extern void shot_bullet_H002(int);
extern void shot_bullet_H003(int);
extern void shot_bullet_H004(int);
extern void shot_bullet_H005(int);
extern void shot_bullet_H006(int);

void (*shot_bullet[SHOT_KND_MAX])(int) ={
        shot_bullet_H000,
        shot_bullet_H001,
        shot_bullet_H002,
        shot_bullet_H003,
        shot_bullet_H004,
        shot_bullet_H005,
        shot_bullet_H006,
};



---- function.h 裡新增下面這行 ----

GLOBAL double rang(double);


---- define.h 做如下變更 ----

#define SHOT_KND_MAX 7
————————————————————————————————————————————————————————————————————

執行結果

(又停了好久,我感覺我翻譯完估計要幾年,然後學著做又要幾年。。。 之前玩劍靈,覺得沒意思了。又蛋疼玩起dota了,也覺得浪費時間,於是現在又抽時間把這個繼續做下去)

(2014-3-5 筆記:

從這章和上一章的程式碼對比,可以看到改動很少,主要就3個檔案。一個是敵機進入的資料,儲存在csv檔案中,控制敵機登場的時間,移動模式,發彈時間和型別等等。
看了下這次的csv檔案,可以看到敵機的移動都使用第9種移動方式,在某個時間出現,過了wait 時間後,就往上移動。這次主要是展示不同的彈幕。
0號彈幕和之前一樣,在敵機位置生成一顆子彈,角度朝向自機移動。
1號彈幕,從0到100的時間刻度內,每過10個時間刻度,發射一枚子彈,朝向自機。(10枚每個發射時都朝自機方向)
2號彈幕,也是像上面這樣100幀內發射10顆。但只有第一顆會朝自機方向,後面的子彈都按照這個角度發射。(10枚都朝同一個方向,也就是記下了角度的)
3號彈幕,10枚都朝向自機,每枚子彈都會比上一枚速度更快。
4號彈幕,120幀內每20幀發射一次,每次往四周平均發射20枚子彈,也就是圓圈形狀。(for裡迴圈20次,每次角度加2*pi/20)
5號彈幕,120幀內每2幀發射一枚子彈,角度隨機在朝自機的角度+- pi/4 的範圍內,速度在1.5~4.5的範圍之內。(rang(n) 生成正負n之內的隨機數)
6號彈幕,生成和5號一樣,但速度在2~4的範圍內,並且速度會慢慢減為1.5.

本人CSDN部落格目錄: