三角型の弾幕について・・・
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);
}
}でしょうかね、