誰か教えてください。
誰か教えてください。
東方風のSTGを作っているんですが、
「東方永夜抄」の夢符「封魔陣」の弾幕を真似したいんですけど、
どうしても、途中で5つの角度に分かれる弾幕の作り方がわからないんです。
弾が5つ重なって真下に下りてきて、途中に真ん中の1つはそのままの角度。
あとの二つは、まっすぐから±45度で、
もう二つは、まっすぐから±22.5度なんですけど、
誰か、教えてください。
環境は、VC++ 2008EEで、XPをつかっています。
知識は、興味本位でやり始めたばっかりなので、
簡単な文は分かるぐらいです。
よろしくお願いします。
「東方永夜抄」の夢符「封魔陣」の弾幕を真似したいんですけど、
どうしても、途中で5つの角度に分かれる弾幕の作り方がわからないんです。
弾が5つ重なって真下に下りてきて、途中に真ん中の1つはそのままの角度。
あとの二つは、まっすぐから±45度で、
もう二つは、まっすぐから±22.5度なんですけど、
誰か、教えてください。
環境は、VC++ 2008EEで、XPをつかっています。
知識は、興味本位でやり始めたばっかりなので、
簡単な文は分かるぐらいです。
よろしくお願いします。
Re:誰か教えてください。
うまく説明が出来ないんですけど、
まず、8way弾で、その弾には5つ弾が重なっていて、
発射された後、弾一つ一つに、発射されてある一定時間以上たったなら、
弾の角度を変える。ってやつなんですけど、
一気じゃなくて、弾一つ一つで連続して変化するという弾幕です。
>それとも条件分岐の具体的な内容ですか?
はい、できればそれでお願いします。
まず、8way弾で、その弾には5つ弾が重なっていて、
発射された後、弾一つ一つに、発射されてある一定時間以上たったなら、
弾の角度を変える。ってやつなんですけど、
一気じゃなくて、弾一つ一つで連続して変化するという弾幕です。
>それとも条件分岐の具体的な内容ですか?
はい、できればそれでお願いします。
Re:誰か教えてください。
bさん、返答ありがとうございます。
でも、できればソースを載せてほしいです。
正直、自分の知識的にちょっと危ないので、
龍神録のソースを使っていますので、ぜひともお願いします。
でも、できればソースを載せてほしいです。
正直、自分の知識的にちょっと危ないので、
龍神録のソースを使っていますので、ぜひともお願いします。
Re:誰か教えてください。
はい、指摘?ありがとうございます。
一応自分でも、軽く分かる範囲で作ってみました。
ですが、やはり知識不足で理想にはぜんぜん遠くて
そのために、投稿しました。良い返答を期待しています。
一応自分でも、軽く分かる範囲で作ってみました。
ですが、やはり知識不足で理想にはぜんぜん遠くて
そのために、投稿しました。良い返答を期待しています。
Re:誰か教えてください。
まあ永夜抄やった事があるのでどんな弾幕かはわかりますけどね
封魔陣は二回曲がると思いますけど
一回も二回もそれほど変わらないので省略します
bさんの方法でも良いですがパッと思いついた方法を書きます
まず弾の構造体に角度を格納するAngleと言う変数と
多目的に使えるDATAと言う変数があるとします
弾を一度に五個登録する時にfor文でも使って
DATA変数に何でも良いんですが
とりあえず 0 1 2 3 4 の順番に数値を入れます
それ以外の数値は同じなので
重なって飛んで行きます
そして弾の移動パターンの中で
弾のカウンタが指定した時間になったら
Angle変数に角度を加算します
45度と22.5度を導く効率の良い式が浮かばないので
#define PI 3.1415926535898
と言う宣言が行われているとして
PI=180度なので
45度=PI/180*45
22.5度=PI/180*22.5
で求めます
そして
if( Shot.Count==60 ){
if( Shot.DATA==0 )Shot.Angle+=PI/180*45;
if( Shot.DATA==1 )Shot.Angle+=PI/180*22.5;
if( Shot.DATA==3 )Shot.Angle-=PI/180*22.5;
if( Shot.DATA==4 )Shot.Angle-=PI/180*45;
}
のような処理で実現します
これで発射されてから一秒後に五方向に別れる・・と思う
簡単にするために無駄が多くなってるので
慣れて来たら効率化してみてください
bさんのように登録時に角度を求めて時間になったら
角度に足す事で曲げる事もできます
私は説明では不十分かもしれないので
わからない事があったら言って下さい
サンプルとかも作りますよ
封魔陣は二回曲がると思いますけど
一回も二回もそれほど変わらないので省略します
bさんの方法でも良いですがパッと思いついた方法を書きます
まず弾の構造体に角度を格納するAngleと言う変数と
多目的に使えるDATAと言う変数があるとします
弾を一度に五個登録する時にfor文でも使って
DATA変数に何でも良いんですが
とりあえず 0 1 2 3 4 の順番に数値を入れます
それ以外の数値は同じなので
重なって飛んで行きます
そして弾の移動パターンの中で
弾のカウンタが指定した時間になったら
Angle変数に角度を加算します
45度と22.5度を導く効率の良い式が浮かばないので
#define PI 3.1415926535898
と言う宣言が行われているとして
PI=180度なので
45度=PI/180*45
22.5度=PI/180*22.5
で求めます
そして
if( Shot.Count==60 ){
if( Shot.DATA==0 )Shot.Angle+=PI/180*45;
if( Shot.DATA==1 )Shot.Angle+=PI/180*22.5;
if( Shot.DATA==3 )Shot.Angle-=PI/180*22.5;
if( Shot.DATA==4 )Shot.Angle-=PI/180*45;
}
のような処理で実現します
これで発射されてから一秒後に五方向に別れる・・と思う
簡単にするために無駄が多くなってるので
慣れて来たら効率化してみてください
bさんのように登録時に角度を求めて時間になったら
角度に足す事で曲げる事もできます
私は説明では不十分かもしれないので
わからない事があったら言って下さい
サンプルとかも作りますよ
Re:誰か教えてください。
書いている間に更新されましたね
私は龍神録のコードが理解できなかったので
オリジナルのコードを使っています
なのでサンプルを作るのが難しいですが
できる限り善処します
私は龍神録のコードが理解できなかったので
オリジナルのコードを使っています
なのでサンプルを作るのが難しいですが
できる限り善処します
Re:誰か教えてください。
簡単に書いてみました。間違いとかあるかもしれませんが(^^;)
さすがに初見で龍神録の変数の仕様とかはわからないので、要所のみ書いてみました。
仕様は封魔陣ノーマルのスぺカを基準で。
さすがに初見で龍神録の変数の仕様とかはわからないので、要所のみ書いてみました。
仕様は封魔陣ノーマルのスぺカを基準で。
//弾の発射フラグ立て============================= int i , j ; double angle1 , angle2 ;//第一、第二動作角度 const double addangle1 = 2 * PI / 弾の数(8WAYなら8) ; const double addangle2 = 弾の間隔の角度(ラジアンで22.5度) ; angle1 = 起点となる角度、自機狙いなら自機の角度を入れておく for( i = 0 ; i < 弾の数(8WAYなら8) ; i++ )//すみません、抜けてました { angle1 += addangle1 ; //↓どちらかを使ってください、今回は5Wayということで上の方のみで //Nway弾が奇数のとき angle2 = -(double)( nWay / 2 ) * addangle2 ; //Nway弾が偶数のとき angle2 = -(double)( nWay - 1 ) / 2.0 * addangle2 ; for( j = 0 ; j < 弾の数(5方向に弾を分けるなら5) ; j++ ) { //発射されていない弾のフラグを探す { 第一動作角度にangle1を代入 第二動作角度にangle2を代入 angle2 += addangle2 ; } } }
Re:誰か教えてください。
追記:ちるちるさんの方法ですが、弾の発射個数の分岐が7個に変わった場合にソースを書き換える個所が多数出ると思います。
また、0,1,2,3,4と弾に番号を振っていますが、それが何を指し示すのかわからない数字、マジックナンバーになってしまっているのではないでしょうか?
自分の方法ですと、弾を何個発射するかの変数、const int shotnum = 5 ;とかを弾を発射する関数に用意すれば、その数値を変えるだけで角度調節、発射個数変更が効きます。
また、0,1,2,3,4と弾に番号を振っていますが、それが何を指し示すのかわからない数字、マジックナンバーになってしまっているのではないでしょうか?
自分の方法ですと、弾を何個発射するかの変数、const int shotnum = 5 ;とかを弾を発射する関数に用意すれば、その数値を変えるだけで角度調節、発射個数変更が効きます。
Re:誰か教えてください。
龍神録では、弾の「状態」を表すために「.state」が用意してあります。
このstateに好きな数字を入れて、その数字で条件わけしてやればいいと思います。
今、1箇所から同じ方向に5つ弾が出て、途中でその5つが分岐するなら、
その5つに0~4の数字でもふってやり、その数字に応じてあるカウント数になったら、
角度を変えてみてはどうでしょう?
このstateに好きな数字を入れて、その数字で条件わけしてやればいいと思います。
今、1箇所から同じ方向に5つ弾が出て、途中でその5つが分岐するなら、
その5つに0~4の数字でもふってやり、その数字に応じてあるカウント数になったら、
角度を変えてみてはどうでしょう?
Re:誰か教えてください。
そう言えばそうですね
私は定数項を変更する方法を使う事が多いのでこのような処理にしました
どうも私は例外処理に対して排他的な処理を行ってしまう癖が・・
やはり登録時に変更角度を渡した方が良いかもしれませんね・・
「マジックナンバー」と言う言葉の意味がよく分りませんが確かに脈絡は無いですね・・
私のコードはこんな感じの処理ばっかりですけど
気付かないうちにマジックナンバーだらけになってしまっていたのか・・
私は定数項を変更する方法を使う事が多いのでこのような処理にしました
どうも私は例外処理に対して排他的な処理を行ってしまう癖が・・
やはり登録時に変更角度を渡した方が良いかもしれませんね・・
「マジックナンバー」と言う言葉の意味がよく分りませんが確かに脈絡は無いですね・・
私のコードはこんな感じの処理ばっかりですけど
気付かないうちにマジックナンバーだらけになってしまっていたのか・・
Re:誰か教えてください。
よく回答の流れを見ずに書き込んだら思いっきり不適切なコメントしてしまいました(汗
確かにマジックナンバーを多用すると効率が悪くなる場面が多いと思いますが、
まずは弾幕が作れるようになってから、効率面を考えてもいいのでは無いかなと思います。
そして効率面を追及していくと解り易いと思います。
まぁ今回位の規模でしたらどちらでもいいかもしれませんね。
確かにマジックナンバーを多用すると効率が悪くなる場面が多いと思いますが、
まずは弾幕が作れるようになってから、効率面を考えてもいいのでは無いかなと思います。
そして効率面を追及していくと解り易いと思います。
まぁ今回位の規模でしたらどちらでもいいかもしれませんね。
Re:封魔陣の作り方
封魔陣に挑戦してみました。
}
//弾を発射する関数 void boss_bullet_on(int way,int knd,int col,int flag,double x,double y,double size,double b_angle,double d_angle,double spd,int state,int till){ int i=0,k; for(i=0;i<way;i++){ if((k=search_boss_shot())!=-1){ boss_shot.bullet[k].knd = knd;//弾の種類 if(knd==7) boss_shot.bullet[k].kaiten=1; else boss_shot.bullet[k].kaiten=0; boss_shot.bullet[k].col = col;//弾の色 boss_shot.bullet[k].flag = 1;//flag;1だと当たり判定あり、2だと当たり判定なし boss_shot.bullet[k].cnt = 0; boss_shot.bullet[k].x = x;//座標 boss_shot.bullet[k].y = y; //boss_shot.bullet[k].size = size;弾の大きさ(今は意味なし) boss_shot.bullet[k].angle = b_angle+d_angle*(i - way/2);//角度:bが基準、dが間隔 boss_shot.bullet[k].spd = spd;//スピード boss_shot.bullet[k].state = state;//弾の状態 boss_shot.bullet[k].till = till;//弾が画面外に出ても消えない時間 se_flag[0]=1; } } } //封魔陣のようなもの void boss_shot_bulletH000(){ int i,t=boss_shot.cnt; static double ang=PI/16; if(t==0){ boss.hp_max=150000; boss.hp =30000; } if(t%15==0){ for(i=0;i<5;i++){ boss_bullet_on(8,5,1,1,boss.x,boss.y,1,ang,PI2/8,3,i+1,0); } } if(t>100){ if((t+100)%800<400) ang+=PI/(32*60); else ang-=PI/(32*60); if(t%150==0){ boss_bullet_on(32,10,1,1,boss.x,boss.y,1,bossatan2(),PI2/32,6,6,0); } if(t%100==0){ boss_bullet_on(16,1,0,1,boss.x,boss.y,1,bossatan2()+PI,PI/16,3,7,0); } } for(i=0;i<BOSS_BULLET_MAX;i++){ if(boss_shot.bullet.flag>0){ switch(boss_shot.bullet.state){ case 1: if(boss_shot.bullet.cnt==30 || boss_shot.bullet.cnt==60) boss_shot.bullet.angle-=PI/4; break; case 2: if(boss_shot.bullet.cnt==30 || boss_shot.bullet.cnt==60) boss_shot.bullet.angle-=PI/8; break; case 4: if(boss_shot.bullet.cnt==30 || boss_shot.bullet.cnt==60) boss_shot.bullet[i].angle+=PI/8; break; case 5: if(boss_shot.bullet[i].cnt==30 || boss_shot.bullet[i].cnt==60) boss_shot.bullet[i].angle+=PI/4; break; case 6: if(boss_shot.bullet[i].cnt<30){ boss_shot.bullet[i].spd-=0.2; } if(boss_shot.bullet[i].cnt==120){ boss_shot.bullet[i].knd=6; boss_shot.bullet[i].spd=2; } break; //陰陽玉の代わり //通常時は赤く、当たり判定があるが //低速時は青く、当たり判定がない case 7: if(CheckStatePad(configpad.slow)==0){ boss_shot.bullet[i].flag=1; boss_shot.bullet[i].col=0; } else{ boss_shot.bullet[i].flag=2;//当たり判定がない boss_shot.bullet[i].col=1; } if(boss_shot.bullet[i].cnt<60){ if(cos(boss_shot.bullet[i].angle)>0){ boss_shot.bullet[i].angle+=PI*2/(3*60); } else{ boss_shot.bullet[i].angle-=PI*2/(3*60); } } if(boss_shot.bullet[i].x<16 || FMX-16<boss_shot.bullet[i].x){ boss_shot.bullet[i].angle=PI-boss_shot.bullet[i].angle; } break; } } }
}
Re:封魔陣の作り方
・・・被ってしまいました><
すみません;
自分も作ってみました。
変な処理をしているかもしれませんw
妥協したところが多々有りです・・・
60章を元に作成しました。
boss_shotH.cppにこの関数を追加し、func.hを少し変更すると動くと思います。
後、Tatu様のようにstateはswitchで扱ったほうが良いですね;
どこか分からないところ、おかしなところがあったら言ってください;
#追記
#一部編集しました
すみません;
自分も作ってみました。
変な処理をしているかもしれませんw
妥協したところが多々有りです・・・
60章を元に作成しました。
boss_shotH.cppにこの関数を追加し、func.hを少し変更すると動くと思います。
後、Tatu様のようにstateはswitchで扱ったほうが良いですね;
どこか分からないところ、おかしなところがあったら言ってください;
#追記
#一部編集しました