実時間 〜時間で動かす〜 99/11/20

ゲームでは、「メインループ」というものがあって、それが何度も呼び出されることによって
ゲームが進んでいきます。メインループを一度呼び出すことを「フレーム」ということにします。

たとえば、
「動くもの」があるとします。名前は「ぽく」にしておきます。
こいつは、フレーム毎に「右に2ドット」ずつ動きます。
これを何度も繰り返すことによって、「ぽく」は右に動いていきます。
当たり前ですね。

注意しなければならないのは、この時「ぽく」はパソコンの速度によっては速く動いたり、
遅く動いたりするということです。理由は簡単で、パソコンが速ければ一定時間毎にメインループが
多く呼び出されるし、遅ければ逆に呼び出されることが少なくなるからです。

PlayStation、Nintendo64などのいわゆるコンシューマ機では、速度に違いはないようなので、
内部では時間で計算している、というのが多いと思いますが、
(PlayStationでは結構違ったりするらしいが)上記のようなことを気にする必要はほとんどありません。
しかし、パソコンでは「環境の違い」があるので、上記のことを全く無視するわけにもいきません。
というわけで、この「環境の違い」をなんとか最小限に押さえてみたいと思います。
「別にそんなことどうでもいいよ」と思う方はここから先は読んでも仕方がありません(^^;)

上記の「1フレーム毎の速さ」では環境依存してしまいます。
ということは、環境に依存しない「平等な」単位が必要になります。
さて、何があるかなー、と思ったら「時間」というものがあるんですねー。
詳しいことは分かりませんが、「時間」は環境による影響はほとんどないと考えていいので、
これを使うことにしましょう。時間の取り方については こちらの最後のほうをご覧ください。

それでは、実時間での動かし方を考えていきましょう。

まずはもっとも簡単な移動、「等速直線運動」ってやつで考えてみます。
「等速直線運動」ってのは確か高校の物理で習うもので、読んで字のごとく
ずっと同じ速度でまっすぐに進む、というやつです。

式を立てるとすれば、
p'(移動後の位置)=p(移動前の位置)+v(速度)×t(時間)・・・(1)
だったとおもいます。非常にシンプルな式ですね。

「t(時間)」というのは、「1フレーム実行するのにかかった時間」です。
もちろん、フレーム毎に調べなければなりませんね。
「v(速度)」というのは、具体的にいえば「単位時間に進む距離」ですね。
ここで「単位時間」っていうのが曲者です。

「単位時間」をミリ秒(ms)にするときを考えてみてください。
v=2 ピクセル/ミリ秒
という小さな値を設定しただけでも、一秒間に2000ピクセルも移動してしまいます。
これだと、キャラクタが一気にぶっとんでしまって、何が起こっているのかよく分からない、
ということになります。ということで、単位時間をミリ秒(ms)にするのはあまりよくないようです。

それでは次に単位時間を「秒」で考えてみましょう。
v=2 ピクセル/秒
とすると、今度は一秒間に2ピクセル進むことになりますね。
これはかなりの低速となります(試せば分かると思います)。

それでは、単位時間を「秒」に設定したときの問題点をあげてみます。
こちらで説明した「getTickCount」「timeGetTime」関数は
Windowsが起動してからの経過時間を「ミリ秒」単位で返すものでしたね。
ということは、「ミリ秒 → 秒」の変換が必要となります。

「ミリ秒」というのは「一秒の千分の一」、つまり「1000 ms = 1 s」という関係がありますので、
かんたんに変換できます。単位時間を「秒」に設定したとき、式(1)は

p'(移動後の位置)=p(移動前の位置)+v(速度)×t(時間)/1000・・・(1)'

となりますね。長々と説明しましたが、式に直すと結局これだけのものです。
それにもかかわらず、ここまで説明したのはみなさんが実時間を使っていろいろな処理が
できるようになってほしいからです。基本さえしっかりとおさえておけば
どんなふうにでも応用することは可能なのです。
円運動なども結局等速直線運動を利用すればいいだけですし、ね。








もどる