【四聖龍神錄的程式設計教室】第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部落格目錄: