2009年12月24日 (木) 【YOSHI】第1回:手描きMAPについて

皆様、初めまして。

世界樹の迷宮IIIのチーフプログラマーの小森祥弘(コモリヨシヒロ)です。
ディレクターの小森と苗字が同じで紛らわしいので、開発では「ヨシ」、「ヨシさん」、「ヨシ君」などと呼ばれています。
世界樹の迷宮IIでは開発ツール周りのサポートを、直前にはデビルサバイバーのプログラムをしていました。
今作の主な担当箇所はダンジョン、イベント、航海、ダンジョン下マップ、海図です。
また海外生活が長かったので英語担当だったりもします。施設名の英語表記を考えたり、他のラインの英語の歌詞を書いたりもしてます。

世界樹の迷宮IIIのプログラムですが、今回から社内開発になりました。
世界樹の迷宮IIやデビルサバイバーのライブラリ部分を引き継ぎつつ、ゲーム部分のソースはほぼ全て新規作成しました。
世界樹の迷宮シリーズらしさを残しつつもより快適に、高速に、グラフィックやサウンドデータのメモリを増やし、12x12のサイズのフォントも追加し、その分のメモリはプログラムソースを削ることで帳尻をあわせ、その上処理負荷も軽減する、そんな(プログラマー以外の)全ての人が幸せになれるプログラムを開発してきました。

まだこれから何度かここに書かせてもらう機会もあると思うので、今回は主に手描きマップについて書こうと思います。
手描きマップに関しては前作の時点で基本的な機能は完成していたので、主に手触りや書き消しのしやすさの向上を目指しました。
要素的には「壁を書く」、「壁を消す」、「床を塗る」、「床を消す」、「アイコンを置く」という5つの機能があります。
まず「壁を書く」機能に関しては基本的に前作をベースに、当たり判定を2ドットぐらい拡げたのと、どの方向から書いても同じように書けるように調整しました。

「壁を消す」機能は個人的に一番こだわりました。
書いた壁を消していてたまに消しづらいと思うことがあったので、いろいろと検証してみました。

テストケースとして画面を全て縦線で埋めます。



で、画面左端から右端まで角度をつけて消しゴムで消すと、当然こんな感じになってほしいわけです。



なのですが、実際には



のようにところどころ消されずに線が残ってしまい、少し残念な感じがします。

理論上は必ずどこかの縦線をまたいでいるはずなのですが、実際には1フレームの間に複数の壁をまたぐことが可能らしく、毎フレーム判定を入れるだけでは判定を抜けられることがあることがわかりました。
なので、毎フレーム判定を入れる方式から、前回と今回のフレームを直線で結び、その間を消すというアルゴリズムに変更することにしました。
一言に前回と今回のフレームを直線で結ぶ、と言っても右方向だったり、左方向だったり、斜めだったり、ちょうど角を通っていたりということで、いろんなパターンがあります。
普通に実装すると複雑で、ソースの量も多く処理負荷もかかりそうです。
何かうまい方法はないかなーとしばらく考えた結果、いいアイデアを思いつきました。
Bresenhamアルゴリズムです。
このアルゴリズムはグラフィックプログラミングの基礎中の基礎のアルゴリズムで、四角いドットで構成された画面に直線を引く際に割り算を使わず、全て整数で計算できるというシンプルで高速なアルゴリズムです。
下マップの17ドットx17ドットで構成される1マスを1ドットと見なせばBresenhamアルゴリズムがそのまま適用できるのではないかと思い、実装してみると非常にうまくいきました。
思い描いていた通り、左から右に消しゴムを走らせると、その軌跡がきちんと消えてくれます。
画面を全て壁で埋め尽くしても、消しゴムでさらっと撫でるだけできれいに消えてくれます。
「壁を消す」だけでなく、「床を塗る」、「床を消す」というのもこのBresenhamアルゴリズムが適用できたので、これだけで下マップのほとんどの機能が実装できてしまいました。
このアルゴリズムのおかげで手描きマップは、快適で処理負荷もかからず、ソースも短く実装も楽な、僕も含めてみんなが幸せなプログラムになりました。

ちょっとマニアックな話になってしまいましたが、さらに進化した手描きマップ、是非体験してみてください。



※>モバイルでご覧いただいている皆様
画像はPCにてご覧いただけます。