【四圣龙神录的编程教室】第19章、给敌机加上消灭特效吧

原文地址:

http://dixq.net/rp/19.html


敌机就只是突然消失的话,感觉少了点什么,我们来给他加上消灭的特效吧。

那么首先,我们把特效需要用到的一个文件添加进来。

在解决方案资源管理器里,项目上点击右键,添加项,

选择 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();
}


运行结果:

http://dixq.net/rp/swf/19.swf


本人CSDN博客目录:

http://blog.csdn.net/tidus5


展开阅读全文
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值