第十九章 给敌人加上消灭特效吧

>>点此回到教程目录

如果敌人突然就消失了,看起来实在是很寂寞,现在我们试着做出消灭特效吧。

那么,我先追加一个效果用的文件。

在解决方案管理器里面,右键project项目追加一个新的项目,现在我们往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;//设置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是发光效果。这里设置为光效果。
                                        effect[k].img=img_del_effect[effect[k].col];//设置消灭的图像
                                        effect[k].knd=0;//效果的种类是0号(消灭特效的knd一定是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秒登录1次特效。然后,搜索效果的登录编号,最后设置信息。

和之前所说的一样,由于效果变量可以使用任何值,因此我们往knd传入0——它用于标识这是哪个种类的特效。而今后我们就把消灭特效设置为0号的特效。

在out_main中进行自机总射击的子弹与所有敌人的总碰撞判定。

那么与此同时,进行下面那样的修改。

—-在 out.cpp 中进行以下部分的变更 —-

/***修改请注意***/
extern void enter_del_effect(int);
/***修改请注意***/

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;//敌人的击毁声

                /***修改请注意***/
                enter_del_effect(s);
                /***修改请注意***/

—-在 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;
        /***修改请注意***/

        //flag、计数器、移动模式、方向、敌人的种类、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();//自机射击main
                enemy_main();//敌人处理main
                shot_main(); //射击main
                out_main();  //碰撞判定

                /***修改请注意***/
                effect_main();//特效main
                /***修改请注意***/

                graph_main();//绘制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();
}

运行结果


>>点此回到教程目录

results matching ""

    No results matching ""