ボスはボーっとたってるだけでは見栄えがしないので、周りに紋章を回転させたり、エフェクトを付けてみましょう。
またこの節では、敵の移動制御関数をもう少し拡張したりもします。
ボスは上下にフワフワ動いているとそれっぽくみえますね。
表示用の座標をx,yと別にdx,dyとして用意します。そこに、表示用座標を代入します。
では必要な画像を読み込んで、ボスのエフェクトを描画してみましょう。
---- boss_shot.cpp に以下を追加 ---- void calc_boss(){ boss.dx=boss.x; boss.dy=boss.y+sin(PI2/130*(count%130))*10; } ---- load関数に以下を追加 ---- img_etc[2] = LoadGraph( "../dat/img/enemy/bossback.png" ); img_etc[5] = LoadGraph( "../dat/img/enemy/bossback3.png" ); img_etc[6] = LoadGraph( "../dat/img/enemy/bossback4.png" ); ---- graph.cpp の以下の箇所を修正 ---- void graph_boss_effect(){ SetDrawBlendMode( DX_BLENDMODE_ALPHA, 150) ; DrawRotaGraphF(boss.dx+FX, boss.dy+FY, (0.4+0.05*sin(PI2/360*(count%360)))*3, 2*PI*(count%580)/580, img_etc[5], TRUE); DrawRotaGraphF(boss.dx+FX, boss.dy+FY, (0.5+0.1*sin(PI2/360*(count%360)))*2, 2*PI*(count%340)/340,img_etc[2], TRUE); DrawRotaGraphF(boss.dx+60*sin(PI2/153*(count%153))+FX, boss.dy+80*sin(PI2/120*(count%120))+FY, 0.4+0.05*sin(PI2/120*(count%120)), 2*PI*(count%30)/30,img_etc[6], TRUE); DrawRotaGraphF(boss.dx+60*sin(PI2/200*((count+20)%200))+FX, boss.dy+80*sin(PI2/177*((count+20)%177))+FY, 0.3+0.05*sin(PI2/120*(count%120)), 2*PI*(count%35)/35,img_etc[6], TRUE); SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0) ; DrawRotaGraphF(boss.dx+60*sin(PI2/230*((count+40)%230))+FX, boss.dy+80*sin(PI2/189*((count+40)%189))+FY, 0.6+0.05*sin(PI2/120*(count%120)), 2*PI*(count%40)/40,img_etc[6], TRUE); } void graph_boss(){ int i; if(boss.flag==0)return; graph_boss_effect(); DrawRotaGraphF(boss.dx+FX+dn.x,boss.dy+FY+dn.y, 1.0f,0.0f,img_dot_riria[0],TRUE);
また、前回までに作った物理的に移動した方程式で移動する関数を拡張子、
「今いる地点からどれだけ離れた位置に、何カウントで、移動する」
という指定が出来る関数を作ってみましょう。
---- boss_shot.cpp に以下を追加 ---- //物理的計算を点と距離指定で登録をする(指定時間tで定位置に戻す) void input_phy_pos(double x,double y,int t){//t=移動にかける時間 double ymax_x,ymax_y; if(t==0)t=1; boss.phy.flag=1;//登録オン boss.phy.cnt=0;//カウンタ初期化 boss.phy.set_t=t;//移動にかける時間をセット ymax_x=boss.x-x;//移動したい水平距離 boss.phy.v0x=2*ymax_x/t;//水平成分の初速度 boss.phy.ax =2*ymax_x/(t*t);//水平成分の加速度 boss.phy.prex=boss.x;//初期x座標 ymax_y=boss.y-y;//移動したい鉛直距離 boss.phy.v0y=2*ymax_y/t;//鉛直成分の初速度 boss.phy.ay =2*ymax_y/(t*t);//鉛直成分の加速度 boss.phy.prey=boss.y;//初期y座標 } //今いる位置からdist離れた位置にtカウントで移動する int move_boss_pos(double x1,double y1,double x2,double y2,double dist, int t){ int i=0; double x,y,angle; for(i=0;i<1000;i++){ x=boss.x,y=boss.y;//今のボスの位置をセット angle=rang(PI);//適当に向かう方向を決める x+=cos(angle)*dist;//そちらに移動させる y+=sin(angle)*dist; if(x1<=x&&x<=x2 && y1<=y&&y<=y2){//その点が移動可能範囲なら input_phy_pos(x,y,t); return 0; } } return -1;//1000回試してダメならエラー } ---- boss_shot.cpp の boss_shotmain の以下(赤部)を追加 ---- // void boss_shot_main(){ if(stage_count==boss.appear_count[boss.knd] && boss.flag==0)//開始時間なら enter_boss(boss.knd);//開始 if(boss.flag==0)//ボスが登録されて無ければ戻る return; calc_boss(); if(boss.phy.flag==1)//物理演算移動オンなら ---- boss_shotH.cpp の先頭に以下を追加 ---- extern int move_boss_pos(double x1,double y1,double x2,double y2,double dist, int t); ---- struct.h に以下を追加 ---- //ボスの情報 typedef struct{ int flag,cnt,knd,wtime,state,endtime,hagoromo,graph_flag; int hp,hp_max; int appear_count[2],set_hp[DANMAKU_MAX],back_knd[DANMAKU_MAX]; double x,y,dx,dy,ang,spd; phy_t phy; }boss_t;
move_boss_pos関数では x1以上x2以下 y1以上y1以下の範囲でdist離れた位置にtカウントで移動させる関数です。
適当にあっちこっち向かせてよい位置を決めています。
1000回試して無理なら諦めます。
この関数は次の章から使うので、実行結果はそちらをご覧下さい。
- Remical Soft -