三角型の弾幕について・・・
Posted: 2009年5月05日(火) 16:30
チェンやチルノ、龍神録の2面でも使われる、
2つ(ひとつはたぶん応用)のつくりはどうなっているのですか?
使いたいのですが、考えても計算式が思いつきません。
2つ(ひとつはたぶん応用)のつくりはどうなっているのですか?
使いたいのですが、考えても計算式が思いつきません。
V字型 float Angle=atan2( Player.y-Boss.y , Player.x-Boss.x );//とりあえず自機を狙う for( j=-3;j<4;j++ ){//ショットfor文 for( i=0;i<MAX;i++ ){//ショットfor文 if( EnemyShot.flag==0 )break; } EnemyShot.flag=1;//フラグ EnemyShot.x=Boss.x+cos(Angle-PI/2)*(j*15)+cos(Angle)*((3-fabs(j))*15);//X座標 EnemyShot.y=Boss.y+sin(Angle-PI/2)*(j*15)+sin(Angle)*((3-fabs(j))*15);//Y座標 EnemyShot.Angle=Angle;//角度 EnemyShot.Speed=3;//スピード }//ショットfor文 ピラミット型 float Angle=atan2( Player.y-Boss.y , Player.x-Boss.x );//とりあえず自機を狙う for( t=0;t<7;t++ ){//ショットfor文 for( j=-6+t;j<7-t;j+=2 ){//ショットfor文 for( i=0;i<MAX;i++ ){//ショットfor文 if( EnemyShot.flag==0 )break; } EnemyShot.flag=1;//フラグ EnemyShot.x=Boss.x;//X座標 EnemyShot.y=Boss.y;//Y座標 EnemyShot[i].Angle=Angle+(float)j/20;//角度 EnemyShot[i].Speed=2+(float)t/2;//スピード }//ショットfor文 }//ショットfor文ちなみにfabsは絶対値関数です。
fabsを使うには<math.h>ヘッダをインクルードする必要がありますが シューティングだとサインとかコサインとかを使いますから、おそらくインクルードしてますよね。 とりあえずfabsがなぜ使えないのかを教えて下さい、 でもよく考えたらfabsは実数型ですが、今回は整数を使っているのでabs関数でよかったですね・・ abs関数もfabsと使い方は同じです、abs関数を使う場合は<stdlib.h>または<math.h>ヘッダをインクルードして下さい。 なぜ三角弾幕になるかと言うと、V字型の場合はカウンタの値を使って弾をV字型に配置して Angleの方向に同じ速度で飛ばしています。 EnemyShot.x=Boss.x+cos(Angle-PI/2)*(j*15)+cos(Angle)*((3-fabs(j))*15);//X座標 EnemyShot.y=Boss.y+sin(Angle-PI/2)*(j*15)+sin(Angle)*((3-fabs(j))*15);//Y座標 のBoss.x+はボスの座標なので発射点です、 cos(Angle-PI/2)*(j*15)は弾をAngleと直角に動かす式です、 Angle-PI/2でAngleと直角の角度にしています。 (j*15)は移動距離でもあり移動方向でもあります、 jはマイナスからプラスになるので0の時は発射点から動きません。 cos(Angle)*((3-fabs(j))*15)は弾をAngleの方向に動かす式です、 jは-3,-2,-1,0,+1,+2,+3と変化するので、 fabs関数で絶対値を求めると+3,+2,+1,0,+1,+2,+3になります、 この値を3から引いて反比例させると0,+1,+2,+3,+2,+1,0になるので、 これを移動距離にすれば真ん中に近いほど前に進み、端に行くほど動かないようになります。 この二つの動きを組み合わせるとV字型になります。 ピラミット型は最初は弾が全部発射点に重なっているんですが、 角度とスピードに差を付けることで進んでいくうちにピラミット型になります。 EnemyShot.Angle=Angle+(float)j/20;//角度 EnemyShot.Speed=2+(float)t/2;//スピード のスピードの方はtが0~6まで変化するので tが大きくなるほど弾のスピードが速くなるようになっています、 そのままだと差が大きすぎるしtが0の時はスピードも0になってしまうので、 2+(float)t/2としています、 角度の方なんですが、 -6 -5 -4 -3 -2 -1 0 +1 +2 +3 +4 +5 +6 と言う数値の並びを想像して下さい、 jはこの範囲で変化します、 そしてこの数値を使って角度をAngleからずらしていきます、 j+=2としているので二個置きに変化します、 tが増えるごとにjの最小値と最大値が減っていきます、 tが0の時はjが-6 -4 -2 0 +2 +4 +6と変化して、 tが6の時はjは0で一回実行されて終わりです、 この二つを組み合わせることで上の段に行くと弾が一つ減りスピードが上がると言う変化を作ります。 私は説明も下手なので多分この説明じゃ不十分だと思うので、遠慮せずに聞いて下さい。
//ただの円形発射 void boss_shot_bulletH010(){ #define TM010 180 #define WIDE010 20 int i,k,t=boss_shot.cnt%TM010,t2=boss_shot.cnt; static double RemAngle; if(t==0){//最初の角度を記憶 RemAngle = bossatan2(); } //60カウント以下で10カウントに1回 if(t<60 && t%10==0){ for(i=0; i<t/10+1; i++){ if((k=search_boss_shot())!=-1){ double x_sub1 = cos(RemAngle+PI/2)*(WIDE010/2) * (t/10); double y_sub1 = sin(RemAngle+PI/2)*(WIDE010/2) * (t/10); double x_sub2 = cos(RemAngle+PI/2)*(WIDE010/2) * (i*2); double y_sub2 = sin(RemAngle+PI/2)*(WIDE010/2) * (i*2); boss_shot.bullet[k].col = 0;//弾の色 boss_shot.bullet[k].x = boss.x - x_sub1 + x_sub2;//座標 boss_shot.bullet[k].y = boss.y - y_sub1 + y_sub2; boss_shot.bullet[k].knd = 8;//弾の種類 boss_shot.bullet[k].angle = RemAngle;//角度 boss_shot.bullet[k].flag = 1; boss_shot.bullet[k].cnt = 0; boss_shot.bullet[k].spd = 2;//スピード se_flag[0]=1; } } } }
void enemy_shot_pat7(int i){ #define WIDE010 20 int h,t2=e_shot.count; int t = e_shot.count; int j = e_shot.count; static double RemAngle; if(t==0){//最初の角度を記憶 RemAngle = atan2(enemy.x-player.x,enemy.y-player.y); } //60カウント以下で10カウントに1回 if(t<60 && t%10==0){ for(h=0; h<t/10+1; h++){ double x_sub1 = cos(RemAngle+PI/2)*(WIDE010/2) * (t/10); double y_sub1 = sin(RemAngle+PI/2)*(WIDE010/2) * (t/10); double x_sub2 = cos(RemAngle+PI/2)*(WIDE010/2) * (h*2); double y_sub2 = sin(RemAngle+PI/2)*(WIDE010/2) * (h*2); e_shot.bullet[j].flag=1; e_shot.bullet[j].x=enemy.x - x_sub1 + x_sub2; e_shot.bullet[j].y=enemy.y - y_sub1 + y_sub2; e_shot[i].bullet[j].img=5; e_shot[i].bullet[j].col=3; e_shot[i].bullet[j].spd=3.0f; e_shot[i].bullet[j].angle=RemAngle;//角度 } } for(int j=0;j<200;j++){ e_shot[i].bullet[j].x+=e_shot[i].bullet[j].spd*cos(e_shot[i].bullet[j].angle); e_shot[i].bullet[j].y+=e_shot[i].bullet[j].spd*sin(e_shot[i].bullet[j].angle); } }
for(int j=0;j<200;j++){ e_shot.bullet[j].x+=e_shot.bullet[j].spd*cos(e_shot.bullet[j].angle); e_shot.bullet[j].y+=e_shot.bullet[j].spd*sin(e_shot.bullet[j].angle); }
void enemy_shot_pat1_e(int i){ for(int j=0;j<1;j++){ if(e_shot.count==0){ e_shot.bullet[j].flag=1; e_shot.bullet[j].x=e_shot[i].ex; e_shot[i].bullet[j].y=e_shot[i].ey; e_shot[i].bullet[j].img=5; e_shot[i].bullet[j].col=j%6; e_shot[i].bullet[j].spd=1.0f; e_shot[i].bullet[j].angle=PI2/100*j+atan2(player.y-e_shot[i].bullet[j].y,player.x-e_shot[i].bullet[j].x); PlaySoundMem( sound_effect[4] , DX_PLAYTYPE_BACK ) ; } } for(int j=0;j<1;j++){ e_shot[i].bullet[j].x+=e_shot[i].bullet[j].spd*cos(e_shot[i].bullet[j].angle); e_shot[i].bullet[j].y+=e_shot[i].bullet[j].spd*sin(e_shot[i].bullet[j].angle); } }
void enemy_shot_pat1_e(int i){ static float Angle; if( e_shot.count==0 )Angle=atan2(player.y-e_shot.bullet[j].y,player.x-e_shot.bullet[j].x); static int j,t; if( e_shot.count==0 )j=0; if(e_shot.count<=20 && e_shot.count%5==0){ t=j+e_shot.count/5; float p=(float)(t-j)/2; for(;j<=t;j++){ e_shot.bullet[j].flag=1; e_shot.bullet[j].x=e_shot.ex+cos(Angle+PI/2)*(float)(10*(t-j)-5*p); e_shot[i].bullet[j].y=e_shot[i].ey+sin(Angle+PI/2)*(float)(10*(t-j)-5*p); e_shot[i].bullet[j].img=5; e_shot[i].bullet[j].col=j%6; e_shot[i].bullet[j].spd=1.0f; e_shot[i].bullet[j].angle=Angle; } PlaySoundMem( sound_effect[4] , DX_PLAYTYPE_BACK ) ; } for(int j=0;j<15;j++){ e_shot[i].bullet[j].x+=e_shot[i].bullet[j].spd*cos(e_shot[i].bullet[j].angle); e_shot[i].bullet[j].y+=e_shot[i].bullet[j].spd*sin(e_shot[i].bullet[j].angle); } }こんな感じでしょうかね?
if( e_shot.count==0 )Angle=atan2(player.y-e_shot.bullet[j].y,player.x-e_shot.bullet[j].x);
void enemy_shot_pat1_e(int i){ static float Angle; static int j,t; if( e_shot.count==0 ){ j=0; Angle=PI2/100*j+atan2(player.y-e_shot.bullet[j].y,player.x-e_shot.bullet[j].x); } if(e_shot.count<=20 && e_shot.count%5==0){ t=j+e_shot[i].count/5; float p=(float)(t-j)/2; for(;j<=t;j++){ e_shot[i].bullet[j].flag=1; e_shot[i].bullet[j].x=e_shot[i].ex+cos(Angle+PI/2)*(float)(10*(t-j)-5*p); e_shot[i].bullet[j].y=e_shot[i].ey+sin(Angle+PI/2)*(float)(10*(t-j)-5*p); e_shot[i].bullet[j].img=5; e_shot[i].bullet[j].col=j%6; e_shot[i].bullet[j].spd=1.0f; e_shot[i].bullet[j].angle=Angle; } PlaySoundMem( sound_effect[4] , DX_PLAYTYPE_BACK ) ; } for(int j=0;j<15;j++){ e_shot[i].bullet[j].x+=e_shot[i].bullet[j].spd*cos(e_shot[i].bullet[j].angle); e_shot[i].bullet[j].y+=e_shot[i].bullet[j].spd*sin(e_shot[i].bullet[j].angle); } }でしょうかね、