[HMC]年間5250円で独自ドメイン付属、ウィルスチェックありのレンタルサーバ!
Last update : 1999/12/31
ゲーム制作基礎 第11回
自機の方向へ弾を撃つ&アニメーション基礎
サンプルコードのダウンロード
  では、まずサンプルコードをダウンロードし、解凍して下さい。 私はVisual C++6.0でコンパイルしているので、をお持ちの方は Visual C++でプロジェクトファイルを開いて下さい(「game_11.dsw」をダブルクリックすれば開けます)。 圧縮ファイルに含まれる「game_11.exe」をダブルクリックし、実行してみて下さい。どうでしょう?画面が切り替わり、フルスクリーン化すると思います。 そして、どこからか弾が沸き、自機(スライム)の方向へ飛んできますよね?
  というわけで、今回は角度の算出とアニメーションについて説明していきたいと思います。
三角関数のお勉強 その1
  第4回では、三角関数としてsin、cos、tanを説明しました。 しかし、これだけで、敵から、自機への角度を算出する事は出来ません。

そこで、今回はatan(アークタンジェント)というものを使用します。
普通のtanは

tanΘ=b/a

でしたが、アークタンジェントは

Θ=atan(b/a)

となります。要するに、タンジェントの逆算みたいな感じですね(ぉ。
三角関数のお勉強 その2
  というわけで、基本が解れば、あとは当てはめるだけですね。 左の図のように敵、自機が存在し、角度Θを求めたい場合、

Θ=atan((sy-my)/(sx-mx))

とすればいいですよね?
ただし、y/xが例えば1/1、-1/-1の場合、値は一緒ですよね? という事で、atanの返値Θも半分の180度周期になってしまいます。(ちなみにsin,cosは360度周期,sin(0)=sin(360)=sin(360*n))

そこで、x,yの符号を利用して、ある条件の時はΘに180を足すと言った処理が 必要になってきます。

また、xが0の場合、y/0=∞となってしまい、エラーとなってしまいます。これも 回避しなければなりません。
アークタンジェントをC言語で使用する
  C言語でアークタンジェントを使用したい場合は、「math.h」をインクルードした後、atan( double v ) を呼び出せば出来ます。 ただ、上でも書いたように、返ってくる角度Θは180度周期だったり、xが0だった場合に エラーとなったりします。で、いろいろ判定して正しい値を出そうとしがちですが、C言語には atan2( double y, double x) という関数が用意されています。この、yとxに値を引き渡してやると、 360度周期で角度を返してくれます。しかも、xが0の時の処理もしっかりやってくれるので便利です。

ただ、atanもそうですが、atan2の返値の単位はラジアンです(0〜360度=0〜2π)。 atan2の場合は-π〜+πまでが返ってくるので、 atan2の返値をπで割れば、-1〜+1までになりますよね? そしてπは180°ですから、その値に180を掛けてやると、 値は-180°〜+180°になりますね?
これに、360°を足し、360で割った余りを出すと、0〜359°の値が出てきます(疲。

こんな感じかな。
これで敵から自機への角度Θが出せますね?
サンプルコードの解説
今回のコードは、「第9回 キー入力によって弾を発射」 を少し改良し、ランダムに弾を作成し、自機の方向へ飛ばすようにします。弾の移動等、詳しい事は第9回を参照して下さい。

今回は、ついでに弾をアニメーションさせる事にするので、_bullet構造体にanimationという変数を 追加しておきます。

では、メインループを見てみます。

第9回と見た目が同じですが、Shoot()とMoveBullet()、Show()の中身を変更しています。(他は全部同じ)
ここでは、1/100の確立で適当な位置を出し、自機への角度を取得して、弾を作成しています。 rand()という関数は0〜RAND_MAXまでの乱数を返してくれるので、適当な値pで割った余りを出せば、 0からpのランダム値が出せます。

で、GetAngle(int mx,int my,int sx,int sy);関数は自作関数で、mx,myからsx,syまでの角度を算出します。 GetAngle(x+8,y+8,(int)player.x+16,(int)player.y+16);のx+8,y+8というように、ある値を足していますが、 自機などの座標は、画像の左端を表わしているため、画像の中心を表わすためには、画像サイズの半分の値を 足せばいいですよね?
この自作関数は上の方で説明したので解りますね(^^;

で、弾をアニメーションさせるためには、弾移動中にanimationの値をどんどん増やしていきます。
今回使用する画像はです。弾のアニメーションは12パターンありますよね? ですから、animationの値は0〜11の間を繰り返し変化するようにプログラムしてやります。

で、後は、このanimationの値をうまく画像に照らし合わせて画面に表示してやればいいわけです。 1つの弾の画像サイズが16×16で左にスライムが32ドットあるので、弾画像のx座標は32+16×アニメーションという事になりますよね?
まぁ、このアニメーションは、繰り返し行われる弾やら敵に限りますね。自機のようなキー入力によって 画像を変えたいときには使えませんね。
ってアニメーションくらいならいちいち説明しなくても解りますね(^^;簡単だし。