2006年3月7日の日記

<2006/03/08 2006/03/06>

キャラを動かす続き

今日は押すアルゴリズムの改良と行動タイプ"Random"を実装しました。

押すアルゴリズムは、昨日作ったものだとキャラが沢山いたとき再帰呼び出しで無制限に次のキャラに動くよう促し続けると、袋小路などで「お前がどけ」「そっちこそ邪魔だ」の無限ループが発生し、フリーズすることがあったので、再帰呼び出しに制限を設け、一定回数以内の処理で動けなければその方向には移動できないということで解決しておきました。
一度これを呼び出し回数ではなく再帰の深さで判定するようにしていたのですがそうすると処理回数が4深さのオーダーで増えて、飛び出し回数で制限したときと同じ1024回で打ち切りにできるようにするには押せるキャラクターは高々5人程度になってしまい、人ごみをかき分けて進むようなネタが使えなくなってしまうことがわかったので、元の呼び出し回数式に戻しました。
再帰の深さを使ったバージョンは確実に動く人数を制限できるため、打ち切り深さを1から始めて順に深くしていけば動く人数を最小限に抑えることが可能だったはずなのですが、ちょっと袋小路の中に30人ほど人がいたら処理回数は10億回程度になりますからね、とてもじゃないが使い物になりません。
一方処理回数で打ち切る方式は適当に次々呼び出してどこかで道が開けた時点で処理終了になるのでどんなに遠回りだったとしても呼び出した経路上にいた人全員が動き出し、一人を動かすつもりが百人以上ごそっと動き出すこともしばしばです(もちろん数百人が密集していた場合だけですけどね)。
この方式だと呼び出し回数が確実に1024以下になるため、CPU負荷はそれほどかかりません。
まれに処理回数が1024に達してしまうほどの遠回りをして打ち切られることもありますが、その場合はそのフレームでは移動を諦めて、次のフレームで改めで最初から処理を開始すれば、動けるなら今度こそ高い確率で動けるでしょうし、動けなければ高々1024回の処理の後に何もしないだけです。

で、行動タイプ"Random"は、次の動きを決めるフレームでは上下左右に動くか、あるいは何もしないか、をランダムで決めます。
しかし今考えると、RPGの場合、話しかけられたら止まらなければいけません。
"Random"にしたキャラクターは結構せわしなく動くので一時的に行動タイプを"Still"などにして止めなきゃならないんですが(キャラは行動タイプを与えると勝手に動くので外部から制御するには行動タイプを変更するしかない)、そのあとはまた本来のキャラの動きに戻す必要があるので、行動タイプを変更するときは前の行動タイプを、関連する変数と共にスタックにつんでおかなければいけません。
つまり、動作とデータをひとまとめにして扱う必要があるのです。
これって…オブジェクト指向にする理由に一致するよね?
というわけで行動決定アルゴリズムはクラスにすること決定。
数が多いので少し面倒くさそうですが。

ダウンロードページのギャラリーに開発中の画像を公開し始めました。

<2006/03/08 2006/03/06>