第二十二章 让自机放出Boom吧

>>点此回到教程目录

本章我们讨论Boom。

我们再次和之前一样,先制作登录信息数据库,然后在数据库里面登录数据,之后让其自动计算。

在前面的章节中,我们准备了用于“特效”执行的变量。

之前我们将其用于敌人的消灭特效,这次我们试着在同一个数据库里面放入Boom的特效吧。

之前也说过了,在这个特效登录函数里面登录什么都是可以的。

只要我们往特效的识别编号knd里面放入决定好了的编号,然后和之前一样计算的话,我们就可以使用同一个数据库了。

在龙神录的特效里面,有“biu……咚”的特效(这个是特效编号1),以及特效线上下左右移动的特效(这个是特效编号2),还有角色突然往上移动的特效。(这个是特效编号3)

登录Boom的时候,用这些特效编号分别登录,然后试着实现它们吧。

首先做以下准备。 1 —-在 struct.h 中进行以下追加 —-

//特效
typedef struct{
    int flag,cnt,col,knd,img,eff;
    double x,y,r,ang,spd,mvang,brt;
}effect_t;
//Boom的信息
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];      //Boom的特效图像
GLOBAL bom_t bom;               //Boom
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函数中进行以下变更 —-

//碰撞判定main
void out_main(){
    cbom_and_enemy();
    cshot_and_enemy();
    enemyshot_and_ch();
}

—-在 out.cpp 的任意地方进行以下变更 —-

//让s编号的敌人承受power的伤害
void hit_enemy(int s,int power){
    enemy[s].hp-=power;//减少子弹所有的power量的HP
    enemy_death_judge(s);//判断敌人是否击毁
}

//Boom和敌人的处理
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();//背景绘制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);// Boom特效
        graph_effect(2);// Boom线特效
        graph_effect(3);// Boom角色特效
        graph_board();//面板绘制
}

这个章节中我们往结构体中新加入这样三个成员:

保存Boom信息的bom_t 设定画面亮度的bright_set_t 咚! 地摇晃画面的信息dn_t 用bright_set_t保存的变量通常是255,如果有必要降低亮度的话再修改它即可。

用dn_t保存的变量用和之前一样的方法,在想要登录、计算、摇动画面的时候使用。

Boom的变量的使用方法和前面一样。

我们已经完成了预先准备。那么我们试着开始特效的计算吧。

—- 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:// Boom的特效
                                        //坐标计算
                                        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:// Boom特效(角色)
                                        //座標計算 坐标计算
                                        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://Boom的特效(线)
                                        //坐标计算
                                        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;//设置flag为有效
                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;//设置flag为有效
                                        effect[k].brt=255;//亮度设置为最大值
                                        effect[k].ang=rang(PI);//随机角度
                                        effect[k].col=del_effect[i].col;//设置颜色
                                        effect[k].eff=1;// 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++;
                }
        }
}

//登录Boom
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;// Boom的线的特效
                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;// Boom的线的特效
                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;//Boom的角色、线的特效
                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;
        }
}

//Boom计算
void bom_calc(){
        int n,k,shot_angle[4]={0,PI,PI/2,PI*1.5};//4发特效飞行的角度
        if(ch.flag==0 && bom.flag==0){//角色如果是通常状态且没有放Boom
                if(CheckStatePad(configpad.bom)==1){//如果Boom键被按下
                        enter_bom();
                }
        }
        if(bom.flag==1){//如果Boom已经被登录
                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:Boom的特效
                                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;
                }
        }
}

//咚梆地摇动画面的处理
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();//咚梆地摇晃画面的处理
        calc_del_effect();//消灭特效的计算
        calc_effect();//特效的计算
        bom_calc();//Boom计算
}

在enter_bom中登录Boom。登录了的Boom在130次计数中计算,进行特效的登录、画面的亮度的变更等处理。

在calc_effect()函数中进行特效的计算,在本章中追加了的特效编号为1、2、3的处理。


运行结果


>>点此回到教程目录

results matching ""

    No results matching ""