[HMC]年間5250円で独自ドメイン付属、ウィルスチェックありのレンタルサーバ!
Last update : 1999/12/13
ゲーム制作基礎 第4回
指定した角度の方向へキャラクタを動かす
サンプルコードのダウンロード
  では、まずサンプルコードをダウンロードし、解凍して下さい。 私はVisual C++6.0でコンパイルしているので、をお持ちの方は Visual C++でプロジェクトファイルを開いて下さい(「game_04.dsw」をダブルクリックすれば開けます)。 圧縮ファイルに含まれる「game_04.exe」をダブルクリックし、実行してみて下さい。どうでしょう?画面が切り替わり、フルスクリーン化すると思います。 そして、カーソルの左右で角度を変更でき、上でその角度の方向へキャラクタが移動すると思います。
三角関数のお勉強 ステップ1
  さて、三角関数とはなんぞや?という人のためにササっと解説してしまいます。 (高校2までに習うとは思いますが・・・)

左の図形を見て下さい。こういった直角三角形がある場合、

@ sinΘ=b/c
A cosΘ=a/c
B tanΘ=b/a

といった定義が存在します。ちなみに、@から順番に、サイン・コサイン・タンジェントと読みます。

ここでよくある(?)問題
A君は、とある木から10m離れた所で、地面に突っ伏し、そこから 丁度45度の角度でその木の一番高い所を見ていました。 さて、この木の高さは何mでしょう。

まぁ、この場合↑の図形で言う所のbが高さ、aが10m(木とA君の距離)ですね。 で、bを求めたくて、解っているのがaと45度という角度なのでBの「tanΘ=b/a」を使って解いてやればいいですね?

tan45°=b/10
b=tan45°×10
b=1×10
答え 10m

となります。 まぁ「tan45°」のように 解りやすい角度なら頭の中でも計算できますが「tan2°」だと、直ぐ答えれる人はなかなかいないでしょう(たぶん。 幸い、C言語にはあらかじめ、sin,cos,tanの関数が用意されているので、値を簡単に出せます。
三角関数のお勉強 ステップ2
  さて、基本が解ったところで(?)左のような半径1の円上にある点Pの座標(a,b)を表わすには どうすればいいでしょう(かなり強引)。
こいつらも三角関数を使用してやります。

まず、点pのX座標がa、原点から点pまでの長さが1(半径1より)という事で

cosΘ=a/1
a=cosΘ

となります。
同様に、点pのY座標がb、原点から点pまでの長さが1という事で

sinΘ=b/1
b=sinΘ

となります。よって、半径1の円上にある点Pの座標はP(cosΘ、sinΘ)と表わす事が出来るわけです。
三角関数のお勉強 ステップ3
さて、ここで問題(またかよー)。点P(cx,cy)がΘ°の方向へ1進んだ時の座標はどう表されるでしょう?
もうお分かりですね?半径1の円上にある点Pの座標はP(cosΘ、sinΘ)という事から、

P( cx+cosΘ , cy+sinΘ )

となりますね。また、進みたい距離が1ではなく t だとしたら

P( cx+cosΘ×t , cy+sinΘ×t )

という事になります。
C言語で三角関数を使用する方法
ここまでで、三角関数の基本はバッチリ身に付いたと思います(そんなことないってか?)。 C言語で三角関数を使用するには、まず「math.h」をインクルードしてやります(まぁ当たり前ですね)。

それでは「三角関数のお勉強ステップ3」をそのままC言語で表してみましょうか。
キャラクターの座標が cx , cy の時、 angle 度の方向へ t 進みたい場合、

と、なるはずですが、パソコンのディスプレイ上の y 座標は、下に行く程増加していく、つまり数学上の座標とはy軸の向きが反対になります。 ですから、

でOK・・・となるはずですが、まだです(爆
C言語の cos , sin 等の引数はラジアンという単位で指定しなければなりません。まぁラジアンについては私もよく知らないので数学の先生に聞いて下さい(爆。 とにかく180°はラジアンでπと表わされるので、 1°はπ/180ですよね?よって

これで、一応動作します(おぃ
ちょっとした高速化のお話
  さて、C言語で毎回 cos() , sin() とかを呼び出してごちゃごちゃ計算させるのは処理の無駄であり、 ゲームの速度を落とす原因となりかねません。ですから、ちょっと工夫して高速化させてやります。

と言っても、ただあらかじめテーブル作成しておくだけなんですけどね(爆
こいつらを作成してやれば

で済みます。ただ、角度angleは0〜359の範囲でないといけないし、 0.5といった少数で指定する事も出来なくなります。 ですが、シューティングゲームのように、速度重視且つ、 sin , cos で精度にあまりとらわれなくても良いような場合は テーブルでやった方が良いですね。
サンプルコードの解説
  では、サンプルコードを見てみましょう。

キャラクタの座標(cx,cy)はfloat型で宣言します (「int a=0; a+=0.5」とやってもaの値は0のままというのは当たり前ですからね)。 んー、まぁ後は大体上の方で説明したので解りますね?(手抜き)