原文地址:
http://dixq.net/rp/23.html
继续讲炸弹制作,这次是讲怎么制作决死炸弹(中弹后立刻按炸弹,来消耗炸弹而自己不死)。
这里,我们首先来重温一下,关于角色状态变化的标志flag。
ch.flag 是
0的时候,是通常的状态。
1的时候,是释放炸弹时的状态。
2的时候,是死了之后,从下往上浮的状态。
被子弹击中的瞬间,flag设置为1,并且还等于1的时候,可以接受放炸弹。
这里并不需要特意添加可以放炸弹的处理,只要让
if(ch.flag==0 || ch.flag==1)
的时候,可以允许放炸弹,这样改动的地方就非常少啦。
放决死弹的时候,把画面变暗,再播放特效看看。
特效呢,还是和之前一样,用一个特效变量进行播放就行了。
把敌机死亡时用的特效图像,从自机处发射出去就好啦。
首先,是如下的准备动作。
---- char.cpp 的 calc_ch函数添加成如下的样子 ----
void calc_ch(){
if(ch.flag==1){//决死炸弹可以释放的话
bright_set.brt=80;//变暗
if(ch.cnt>20){//0.33秒内可以释放决死炸弹
ch.flag =2; //1:可以释放决死的状态 2:死后往上浮动的状态
ch.cnt =0;
bright_set.brt=255;
}
}
if(ch.cnt==0 && ch.flag==2){//当前的瞬间死了的话
ch.x=FIELD_MAX_X/2;//设置坐标
ch.y=FIELD_MAX_Y+30;
ch.mutekicnt++;//设置成无敌
}
if(ch.flag==2){//死后往上浮动的状态的话
unsigned int push=CheckStatePad(configpad.left)+CheckStatePad(configpad.right)
+CheckStatePad(configpad.up)+CheckStatePad(configpad.down);
ch.y-=1.5;//把角色往上移动
//往上移动1秒、或者往上移动一定距离并且有键按下
if(ch.cnt>60 || (ch.y<FIELD_MAX_Y-20 && push)){
ch.cnt=0;
ch.flag=0;//把角色的状态恢复原装
}
}
if(ch.mutekicnt>0){//如果无敌计数不等于0
ch.mutekicnt++;
if(ch.mutekicnt>150)//如果大于150
ch.mutekicnt=0;//计数重置
}
ch.cnt++;//角色的计数增加
ch.img=(ch.cnt%24)/6;//选择当前所用的图像
}
---- effect.cpp 的以下函数做如下更改 ----
//计算特效
void calc_effect(){
for(int i=0;i<EFFECT_MAX;i++){
if(effect[i].flag>0){//如果特效已经注册
effect[i].x+=cos(effect[i].mvang)*effect[i].spd;
effect[i].y+=sin(effect[i].mvang)*effect[i].spd;
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://炸弹的特效
//速度计算
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://炸弹特效(主角)
//亮度计算
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://炸弹的特效(线条)
//亮度计算
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;
case 4://决死炸弹特效
//亮度计算
if(effect[i].cnt>=6)
effect[i].brt-=255/6;
effect[i].r+=0.12;
effect[i].cnt++;
if(effect[i].cnt>=12 || ch.flag!=1)
effect[i].flag=0;
break;
default:
printfDx("effect设定错误\n");
break;
}
}
}
}
//炸弹计算
void bom_calc(){
int n,k,shot_angle[4]={0,PI,PI/2,PI*1.5};//4个特效的飞行角度
if((ch.flag==0||ch.flag==1) && 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;
}
}
}
void enter_crybom_effect(){
int k;
if(ch.flag==1){
if(ch.cnt%2==0){
if((k=search_effect())!=-1){
effect[k].flag=1;
effect[k].cnt=0;
effect[k].knd=4;//决死炸弹特效
effect[k].brt=255;
effect[k].ang=rang(PI);
effect[k].spd=0;
effect[k].r=0;
effect[k].eff=2;
effect[k].img=img_del_effect[GetRand(4)];
effect[k].x=ch.x;
effect[k].y=ch.y;
}
}
}
}
void effect_main(){
dn_calc();//震屏和画面摇晃的处理
calc_del_effect();//消除特效的处理
calc_effect();//特效的处理
bom_calc();//炸弹的处理
enter_crybom_effect();
}
---- out.cpp enemyshot_and_ch函数----
//敌机射击和自机的处理
void enemyshot_and_ch(){
int s,n;
for(s=0;s<SHOT_MAX;s++){//敌机弹幕总数
if(shot[s].flag>0){//那个弹幕在显示的话
for(n=0;n<SHOT_BULLET_MAX;n++){//子弹总数
if(shot[s].bullet[n].flag==1){//子弹在显示的话
if(out_judge_enemyshot(s,n)==1){//自机和那个子弹接触的话
shot[s].bullet[n].flag=0;//子弹消失
if(ch.flag==0 && ch.mutekicnt==0){
ch.cnt=0;
ch.flag=1;
se_flag[3]=1;
}
}
}
}
}
}
}
---- 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);//敌机死亡特效
if(bright_set.brt!=255)SetDrawBright(255,255,255);
graph_effect(4);//决死炸弹的特效
if(bright_set.brt!=255)SetDrawBright(bright_set.brt,bright_set.brt,bright_set.brt);
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();//得分面板的绘制
}
---- char.cpp 的 ch_move函数的改动 ----
void ch_move(){
int i,sayu_flag=0,joge_flag=0;
double x,y,mx,my,naname=1;
double move_x[4]={-4.0,4.0,0,0},move_y[4]={0,0,4.0,-4.0};
int inputpad[4];
inputpad[0]=CheckStatePad(configpad.left); inputpad[1]=CheckStatePad(configpad.right);
inputpad[2]=CheckStatePad(configpad.down); inputpad[3]=CheckStatePad(configpad.up);
if(ch.flag==1)return;//正在等待按决死,不能移动
说明就不加了。
运行结果
PS: 这个坑已经好久没填了。前些日子,忙着项目上线,以为能过上好日子了。
结果,还是继续坑,继续改。。。唉,感觉今年这时候和去年这时候,没啥改变,薪水多了1k 。何时才能熬出头啊。。。 真是走也不是,留也蛋疼。
本人CSDN博客目录:
http://blog.csdn.net/tidus5
本人github博客:
http://tidus5.github.io