今回はボムの話です。
またまた例によって、登録情報格納庫を作ってやり、そこに登録し、後は自動的に計算させるという感じで行います。
前の章で「エフェクト」を行う変数を用意しましたね。
前は敵の消滅エフェクトに使用しましたが、今度は同じ格納庫にボムのエフェクトを入れてみましょう。
前にも言いましたが、このエフェクトを登録する変数には何を登録してもいいのです。
エフェクトの識別番号であるkndに決めた番号をいれてやれば、その通りに計算されるようにすれば、
同じ格納庫を使えるのです。
龍神録のボムのエフェクトには、
「ピュー・・・ドン」となるエフェクトと、(これをエフェクト番号1とする)
エフェクトラインが上下左右に移動するエフェクトと、(これをエフェクト番号2とする)
キャラクタが上にスーっと移動するエフェクトがあります。(これをエフェクト番号3とする)
ボムを登録する時、このエフェクト番号にわけて登録することで、これを実現してみましょう。
まずは下準備です、。
---- 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の敵にpower食らわす 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();//ボードの描画 }
---- 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秒に1回 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 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();//ドガーンとゆれる画面の処理 calc_del_effect();//消滅エフェクトの計算 calc_effect();//エフェクトの計算 bom_calc();//ボム計算 }
enter_bomでボムを登録します。登録されたボムは130カウントの間計算され、
エフェクトの登録や、画面の明るさの変更などを行います。
calc_effect()関数では、エフェクトの計算を行っており、今回増えたエフェクト番号1,2,3の処理が追加されています。
実行結果
- Remical Soft -