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

原文地址:
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;//正在等待按决死,不能移动

说明就不加了。

运行结果

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

PS: 这个坑已经好久没填了。前些日子,忙着项目上线,以为能过上好日子了。
结果,还是继续坑,继续改。。。唉,感觉今年这时候和去年这时候,没啥改变,薪水多了1k 。何时才能熬出头啊。。。 真是走也不是,留也蛋疼。

本人CSDN博客目录:
http://blog.csdn.net/tidus5

本人github博客:
http://tidus5.github.io

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

抵扣说明:

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

余额充值