1. 程式人生 > >【四聖龍神錄的程式設計教室】第22章、放炸彈來攻擊吧

【四聖龍神錄的程式設計教室】第22章、放炸彈來攻擊吧

原文地址:

這次講炸彈攻擊。
和往常一樣,準備好資訊儲存的地方,然後進行載入,然後讓他自動計算,大概就是這樣的感覺就行了。。。
在之前的章節裡,我們準備了變數來展現特效。
之前敵機消滅時,使用了特效。現在在同一個儲存區裡,載入炸彈的特效看看。
之前也說過了,這個特效變數裡,載入任何特效都是可以的。
以knd作為識別編號的特效,對應的特效被載入後,就那樣一直運算的話,那就可以放在同一個儲存空間裡面了。
龍神錄的炸彈特效是:
“BIU。。。 DON”  這樣的一個特效,(這個的編號為1)
特效的線條上下左右的移動,(這個的編號為2)
從角色身上“咻~”的冒出來的特效,(這個的編號為3)
放炸彈的時候,把這些特效的編號分別進行載入,讓我們來實現一下吧。
首先準備以下的東西。
——————————————————————————————————————————————————————————————————————————

<span style="font-size:14px;"><span style="font-size:12px;">---- struct.h 新增如下程式碼 ----

//特效
typedef struct{
	int flag,cnt,col,knd,img,eff;
	double x,y,r,ang,spd,mvang,brt;
}effect_t;
//炸彈的資訊
typedef struct{
        int flag,cnt,knd;
        double x,y;
}bom_t;
//畫面明暗的資訊
typedef struct{
        unsigned char brt;
}bright_set_t;
//咚!這樣的畫面搖晃的資訊
typedef struct{
        int flag,cnt,time,size;
        int x,y;
}dn_t;


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

GLOBAL int img_eff_bom[5];      //炸彈的效果的影象
GLOBAL bom_t bom;               //炸彈
GLOBAL bright_set_t bright_set; //繪製的亮度
GLOBAL dn_t dn;                 //咚一下的搖晃


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


        img_eff_bom[0] = LoadGraph( "../dat/img/effect/bom0.png" );
        img_eff_bom[1] = LoadGraph( "../dat/img/effect/bom1.png" );
        img_eff_bom[2] = LoadGraph( "../dat/img/char/body.png" );
        img_eff_bom[3] = LoadGraph( "../dat/img/bullet/bom_title0.png" );
        sound_se[14]=LoadSoundMem("../dat/se/bom0.wav");
        sound_se[15]=LoadSoundMem("../dat/se/bom1.wav");


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

        memset(&bom,0,sizeof(bom_t));
        memset(&bright_set,0,sizeof(bright_set_t));
        memset(&dn,0,sizeof(dn_t));

        bright_set.brt=255;


---- out.cpp 的out_main函式改動 ----

//碰撞判定的主函式
void out_main(){
        cbom_and_enemy();
    cshot_and_enemy();
    enemyshot_and_ch();
}


---- out.cpp 的下面任意地方進行改動 ----


//第s個敵人受到炸彈的傷害
void hit_enemy(int s,int power){
    enemy[s].hp-=power;//根據炸彈的威力,減去對應的HP
    enemy_death_judge(s);//判斷敵機是不是掛了
}

//炸彈和敵機的處理
void cbom_and_enemy(){
    int s;
    if(bom.flag!=1)return;
    for(s=0;s<ENEMY_MAX;s++){//敵機總數
        if(enemy[s].flag>0)
            hit_enemy(s,ch.power/20);//第s個敵機扣掉ch.power/20的血
    }
}

//自己子彈和敵機的處理
void cshot_and_enemy(){
    int i,s;
    for(i=0;i<CSHOT_MAX;i++){//自機子彈的總數
        if(cshot[i].flag>0){
            for(s=0;s<ENEMY_MAX;s++){//敵機總數
                if(enemy[s].flag>0){
                    if(out_judge_cshot(i,s)){//自機子彈和敵機發生碰撞的話
                        cshot[i].flag=0;//把那個自機子彈消除掉
                        hit_enemy(s,cshot[i].power);//第s個敵機 扣掉 power那麼多的血
                    }
                }
            }
        }
    }
}


---- graph.cpp 的 graph_effect 的紅字部分進行追加----

void graph_effect(int knd){
        for(int i=0;i<EFFECT_MAX;i++){
                if(effect[i].flag>0 && effect[i].knd==knd){
                        if(effect[i].eff==1)//特效是光的話
                                SetDrawBlendMode( DX_BLENDMODE_ADD, effect[i].brt) ;
                        if(effect[i].eff==2)//特效是α特效的話
                                SetDrawBlendMode( DX_BLENDMODE_ALPHA, effect[i].brt) ;
                        DrawRotaGraphF(effect[i].x+FIELD_X+dn.x,effect[i].y+FIELD_Y+dn.y,effect[i].r,effect[i].ang,effect[i].img,TRUE);
                        if(effect[i].eff==1 || effect[i].eff==2)
                                SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0) ;
                }
        }
}


---- graph.cpp 的 graph_main 的改動 ----

void graph_main(){
        if(bright_set.brt!=255)SetDrawBright(bright_set.brt,bright_set.brt,bright_set.brt);

        graph_back_main();//繪製背景的主函式
        graph_effect(0);//敵機死亡的特效
        graph_enemy();//敵機的繪製
        graph_cshot();//自機子彈的繪製

        if(bright_set.brt!=255)SetDrawBright(255,255,255);

        graph_ch();//自機的繪製

        if(bright_set.brt!=255)SetDrawBright(bright_set.brt,bright_set.brt,bright_set.brt);
        
        graph_bullet();//子彈的繪製

        if(bright_set.brt!=255)SetDrawBright(255,255,255);

        graph_effect(1);//炸彈的特效
        graph_effect(2);//炸彈線的特效
        graph_effect(3);//炸彈人物的特效
        graph_board();//板子的繪製
}</span></span>
——————————————————————————————————————————————————————————————————————————

這次在新的構造體裡,

・儲存炸彈資訊的bom_t,

・儲存畫面明暗資訊的 bright_set_t,

・咚!的搖晃畫面的資訊  dn_t,

準備了這三個東西。

用 bright_set_t 表示的變數,一般都是255,只有當畫面明暗需要變化時才發生變動。

 dn_t 這個變數使用方法和以前一樣,載入,計算,在畫面抖動的時候使用。

炸彈的變數的使用方法,都和以前的一樣。

那麼準備工作都做好了。現在就把實際的效果來運算出來看看吧。

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

<span style="font-size:14px;"><span style="font-size:12px;">---- 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://敵機消滅的特效
                                        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;
                                case 1://炸彈的特效
                                        //座標計算
                                        effect[i].x+=cos(effect[i].mvang)*effect[i].spd;
                                        effect[i].y+=sin(effect[i].mvang)*effect[i].spd;
                                        //速度計算
                                        if(effect[i].cnt<60)
                                                effect[i].spd-=(0.2+effect[i].cnt*effect[i].cnt/3000.0);
                                        if(effect[i].cnt==60){
                                                effect[i].spd=0;
                                                se_flag[15]=1;
                                                dn.flag=1;
                                                dn.cnt=0;
                                                dn.size=11;
                                                dn.time=20;
                                        }
                                        //明暗和大小的計算
                                        effect[i].r+=0.015;
                                        if(effect[i].cnt<51)
                                                effect[i].brt+=5;
                                        if(effect[i].cnt>=60){
                                                effect[i].r+=0.04;
                                                effect[i].brt-=255/30.0;
                                        }
                                        //計數增加,和消除的計算
                                        effect[i].cnt++;
                                        if(effect[i].cnt>=90)
                                                effect[i].flag=0;
                                        break;
                                case 2://炸彈特效(文字)
                                        //座標計算
                                        effect[i].x+=cos(effect[i].mvang)*effect[i].spd;
                                        effect[i].y+=sin(effect[i].mvang)*effect[i].spd;
                                        //明暗計算
                                        if(effect[i].cnt<51)
                                                effect[i].brt+=4;
                                        if(effect[i].cnt>130-51)
                                                effect[i].brt-=4;
                                        //計數增加,和消除計算
                                        effect[i].cnt++;
                                        if(effect[i].cnt>=130)
                                                effect[i].flag=0;
                                        break;
                                case 3://炸彈的特效(線條)
                                        //座標計算
                                        effect[i].x+=cos(effect[i].mvang)*effect[i].spd;
                                        effect[i].y+=sin(effect[i].mvang)*effect[i].spd;
                                        //明暗計算
                                        if(effect[i].cnt<51)
                                                effect[i].brt+=2;
                                        if(effect[i].cnt>130-51)
                                                effect[i].brt-=2;
                                        //計數增加,和消除計算
                                        effect[i].cnt++;
                                        if(effect[i].cnt>=130)
                                                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;
                                        effect[k].spd=0;
                                }
                        }
                        if(del_effect[i].cnt>8){
                                del_effect[i].flag=0;
                        }
                        del_effect[i].cnt++;
                }
        }
}

//炸彈的載入
void enter_bom(){
        int k;
        bom.flag=1;
        bom.cnt=0;
        bom.knd=0;
        ch.mutekicnt=1;//無敵
        se_flag[14]=1;//啾~ 的聲音
        //豎線
        if((k=search_effect())!=-1){
                effect[k].flag=1;
                effect[k].cnt=0;
                effect[k].knd=3;//炸彈的線條的特效
                effect[k].brt=0;//α值
                effect[k].ang=PI/2;//影象的朝向
                effect[k].mvang=-PI/2;//特效前進的方向
                effect[k].spd=1;//速度
                effect[k].r=1;//大小
                effect[k].eff=2;//α混合
                effect[k].img=img_eff_bom[3];
                effect[k].x=70;//座標
                effect[k].y=300;
        }
        //橫線
        if((k=search_effect())!=-1){
                effect[k].flag=1;
                effect[k].cnt=0;
                effect[k].knd=3;//炸彈的線條的特效
                effect[k].brt=0;
                effect[k].ang=0;
                effect[k].mvang=0;
                effect[k].spd=1;
                effect[k].r=1;
                effect[k].eff=2;
                effect[k].img=img_eff_bom[3];
                effect[k].x=100;
                effect[k].y=350;
        }
        //字元
        if((k=search_effect())!=-1){
                effect[k].flag=1;
                effect[k].cnt=0;
                effect[k].knd=2;//炸彈的文字・線的特效
                effect[k].brt=0;
                effect[k].ang=0;
                effect[k].mvang=-PI/2;
                effect[k].spd=0.7;
                effect[k].r=1;
                effect[k].eff=2;
                effect[k].img=img_eff_bom[2];
                effect[k].x=260;
                effect[k].y=300;
        }
}

//炸彈的計算
void bom_calc(){
        int n,k,shot_angle[4]={0,PI,PI/2,PI*1.5};//4發特效飛行的角度
        if(ch.flag==0 && bom.flag==0){//角色在通常的狀態、炸彈在關閉狀態的話
                if(CheckStatePad(configpad.bom)==1){//炸彈鍵被按下的話
                        enter_bom();
                }
        }
        if(bom.flag==1){//炸彈正在釋放狀態下的話
                if(bom.cnt%10==0){//每1/6秒執行一次
                        n=(bom.cnt/10);
                        if(n<4 && (k=search_effect())!=-1){
                                effect[k].flag=1;
                                effect[k].cnt=0;
                                effect[k].knd=1;//特效編號1:炸彈的特效
                                effect[k].brt=0;
                                effect[k].ang=rang(PI);//影象的朝向隨機
                                effect[k].mvang=shot_angle[n]-PI/4;//飛行方向
                                effect[k].spd=13+rang(2);//速度
                                effect[k].r=0.5;//大小
                                effect[k].eff=2;//α混合
                                effect[k].img=img_eff_bom[(bom.cnt/10)/3];//影象
                                effect[k].x=ch.x;//座標
                                effect[k].y=ch.y;
                        }
                }
                bom.cnt++;
                if(bom.cnt<40)
                        bright_set.brt=255-bom.cnt*5;//影象的明暗設定(變暗)
                if(bom.cnt>90)
                        bright_set.brt=255-40*5+(bom.cnt-90)*5;//影象的明暗設定(變亮)
                if(bom.cnt>130){
                        bom.flag=0;
                        bright_set.brt=255;
                }
        }
}

// DUANG 和畫面震動的處理
void dn_calc(){
        if(dn.flag==1){
                dn.x=(int)rang(dn.size);
                dn.y=(int)rang(dn.size);
                dn.cnt++;
                if(dn.cnt>dn.time){//到達指定的時間就停止
                        dn.flag=0;
                        dn.x=0;
                        dn.y=0;
                }
        }
}

void effect_main(){
        dn_calc();//DUANG 和畫面震動的處理
        calc_del_effect();//消除特效的計算
        calc_effect();//特效的計算
        bom_calc();//炸彈的計算
}</span></span>

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

enter_bom 裡,炸彈進行載入播放。載入的炸彈在130 個計數內進行計算,

進行載入特效,畫面的明暗度調整等。

calc_effect()函式是特效的計算函式、添加了對本次新增的1,2,3號特效的處理。

執行結果:

(PS: 繼續來填坑。。。  公司專案蛋疼。。。照著成功專案換皮,問題是,你皮難看,做出來的東西還不是隻能呵呵。。。  結果和原先的相差無幾。。。

好啦,過兩天要考科二了。攢人品啊攢人品。。

文字基本是照翻,有啥不通順的,對照程式碼看吧。。。 我程式碼還沒仔細看呢。。。)

本人CSDN部落格目錄: