ページ 1 / 1
STGの弾ごとの当たり判定
Posted: 2011年3月06日(日) 23:14
by YYSS
STGの敵弾のバリエーションを増やしたくて、いままで中サイズだけだったのを
以下のように小・中・大にまとめたのですが
Shot_S[8]
Shot_M[8]
Shot_L[8]
配列名が弾のサイズ
数値が弾の色(赤・橙・黄・緑・水・青・紫・白)
当たり判定の処理で区別の仕方が分かりません・・・
いままではサイズが1種類だけだったので
コード:
int ShotSize =6;
int PlayerSize =3;
double xx = Player.X - Shot[p].X;
double yy = Player.Y - Shot[p].Y;
double Span = hypot( xx, yy );
//距離で判断
if( Span <= ( ShotSize + PlayerSize ) ){
~処理~
}
とやっていたのですが、これだと弾の種類関係なく同じ当たり判定になってしまうので
Shot_Sだったら「3」
Shot_Mだったら「6」
Shot_Lだったら「9」
といった感じにしたいのですが、配列の比較がうまく出来ません
何かいい方法はないでしょうか?
~開発環境~
○Windows 7 Ultimate SP1
○Visual C++ 2010 Express
○DXライブラリ使用
Re: STGの弾ごとの当たり判定
Posted: 2011年3月07日(月) 12:39
by ookami
こんにちわ。ookamiです。
クラスか構造体かわかりませんが、
Shot[p].X
Shot[p].Y
に加えて
Shot[p].R
のようなメンバを加えて管理するのが良いと思います。
弾の初期化時に
Shot[p].R=3 (とか6とか9とか)
などと代入して、
if文のShotSizeの代わりにShot[p].Rを使う。
いかがでしょう。
Re: STGの弾ごとの当たり判定
Posted: 2011年3月07日(月) 20:30
by YYSS
ookamiさんありがとうございます。
その方法も考えたのですが、弾の種類から当たり判定を自動的に判断してくれるようにしたいのです。
弾の種類と当たり判定を別々に指定して定義すると、
弾の種類を変えたときに、当たり判定を変え忘れて不具合を作りやすくなってしまうような気がして;;
いま考えているのは、初期化で弾の種類を、構造体Shot[p].Graphに格納し
コード:
for( int i = 0 ; 1 < 8 ; i++ ){
if( Shot[p].Graph == Shot_S[i] ){
Shot[p].R = 3;
break;
}
else if( Shot[p].Graph == Shot_M[i] ){
Shot[p].R = 6;
break;
}
}
というのを考えたのですが、なんか無駄が多いような気がして・・・
弾が何百と出現したときに重くなってしまいそうで、もうすこし簡潔にしたいのですが、これ以上は無理でしょうか?
Re: STGの弾ごとの当たり判定
Posted: 2011年3月07日(月) 20:49
by xxx
>弾の種類から〜
添字を弾の番号と対応させればできます
何百程度ならすぐに終わりますよ
ゲーム中に当たり判定が変わることがないならゲーム開始時に初期化するだけで済みますし大丈夫です
あとそのコードでbreakはcontinueであるべきじゃないでしょうか。
Re: STGの弾ごとの当たり判定
Posted: 2011年3月07日(月) 21:41
by Tatu
こういうふうにしたらどうでしょうか?
Shot[p]のメンバ変数に
kind//弾の種類を表す
color//弾の色を表す
を加える。
小・中・大それぞれの当たり判定を
int shot_size[3]={
3,6,9
};
とし、
当たり判定を行うときに
ShotSize= shot_size[Shot[p].kind];
とする。
描画関数は
DrawGraph(Shot[p].x,Shot[p].y,image_shot[Shot[p].kind][Shot[p].color],TRUE);
などのようにする。
Re: STGの弾ごとの当たり判定
Posted: 2011年3月07日(月) 22:59
by MNS
初期化の処理なら、それで構わないと思いますよ。
その程度なら大した負荷にはなりません。千発でても大丈夫でしょう。
私も反発半径はメンバ変数として持たせるべきだと思います。
処理の負荷を心配するなら、むしろ衝突判定の処理のほうを変えるべきでしょう。
hypot関数はsqrt関数が使われていて、こいつは負荷が大きいことで有名です。
if( Span <= ( ShotSize + PlayerSize ) ) これは次の処理と等価です。
⇒ if( sqrt(xx*xx + yy*yy) <= ( ShotSize + PlayerSize ) )
a ≦ bのとき、a≧0, b≧0ならば、a*a ≦ b*bということは決まっているので、
(加えてxx*xx + yy*yy、ShotSize+PlayerSizeは必ず正かゼロです)
ですから、次のように書くと高速化できます。
if( (xx*xx+yy*yy) <= (ShotSize+PlayerSize)*(ShotSize+PlayerSize) )
余談でしたが、負荷で困っているなら実装するとわりかしいい効果を出すかもしれません。
Re: STGの弾ごとの当たり判定
Posted: 2011年3月08日(火) 23:23
by YYSS
色々な意見をどうもありがとございます!
>>roxion1377さん
breakで良いと思うのですが?
当たり判定が確定したら、ループを続ける意味は無いと思うので
>>Tatuさん
2次元配列は、弾の種類が直感的に分からないという面で避けていたのですが、
意外とそうでもない気がしますね
ありがたく参考にさせてもらいます。
>>MNSさん
sqrtが重いというのは始めて聞きました;;
sqrtを使わない判定式も試してみようと思います。
アドバイスありがとうございます。