1. 程式人生 > >【四聖龍神錄的程式設計教室】第19章、給敵機加上消滅特效吧

【四聖龍神錄的程式設計教室】第19章、給敵機加上消滅特效吧

原文地址:

敵機就只是突然消失的話,感覺少了點什麼,我們來給他加上消滅的特效吧。

那麼首先,我們把特效需要用到的一個檔案新增進來。

在解決方案資源管理器裡,專案上點選右鍵,新增項,

選擇 mydat 資料夾的 source 裡的  effect.cpp 加入。

在裡面複製下面的內容貼上進去。

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

---- effect.cpp ----

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

//尋找空的特效存放位置
int search_effect(){
        for(int i=0;i<EFFECT_MAX;i++){
                if(effect[i].flag==0)
                        return i;
        }
        return -1;
}

//計算特效
void calc_effect(){
        for(int i=0;i<EFFECT_MAX;i++){
                if(effect[i].flag>0){//特效已經註冊了的話
                        switch(effect[i].knd){//根據特效的種類進行分支處理
                                case 0://0番の処理
                                        effect[i].cnt++;
                                        effect[i].r+=0.08;          //特效的大小逐漸變大
                                        if(effect[i].cnt>10)        //過了10幀的話
                                                effect[i].brt-=25;  //明亮程度減少
                                        if(effect[i].cnt>20)        //過了20幀的話
                                                effect[i].flag=0;   //消失
                                        break;
                                default:
                                        printfDx("effect設定エラー\n");
                                        break;
                        }
                }
        }
}

//尋找消滅特效的空的存放位置
int search_del_effect(){
        for(int i=0;i<DEL_EFFECT_MAX;i++){
                if(del_effect[i].flag==0)
                        return i;
        }
        return -1;
}

//消滅特效的註冊
void enter_del_effect(int s){
        int k=search_del_effect();
        if(k!=-1){
                del_effect[k].flag=1;   //設定標誌
                del_effect[k].cnt=0;
                del_effect[k].col=enemy[s].back_col;    //消除顏色設定為敵機的背景色
                del_effect[k].x=enemy[s].x;             //消滅位置設定為敵機的座標
                del_effect[k].y=enemy[s].y;
        }
}

//消滅特效的計算和特效的註冊
void calc_del_effect(){
        int k;
        for(int i=0;i<DEL_EFFECT_MAX;i++){
                if(del_effect[i].flag>0){
                        if(del_effect[i].cnt%2==0){             // 每1/30秒進行設定
                                if((k=search_effect())!=-1){    //尋找空的編號
                                        memset(&effect[k],0,sizeof(effect_t));  //初始化
                                        effect[k].flag=1;       //設定標記
                                        effect[k].brt=255;      //亮度設為最大值
                                        effect[k].ang=rang(PI); //設定隨機的角度
                                        effect[k].col=del_effect[i].col;    //設定顏色
                                        effect[k].eff=1;            //1號是光的特效。這裡設定為光特效
                                        effect[k].img=img_del_effect[effect[k].col];    //設定消滅的影象
                                        effect[k].knd=0;            //特效的種類是0號(消滅特效是0)
                                        effect[k].x=del_effect[i].x;//設定座標
                                        effect[k].y=del_effect[i].y;
                                }
                        }
                        if(del_effect[i].cnt>8){    //計數比8大的話,就結束
                                del_effect[i].flag=0;
                        }
                        del_effect[i].cnt++;
                }
        }
}

void effect_main(){
        calc_del_effect();  //計算消除特效
        calc_effect();      //計算特效
}
——————————————————————————————————————————————————————————————————————————

enter_del_effect 裡消除特效註冊了的話,然後就是全自動的對特效進行計算,十分方便。

這個函式裡,引數s 傳入的是敵機的識別編號。這樣,s號敵機消滅後特效就進行註冊。

這次也是準備了新的資料存放的地方。

消除特效存放在 del_effect

特效存在 effect 裡

為什麼要準備消除特效和普通特效這樣兩種呢,也許有人在想這個問題。

消除特效不僅僅是實際特效的播放,還要管理什麼時候特效登陸,

什麼樣的特效登陸等資訊。 (譯者注:個人理解,就是彈幕和子彈的關係。這裡消除特效是由特效組成的)

總之,就是實際的特效是 effect 的計算,繪製。

這個effect 變數 是一個通用的東西,除了消除特效,還能展示各種各樣的東西。

從此特效裡可以放各種各樣的東西,幾乎都在這了。

各種各樣的特效要使用的話,就要準備各種各樣的變數,這樣太麻煩了所以我們採用更有效率的方法。

所以,目前要記住這點,“消除特效的變數上,承載著特效變數。只有消除特效變數的話,是不能成為特效的。

消除特效變數,是做特效的管理工作這樣的事情的”。

enter_del_effect 函式裡註冊了的資訊,在 calc_del_effect() 函式裡進行計算。

看了註釋應該就能明白,尋找註冊了的消除特效,如果有,就每1/30 秒註冊一個特效。

然後,尋找特效的註冊編號,在那裡設定資訊。

之前也說了,特效變數可以用在任何方面,在表示什麼樣的特效的種類 knd裡代入0。以後消除特效就是0號的特效了。

out_main 裡,自機射擊總數和敵機總數進行全部的碰撞判定。

那麼這裡也要新增如下的改動。

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

---- out.cpp 做出如下改動 ----

extern void enter_del_effect(int);<span>	</span>//這是新加的

void enemy_death_judge(int s){
        int i;
        se_flag[8]=1;   //敵機被擊中的音效
        if(enemy[s].hp<0){  //敵機的HP小於0的話
                enemy[s].flag=0;    //敵機消除
                se_flag[1]=1;       //敵機的BIU的音效
                enter_del_effect(s);<span>	</span>/<span style="font-family:Arial, Helvetica, sans-serif;">/這是新加的</span><span>
</span>


---- define.h 新增如下程式碼 ----

//特效的最大數目
#define EFFECT_MAX 100
//消除特效的最大數目
#define DEL_EFFECT_MAX 30


---- struct.h 做出以下改動 ----

//敵機相關的構造體
typedef struct{
        int flag,cnt,pattern,muki,knd,hp,hp_max,item_n[6],img,back_col;       //背景色是新加的
        //標誌,計數,移動模式,方向,敵機的種類,HP的最大值,掉落的道具,背景色
        double x,y,vx,vy,sp,ang;
        //座標,速度的x分量,速度的y分量,速度,角度
        int bltime,blknd,blknd2,col,state,wtime,wait;
        //彈幕的開始時間,彈幕的種類,子彈的種類,顏色,狀態,待機時間,停滯時間
}enemy_t;


---- enemy.cpp 的 enemy_enter函式的登陸部分裡新增如下程式碼 ----

enemy[i].back_col=GetRand(4);


---- function.h 裡新增如下程式碼 ----

//effect.cpp
GLOBAL void effect_main();


---- GV.h 裡新增如下程式碼 ----

GLOBAL int img_del_effect[5];

GLOBAL del_effect_t del_effect[DEL_EFFECT_MAX]; //消滅特效
GLOBAL effect_t effect[EFFECT_MAX];     //特效


---- ini.cpp 的 ini函式裡新增如下程式碼 ----

memset(effect,0,sizeof(effect_t)*EFFECT_MAX);
memset(del_effect,0,sizeof(del_effect_t)*DEL_EFFECT_MAX);


---- load.cpp 的 load函式裡新增如下程式碼 ----

LoadDivGraph( "../dat/img/enemy/hit_effect.png" , 5 , 5 , 1 , 140 , 140 , img_del_effect ) ;


---- main.cpp 的main函式裡新增如下程式碼 ----

            case 100:       //通常處理
                calc_ch();   //角色計算
                ch_move();   //角色的移動操作
                cshot_main();//自機射擊的主函式
                enemy_main();//敵機處理的主函式
                shot_main(); //射擊的主函式
                out_main();  //碰撞檢測
                effect_main();//特效主函式,這是新加的
                graph_main();//繪畫主函式
                stage_count++;
                break;


---- struct.h 裡新增如下程式碼 ----

//特效
typedef struct{
        int flag,cnt,col,knd,img,eff,brt;
        double x,y,r,ang;
}effect_t;

//消除特效
typedef struct{
        int flag,cnt,col;
        double x,y;
}del_effect_t;


---- graph.cpp 裡新增如下程式碼 ----//這段都是新加的

void graph_effect(){
    for(int i=0;i<EFFECT_MAX;i++){
        if(effect[i].flag>0){
            if(effect[i].eff==1)    //特效是光特效的話
                SetDrawBlendMode( DX_BLENDMODE_ADD, effect[i].brt) ;

            DrawRotaGraphF(effect[i].x+FIELD_X,effect[i].y+FIELD_Y,effect[i].r,effect[i].ang,effect[i].img,TRUE);

            if(effect[i].eff==1)
                SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0) ;
        }
    }
}

void graph_main(){
        graph_effect();    //新加的特效繪製
        graph_enemy();
        graph_cshot();
        graph_ch();
        graph_bullet();
        graph_board();
}


執行結果:

本人CSDN部落格目錄: