ページ 1 / 1
本編のオプションのホーミング弾の誘導について2
Posted: 2010年11月20日(土) 00:17
by LisetteLander
http://www.play21.jp/board/formz.cgi?ac ... &rln=65523
過去の質問です。誤って解決にチェックを入れてしまったためもう一度質問することにしました。
ISLe様の
>そのまま代入しないで、cshot[k].angleの元の値とatan2(y,x)の値を比較して回転方向(プラスマイナス)を求めて、一定値を加算(あるいは減算)すれば良いと思います。
これは具体的にどうすればいいのでしょうか?
なんだかんだいってできませんでした。
angleの値を比較して弾が今向いている方向と、atan2の敵の方角を比べて、左右どちらが近いかを比べて
angleの値を分岐させ、
一定の値を代入させ続けて、なめらかにホーミングさせる・・・というのであっているのでしょうか?
できないところは左右どちらから回転したほうが近いかなどはangleの最大値(一周の値)がわかっていないとできず
また角度に一定の値を代入させ続けるというのができませんでした。
目指しているものをと言うと
オプションが後方(y軸+方向)に発射する弾を、大きく左右に回って両脇から敵に命中させるというものです。
雰囲気以外まったくにてませんが
http://dixq.net/rp/30.html
こんな感じです。大きい水玉が誘導する感じです。
Re:本編のオプションのホーミング弾の誘導について2
Posted: 2010年11月20日(土) 01:01
by ISLe
前の質問に回答しましたが、角度はラジアンという単位で一周はPI*2です。
angleを更新したら合わせて移動量(vx,vy)も更新する必要があるかもしれません。
(目標座標-現在座標)と移動量(vx,vy)の二次元ベクトル同士で外積を計算して符号で回転方向を決めることもできますよ。
Re:本編のオプションのホーミング弾の誘導について2
Posted: 2010年11月20日(土) 08:23
by LisetteLander
>(目標座標-現在座標)と移動量(vx,vy)の二次元ベクトル同士で外積を計算して符号で回転方向を決めることもできますよ。
すいません、もう少しわかりやすくお願いします・・・
Re:本編のオプションのホーミング弾の誘導について2
Posted: 2010年11月20日(土) 08:45
by Tatu
一回の処理ごとの角度の変化
ラジアンは円弧と半径の比になります。
半径が1の円(単位円)の円周は2πだから一回転するときの角度は2πラジアンです。
というわけで一回転するには角度が2π変わるようにします。60FPSの場合、
一秒に60回だけ角度が変わっているということだから5秒間で一回転するようにするには
一回ごとの角度の変化量の大きさは 2π/(5*60) にすればよいことになります。
2πラジアン=360°
πラジアン=180°
π/2ラジアン=90°
π/3ラジアン=60°
π/4ラジアン=45°
π/6ラジアン=30°
とそれらの角度での三角比(sin,cos,tan)
ぐらいは覚えておいたほうがよいでしょう。
緩やかにホーミングさせる方法
弾から敵への方向はatan2(enemy.y-bullet.y,enemy.x-bullet.x)のように求めることができます。
そして、弾の進行方向はbullet.angleでわかります。そこで、これらの差をd = atan2(略) - bullet.angle、
また、曲がる角度をαとしてcos(d) > cos(α)のとき、弾の角度をatan2()と同じにする。
そうでないときはsin(d)が正のときは弾の角度にαだけ足し、
負ならばαだけ引くことにすればよいでしょう。
今回の場合は状態を表す変数を用意し、最初の状態では常に角度を同じだけ変化させ、
cos(d) > cos(α) または bullet.cnt>(適切と思える値)
の条件を満たしたときに状態を変え、それ以上角度を変えないようにする。
というようにすればよいのではないでしょうか。
Re:本編のオプションのホーミング弾の誘導について2
Posted: 2010年11月20日(土) 08:57
by LisetteLander
回答ありがとうございます。
bullet.angleですが、同じドキュメントの中にはなかったので
変数名が違うのでしょうか?
予想ではcshot[k].angleあたりが同じ働きだと思うのですが・・・
Re:本編のオプションのホーミング弾の誘導について2
Posted: 2010年11月20日(土) 09:18
by LisetteLander
b = atan2(y,x) - cshot[k].angle;
if(cos(b) > cos(2*PI/5*360)){
cshot[k].angle=atan2(y,x);
}else if(sin(b)>0){
cshot[k].angle += cos(2*PI/5*360);
}else if(sin(b)<0){
cshot[k].angle -= cos(2*PI/5*360);
}else{
cshot[k].angle=atan2(y,x);
}
自分なりにやってみた結果、このようになりました。
cshot[k].angle = bullet.angleと解釈し、
dは使われていたのでbを使用しました。
が、sin、cosの使い方を自分でもまだ理解していないのかオーバーロード関数の呼び出しエラーなどが出てきました。
Re:本編のオプションのホーミング弾の誘導について2
Posted: 2010年11月20日(土) 09:43
by Tatu
変数名は説明のため、てきとうにつけました。
オーバーロード関数の呼び出しエラーはおそらく
引数にint型が使われているからでしょう。
bの型は何ですか?
Re:本編のオプションのホーミング弾の誘導について2
Posted: 2010年11月20日(土) 09:59
by LisetteLander
intでした、doubleで宣言したら、玉が点滅というか、分裂して徐々に誘導するようになってました。
Spdの値を変えても点滅速度は変わらないようなので・・同じところをグルグル回ってるのでしょうか?
Re:本編のオプションのホーミング弾の誘導について2
Posted: 2010年11月20日(土) 10:19
by Tatu
分裂して見える理由はその通りでしょう。
プログラムをみると一回の処理毎の角度の変化量は2*PI/5 * 360
これで大丈夫ですか?
また、 cshot[k].angle += cos(2*PI/5*360);
となっていますが足すのは角度ではないですか?
Re:本編のオプションのホーミング弾の誘導について2
Posted: 2010年11月20日(土) 10:30
by LisetteLander
60秒という意味と360度の角度ですっとぼけていました。
>cshot[k].angle += cos(2*PI/5*360);
弾の角度にcosの角度を足したのですけど・・・
Re:本編のオプションのホーミング弾の誘導について2
Posted: 2010年11月20日(土) 11:30
by Tatu
>弾の角度にcosの角度を足したのですけど
弾の角度をPI/2だけ変えたいとき、正しい処理はどれかわかりますか?
a) cshot[k].angle += PI/2;
b) cshot[k].angle += cos(PI/2);
c) cshot[k].angle += sin(PI/2);
Re:本編のオプションのホーミング弾の誘導について2
Posted: 2010年11月20日(土) 11:36
by LisetteLander
l_a = (2*PI)/(5*60); //一定の角度(曲がる)
l_b = atan2(y,x) - cshot[k].angle; //敵への角度-弾の角度
if(cos(l_b) > cos(l_a)){ //もしも「弾の進行方向と敵への角度の差」が「曲がる角度」より大きかったら
cshot[k].angle=atan2(y,x); //敵への角度を弾の角度へ代入
}else if(sin(l_b)>0){ //弾の正面ではなく右寄りならば
cshot[k].angle += cos(l_a); //弾の角度に左向きに修正(angleに一定値を足す)
}else if(sin(l_b)<0){ //弾の正面ではなく左寄りならば
cshot[k].angle -= cos(l_a); //弾の角度に右向きに修正(angleから一定値を引く)
}else{ //弾が正面ならば引き続き誘導
cshot[k].angle=atan2(y,x);
}
このソースでは
弾が真っ先に敵を向き、回転・点滅しながら敵へ誘導され、速度は通常のものではなかった。
Re:本編のオプションのホーミング弾の誘導について2
Posted: 2010年11月20日(土) 11:38
by LisetteLander
>No:65568
回答は・・
a) cshot[k].angle += PI/2;
です・・
Re:本編のオプションのホーミング弾の誘導について2
Posted: 2010年11月20日(土) 11:42
by LisetteLander
できました!!!!
Tatu様、付き合ってくれてありがとうございます!
そりゃあ角度を変えたいのにcosごと代入しては値がわけのわからないことになりますよね。。
Re:本編のオプションのホーミング弾の誘導について2
Posted: 2010年11月20日(土) 17:32
by ISLe
double cross = (x-cshot[k].x)*cshot[k].vy-(y-cshot[k].y)*cshot[k].vx;
#vx,vyにangleに対応した移動量が入っているとみなしてます。
二次元ベクトルの外積です。
crossの符号で進行方向(vx,vy)に対して(x,y)が右寄りにあるか左寄りにあるか分かります。
真正面か真後ろのとき0です。