【コード】[追記]n-way弾の実装

[追記は一番下]

偶数パターンの n-way 弾
偶数n-way

奇数パターンの n-way 弾
奇数n-way

n-way 弾の実装が完了しました。
弾を生成するコードも前に比べてスッキリしたように思います。
もっとスッキリ書けるのではないかと思い、
ソース付きで n-way 弾の生成アルゴリズムを探してたのですが
概念的なお話が多かったように思います。

n-way 弾のポイントは、n-way 弾の中心角度、弾と弾の間隔、
そして偶数パターンか、奇数パターンかだと思います。
0度を右方向、90度を下方向、180度を左方向として説明します。

まず、n-way 弾の中心角度(BaseAngle)を決めます。
固定でもいいですし、自機と敵の角度を取得しても構いません。
ここでは説明のために180度をベースに、弾の間隔が30度の5way弾を撃つ事にしましょう。

ベースが180度で、30度の間隔、5方向に発射と言う事は
弾の角度はそれぞれ[ 240度, 210度, 180度(ベース), 150度, 120度 ] と言う事になります。

単純に、生成する時に一番端の角度(240度)が解れば
それに沿って30度ずらしながら生成するだけで5way弾が発射できます。


// 一番端の角度を計算
float 一番端の角度 = BaseAngle + WayNum/2*ChangeAngle;

この式を展開すると「 180度 + 5way/2 * 30度 」と言う事になります。
計算すると 180 + 2 * 30 = 240 となり端の角度が求まります。
(5way/2 が2.5にならないのは整数の計算だからです)

で、この240度から変化分を引いていって WayNum 分ループさせていけば弾の生成は完了です。

for(int i=0; i<WayNum; ++i, 一番端の角度 -= ChangeAngle)
  NWayCreate(一番端の角度を渡して生成);

これで毎ループ、一番端の角度-=ChangeAngle が実行され
[ 240度, 210度, 180度, 150度, 120度 ] の角度が得られて生成出来ます。


では、偶数パターンについて上の式を適用してみます。
同じく180度をベースに、弾の間隔が30度の6way弾を撃つ事にしましょう。

ベースが180度で、30度の間隔、6方向・・・
奇数パターンの場合は真ん中に発射する弾があったので変化角度分ずらすのは簡単でした。
偶数はベースの角度に配置されません。
なぜならベースを境に左右できっちり別れるからです。

と言う事は弾の角度はそれぞれ
[ 255度, 225度, 195度, 170度, 140度, 110度 ]と言う事になります。
ベースを通らない弾の生成が必要な訳です。

丁度中心の角度計算が出来ればさほど難しいものではありませんが、
奇数よりちょっとややこしいです。

// 一番端の角度を計算
float 一番端の角度 = BaseAngle + WayNum/2*ChangeAngle - ChangeAngle/2: ;

偶数パターンの計算式から、ChangeAngle/2 を引いている所がポイントです。
ベースである180度のお隣を見て貰えれば
ベースの次の角度が「195度」ですので、30度の変化ではなく15度のため
ChangeAngle/2 引かないといけません。

この式を展開すると「 180度 + 6way/2*30度 - 30度/2 」と言う事になります。
計算すると 180 + 3*30 - 15 = 255 となり、これで偶数パターンの端の角度が求まります。

8way でベースが同じく180度、変化角度が20度の場合はこうなります。
「 180度 + 8way/2*20度 - 20度/2 」
計算すると、180 + 80 - 10 = 250 となり、やはり端の角度が求まります。


生成する関数は、端の角度から変化分引いていくループなので、
生成する関数は偶数パターンと同じです。
変わるのは、求める端の角度だけです。

float 一番端の角度 = (WayNum%2) ? BaseAngle + WayNum/2*ChangeAngle : BaseAngle + WayNum/2*ChangeAngle - ChangeAngle/2;

for(int i=0; i<WayNum; ++i, wEndAngle-=ChangeAngle)
{
  NWayCreate(一番端の角度を渡して生成);
}


一番端の角度 = (WayNum%2) とすることで、条件分岐し、偶数・奇数パターンでの端の角度が代入されます。


と言う訳で今回は n-way 弾の実装でしたがこんな感じで実装出来ますよと言う一例でした。
ではでは、外は雨でしょうもないですが今回はこんな感じで!


[--- 追記 ---]
なんと・・・今回も神の啓示がありました。
Justy さん曰く「N-Wayは空間を N-1に分割するということ」だそうです。

例えば添付画像の上が6way、下が5wayになってますが、
「空間を N-1」と言うのは、この弾と弾の間の空間の数の事を指しています。

6wayだと弾と弾の間の空間は5つ。
5wayだと4つ、2wayだと1つあると言う事になります。

n-way 弾は、端の角度さえ解ってしまえば変化角度分ずらしながら Way数分ループすると言うのは
上で書いたとおりですが、端の計算方法が変わります。

上の記事だと、

float 一番端の角度 = (WayNum%2) ? BaseAngle + WayNum/2*ChangeAngle : BaseAngle + WayNum/2*ChangeAngle - ChangeAngle/2;

偶数パターンの場合と、奇数パターンの場合で条件分岐されてました。

Justy さんの計算方法は分岐を使うことなく端の角度を計算する方法です。

BaseAngle + (WayNum - 1)/2.f*ChangeAngle

空間を N-1 に分割すると言う発想があるからこそできる計算法です!
と言う訳で、条件分岐がなくなったため長々と書いた記事がこれ一発で終了になります。

float 一番端の角度 = BaseAngle + (WayNum - 1)/2.f*ChangeAngle;

上の例通り、180度ベースの5wayで30度ずつ変化の場合。
180度 + (5way - 1)/2.0f*30度
180 + 2.0*30 = 240度。

端の角度が出てきてますね!

もういっちょ、180度ベースの8wayで20度ずつ変化の場合。
180度 + (8way - 1)/2.0f*20度
180 + 3.5*20 = 250度。

やはり端の角度が計算されてます!
計算式一つで端の角度が出るなんて思わなかったので非常に勉強になりました!

改めて、Justy さんにお礼申し上げます!!
ほんと、いつもありがとうございますw

この記事へのコメント

- Justy - 2012年04月22日 14:59:07

 えーと、あんまり検証していないんで間違っているかもしれませんが、N-Wayは空間を N-1に分割するということなので
BaseAngle + (WayNum - 1)/2.f*ChangeAngle
で良かったりしません?

- DVDM♪管理人♪ - 2012年04月22日 19:44:24

>>Justy さん
またも返信ありがとうございます♪
今実行できる環境にいないですが、
これは確かに端の角度が求められますね!
way - 1 の空間と言う発想がなかったのでこれは熱い計算式です!

帰ったら早速追記させて頂きたいのですが宜しいでしょうか?

- Justy - 2012年04月22日 22:23:32

DVDMさん
>早速追記させて頂きたいのですが宜しいでしょうか?
 構わないですよ。

- DVDM♪管理人♪ - 2012年04月23日 01:55:27

>> Justy さん
早速記事に追記させて頂きました!
ありがとうございます♪

トラックバック

まとめwoネタ速suru - 2012年04月22日 14:51

まとめteみた.【【コード】n-way弾の実装】

偶数パターンのn-way弾奇数パターンのn-way弾n-way弾の実装が完了しました。弾を生成するコードも前に比うに思います。もっとスッキリ書けるのではないかと思い、ソース付きでn-way弾の生成アルゴリズムを探してたのです的なお話が多かったように思います。n-way弾のポイ?...

URL :

検索フォーム
プロフィール

DVDM

Author:DVDM
自作ゲームの開発過程ブログ。
赤髪愛なら誰にも負けない。

 
Pixiv バナー


ブロとも申請フォーム
最新記事
カテゴリ
最新コメント
最新トラックバック
RSSリンクの表示
リンク
ブロとも一覧