nWayショット


 シューティングにおいて、自機狙い弾の次に基本的なアルゴリズムです。

では図で見てみましょう。



 左側はnが偶数のとき、右側が奇数のときです。
 文字が入っているのは与えられる引数を示しています。これを参考にして引数を考えてみましょう。理想的にするため、データ結合です。
宣言 int getNWayData( vector<HPLVector2> *vdistpos, vector2<HPLVector2> *vdistvel, HPLVector2 basepos, HPLVector2 basevel, float delta, float distance, int n)
返り値 成功すれば0、失敗すれば負数。エラー処理は自分ですること。
引数説明 *vdistpos 結果得られた弾の位置
*vdistvel 結果得られた弾の方向
basepos 基本位置
basevel 基本方向
delta 間隔角度 ( allrange として delta = allrange / (n-1) としてもよい。n==0のチェックはすること!)
distance 発射位置は中心とは限らないので用意。中心からの距離
※HPLVector2 は2次元ベクトルを扱うクラスです。CVector2とかありましたが、それと同じで(x,y)のデータを持ち、いくつかの演算ができるようになっています。

では関数を作っていきましょう。

int getNWayData( vector<HPLVector2> *vdistpos, vector2<HPLVector2> *vdistvel, HPLVector2 basepos, HPLVector2 basevel, float delta, float distance, int n){
  vdisvel->clear();
  vdistpos->clear();

  if( n <= 0){
    return  -1;
  }
 まずは忘れていけないエラー処理。できる人は例外をはくようにするでしょう。でも divide ZERO じゃないので自分で assert なりしたほうがいいかもね。

  if( n / 2 == 1){
    HPLVector2 vel = basevel;
    HPLVector2 pos = basepos;
    //長さを1にする
    vel.normalize();
    pos += vel * distance;
    vdistpos->push_back( pos);
    vdistvel->push_back( vel);
  }
 奇数ならば基本方向のものも必要なので別で用意しましょう。後で普通のものと一緒にやってもいいですが、2つになったりと面倒になるのでこっちでやりました。
 ちなみに int 型は割ると結果も int なのです。

  int i;
  for( i = 0; i < n / 2; i ++){
    int j;
    for( j = -1; j < 2; j += 2){
      HPLVector2 vel;
      HPLVector2 pos = basepos;
      //角度にする
      float basedegree = basevel.vectorToDegree();
      float degree = basedegree + j * i * delta;
 さて、核心部分です。まずは方向を角度で考えるようにしましょう。

      if( n / 2 == 1){
        degree += j * delta;
      }else{
        degree += j * delta / 2;
      }
      //ベクトルに戻す
      vel.setByDegree( degree);
      pos += vel * distance;
      vdistpos->push_back( pos);
      vdistvel->push_back( vel);
    }
  }
  return 0;
}
 もう一度図を見てみましょう。中心からの位置が n が偶数と奇数の時とで微妙に違います。n が偶数のときは開始位置が ±delta / 2 で、奇数の場合は基本方向をすでに作っているので±delta となります。

以上で nWayは完成です。



1 1