【四圣龙神录的编程教室】第22章、放炸弹来攻击吧

翻译 2015年07月09日 01:16:32
原文地址:

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



这次讲炸弹攻击。
和往常一样,准备好信息保存的地方,然后进行加载,然后让他自动计算,大概就是这样的感觉就行了。。。
在之前的章节里,我们准备了变量来展现特效。
之前敌机消灭时,使用了特效。现在在同一个存储区里,加载炸弹的特效看看。
之前也说过了,这个特效变量里,加载任何特效都是可以的。
以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号特效的处理。

运行结果:

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



(PS: 继续来填坑。。。  公司项目蛋疼。。。照着成功项目换皮,问题是,你皮难看,做出来的东西还不是只能呵呵。。。  结果和原先的相差无几。。。

好啦,过两天要考科二了。攒人品啊攒人品。。

文字基本是照翻,有啥不通顺的,对照代码看吧。。。 我代码还没仔细看呢。。。)



本人CSDN博客目录:

http://blog.csdn.net/tidus5


相关文章推荐

【四圣龙神录的编程教室】第23章、来制作决死炸弹吧

原文地址: http://dixq.net/rp/23.html继续讲炸弹制作,这次是讲怎么制作决死炸弹(中弹后立刻按炸弹,来消耗炸弹而自己不死)。 这里,我们首先来重温一下,关于角色状态变化的标...
  • Tidus5
  • Tidus5
  • 2016年02月27日 16:56
  • 601

【四圣龙神录的编程教室】第9章、试试操作人物的移动吧

原文地址: http://dixq.net/rp/9.html 让我们给角色加上在可移动范围之内可以上下左右任意移动的功能吧。 当我们斜向移动的时候,如果不把速度减为1/根号2,那么移动速度就不...
  • Tidus5
  • Tidus5
  • 2013年11月24日 21:16
  • 1366

【四圣龙神录的编程教室】第1章、准备项目的素材

原文地址: http://dixq.net/rp/1.html 龙神录的编程教室,是使用VisualStudio 2005 或者 2008 作为工具来讲解的。 下面的项目,是带上了素材一起打包进去...
  • Tidus5
  • Tidus5
  • 2013年11月14日 00:57
  • 2094

【四圣龙神录的编程教室】第24章、来制作boss吧

原文地址: http://dixq.net/rp/24.html 那么接下来、终于要进入弹幕的制作了。 首先,要制作BOSS的弹幕的话,就需要有个BOSS。 BOSS的身体的制作的,要注意很多...
  • Tidus5
  • Tidus5
  • 2016年03月10日 17:19
  • 912

【四圣龙神录的编程教室】第0章 开始

原文地址: http://dixq.net/rp/0.html 龙神录的编程教室,是以通俗易懂的方式,来讲解基本的射击游戏作为目标的地方。 如果把这里的每个章节,都认真学习了之后,你就可以制作出...
  • Tidus5
  • Tidus5
  • 2013年11月13日 23:07
  • 1999

【四圣龙神录的编程教室】第4章、画个自机形象看看吧

原文地址: http://dixq.net/rp/4.html 接下来,画个人自机试试吧。 为此,我们首先得定义个结构体,把自机所需的变量都定义好。 自机的结构体,定义成如下这样。 ——————...
  • Tidus5
  • Tidus5
  • 2013年11月17日 21:44
  • 1542

【四圣龙神录的编程教室】第6章、定制一下主循环里的调用函数吧

原文地址: http://dixq.net/rp/6.html MainLoop里调用的函数,会把当前的各种各样的状态返回,对吧。 也就是说,我们有必要定制一下MainLoop里面调用的函数。 ...
  • Tidus5
  • Tidus5
  • 2013年11月23日 20:41
  • 1161

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

原文地址: http://dixq.net/rp/19.html 敌机就只是突然消失的话,感觉少了点什么,我们来给他加上消灭的特效吧。 那么首先,我们把特效需要用到的一个文件添加进来。 在解决方...
  • Tidus5
  • Tidus5
  • 2014年04月02日 22:50
  • 1288

【四圣龙神录的编程教室】第16章、来制作洩矢大人的弹幕吧

因为之前已经做好了固定的模式,所以弹幕的添加就变的很容易了。 这次只要把弹幕函数进行改动就行了。 我们就用shot_bullet_H008来实现洩矢大人的弹幕吧。 【洩矢大人】这个弹幕是东方风神录E...
  • Tidus5
  • Tidus5
  • 2014年03月09日 15:32
  • 1457

【四圣龙神录的编程教室】第14章、来制作各种各样的弹幕数据吧

那些麻烦的设定终于搞定了,那么这次我们就来做各种各样的弹幕数据吧。 一直发射自机狙的弹幕函数001....
  • Tidus5
  • Tidus5
  • 2014年02月18日 00:18
  • 2517
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【四圣龙神录的编程教室】第22章、放炸弹来攻击吧
举报原因:
原因补充:

(最多只允许输入30个字)