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